[U-Boot] [PATCH 1/2] ARM: k2g: Add support for dynamic programming of PLL based on SYSCLK

Lokesh Vutla lokeshvutla at ti.com
Wed May 3 11:28:25 UTC 2017


K2G supports various sysclk frequencies which can be
determined using sysboot pins. PLLs should be configured
based on this sysclock frequency. Add PLL configurations
for all supported sysclk frequencies.

Signed-off-by: Lokesh Vutla <lokeshvutla at ti.com>
---
 arch/arm/mach-keystone/include/mach/clock-k2g.h    |   4 +-
 arch/arm/mach-keystone/include/mach/hardware-k2g.h |  21 ++++
 board/ti/ks2_evm/board_k2g.c                       | 116 +++++++++++++++++----
 3 files changed, 118 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-keystone/include/mach/clock-k2g.h b/arch/arm/mach-keystone/include/mach/clock-k2g.h
index 74de6202fe..374f0d92af 100644
--- a/arch/arm/mach-keystone/include/mach/clock-k2g.h
+++ b/arch/arm/mach-keystone/include/mach/clock-k2g.h
@@ -12,8 +12,8 @@
 
 #define PLLSET_CMD_LIST		"<pa|arm|ddr3>"
 
-#define DEV_SUPPORTED_SPEEDS	0x1ff
-#define ARM_SUPPORTED_SPEEDS	0xff
+#define DEV_SUPPORTED_SPEEDS	0xff
+#define ARM_SUPPORTED_SPEEDS	0x3ff
 
 #define KS2_CLK1_6 sys_clk0_6_clk
 
diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2g.h b/arch/arm/mach-keystone/include/mach/hardware-k2g.h
index 0f6bf61867..90ca1208d4 100644
--- a/arch/arm/mach-keystone/include/mach/hardware-k2g.h
+++ b/arch/arm/mach-keystone/include/mach/hardware-k2g.h
@@ -86,4 +86,25 @@
 #define RSTMUX_OMODE8_INT		0x3
 #define RSTMUX_OMODE8_INT_AND_DEV_RESET	0x4
 
+/* DEVSTAT register definition */
+#define KS2_DEVSTAT_REFCLK_SHIFT	 7
+#define KS2_DEVSTAT_REFCLK_MASK		(0x7 << 7)
+
+/* GPMC */
+#define KS2_GPMC_BASE			0x21818000
+
+/* SYSCLK indexes */
+#define SYSCLK_19MHz	0
+#define SYSCLK_24MHz	1
+#define SYSCLK_25MHz	2
+#define SYSCLK_26MHz	3
+#define MAX_SYSCLK	4
+
+#ifndef __ASSEMBLY__
+static inline u8 get_sysclk_index(void)
+{
+	u32 dev_stat = __raw_readl(KS2_DEVSTAT);
+	return (dev_stat & KS2_DEVSTAT_REFCLK_MASK) >> KS2_DEVSTAT_REFCLK_SHIFT;
+}
+#endif
 #endif /* __ASM_ARCH_HARDWARE_K2G_H */
diff --git a/board/ti/ks2_evm/board_k2g.c b/board/ti/ks2_evm/board_k2g.c
index de881596d4..6c590b4ff9 100644
--- a/board/ti/ks2_evm/board_k2g.c
+++ b/board/ti/ks2_evm/board_k2g.c
@@ -20,6 +20,13 @@
 #define SYS_CLK		24000000
 #define K2G_GP_AUDIO_CODEC_ADDRESS	0x1B
 
+const unsigned int sysclk_array[MAX_SYSCLK] = {
+	19200000,
+	24000000,
+	25000000,
+	26000000,
+};
+
 unsigned int external_clk[ext_clk_count] = {
 	[sys_clk]	=	SYS_CLK,
 	[pa_clk]	=	SYS_CLK,
@@ -52,49 +59,116 @@ static int dev_speeds[DEVSPEED_NUMSPDS] = {
 	SPD400,
 };
 
-static struct pll_init_data main_pll_config[NUM_SPDS] = {
-	[SPD400]	= {MAIN_PLL, 100, 3, 2},
-	[SPD600]	= {MAIN_PLL, 300, 6, 2},
-	[SPD800]	= {MAIN_PLL, 200, 3, 2},
-	[SPD900] =	{TETRIS_PLL, 75, 1, 2},
-	[SPD1000] =	{TETRIS_PLL, 250, 3, 2},
+static struct pll_init_data main_pll_config[MAX_SYSCLK][NUM_SPDS] = {
+	[SYSCLK_19MHz] = {
+		[SPD400]	= {MAIN_PLL, 125, 3, 2},
+		[SPD600]	= {MAIN_PLL, 125, 2, 2},
+		[SPD800]	= {MAIN_PLL, 250, 3, 2},
+		[SPD900]	= {TETRIS_PLL, 187, 2, 2},
+		[SPD1000]	= {TETRIS_PLL, 104, 1, 2},
+	},
+	[SYSCLK_24MHz] = {
+		[SPD400]	= {MAIN_PLL, 100, 3, 2},
+		[SPD600]	= {MAIN_PLL, 300, 6, 2},
+		[SPD800]	= {MAIN_PLL, 200, 3, 2},
+		[SPD900]	= {TETRIS_PLL, 75, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 250, 3, 2},
+	},
+	[SYSCLK_25MHz] = {
+		[SPD400]	= {MAIN_PLL, 32, 1, 2},
+		[SPD600]	= {MAIN_PLL, 48, 1, 2},
+		[SPD800]	= {MAIN_PLL, 64, 1, 2},
+		[SPD900]	= {TETRIS_PLL, 72, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 80, 1, 2},
+	},
+	[SYSCLK_26MHz] = {
+		[SPD400]	= {MAIN_PLL, 400, 13, 2},
+		[SPD600]	= {MAIN_PLL, 230, 5, 2},
+		[SPD800]	= {MAIN_PLL, 123, 2, 2},
+		[SPD900]	= {TETRIS_PLL, 69, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 384, 5, 2},
+	},
 };
 
-static struct pll_init_data tetris_pll_config[NUM_SPDS] = {
-	[SPD200] =	{TETRIS_PLL, 250, 3, 10},
-	[SPD400] =	{TETRIS_PLL, 100, 1, 6},
-	[SPD600] =	{TETRIS_PLL, 100, 1, 4},
-	[SPD800] =	{TETRIS_PLL, 400, 3, 4},
-	[SPD900] =	{TETRIS_PLL, 75, 1, 2},
-	[SPD1000] =	{TETRIS_PLL, 250, 3, 2},
+static struct pll_init_data tetris_pll_config[MAX_SYSCLK][NUM_SPDS] = {
+	[SYSCLK_19MHz] = {
+		[SPD200]	= {TETRIS_PLL, 625, 6, 10},
+		[SPD400]	= {TETRIS_PLL, 125, 1, 6},
+		[SPD600]	= {TETRIS_PLL, 125, 1, 4},
+		[SPD800]	= {TETRIS_PLL, 333, 2, 4},
+		[SPD900]	= {TETRIS_PLL, 187, 2, 2},
+		[SPD1000]	= {TETRIS_PLL, 104, 1, 2},
+	},
+	[SYSCLK_24MHz] = {
+		[SPD200]	= {TETRIS_PLL, 250, 3, 10},
+		[SPD400]	= {TETRIS_PLL, 100, 1, 6},
+		[SPD600]	= {TETRIS_PLL, 100, 1, 4},
+		[SPD800]	= {TETRIS_PLL, 400, 3, 4},
+		[SPD900]	= {TETRIS_PLL, 75, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 250, 3, 2},
+	},
+	[SYSCLK_25MHz] = {
+		[SPD200]	= {TETRIS_PLL, 80, 1, 10},
+		[SPD400]	= {TETRIS_PLL, 96, 1, 6},
+		[SPD600]	= {TETRIS_PLL, 96, 1, 4},
+		[SPD800]	= {TETRIS_PLL, 128, 1, 4},
+		[SPD900]	= {TETRIS_PLL, 72, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 80, 1, 2},
+	},
+	[SYSCLK_26MHz] = {
+		[SPD200]	= {TETRIS_PLL, 307, 4, 10},
+		[SPD400]	= {TETRIS_PLL, 369, 4, 6},
+		[SPD600]	= {TETRIS_PLL, 369, 4, 4},
+		[SPD800]	= {TETRIS_PLL, 123, 1, 4},
+		[SPD900]	= {TETRIS_PLL, 69, 1, 2},
+		[SPD1000]	= {TETRIS_PLL, 384, 5, 2},
+	},
+};
+
+static struct pll_init_data uart_pll_config[MAX_SYSCLK] = {
+	[SYSCLK_19MHz] = {UART_PLL, 160, 1, 8},
+	[SYSCLK_24MHz] = {UART_PLL, 128, 1, 8},
+	[SYSCLK_25MHz] = {UART_PLL, 768, 5, 10},
+	[SYSCLK_26MHz] = {UART_PLL, 384, 13, 2},
 };
 
-static struct pll_init_data uart_pll_config = {UART_PLL, 64, 1, 4};
-static struct pll_init_data nss_pll_config = {NSS_PLL, 250, 3, 2};
-static struct pll_init_data ddr3_pll_config = {DDR3A_PLL, 133, 1, 16};
+static struct pll_init_data nss_pll_config[MAX_SYSCLK] = {
+	[SYSCLK_19MHz] = {NSS_PLL, 625, 6, 2},
+	[SYSCLK_24MHz] = {NSS_PLL, 250, 3, 2},
+	[SYSCLK_25MHz] = {NSS_PLL, 80, 1, 2},
+	[SYSCLK_26MHz] = {NSS_PLL, 1000, 13, 2},
+};
+
+static struct pll_init_data ddr3_pll_config[MAX_SYSCLK] = {
+	[SYSCLK_19MHz] = {DDR3A_PLL, 167, 1, 16},
+	[SYSCLK_24MHz] = {DDR3A_PLL, 133, 1, 16},
+	[SYSCLK_25MHz] = {DDR3A_PLL, 128, 1, 16},
+	[SYSCLK_26MHz] = {DDR3A_PLL, 123, 1, 16},
+};
 
 struct pll_init_data *get_pll_init_data(int pll)
 {
 	int speed;
 	struct pll_init_data *data = NULL;
+	u8 sysclk_index = get_sysclk_index();
 
 	switch (pll) {
 	case MAIN_PLL:
 		speed = get_max_dev_speed(dev_speeds);
-		data = &main_pll_config[speed];
+		data = &main_pll_config[sysclk_index][speed];
 		break;
 	case TETRIS_PLL:
 		speed = get_max_arm_speed(arm_speeds);
-		data = &tetris_pll_config[speed];
+		data = &tetris_pll_config[sysclk_index][speed];
 		break;
 	case NSS_PLL:
-		data = &nss_pll_config;
+		data = &nss_pll_config[sysclk_index];
 		break;
 	case UART_PLL:
-		data = &uart_pll_config;
+		data = &uart_pll_config[sysclk_index];
 		break;
 	case DDR3_PLL:
-		data = &ddr3_pll_config;
+		data = &ddr3_pll_config[sysclk_index];
 		break;
 	default:
 		data = NULL;
-- 
2.11.0



More information about the U-Boot mailing list