From: Hao Zhang <hzh...@ti.com>

This patch adds clock definitions and commands to support Keystone II
K2L SOC.

Acked-by: Vitaly Andrianov <vita...@ti.com>
Signed-off-by: Hao Zhang <hzh...@ti.com>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronz...@ti.com>
---
 arch/arm/cpu/armv7/keystone/Makefile           |   1 +
 arch/arm/cpu/armv7/keystone/clock-k2l.c        | 139 +++++++++++++++++++++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c        |  10 ++
 arch/arm/include/asm/arch-keystone/clock-k2l.h |  88 ++++++++++++++++
 arch/arm/include/asm/arch-keystone/clock.h     |   4 +
 5 files changed, 242 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/keystone/clock-k2l.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2l.h

diff --git a/arch/arm/cpu/armv7/keystone/Makefile 
b/arch/arm/cpu/armv7/keystone/Makefile
index 3d8fb70..4750371 100644
--- a/arch/arm/cpu/armv7/keystone/Makefile
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -10,6 +10,7 @@ obj-y += psc.o
 obj-y  += clock.o
 obj-$(CONFIG_SOC_K2HK) += clock-k2hk.o
 obj-$(CONFIG_SOC_K2E) += clock-k2e.o
+obj-$(CONFIG_SOC_K2L) += clock-k2l.o
 obj-y  += cmd_clock.o
 obj-y  += cmd_mon.o
 obj-y  += msmc.o
diff --git a/arch/arm/cpu/armv7/keystone/clock-k2l.c 
b/arch/arm/cpu/armv7/keystone/clock-k2l.c
new file mode 100644
index 0000000..783355a
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock-k2l.c
@@ -0,0 +1,139 @@
+/*
+ * Keystone2: get clk rate for K2L
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clock_defs.h>
+
+const struct keystone_pll_regs keystone_pll_regs[] = {
+       [CORE_PLL] = {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1},
+       [PASS_PLL] = {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1},
+       [TETRIS_PLL] = {KS2_ARMPLLCTL0,  KS2_ARMPLLCTL1},
+       [DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
+};
+
+int dev_speeds[] = {
+       SPD800,
+       SPD1000,
+       SPD1200,
+       SPD800,
+       SPD800,
+       SPD800,
+       SPD800,
+       SPD800,
+       SPD1200,
+       SPD1000,
+       SPD800,
+       SPD800,
+       SPD800,
+};
+
+int arm_speeds[] = {
+       SPD800,
+       SPD1000,
+       SPD1200,
+       SPD1350,
+       SPD1400,
+       SPD800,
+       SPD1400,
+       SPD1350,
+       SPD1200,
+       SPD1000,
+       SPD800,
+       SPD800,
+       SPD800,
+};
+
+/**
+ * pll_freq_get - get pll frequency
+ * Fout = Fref * NF(mult) / NR(prediv) / OD
+ * @pll:       pll identifier
+ */
+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(KS2_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 = KS2_PASSPLLCTL0;
+                       break;
+               case TETRIS_PLL:
+                       ret = external_clk[tetris_clk];
+                       reg = KS2_ARMPLLCTL0;
+                       break;
+               case DDR3_PLL:
+                       ret = external_clk[ddr3_clk];
+                       reg = KS2_DDR3APLLCTL0;
+                       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 ddr3_pll_clk:      return pll_freq_get(DDR3_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;
+}
diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c 
b/arch/arm/cpu/armv7/keystone/cmd_clock.c
index d97c95b..9204887 100644
--- a/arch/arm/cpu/armv7/keystone/cmd_clock.c
+++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
@@ -72,6 +72,13 @@ U_BOOT_CMD(
        "<pa|ddr3> <mult> <div> <OD>\n"
 );
 #endif
+#ifdef CONFIG_SOC_K2L
+U_BOOT_CMD(
+       pllset, 5,      0,      do_pll_cmd,
+       "set pll multiplier and pre divider",
+       "<pa|arm|ddr3> <mult> <div> <OD>\n"
+);
+#endif
 
 int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -101,6 +108,9 @@ U_BOOT_CMD(
 #ifdef CONFIG_SOC_K2E
        "See the 'enum clk_e' in the clock-k2e.h for clk indexes\n"
 #endif
+#ifdef CONFIG_SOC_K2L
+       "See the 'enum clk_e' in the clock-k2l.h for clk indexes\n"
+#endif
 );
 
 int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2l.h 
b/arch/arm/include/asm/arch-keystone/clock-k2l.h
new file mode 100644
index 0000000..8cacee0
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock-k2l.h
@@ -0,0 +1,88 @@
+/*
+ * K2L: Clock management APIs
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_K2L_H
+#define __ASM_ARCH_CLOCK_K2L_H
+
+enum ext_clk_e {
+       sys_clk,
+       alt_core_clk,
+       pa_clk,
+       tetris_clk,
+       ddr3_clk,
+       pcie_clk,
+       sgmii_clk,
+       usb_clk,
+       rp1_clk,
+       ext_clk_count /* number of external clocks */
+};
+
+extern unsigned int external_clk[ext_clk_count];
+
+enum clk_e {
+       core_pll_clk,
+       pass_pll_clk,
+       tetris_pll_clk,
+       ddr3_pll_clk,
+       sys_clk0_clk,
+       sys_clk0_1_clk,
+       sys_clk0_2_clk,
+       sys_clk0_3_clk,
+       sys_clk0_4_clk,
+       sys_clk0_6_clk,
+       sys_clk0_8_clk,
+       sys_clk0_12_clk,
+       sys_clk0_24_clk,
+       sys_clk1_clk,
+       sys_clk1_3_clk,
+       sys_clk1_4_clk,
+       sys_clk1_6_clk,
+       sys_clk1_12_clk,
+       sys_clk2_clk,
+       sys_clk3_clk
+};
+
+#define KS2_CLK1_6     sys_clk0_6_clk
+
+/* PLL identifiers */
+enum pll_type_e {
+       CORE_PLL,
+       PASS_PLL,
+       TETRIS_PLL,
+       DDR3_PLL,
+};
+
+enum {
+       SPD800,
+       SPD1000,
+       SPD1200,
+       SPD1350,
+       SPD1400,
+       SPD_RSV
+};
+
+#define CORE_PLL_799   {CORE_PLL, 13, 1, 2}
+#define CORE_PLL_983   {CORE_PLL, 16, 1, 2}
+#define CORE_PLL_1167  {CORE_PLL, 19, 1, 2}
+#define CORE_PLL_1228  {CORE_PLL, 20, 1, 2}
+#define PASS_PLL_1228  {PASS_PLL, 20, 1, 2}
+#define PASS_PLL_983   {PASS_PLL, 16, 1, 2}
+#define PASS_PLL_1050  {PASS_PLL, 205, 12, 2}
+#define TETRIS_PLL_491 {TETRIS_PLL, 8, 1, 2}
+#define TETRIS_PLL_737 {TETRIS_PLL, 12, 1, 2}
+#define TETRIS_PLL_799 {TETRIS_PLL, 13, 1, 2}
+#define TETRIS_PLL_983 {TETRIS_PLL, 16, 1, 2}
+#define TETRIS_PLL_1167        {TETRIS_PLL, 19, 1, 2}
+#define TETRIS_PLL_1228        {TETRIS_PLL, 20, 1, 2}
+#define DDR3_PLL_200   {DDR3_PLL, 4, 1, 2}
+#define DDR3_PLL_400   {DDR3_PLL, 16, 1, 4}
+#define DDR3_PLL_800   {DDR3_PLL, 16, 1, 2}
+#define DDR3_PLL_333   {DDR3_PLL, 20, 1, 6}
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock.h 
b/arch/arm/include/asm/arch-keystone/clock.h
index dae000e..bc31267 100644
--- a/arch/arm/include/asm/arch-keystone/clock.h
+++ b/arch/arm/include/asm/arch-keystone/clock.h
@@ -20,6 +20,10 @@
 #include <asm/arch/clock-k2e.h>
 #endif
 
+#ifdef CONFIG_SOC_K2L
+#include <asm/arch/clock-k2l.h>
+#endif
+
 #define MAIN_PLL CORE_PLL
 
 #include <asm/types.h>
-- 
1.8.3.2

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

Reply via email to