Skip to contentSkip to conversation

sunxi: Add clock_get_pll5p() function

PATCH New Hans de Goede 3 participants 7 messages Oct 22, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 sunxi: Add clock_get_pll5p() function

This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig.

---
 arch/arm/cpu/armv7/sunxi/clock_sun4i.c        | 11 +++++++++++
 arch/arm/include/asm/arch-sunxi/clock.h       |  1 +
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |  3 +++
 3 files changed, 15 insertions(+)
arch/arm/cpu/armv7/sunxi/clock_sun4i.c +11 -0
index ecbdb01..4a0d64f 100644
@@ -180,6 +180,17 @@ void clock_set_pll1(unsigned int hz)
 }
 #endif
 
+unsigned int clock_get_pll5p(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	uint32_t rval = readl(&ccm->pll5_cfg);
+	int n = ((rval & CCM_PLL5_CTRL_N_MASK) >> CCM_PLL5_CTRL_N_SHIFT);
+	int k = ((rval & CCM_PLL5_CTRL_K_MASK) >> CCM_PLL5_CTRL_K_SHIFT) + 1;
+	int p = ((rval & CCM_PLL5_CTRL_P_MASK) >> CCM_PLL5_CTRL_P_SHIFT);
+	return (24000000 * n * k) >> p;
+}
+
 unsigned int clock_get_pll6(void)
 {
 	struct sunxi_ccm_reg *const ccm =
arch/arm/include/asm/arch-sunxi/clock.h +1 -0
index 8f5d860..9775c85 100644
@@ -25,6 +25,7 @@
 int clock_init(void);
 int clock_twi_onoff(int port, int state);
 void clock_set_pll1(unsigned int hz);
+unsigned int clock_get_pll5p(void);
 unsigned int clock_get_pll6(void);
 void clock_init_safe(void);
 void clock_init_uart(void);
arch/arm/include/asm/arch-sunxi/clock_sun4i.h +3 -0
index 1ba997a..90af8e2 100644
@@ -199,13 +199,16 @@ struct sunxi_ccm_reg {
 #define CCM_PLL5_CTRL_M1_MASK CCM_PLL5_CTRL_M1(0x3)
 #define CCM_PLL5_CTRL_M1_X(n) ((n) - 1)
 #define CCM_PLL5_CTRL_K(n) (((n) & 0x3) << 4)
+#define CCM_PLL5_CTRL_K_SHIFT 4
 #define CCM_PLL5_CTRL_K_MASK CCM_PLL5_CTRL_K(0x3)
 #define CCM_PLL5_CTRL_K_X(n) ((n) - 1)
 #define CCM_PLL5_CTRL_LDO (0x1 << 7)
 #define CCM_PLL5_CTRL_N(n) (((n) & 0x1f) << 8)
+#define CCM_PLL5_CTRL_N_SHIFT 8
 #define CCM_PLL5_CTRL_N_MASK CCM_PLL5_CTRL_N(0x1f)
 #define CCM_PLL5_CTRL_N_X(n) (n)
 #define CCM_PLL5_CTRL_P(n) (((n) & 0x3) << 16)
+#define CCM_PLL5_CTRL_P_SHIFT 16
 #define CCM_PLL5_CTRL_P_MASK CCM_PLL5_CTRL_P(0x3)
 #define CCM_PLL5_CTRL_P_X(n) ((n) - 1)
 #define CCM_PLL5_CTRL_BW (0x1 << 18)
Signature · 1 line
2.1.0
#1 lore raw

PATCH 2/3 sunxi: dram: Use clock_get_pll5p to calculate mbus, rather then hardcoding

This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig.

---
 arch/arm/cpu/armv7/sunxi/dram.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)
arch/arm/cpu/armv7/sunxi/dram.c +14 -18
index 584f742..0cbcf57 100644
@@ -252,15 +252,9 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 {
 	u32 reg_val;
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
-	/* PLL5P and PLL6 are the potential clock sources for MBUS */
-	u32 pll6x_div, pll5p_div;
-	u32 pll6x_clk = clock_get_pll6() / 1000000;
-	u32 pll5p_clk = clk / 24 * 48;
+	u32 pll5p_clk, pll6x_clk;
+	u32 pll5p_div, pll6x_div;
 	u32 pll5p_rate, pll6x_rate;
-#ifdef CONFIG_SUN7I
-	pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
-#endif
 
 	/* setup DRAM PLL */
 	reg_val = readl(&ccm->pll5_cfg);
@@ -269,32 +263,27 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 	reg_val &= ~CCM_PLL5_CTRL_N_MASK;		/* set N to 0 (x0) */
 	reg_val &= ~CCM_PLL5_CTRL_P_MASK;		/* set P to 0 (x1) */
 	if (clk >= 540 && clk < 552) {
-		/* dram = 540MHz, pll5p = 1080MHz */
-		pll5p_clk = 1080;
+		/* dram = 540MHz */
 		reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
 	} else if (clk >= 512 && clk < 528) {
-		/* dram = 512MHz, pll5p = 1536MHz */
-		pll5p_clk = 1536;
+		/* dram = 512MHz */
 		reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
 	} else if (clk >= 496 && clk < 504) {
-		/* dram = 496MHz, pll5p = 1488MHz */
-		pll5p_clk = 1488;
+		/* dram = 496MHz */
 		reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
 	} else if (clk >= 468 && clk < 480) {
-		/* dram = 468MHz, pll5p = 936MHz */
-		pll5p_clk = 936;
+		/* dram = 468MHz */
 		reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
 	} else if (clk >= 396 && clk < 408) {
-		/* dram = 396MHz, pll5p = 792MHz */
-		pll5p_clk = 792;
+		/* dram = 396MHz */
 		reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
@@ -322,6 +311,13 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 	/* setup MBUS clock */
 	if (!mbus_clk)
 		mbus_clk = 300;
+
+	/* PLL5P and PLL6 are the potential clock sources for MBUS */
+	pll6x_clk = clock_get_pll6() / 1000000;
+#ifdef CONFIG_SUN7I
+	pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
+#endif
+	pll5p_clk = clock_get_pll5p() / 1000000;
 	pll6x_div = DIV_ROUND_UP(pll6x_clk, mbus_clk);
 	pll5p_div = DIV_ROUND_UP(pll5p_clk, mbus_clk);
 	pll6x_rate = pll6x_clk / pll6x_div;
Signature · 1 line
2.1.0
#3 lore raw

PATCH 3/3 sunxi: Add CONFIG_OLD_KERNEL_COMPAT Kconfig option

In reply to Hans de Goede

Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds.

---
 arch/arm/cpu/armv7/sunxi/dram.c | 4 ++++
 board/sunxi/Kconfig             | 7 +++++++
 2 files changed, 11 insertions(+)
arch/arm/cpu/armv7/sunxi/dram.c +4 -0
index 0cbcf57..c0dc456 100644
@@ -293,6 +293,10 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
 	}
+#ifdef CONFIG_OLD_KERNEL_COMPAT
+	/* Old kernels are hardcoded to P=1 (divide by 2) */
+	reg_val |= CCM_PLL5_CTRL_P(1);
+#endif
 	reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN;		/* PLL VCO Gain off */
 	reg_val |= CCM_PLL5_CTRL_EN;			/* PLL On */
 	writel(reg_val, &ccm->pll5_cfg);
board/sunxi/Kconfig +7 -0
index 66261fc..0331088 100644
@@ -19,6 +19,13 @@ config SYS_SOC
 config FDTFILE
 	string "Default fdtfile env setting for this board"
 
+config OLD_KERNEL_COMPAT
+	boolean "Enable workarounds for booting old kernels"
+	default n
+	---help---
+	Set this to enable various workarounds for old kernels, this results in
+	sub-optimal settings for newer kernels, only enable if needed.
+
 config MMC0_CD_PIN
 	string "Card detect pin for mmc0"
 	default ""
Signature · 1 line
2.1.0
#4 lore raw

PATCH 3/3 sunxi: Add CONFIG_OLD_KERNEL_COMPAT Kconfig option

Quoted 16 lines · Hans de Goede

Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds.

---
 arch/arm/cpu/armv7/sunxi/dram.c | 4 ++++
 board/sunxi/Kconfig             | 7 +++++++
 2 files changed, 11 insertions(+)
arch/arm/cpu/armv7/sunxi/dram.c +0 -0
index 0cbcf57..c0dc456 100644

arch/arm/cpu/armv7/sunxi/dram.c static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) · line 299

Quoted 7 lines
arch/arm/cpu/armv7/sunxi/dram.c +4 -0
@@ -293,6 +293,10 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
 		reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
 		reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
 	}
+#ifdef CONFIG_OLD_KERNEL_COMPAT
+	/* Old kernels are hardcoded to P=1 (divide by 2) */
+	reg_val |= CCM_PLL5_CTRL_P(1);
+#endif

I think this would be better placed above the if/else ladder, just next to the:

    reg_val &= ~CCM_PLL5_CTRL_P_MASK;               /* set P to 0 (x1) */

i.e. keep the frobbings of P in the same place.

Ian.

#5 lore raw

PATCH 3/3 sunxi: Add CONFIG_OLD_KERNEL_COMPAT Kconfig option

In reply to Hans de Goede
Quoted 4 lines · Hans de Goede

Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds.

Conceptually fine, but please do CONFIG_OLD_SUNXI_KERNEL_COMPAT so that we don't start using this symbol more broadly and so it's clear where exactly it's compat for. Thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141022/75c8f914/attachment.pgp>