[U-Boot] [PATCH V3 10/14] ARM: AM43xx: clocks: Update DPLL details

Lokesh Vutla lokeshvutla at ti.com
Tue Dec 10 10:32:20 CET 2013


Updating the Multiplier and Dividers value for all DPLLs.
Safest OPP is read from DEV ATTRIBUTE register. Accoring to the value
returned the MPU DPLL is locked.
At different OPPs follwoing are the MPU locked frequencies.
OPP50	300MHz
OPP100	600MHz
OPP120	720MHz
OPPTB	800MHz
OPPNT	1000MHz
According to the latest DM following is the OPP table dependencies:
	VDD_CORE 	VDD_MPU
	OPP50		OPP50
	OPP50 		OPP100
	OPP100		OPP50
	OPP100		OPP100
	OPP100		OPP120
So at different OPPs of MPU it is safest to lock CORE at OPP_NOM.
Following are the DPLL locking frequencies at OPP NOM:
Core locks at 1000MHz
Per locks at 960MHz
LPDDR2 locks at 266MHz
DDR3 locks at 400MHz

Touching AM33xx files also to get DPLL values specific to board but no
functionality difference.
Signed-off-by: Lokesh Vutla <lokeshvutla at ti.com>
---
Changes since V2:
-> Populated DPLLs data for all OPPs and SYS CLK inputs and the correct values
   to be read from eFuse.

 arch/arm/cpu/armv7/am33xx/clock.c                  |   12 +-
 arch/arm/cpu/armv7/am33xx/clock_am33xx.c           |   15 +++
 arch/arm/cpu/armv7/am33xx/clock_am43xx.c           |    8 +-
 arch/arm/include/asm/arch-am33xx/clock.h           |    7 +-
 arch/arm/include/asm/arch-am33xx/cpu.h             |    2 +
 arch/arm/include/asm/arch-am33xx/hardware_am43xx.h |   13 ++
 board/ti/am43xx/board.c                            |  138 +++++++++++++++++++-
 board/ti/am43xx/board.h                            |    4 +
 board/ti/am43xx/mux.c                              |    5 +
 9 files changed, 187 insertions(+), 17 deletions(-)

diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index 8e5f3c6..0672798 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -101,9 +101,15 @@ void do_setup_dpll(const struct dpll_regs *dpll_regs,
 static void setup_dplls(void)
 {
 	const struct dpll_params *params;
-	do_setup_dpll(&dpll_core_regs, &dpll_core);
-	do_setup_dpll(&dpll_mpu_regs, &dpll_mpu);
-	do_setup_dpll(&dpll_per_regs, &dpll_per);
+
+	params = get_dpll_core_params();
+	do_setup_dpll(&dpll_core_regs, params);
+
+	params = get_dpll_mpu_params();
+	do_setup_dpll(&dpll_mpu_regs, params);
+
+	params = get_dpll_per_params();
+	do_setup_dpll(&dpll_per_regs, params);
 	writel(0x300, &cmwkup->clkdcoldodpllper);
 
 	params = get_dpll_ddr_params();
diff --git a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
index fabe259..92142c8 100644
--- a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
+++ b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
@@ -62,6 +62,21 @@ const struct dpll_params dpll_core = {
 const struct dpll_params dpll_per = {
 		960, OSC-1, 5, -1, -1, -1, -1};
 
+const struct dpll_params *get_dpll_mpu_params(void)
+{
+	return &dpll_mpu;
+}
+
+const struct dpll_params *get_dpll_core_params(void)
+{
+	return &dpll_core;
+}
+
+const struct dpll_params *get_dpll_per_params(void)
+{
+	return &dpll_per;
+}
+
 void setup_clocks_for_console(void)
 {
 	clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
diff --git a/arch/arm/cpu/armv7/am33xx/clock_am43xx.c b/arch/arm/cpu/armv7/am33xx/clock_am43xx.c
index 22963b7..97c00b4 100644
--- a/arch/arm/cpu/armv7/am33xx/clock_am43xx.c
+++ b/arch/arm/cpu/armv7/am33xx/clock_am43xx.c
@@ -48,15 +48,9 @@ const struct dpll_regs dpll_ddr_regs = {
 	.cm_idlest_dpll		= CM_WKUP + 0x5A4,
 	.cm_clksel_dpll		= CM_WKUP + 0x5AC,
 	.cm_div_m2_dpll		= CM_WKUP + 0x5B0,
+	.cm_div_m4_dpll		= CM_WKUP + 0x5B8,
 };
 
-const struct dpll_params dpll_mpu = {
-		-1, -1, -1, -1, -1, -1, -1};
-const struct dpll_params dpll_core = {
-		-1, -1, -1, -1, -1, -1, -1};
-const struct dpll_params dpll_per = {
-		-1, -1, -1, -1, -1, -1, -1};
-
 void setup_clocks_for_console(void)
 {
 	/* Do not add any spl_debug prints in this function */
diff --git a/arch/arm/include/asm/arch-am33xx/clock.h b/arch/arm/include/asm/arch-am33xx/clock.h
index 519249e..7637457 100644
--- a/arch/arm/include/asm/arch-am33xx/clock.h
+++ b/arch/arm/include/asm/arch-am33xx/clock.h
@@ -98,13 +98,12 @@ extern const struct dpll_regs dpll_mpu_regs;
 extern const struct dpll_regs dpll_core_regs;
 extern const struct dpll_regs dpll_per_regs;
 extern const struct dpll_regs dpll_ddr_regs;
-extern const struct dpll_params dpll_mpu;
-extern const struct dpll_params dpll_core;
-extern const struct dpll_params dpll_per;
-extern const struct dpll_params dpll_ddr;
 
 extern struct cm_wkuppll *const cmwkup;
 
+const struct dpll_params *get_dpll_mpu_params(void);
+const struct dpll_params *get_dpll_core_params(void);
+const struct dpll_params *get_dpll_per_params(void);
 const struct dpll_params *get_dpll_ddr_params(void);
 void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *);
 void prcm_init(void);
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index 19b8469..3ee37dc 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -480,6 +480,8 @@ struct ctrl_stat {
 	unsigned int statusreg;		/* ofset 0x40 */
 	unsigned int resv2[51];
 	unsigned int secure_emif_sdram_config;	/* offset 0x0110 */
+	unsigned int resv3[319];
+	unsigned int dev_attr;
 };
 
 /* AM33XX GPIO registers */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h b/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
index 8fee929..ada1b4c 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
@@ -63,4 +63,17 @@
 #define PRM_PER_USBPHYOCP2SCP1_CLKCTRL (CM_PER + 0x5c0)
 #define USBPHYOCPSCP_MODULE_EN	(1 << 2)
 
+/* Control status register */
+#define CTRL_CRYSTAL_FREQ_SRC_MASK		(1 << 31)
+#define CTRL_CRYSTAL_FREQ_SRC_SHIFT		31
+#define CTRL_CRYSTAL_FREQ_SELECTION_MASK	(0x3 << 29)
+#define CTRL_CRYSTAL_FREQ_SELECTION_SHIFT	29
+#define CTRL_SYSBOOT_15_14_MASK			(0x3 << 22)
+#define CTRL_SYSBOOT_15_14_SHIFT		22
+
+#define CTRL_CRYSTAL_FREQ_SRC_SYSBOOT		0x0
+#define CTRL_CRYSTAL_FREQ_SRC_EFUSE		0x1
+
+#define NUM_CRYSTAL_FREQ			0x4
+
 #endif /* __AM43XX_HARDWARE_AM43XX_H */
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index 723d0ca..5c92ac7 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -65,12 +65,144 @@ static int read_eeprom(struct am43xx_board_id *header)
 
 #ifdef CONFIG_SPL_BUILD
 
-const struct dpll_params dpll_ddr = {
-		-1, -1, -1, -1, -1, -1, -1};
+#define NUM_OPPS	6
+
+const struct dpll_params dpll_mpu[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
+	{	/* 19.2 MHz */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP 100 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP 120 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP TB */
+		{-1, -1, -1, -1, -1, -1, -1}	/* OPP NT */
+	},
+	{	/* 24 MHz */
+		{300, 23, 1, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{600, 23, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{720, 23, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{800, 23, 1, -1, -1, -1, -1},	/* OPP TB */
+		{1000, 23, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+	{	/* 25 MHz */
+		{300, 24, 1, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{600, 24, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{720, 24, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{800, 24, 1, -1, -1, -1, -1},	/* OPP TB */
+		{1000, 24, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+	{	/* 26 MHz */
+		{300, 25, 1, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{600, 25, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{720, 25, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{800, 25, 1, -1, -1, -1, -1},	/* OPP TB */
+		{1000, 25, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+};
+
+const struct dpll_params dpll_core[NUM_CRYSTAL_FREQ] = {
+		{-1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+		{1000, 23, -1, -1, 10, 8, 4},	/* 24 MHz */
+		{1000, 24, -1, -1, 10, 8, 4},	/* 25 MHz */
+		{1000, 25, -1, -1, 10, 8, 4}	/* 26 MHz */
+};
+
+const struct dpll_params dpll_per[NUM_CRYSTAL_FREQ] = {
+		{-1, -1, -1, -1, -1, -1, -1},	/* 19.2 MHz */
+		{960, 23, 5, -1, -1, -1, -1},	/* 24 MHz */
+		{960, 24, 5, -1, -1, -1, -1},	/* 25 MHz */
+		{960, 25, 5, -1, -1, -1, -1}	/* 26 MHz */
+};
+
+const struct dpll_params epos_evm_dpll_ddr = {
+		266, 24, 1, -1, 1, -1, -1};
+
+const struct dpll_params gp_evm_dpll_ddr = {
+		400, 23, 1, -1, 1, -1, -1};
 
 const struct dpll_params *get_dpll_ddr_params(void)
 {
-	return &dpll_ddr;
+	struct am43xx_board_id header;
+
+	enable_i2c0_pin_mux();
+	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
+	if (read_eeprom(&header) < 0)
+		puts("Could not get board ID.\n");
+
+	if (board_is_eposevm())
+		return &epos_evm_dpll_ddr;
+	else if (board_is_gpevm())
+		return &gp_evm_dpll_ddr;
+
+	puts(" Board not supported\n");
+	return NULL;
+}
+
+/*
+ * get_sys_clk_index : returns the index of the sys_clk read from
+ *			ctrl status register. This value is either
+ *			read from efuse or sysboot pins.
+ */
+static u32 get_sys_clk_index(void)
+{
+	struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
+	u32 ind = readl(&ctrl->statusreg), src;
+
+	src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
+	if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
+		return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
+			CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
+	else /* Value read from SYS BOOT pins */
+		return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
+			CTRL_SYSBOOT_15_14_SHIFT);
+}
+
+/*
+ * get_opp_offset:
+ * Returns the index for safest OPP of the device to boot.
+ * max_off:	Index of the MAX OPP in DEV ATTRIBUTE register.
+ * min_off:	Index of the MIN OPP in DEV ATTRIBUTE register.
+ * This data is read from dev_attribute register which is e-fused.
+ * A'1' in bit indicates OPP disabled and not available, a '0' indicates
+ * OPP available. Lowest OPP starts with min_off. So returning the
+ * bit with rightmost '0'.
+ */
+static int get_opp_offset(int max_off, int min_off)
+{
+	struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
+	int opp = readl(&ctrl->dev_attr), offset, i;
+
+	for (i = max_off; i >= min_off; i--) {
+		offset = opp & (1 << i);
+		if (!offset)
+			return i;
+	}
+
+	return min_off;
+}
+
+const struct dpll_params *get_dpll_mpu_params(void)
+{
+	int opp = get_opp_offset(DEV_ATTR_MAX_OFFSET, DEV_ATTR_MIN_OFFSET);
+	u32 ind = get_sys_clk_index();
+
+	return &dpll_mpu[ind][opp];
+}
+
+const struct dpll_params *get_dpll_core_params(void)
+{
+	int ind = get_sys_clk_index();
+
+	return &dpll_core[ind];
+}
+
+const struct dpll_params *get_dpll_per_params(void)
+{
+	int ind = get_sys_clk_index();
+
+	return &dpll_per[ind];
 }
 
 void set_uart_mux_conf(void)
diff --git a/board/ti/am43xx/board.h b/board/ti/am43xx/board.h
index 9268895..091162e 100644
--- a/board/ti/am43xx/board.h
+++ b/board/ti/am43xx/board.h
@@ -25,6 +25,9 @@ static char *const am43xx_board_name = (char *)AM4372_BOARD_NAME_START;
 #define HDR_ETH_ALEN		6
 #define HDR_NAME_LEN		8
 
+#define DEV_ATTR_MAX_OFFSET	5
+#define DEV_ATTR_MIN_OFFSET	0
+
 struct am43xx_board_id {
 	unsigned int  magic;
 	char name[HDR_NAME_LEN];
@@ -46,4 +49,5 @@ static inline int board_is_gpevm(void)
 
 void enable_uart0_pin_mux(void);
 void enable_board_pin_mux(void);
+void enable_i2c0_pin_mux(void);
 #endif
diff --git a/board/ti/am43xx/mux.c b/board/ti/am43xx/mux.c
index 46bad01..a2d72dd 100644
--- a/board/ti/am43xx/mux.c
+++ b/board/ti/am43xx/mux.c
@@ -43,3 +43,8 @@ void enable_board_pin_mux(void)
 	configure_module_pin_mux(mmc0_pin_mux);
 	configure_module_pin_mux(i2c0_pin_mux);
 }
+
+void enable_i2c0_pin_mux(void)
+{
+	configure_module_pin_mux(i2c0_pin_mux);
+}
-- 
1.7.9.5



More information about the U-Boot mailing list