[U-Boot] [U-boot] [Patch v4 2/6] keystone2: clock: add K2L clock definitions and commands

Ivan Khoronzhuk ivan.khoronzhuk at ti.com
Wed Oct 15 01:55:28 CEST 2014


From: Hao Zhang <hzhang at ti.com>

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

Acked-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Hao Zhang <hzhang at ti.com>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk at ti.com>
---
 arch/arm/cpu/armv7/keystone/Makefile           |   1 +
 arch/arm/cpu/armv7/keystone/clock-k2l.c        | 138 +++++++++++++++++++++++++
 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, 241 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..1c5e4d5
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock-k2l.c
@@ -0,0 +1,138 @@
+/*
+ * 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



More information about the U-Boot mailing list