On 04/01/2014 09:44 PM, Murali Karicheri wrote:
From: Vitaly Andrianov<vita...@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<vita...@ti.com>
Signed-off-by: Murali Karicheri<m-kariche...@ti.com>
Signed-off-by: WingMan Kwok<w-kw...@ti.com>
Signed-off-by: Sandeep Nair<sandee...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to