All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v5 7/9] k2hk: add support for k2hk SOC and EVM
Date: Thu, 3 Apr 2014 15:32:20 +0300	[thread overview]
Message-ID: <533D54D4.7050706@ti.com> (raw)
In-Reply-To: <1396377869-15724-8-git-send-email-m-karicheri2@ti.com>


On 04/01/2014 09:44 PM, Murali Karicheri wrote:
> From: Vitaly Andrianov<vitalya@ti.com>
>
> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
> refer the ti/k2hk_evm/README for details on the board, build and other
> information.
>
> This patch add support for keystone architecture and k2hk evm.
>
> Signed-off-by: Vitaly Andrianov<vitalya@ti.com>
> Signed-off-by: Murali Karicheri<m-karicheri2@ti.com>
> Signed-off-by: WingMan Kwok<w-kwok2@ti.com>
> Signed-off-by: Sandeep Nair<sandeep_n@ti.com>
> ---
>   Makefile                                           |   10 +
>   arch/arm/cpu/armv7/keystone/Makefile               |   17 ++
>   arch/arm/cpu/armv7/keystone/aemif.c                |   71 +++++
>   arch/arm/cpu/armv7/keystone/clock.c                |  318 ++++++++++++++++++++
>   arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124 ++++++++
>   arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 ++++++++
>   arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 +++++
>   arch/arm/cpu/armv7/keystone/init.c                 |   56 ++++
>   arch/arm/cpu/armv7/keystone/msmc.c                 |   68 +++++
>   arch/arm/cpu/armv7/keystone/psc.c                  |  238 +++++++++++++++
>   arch/arm/cpu/armv7/keystone/spl.c                  |   45 +++
>   arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++++++
>   arch/arm/include/asm/arch-keystone/clock.h         |   17 ++
>   arch/arm/include/asm/arch-keystone/clock_defs.h    |  111 +++++++
>   arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 +++++
>   arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  150 +++++++++
>   arch/arm/include/asm/arch-keystone/hardware.h      |  175 +++++++++++
>   arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 ++
>   arch/arm/include/asm/arch-keystone/nand_defs.h     |   23 ++
>   arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 ++++++
>   arch/arm/include/asm/arch-keystone/spl.h           |   12 +
>   board/ti/k2hk_evm/Makefile                         |    9 +
>   board/ti/k2hk_evm/README                           |  122 ++++++++
>   board/ti/k2hk_evm/board.c                          |  236 +++++++++++++++
>   board/ti/k2hk_evm/ddr3.c                           |  269 +++++++++++++++++
>   boards.cfg                                         |    1 +
>   drivers/serial/ns16550.c                           |    8 +
>   include/configs/k2hk_evm.h                         |  212 +++++++++++++
>   28 files changed, 2781 insertions(+)
>   create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
>   create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/init.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
>   create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
>   create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
>   create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
>   create mode 100644 board/ti/k2hk_evm/Makefile
>   create mode 100644 board/ti/k2hk_evm/README
>   create mode 100644 board/ti/k2hk_evm/board.c
>   create mode 100644 board/ti/k2hk_evm/ddr3.c
>   create mode 100644 include/configs/k2hk_evm.h
>
> diff --git a/Makefile b/Makefile
> index 25cbc95..27b85ed 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -868,6 +868,16 @@ OBJCOPYFLAGS_u-boot.spr = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
>   u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE
>   	$(call if_changed,pad_cat)
>   
> +MKIMAGEFLAGS_u-boot-spl.gph = -A $(ARCH) -T gpimage -C none \
> +	-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n SPL
> +spl/u-boot-spl.gph: spl/u-boot-spl.bin FORCE
> +	$(call if_changed,mkimage)
> +
> +OBJCOPYFLAGS_u-boot-spi.gph = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
> +			  --gap-fill=0
> +u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE
> +	$(call if_changed,pad_cat)
> +
>   ifneq ($(CONFIG_TEGRA),)
>   OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
>   u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE
> diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile
> new file mode 100644
> index 0000000..7924cfa
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/Makefile
> @@ -0,0 +1,17 @@
> +#
> +# (C) Copyright 2012-2014
> +#     Texas Instruments Incorporated, <www.ti.com>
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y	+= aemif.o
> +obj-y	+= init.o
> +obj-y	+= psc.o
> +obj-y	+= clock.o
> +obj-y	+= cmd_clock.o
> +obj-y	+= cmd_mon.o
> +obj-y	+= msmc.o
> +obj-$(CONFIG_SPL_BUILD)	+= spl.o
> +obj-y	+= ddr3.o
> +
> diff --git a/arch/arm/cpu/armv7/keystone/aemif.c b/arch/arm/cpu/armv7/keystone/aemif.c
> new file mode 100644
> index 0000000..9b26886
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/aemif.c
> @@ -0,0 +1,71 @@
> +/*
> + * Keystone2: Asynchronous EMIF Configuration
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/emif_defs.h>
> +
> +#define AEMIF_CFG_SELECT_STROBE(v)	((v) ? 1 << 31 : 0)
> +#define AEMIF_CFG_EXTEND_WAIT(v)	((v) ? 1 << 30 : 0)
> +#define AEMIF_CFG_WR_SETUP(v)		(((v) & 0x0f) << 26)
> +#define AEMIF_CFG_WR_STROBE(v)		(((v) & 0x3f) << 20)
> +#define AEMIF_CFG_WR_HOLD(v)		(((v) & 0x07) << 17)
> +#define AEMIF_CFG_RD_SETUP(v)		(((v) & 0x0f) << 13)
> +#define AEMIF_CFG_RD_STROBE(v)		(((v) & 0x3f) << 7)
> +#define AEMIF_CFG_RD_HOLD(v)		(((v) & 0x07) << 4)
> +#define AEMIF_CFG_TURN_AROUND(v)	(((v) & 0x03) << 2)
> +#define AEMIF_CFG_WIDTH(v)		(((v) & 0x03) << 0)
> +
> +#define set_config_field(reg, field, val)			\
> +	do {							\
> +		if (val != -1) {				\
> +			reg &= ~AEMIF_CFG_##field(0xffffffff);	\
> +			reg |=	AEMIF_CFG_##field(val);		\
> +		}						\
> +	} while (0)
> +
> +void configure_async_emif(int cs, struct async_emif_config *cfg)
> +{
> +	unsigned long tmp;
> +
> +	if (cfg->mode == ASYNC_EMIF_MODE_NAND) {
> +		tmp = __raw_readl(&davinci_emif_regs->nandfcr);
> +		tmp |= (1 << cs);
> +		__raw_writel(tmp, &davinci_emif_regs->nandfcr);
> +
> +	} else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
> +		tmp = __raw_readl(&davinci_emif_regs->one_nand_cr);
> +		tmp |= (1 << cs);
> +		__raw_writel(tmp, &davinci_emif_regs->one_nand_cr);
> +	}
> +
> +	tmp = __raw_readl(&davinci_emif_regs->abncr[cs]);
> +
> +	set_config_field(tmp, SELECT_STROBE,	cfg->select_strobe);
> +	set_config_field(tmp, EXTEND_WAIT,	cfg->extend_wait);
> +	set_config_field(tmp, WR_SETUP,		cfg->wr_setup);
> +	set_config_field(tmp, WR_STROBE,	cfg->wr_strobe);
> +	set_config_field(tmp, WR_HOLD,		cfg->wr_hold);
> +	set_config_field(tmp, RD_SETUP,		cfg->rd_setup);
> +	set_config_field(tmp, RD_STROBE,	cfg->rd_strobe);
> +	set_config_field(tmp, RD_HOLD,		cfg->rd_hold);
> +	set_config_field(tmp, TURN_AROUND,	cfg->turn_around);
> +	set_config_field(tmp, WIDTH,		cfg->width);
> +
> +	__raw_writel(tmp, &davinci_emif_regs->abncr[cs]);
> +}
> +
> +void init_async_emif(int num_cs, struct async_emif_config *config)
> +{
> +	int cs;
> +
> +	for (cs = 0; cs < num_cs; cs++)
> +		configure_async_emif(cs, config + cs);
> +}
> diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c
> new file mode 100644
> index 0000000..bfa4c9d
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/clock.c
> @@ -0,0 +1,318 @@
> +/*
> + * Keystone2: pll initialization
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm-generic/errno.h>
> +#include <asm/io.h>
> +#include <asm/processor.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/clock_defs.h>
> +
> +static void wait_for_completion(const struct pll_init_data *data)
> +{
> +	int i;
> +	for (i = 0; i < 100; i++) {
> +		sdelay(450);
> +		if ((pllctl_reg_read(data->pll, stat) & PLLSTAT_GO) == 0)
> +			break;
> +	}
> +}
> +
> +struct pll_regs {
> +	u32	reg0, reg1;
> +};
> +
> +static const struct pll_regs pll_regs[] = {
> +	[CORE_PLL]	= { K2HK_MAINPLLCTL0, K2HK_MAINPLLCTL1},
> +	[PASS_PLL]	= { K2HK_PASSPLLCTL0, K2HK_PASSPLLCTL1},
> +	[TETRIS_PLL]	= { K2HK_ARMPLLCTL0,  K2HK_ARMPLLCTL1},
> +	[DDR3A_PLL]	= { K2HK_DDR3APLLCTL0, K2HK_DDR3APLLCTL1},
> +	[DDR3B_PLL]	= { K2HK_DDR3BPLLCTL0, K2HK_DDR3BPLLCTL1},
> +};
> +
> +/* Fout = Fref * NF(mult) / NR(prediv) / OD */
> +static unsigned long pll_freq_get(int pll)
> +{
> +	unsigned long mult = 1, prediv = 1, output_div = 2;
> +	unsigned long ret;
> +	u32 tmp, reg;
> +
> +	if (pll == CORE_PLL) {
> +		ret = external_clk[sys_clk];
> +		if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) {
> +			/* PLL mode */
> +			tmp = __raw_readl(K2HK_MAINPLLCTL0);
> +			prediv = (tmp & PLL_DIV_MASK) + 1;
> +			mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) |
> +				(pllctl_reg_read(pll, mult) &
> +				 PLLM_MULT_LO_MASK)) + 1;
> +			output_div = ((pllctl_reg_read(pll, secctl) >>
> +				       PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1;
> +
> +			ret = ret / prediv / output_div * mult;
> +		}
> +	} else {
> +		switch (pll) {
> +		case PASS_PLL:
> +			ret = external_clk[pa_clk];
> +			reg = K2HK_PASSPLLCTL0;
> +			break;
> +		case TETRIS_PLL:
> +			ret = external_clk[tetris_clk];
> +			reg = K2HK_ARMPLLCTL0;
> +			break;
> +		case DDR3A_PLL:
> +			ret = external_clk[ddr3a_clk];
> +			reg = K2HK_DDR3APLLCTL0;
> +			break;
> +		case DDR3B_PLL:
> +			ret = external_clk[ddr3b_clk];
> +			reg = K2HK_DDR3BPLLCTL0;
> +			break;
> +		default:
> +			return 0;
> +		}
> +
> +		tmp = __raw_readl(reg);
> +
> +		if (!(tmp & PLLCTL_BYPASS)) {
> +			/* Bypass disabled */
> +			prediv = (tmp & PLL_DIV_MASK) + 1;
> +			mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1;
> +			output_div = ((tmp >> PLL_CLKOD_SHIFT) &
> +				      PLL_CLKOD_MASK) + 1;
> +			ret = ((ret / prediv) * mult) / output_div;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +unsigned long clk_get_rate(unsigned int clk)
> +{
> +	switch (clk) {
> +	case core_pll_clk:	return pll_freq_get(CORE_PLL);
> +	case pass_pll_clk:	return pll_freq_get(PASS_PLL);
> +	case tetris_pll_clk:	return pll_freq_get(TETRIS_PLL);
> +	case ddr3a_pll_clk:	return pll_freq_get(DDR3A_PLL);
> +	case ddr3b_pll_clk:	return pll_freq_get(DDR3B_PLL);
> +	case sys_clk0_1_clk:
> +	case sys_clk0_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(1);
> +	case sys_clk1_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(2);
> +	case sys_clk2_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(3);
> +	case sys_clk3_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(4);
> +	case sys_clk0_2_clk:	return clk_get_rate(sys_clk0_clk) / 2;
> +	case sys_clk0_3_clk:	return clk_get_rate(sys_clk0_clk) / 3;
> +	case sys_clk0_4_clk:	return clk_get_rate(sys_clk0_clk) / 4;
> +	case sys_clk0_6_clk:	return clk_get_rate(sys_clk0_clk) / 6;
> +	case sys_clk0_8_clk:	return clk_get_rate(sys_clk0_clk) / 8;
> +	case sys_clk0_12_clk:	return clk_get_rate(sys_clk0_clk) / 12;
> +	case sys_clk0_24_clk:	return clk_get_rate(sys_clk0_clk) / 24;
> +	case sys_clk1_3_clk:	return clk_get_rate(sys_clk1_clk) / 3;
> +	case sys_clk1_4_clk:	return clk_get_rate(sys_clk1_clk) / 4;
> +	case sys_clk1_6_clk:	return clk_get_rate(sys_clk1_clk) / 6;
> +	case sys_clk1_12_clk:	return clk_get_rate(sys_clk1_clk) / 12;
> +	default:
> +		break;
> +	}
> +	return 0;
> +}
> +
> +void init_pll(const struct pll_init_data *data)
> +{
> +	u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj;
> +
> +	pllm = data->pll_m - 1;
> +	plld = (data->pll_d - 1) & PLL_DIV_MASK;
> +	pllod = (data->pll_od - 1) & PLL_CLKOD_MASK;
> +
> +	if (data->pll == MAIN_PLL) {
> +		/* The requered delay before main PLL configuration */
> +		sdelay(210000);
> +
> +		tmp = pllctl_reg_read(data->pll, secctl);
> +
> +		if (tmp & (PLLCTL_BYPASS)) {
> +			setbits_le32(pll_regs[data->pll].reg1,
> +				     BIT(MAIN_ENSAT_OFFSET));
> +
> +			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
> +					   PLLCTL_PLLENSRC);
> +			sdelay(340);
> +
> +			pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS);
> +			pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN);
> +			sdelay(21000);
> +
> +			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
> +		} else {
> +			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
> +					   PLLCTL_PLLENSRC);
> +			sdelay(340);
> +		}
> +
> +		pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK);
> +
> +		clrsetbits_le32(pll_regs[data->pll].reg0, PLLM_MULT_HI_SMASK,
> +				(pllm << 6));
> +
> +		/* Set the BWADJ     (12 bit field)  */
> +		tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */

Don't see any reason in comment: /* Divide the pllm by 2 */
If need to mark out it, may pllm/2 be better.

> +		clrsetbits_le32(pll_regs[data->pll].reg0, PLL_BWADJ_LO_SMASK,
> +				(tmp_ctl << PLL_BWADJ_LO_SHIFT));
> +		clrsetbits_le32(pll_regs[data->pll].reg1, PLL_BWADJ_HI_MASK,
> +				(tmp_ctl >> 8));
> +
> +		/*
> +		 * Set the pll divider (6 bit field) *
> +		 * PLLD[5:0] is located in MAINPLLCTL0
> +		 */
> +		clrsetbits_le32(pll_regs[data->pll].reg0, PLL_DIV_MASK, plld);
> +
> +		/* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
> +		pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK,
> +			       (pllod << PLL_CLKOD_SHIFT));
> +		wait_for_completion(data);
> +
> +		pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1);
> +		pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2);
> +		pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3);
> +		pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4);
> +		pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5);
> +
> +		pllctl_reg_setbits(data->pll, alnctl, 0x1f);
> +
> +		/*
> +		 * Set GOSET bit in PLLCMD to initiate the GO operation
> +		 * to change the divide
> +		 */
> +		pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GO);
> +		sdelay(1500); /* wait for the phase adj */
> +		wait_for_completion(data);
> +
> +		/* Reset PLL */
> +		pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
> +		sdelay(21000);	/* Wait for a minimum of 7 us*/
> +		pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
> +		sdelay(105000);	/* Wait for PLL Lock time (min 50 us) */
> +
> +		pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS);
> +
> +		tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
> +
> +	} else if (data->pll == TETRIS_PLL) {
> +		bwadj = pllm >> 1;
> +		/* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */
> +		setbits_le32(pll_regs[data->pll].reg0,  PLLCTL_BYPASS);
> +		/*
> +		 * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass)
> +		 * only applicable for Kepler
> +		 */
> +		clrbits_le32(K2HK_MISC_CTRL, ARM_PLL_EN);
> +		/* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */
> +		setbits_le32(pll_regs[data->pll].reg1 ,
> +			     PLL_PLLRST | PLLCTL_ENSAT);
> +
> +		/*
> +		 * 3 Program PLLM and PLLD in PLLCTL0 register
> +		 * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in
> +		 * PLLCTL1 register. BWADJ value must be set
> +		 * to ((PLLM + 1) >> 1) ? 1)
> +		 */
> +		tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) |
> +			(pllm << 6) |
> +			(plld & PLL_DIV_MASK) |
> +			(pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS;
> +		__raw_writel(tmp, pll_regs[data->pll].reg0);
> +
> +		/* Set BWADJ[11:8] bits */
> +		tmp = __raw_readl(pll_regs[data->pll].reg1);
> +		tmp &= ~(PLL_BWADJ_HI_MASK);
> +		tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK);
> +		__raw_writel(tmp, pll_regs[data->pll].reg1);
> +		/*
> +		 * 5 Wait for at least 5 us based on the reference
> +		 * clock (PLL reset time)
> +		 */
> +		sdelay(21000);	/* Wait for a minimum of 7 us*/
> +
> +		/* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */
> +		clrbits_le32(pll_regs[data->pll].reg1, PLL_PLLRST);
> +		/*
> +		 * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1)
> +		 * (PLL lock time)
> +		 */
> +		sdelay(105000);
> +		/* 8 disable bypass */
> +		clrbits_le32(pll_regs[data->pll].reg0, PLLCTL_BYPASS);
> +		/*
> +		 * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass)
> +		 * only applicable for Kepler
> +		 */
> +		setbits_le32(K2HK_MISC_CTRL, ARM_PLL_EN);
> +	} else {
> +		setbits_le32(pll_regs[data->pll].reg1, PLLCTL_ENSAT);
> +		/*
> +		 * process keeps state of Bypass bit while programming
> +		 * all other DDR PLL settings
> +		 */
> +		tmp = __raw_readl(pll_regs[data->pll].reg0);
> +		tmp &= PLLCTL_BYPASS;	/* clear everything except Bypass */
> +
> +		/*
> +		 * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0,
> +		 * bypass disabled
> +		 */
> +		bwadj = pllm >> 1;
> +		tmp |= ((bwadj & PLL_BWADJ_LO_SHIFT) << PLL_BWADJ_LO_SHIFT) |
> +			(pllm << PLL_MULT_SHIFT) |
> +			(plld & PLL_DIV_MASK) |
> +			(pllod << PLL_CLKOD_SHIFT);
> +		__raw_writel(tmp, pll_regs[data->pll].reg0);
> +
> +		/* Set BWADJ[11:8] bits */
> +		tmp = __raw_readl(pll_regs[data->pll].reg1);
> +		tmp &= ~(PLL_BWADJ_HI_MASK);
> +		tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK);
> +
> +		/* set PLL Select (bit 13) for PASS PLL */
> +		if (data->pll == PASS_PLL)
> +			tmp |= PLLCTL_PAPLL;
> +
> +		__raw_writel(tmp, pll_regs[data->pll].reg1);
> +
> +		/* Reset bit: bit 14 for both DDR3 & PASS PLL */
> +		tmp = PLL_PLLRST;
> +		/* Set RESET bit = 1 */
> +		setbits_le32(pll_regs[data->pll].reg1, tmp);
> +		/* Wait for a minimum of 7 us*/
> +		sdelay(21000);
> +		/* Clear RESET bit */
> +		clrbits_le32(pll_regs[data->pll].reg1, tmp);
> +		sdelay(105000);
> +
> +		/* clear BYPASS (Enable PLL Mode) */
> +		clrbits_le32(pll_regs[data->pll].reg0, PLLCTL_BYPASS);
> +		sdelay(21000);	/* Wait for a minimum of 7 us*/
> +	}
> +
> +	/*
> +	 * This is required to provide a delay between multiple
> +	 * consequent PPL configurations
> +	 */
> +	sdelay(210000);
> +}
> +
> +void init_plls(int num_pll, struct pll_init_data *config)
> +{
> +	int i;
> +
> +	for (i = 0; i < num_pll; i++)
> +		init_pll(&config[i]);
> +}
> diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> new file mode 100644
> index 0000000..afd30f3
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> @@ -0,0 +1,124 @@
> +/*
> + * keystone2: commands for clocks
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <asm/arch/hardware.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/psc_defs.h>
> +
> +struct pll_init_data cmd_pll_data = {
> +	.pll			= MAIN_PLL,
> +	.pll_m			= 16,
> +	.pll_d			= 1,
> +	.pll_od			= 2,
> +};
> +
> +int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	if (argc != 5)
> +		goto pll_cmd_usage;
> +
> +	if (strncmp(argv[1], "pa", 2) == 0)
> +		cmd_pll_data.pll = PASS_PLL;
> +	else if (strncmp(argv[1], "arm", 3) == 0)
> +		cmd_pll_data.pll = TETRIS_PLL;
> +	else if (strncmp(argv[1], "ddr3a", 5) == 0)
> +		cmd_pll_data.pll = DDR3A_PLL;
> +	else if (strncmp(argv[1], "ddr3b", 5) == 0)
> +		cmd_pll_data.pll = DDR3B_PLL;
> +	else
> +		goto pll_cmd_usage;
> +
> +	cmd_pll_data.pll_m   = simple_strtoul(argv[2], NULL, 10);
> +	cmd_pll_data.pll_d   = simple_strtoul(argv[3], NULL, 10);
> +	cmd_pll_data.pll_od  = simple_strtoul(argv[4], NULL, 10);
> +
> +	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
> +	       cmd_pll_data.pll, cmd_pll_data.pll_m,
> +	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
> +	init_pll(&cmd_pll_data);
> +
> +	return 0;
> +
> +pll_cmd_usage:
> +	return cmd_usage(cmdtp);
> +}
> +
> +U_BOOT_CMD(
> +	pllset,	5,	0,	do_pll_cmd,
> +	"set pll multiplier and pre divider",
> +	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
> +);
> +
> +int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	unsigned int clk;
> +	unsigned int freq;
> +
> +	if (argc != 2)
> +		goto getclk_cmd_usage;
> +
> +	clk = simple_strtoul(argv[1], NULL, 10);
> +
> +	freq = clk_get_rate(clk);
> +	printf("clock index [%d] - frequency %u\n", clk, freq);
> +	return 0;
> +
> +getclk_cmd_usage:
> +	return cmd_usage(cmdtp);
> +}
> +
> +U_BOOT_CMD(
> +	getclk,	2,	0,	do_getclk_cmd,
> +	"get clock rate",
> +	"<clk index>\n"
> +	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
> +);
> +
> +int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	int	psc_module;
> +	int	res;
> +
> +	if (argc != 3)
> +		goto psc_cmd_usage;
> +
> +	psc_module = simple_strtoul(argv[1], NULL, 10);
> +	if (strcmp(argv[2], "en") == 0) {
> +		res = psc_enable_module(psc_module);
> +		printf("psc_enable_module(%d) - %s\n", psc_module,
> +		       (res) ? "ERROR" : "OK");
> +		return 0;
> +	}
> +
> +	if (strcmp(argv[2], "di") == 0) {
> +		res = psc_disable_module(psc_module);
> +		printf("psc_disable_module(%d) - %s\n", psc_module,
> +		       (res) ? "ERROR" : "OK");
> +		return 0;
> +	}
> +
> +	if (strcmp(argv[2], "domain") == 0) {
> +		res = psc_disable_domain(psc_module);
> +		printf("psc_disable_domain(%d) - %s\n", psc_module,
> +		       (res) ? "ERROR" : "OK");
> +		return 0;
> +	}
> +
> +psc_cmd_usage:
> +	return cmd_usage(cmdtp);
> +}
> +
> +U_BOOT_CMD(
> +	psc,	3,	0,	do_psc_cmd,
> +	"<enable/disable psc module os disable domain>",
> +	"<mod/domain index> <en|di|domain>\n"
> +	"See the hardware.h for Power and Sleep Controller (PSC) Domains\n"
> +);
> diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c
> new file mode 100644
> index 0000000..f9f58a3
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/cmd_mon.c
> @@ -0,0 +1,131 @@
> +/*
> + * K2HK: secure kernel command file
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +asm(".arch_extension sec\n\t");
> +
> +static int mon_install(u32 addr, u32 dpsc, u32 freq)
> +{
> +	int result;
> +
> +	__asm__ __volatile__ (
> +		"stmfd r13!, {lr}\n"
> +		"mov r0, %1\n"
> +		"mov r1, %2\n"
> +		"mov r2, %3\n"
> +		"blx r0\n"
> +		"ldmfd r13!, {lr}\n"
> +		: "=&r" (result)
> +		: "r" (addr), "r" (dpsc), "r" (freq)
> +		: "cc", "r0", "r1", "r2", "memory");
> +	return result;
> +}
> +
> +static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc,
> +			  char * const argv[])
> +{
> +	u32 addr, dpsc_base = 0x1E80000, freq;
> +	int     rcode = 0;
> +
> +	if (argc < 2)
> +		return CMD_RET_USAGE;
> +
> +	freq = clk_get_rate(sys_clk0_6_clk);
> +
> +	addr = simple_strtoul(argv[1], NULL, 16);
> +
> +	rcode = mon_install(addr, dpsc_base, freq);
> +	printf("## installed monitor, freq [%d], status %d\n",
> +	       freq, rcode);
> +
> +	return 0;
> +}
> +
> +U_BOOT_CMD(mon_install, 2, 0, do_mon_install,
> +	   "Install boot kernel at 'addr'",
> +	   ""
> +);
> +
> +static void core_spin(void)
> +{
> +	while (1)
> +		; /* forever */;

/* forever */  - this comment is redundant
And why do you carry ';' ? Why just use while(1); instead

> +}
> +
> +int mon_power_on(int core_id, void *ep)
> +{
> +	int result;
> +
> +	asm volatile (
> +		"stmfd  r13!, {lr}\n"
> +		"mov r1, %1\n"
> +		"mov r2, %2\n"
> +		"mov r0, #0\n"
> +		"smc	#0\n"
> +		"ldmfd  r13!, {lr}\n"
> +		: "=&r" (result)
> +		: "r" (core_id), "r" (ep)
> +		: "cc", "r0", "r1", "r2", "memory");
> +	return  result;
> +}
> +
> +int mon_power_off(int core_id)
> +{
> +	int result;
> +
> +	asm volatile (
> +		"stmfd  r13!, {lr}\n"
> +		"mov r1, %1\n"
> +		"mov r0, #1\n"
> +		"smc	#1\n"
> +		"ldmfd  r13!, {lr}\n"
> +		: "=&r" (result)
> +		: "r" (core_id)
> +		: "cc", "r0", "r1", "memory");
> +	return  result;
> +}
> +
> +int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc,
> +			char * const argv[])
> +{
> +	int     rcode = 0, core_id, on;
> +	void (*fn)(void);
> +
> +	fn = core_spin;

why do you need this pointer?

> +
> +	if (argc < 3)
> +		return CMD_RET_USAGE;
> +
> +	core_id = simple_strtoul(argv[1], NULL, 16);
> +	on = simple_strtoul(argv[2], NULL, 16);
> +
> +	if (on)
> +		rcode = mon_power_on(core_id, fn);

Maybe there is no need to use fn pointer:

rcode = mon_power_on(core_id, core_spin);


> +	else
> +		rcode = mon_power_off(core_id);
> +
> +	if (on) {
> +		if (!rcode)
> +			printf("core %d powered on successfully\n", core_id);
> +		else
> +			printf("core %d power on failure\n", core_id);
> +	} else {
> +		printf("core %d powered off successfully\n", core_id);
> +	}
> +
> +	return 0;
> +}
> +
> +U_BOOT_CMD(mon_power, 3, 0, do_mon_power,
> +	   "Power On/Off secondary core",
> +	   "mon_power <coreid> <oper>\n"
> +	   "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n"
> +	   ""
> +);
> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
> new file mode 100644
> index 0000000..4875db7
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c
> @@ -0,0 +1,69 @@
> +/*
> + * Keystone2: DDR3 initialization
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <asm/arch/hardware.h>
> +#include <asm/io.h>
> +
> +void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg)
> +{
> +	unsigned int tmp;
> +
> +	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET)
> +		 & 0x00000001) != 0x00000001)
> +		;
> +
> +	__raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET);
> +
> +	tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET);
> +	tmp &= ~(phy_cfg->pgcr1_mask);
> +	tmp |= phy_cfg->pgcr1_val;
> +	__raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET);
> +
> +	__raw_writel(phy_cfg->ptr0,   base + KS2_DDRPHY_PTR0_OFFSET);
> +	__raw_writel(phy_cfg->ptr1,   base + KS2_DDRPHY_PTR1_OFFSET);
> +	__raw_writel(phy_cfg->ptr3,  base + KS2_DDRPHY_PTR3_OFFSET);
> +	__raw_writel(phy_cfg->ptr4,  base + KS2_DDRPHY_PTR4_OFFSET);
> +
> +	tmp =  __raw_readl(base + KS2_DDRPHY_DCR_OFFSET);
> +	tmp &= ~(phy_cfg->dcr_mask);
> +	tmp |= phy_cfg->dcr_val;
> +	__raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET);
> +
> +	__raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET);
> +	__raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET);
> +	__raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET);
> +	__raw_writel(phy_cfg->mr0,   base + KS2_DDRPHY_MR0_OFFSET);
> +	__raw_writel(phy_cfg->mr1,   base + KS2_DDRPHY_MR1_OFFSET);
> +	__raw_writel(phy_cfg->mr2,   base + KS2_DDRPHY_MR2_OFFSET);
> +	__raw_writel(phy_cfg->dtcr,  base + KS2_DDRPHY_DTCR_OFFSET);
> +	__raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET);
> +
> +	__raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET);
> +	__raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET);
> +	__raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET);
> +
> +	__raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET);
> +	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
> +		;
> +
> +	__raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET);
> +	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
> +		;
> +}
> +
> +void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg)
> +{
> +	__raw_writel(emif_cfg->sdcfg,  base + KS2_DDR3_SDCFG_OFFSET);
> +	__raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET);
> +	__raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET);
> +	__raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET);
> +	__raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET);
> +	__raw_writel(emif_cfg->zqcfg,  base + KS2_DDR3_ZQCFG_OFFSET);
> +	__raw_writel(emif_cfg->sdrfc,  base + KS2_DDR3_SDRFC_OFFSET);
> +}
> diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c
> new file mode 100644
> index 0000000..044015a
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/init.c
> @@ -0,0 +1,56 @@
> +/*
> + * Keystone2: Architecture initialization
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/hardware.h>
> +
> +void chip_configuration_unlock(void)

why not static inline?

> +{
> +	__raw_writel(KEYSTONE_KICK0_MAGIC, KEYSTONE_KICK0);
> +	__raw_writel(KEYSTONE_KICK1_MAGIC, KEYSTONE_KICK1);
> +}
> +
> +int arch_cpu_init(void)
> +{
> +	chip_configuration_unlock();
> +	icache_enable();
> +
> +#ifdef CONFIG_SOC_K2HK
> +	share_all_segments(8);
> +	share_all_segments(9);
> +	share_all_segments(10); /* QM PDSP */
> +	share_all_segments(11); /* PCIE */
> +#endif
> +
> +	return 0;
> +}
> +
> +void reset_cpu(ulong addr)
> +{
> +	volatile u32 *rstctrl = (volatile u32 *)(KS2_RSTCTRL);
> +	u32 tmp;
> +
> +	tmp = *rstctrl & KS2_RSTCTRL_MASK;
> +	*rstctrl = tmp | KS2_RSTCTRL_KEY;
> +
> +	*rstctrl &= KS2_RSTCTRL_SWRST;
> +
> +	for (;;)
> +		;
> +}
> +
> +void enable_caches(void)
> +{
> +#ifndef CONFIG_SYS_DCACHE_OFF
> +	/* Enable D-cache. I-cache is already enabled in start.S */
> +	dcache_enable();
> +#endif
> +}
...

-- 
Regards,
Ivan Khoronzhuk

  reply	other threads:[~2014-04-03 12:32 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-01 18:44 [U-Boot] [PATCH v5 0/9] Add support for keystone2 SoC and K2HK EVM Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 1/9] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 2/9] tools: mkimage: add support for gpimage format Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 3/9] arm: add support for arch timer Murali Karicheri
2014-04-03  1:46   ` Masahiro Yamada
2014-04-03 11:22     ` Andrianov, Vitaly
2014-04-04 10:12       ` FengHua
2014-04-04 17:20         ` Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 4/9] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 5/9] i2c, davinci: move i2c_defs.h to the drivers/i2c directory Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 6/9] i2c, davinci: convert driver to new mutlibus/mutliadapter framework Murali Karicheri
2014-04-02  4:30   ` Heiko Schocher
2014-04-01 18:44 ` [U-Boot] [PATCH v5 7/9] k2hk: add support for k2hk SOC and EVM Murali Karicheri
2014-04-03 12:32   ` Ivan Khoronzhuk [this message]
2014-04-01 18:44 ` [U-Boot] [PATCH v5 8/9] spi: davinci: add support for multiple bus and chip select Murali Karicheri
2014-04-01 18:44 ` [U-Boot] [PATCH v5 9/9] k2hk-evm: add configuration for spi1 and spi2 support Murali Karicheri

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=533D54D4.7050706@ti.com \
    --to=ivan.khoronzhuk@ti.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.