[U-Boot] [U-boot] [Patch] keystone2: use EFUSE_BOOTROM information to configure PLLs

Ivan Khoronzhuk ivan.khoronzhuk at ti.com
Fri Jul 25 21:23:19 CEST 2014


From: Vitaly Andrianov <vitalya at ti.com>

This patch reads EFUSE_BOOTROM register to see the maximum supported
clock for CORE and TETRIS PLLs and configure them accordingly.

Acked-by: Murali Karicheri <m-karicheri2 at ti.com>
Signed-off-by: Vitaly Andrianov <vitalya at ti.com>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk at ti.com>
---

Based on [U-boot] [Patch 0/6] Add support for k2e SoC and EVM
https://www.mail-archive.com/u-boot@lists.denx.de/msg142351.html

 arch/arm/cpu/armv7/keystone/clock-k2e.c         | 16 +++++++++
 arch/arm/cpu/armv7/keystone/clock-k2hk.c        | 32 ++++++++++++++++++
 arch/arm/cpu/armv7/keystone/clock.c             | 43 +++++++++++++++++++++++++
 arch/arm/include/asm/arch-keystone/clock-k2e.h  | 16 +++++++++
 arch/arm/include/asm/arch-keystone/clock-k2hk.h | 14 ++++++++
 arch/arm/include/asm/arch-keystone/clock.h      |  4 +++
 arch/arm/include/asm/arch-keystone/hardware.h   |  4 +++
 board/ti/ks2_evm/board_k2e.c                    | 23 ++++++++++---
 board/ti/ks2_evm/board_k2hk.c                   | 29 ++++++++++++++---
 9 files changed, 173 insertions(+), 8 deletions(-)

diff --git a/arch/arm/cpu/armv7/keystone/clock-k2e.c b/arch/arm/cpu/armv7/keystone/clock-k2e.c
index 42092e1..31f6661 100644
--- a/arch/arm/cpu/armv7/keystone/clock-k2e.c
+++ b/arch/arm/cpu/armv7/keystone/clock-k2e.c
@@ -17,6 +17,22 @@ const struct keystone_pll_regs keystone_pll_regs[] = {
 	[DDR3_PLL] = {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
 };
 
+int dev_speeds[] = {
+	SPD800,
+	SPD850,
+	SPD1000,
+	SPD1250,
+	SPD1350,
+	SPD1400,
+	SPD1500,
+	SPD1400,
+	SPD1350,
+	SPD1250,
+	SPD1000,
+	SPD850,
+	SPD800
+};
+
 /**
  * pll_freq_get - get pll frequency
  * Fout = Fref * NF(mult) / NR(prediv) / OD
diff --git a/arch/arm/cpu/armv7/keystone/clock-k2hk.c b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
index 96a9f72..1591960 100644
--- a/arch/arm/cpu/armv7/keystone/clock-k2hk.c
+++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
@@ -19,6 +19,38 @@ const struct keystone_pll_regs keystone_pll_regs[] = {
 	[DDR3B_PLL]	= {KS2_DDR3BPLLCTL0, KS2_DDR3BPLLCTL1},
 };
 
+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
diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c
index 03c1d9f..30d76a6 100644
--- a/arch/arm/cpu/armv7/keystone/clock.c
+++ b/arch/arm/cpu/armv7/keystone/clock.c
@@ -11,6 +11,8 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/clock_defs.h>
 
+#define MAX_SPEEDS		13
+
 static void wait_for_completion(const struct pll_init_data *data)
 {
 	int i;
@@ -218,3 +220,44 @@ void init_plls(int num_pll, struct pll_init_data *config)
 	for (i = 0; i < num_pll; i++)
 		init_pll(&config[i]);
 }
+
+static int get_max_speed(u32 val, int *speeds)
+{
+	int j;
+
+	if (!val)
+		return speeds[0];
+
+	for (j = 1; j < MAX_SPEEDS; j++) {
+		if (val == 1)
+			return speeds[j];
+		val >>= 1;
+	}
+
+	return SPD800;
+}
+
+#ifdef CONFIG_SOC_K2HK
+static u32 read_efuse_bootrom(void)
+{
+	return (cpu_revision() > 1) ? __raw_readl(KS2_EFUSE_BOOTROM) :
+		__raw_readl(KS2_REV1_DEVSPEED);
+}
+#else
+static inline u32 read_efuse_bootrom(void)
+{
+	return __raw_readl(KS2_EFUSE_BOOTROM);
+}
+#endif
+
+inline int get_max_dev_speed(void)
+{
+	return get_max_speed(read_efuse_bootrom() & 0xffff, dev_speeds);
+}
+
+#ifndef CONFIG_SOC_K2E
+inline int get_max_arm_speed(void)
+{
+	return get_max_speed((read_efuse_bootrom() >> 16) & 0xffff, arm_speeds);
+}
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2e.h b/arch/arm/include/asm/arch-keystone/clock-k2e.h
index 4147811..df33a78 100644
--- a/arch/arm/include/asm/arch-keystone/clock-k2e.h
+++ b/arch/arm/include/asm/arch-keystone/clock-k2e.h
@@ -56,10 +56,26 @@ enum pll_type_e {
 	DDR3_PLL,
 };
 
+enum {
+	SPD800,
+	SPD850,
+	SPD1000,
+	SPD1250,
+	SPD1350,
+	SPD1400,
+	SPD1500,
+	SPD_RSV
+};
+
 #define CORE_PLL_800	{CORE_PLL, 16, 1, 2}
+#define CORE_PLL_850	{CORE_PLL, 17, 1, 2}
 #define CORE_PLL_1000	{CORE_PLL, 20, 1, 2}
 #define CORE_PLL_1200	{CORE_PLL, 24, 1, 2}
 #define PASS_PLL_1000	{PASS_PLL, 20, 1, 2}
+#define CORE_PLL_1250	{CORE_PLL, 25, 1, 2}
+#define CORE_PLL_1350	{CORE_PLL, 27, 1, 2}
+#define CORE_PLL_1400	{CORE_PLL, 28, 1, 2}
+#define CORE_PLL_1500	{CORE_PLL, 30, 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}
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
index 784a0be..bdb869b 100644
--- a/arch/arm/include/asm/arch-keystone/clock-k2hk.h
+++ b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
@@ -63,21 +63,35 @@ enum pll_type_e {
 	DDR3B_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_999	{CORE_PLL,	122,	15,	1}
 #define CORE_PLL_1167   {CORE_PLL,	19,	1,	2}
 #define CORE_PLL_1228   {CORE_PLL,	20,	1,	2}
+#define CORE_PLL_1200	{CORE_PLL,	625,	32,	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_500  {TETRIS_PLL,	8,	1,	2}
 #define TETRIS_PLL_750  {TETRIS_PLL,	12,	1,	2}
+#define TETRIS_PLL_800	{TETRIS_PLL,	32,	5,	1}
 #define TETRIS_PLL_687  {TETRIS_PLL,	11,	1,	2}
 #define TETRIS_PLL_625  {TETRIS_PLL,	10,	1,	2}
 #define TETRIS_PLL_812  {TETRIS_PLL,	13,	1,	2}
 #define TETRIS_PLL_875  {TETRIS_PLL,	14,	1,	2}
+#define TETRIS_PLL_1000	{TETRIS_PLL,	40,	5,	1}
 #define TETRIS_PLL_1188 {TETRIS_PLL,	19,	2,	1}
 #define TETRIS_PLL_1200 {TETRIS_PLL,	48,	5,	1}
+#define TETRIS_PLL_1350	{TETRIS_PLL,	54,	5,	1}
 #define TETRIS_PLL_1375 {TETRIS_PLL,	22,	2,	1}
 #define TETRIS_PLL_1400 {TETRIS_PLL,	56,	5,	1}
 #define DDR3_PLL_200(x)	{DDR3##x##_PLL,	4,	1,	2}
diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h
index 1513c76..dae000e 100644
--- a/arch/arm/include/asm/arch-keystone/clock.h
+++ b/arch/arm/include/asm/arch-keystone/clock.h
@@ -38,12 +38,16 @@ struct pll_init_data {
 };
 
 extern const struct keystone_pll_regs keystone_pll_regs[];
+extern int dev_speeds[];
+extern int arm_speeds[];
 
 void init_plls(int num_pll, struct pll_init_data *config);
 void init_pll(const struct pll_init_data *data);
 unsigned long clk_get_rate(unsigned int clk);
 unsigned long clk_round_rate(unsigned int clk, unsigned long hz);
 int clk_set_rate(unsigned int clk, unsigned long hz);
+int get_max_dev_speed(void);
+int get_max_arm_speed(void);
 
 #endif
 #endif
diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h
index ddeb06e..d6726a1 100644
--- a/arch/arm/include/asm/arch-keystone/hardware.h
+++ b/arch/arm/include/asm/arch-keystone/hardware.h
@@ -138,6 +138,10 @@ typedef volatile unsigned int   *dv_reg_p;
 /* Flag from ks2_debug options to check if DSPs need to stay ON */
 #define DBG_LEAVE_DSPS_ON		0x1
 
+/* Device speed */
+#define KS2_REV1_DEVSPEED		(KS2_DEVICE_STATE_CTRL_BASE + 0xc98)
+#define KS2_EFUSE_BOOTROM		(KS2_DEVICE_STATE_CTRL_BASE + 0xc90)
+
 /* Queue manager */
 #define KS2_QM_MANAGER_BASE		0x02a02000
 #define KS2_QM_DESC_SETUP_BASE		0x02a03000
diff --git a/board/ti/ks2_evm/board_k2e.c b/board/ti/ks2_evm/board_k2e.c
index d2499b7..5472a43 100644
--- a/board/ti/ks2_evm/board_k2e.c
+++ b/board/ti/ks2_evm/board_k2e.c
@@ -25,15 +25,30 @@ unsigned int external_clk[ext_clk_count] = {
 	[usb_clk]	= 100000000,
 };
 
-static struct pll_init_data pll_config[] = {
-	CORE_PLL_1200,
-	PASS_PLL_1000,
+static struct pll_init_data core_pll_config[] = {
+	CORE_PLL_800,
+	CORE_PLL_850,
+	CORE_PLL_1000,
+	CORE_PLL_1250,
+	CORE_PLL_1350,
+	CORE_PLL_1400,
+	CORE_PLL_1500,
 };
 
+
+static struct pll_init_data pa_pll_config =
+	PASS_PLL_1000;
+
 #if defined(CONFIG_BOARD_EARLY_INIT_F)
 int board_early_init_f(void)
 {
-	init_plls(ARRAY_SIZE(pll_config), pll_config);
+	int speed;
+
+	speed = get_max_dev_speed();
+	init_pll(&core_pll_config[speed]);
+
+	init_pll(&pa_pll_config);
+
 	return 0;
 }
 #endif
diff --git a/board/ti/ks2_evm/board_k2hk.c b/board/ti/ks2_evm/board_k2hk.c
index a369d6b..6fb3d21 100644
--- a/board/ti/ks2_evm/board_k2hk.c
+++ b/board/ti/ks2_evm/board_k2hk.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/clock.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/emac_defs.h>
 
@@ -28,12 +29,23 @@ unsigned int external_clk[ext_clk_count] = {
 	[rp1_clk]	=	123456789
 };
 
-static struct pll_init_data pll_config[] = {
-	CORE_PLL_1228,
-	PASS_PLL_983,
+static struct pll_init_data core_pll_config[] = {
+	CORE_PLL_799,
+	CORE_PLL_999,
+	CORE_PLL_1200,
+};
+
+static struct pll_init_data tetris_pll_config[] = {
+	TETRIS_PLL_800,
+	TETRIS_PLL_1000,
 	TETRIS_PLL_1200,
+	TETRIS_PLL_1350,
+	TETRIS_PLL_1400,
 };
 
+static struct pll_init_data pa_pll_config =
+	PASS_PLL_983;
+
 #ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
 struct eth_priv_t eth_priv_cfg[] = {
 	{
@@ -75,7 +87,16 @@ int get_num_eth_ports(void)
 #ifdef CONFIG_BOARD_EARLY_INIT_F
 int board_early_init_f(void)
 {
-	init_plls(ARRAY_SIZE(pll_config), pll_config);
+	int speed;
+
+	speed = get_max_dev_speed();
+	init_pll(&core_pll_config[speed]);
+
+	init_pll(&pa_pll_config);
+
+	speed = get_max_arm_speed();
+	init_pll(&tetris_pll_config[speed]);
+
 	return 0;
 }
 #endif
-- 
1.8.3.2



More information about the U-Boot mailing list