[coreboot-gerrit] Patch set updated for coreboot: rockchip/rk3399: Change PLL configuration to match Linux kernel

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu Nov 17 12:56:17 CET 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17378

-gerrit

commit b903720000fded4ab174028f3a33525efe100217
Author: Julius Werner <jwerner at chromium.org>
Date:   Tue Nov 1 15:24:54 2016 -0700

    rockchip/rk3399: Change PLL configuration to match Linux kernel
    
    The Kevin project has been too smooth and boring for our tastes in the
    last last few weeks, so we've decided to stir the pot a little bit and
    reshuffle all our PLL settings at the last minute. The new settings
    match exactly what the Linux kernel expects on boot, so it doesn't need
    to reinitialize anything and risk a glitch.
    
    Naturally, changing PLL rates will affect child clocks, so this patch
    changes vop_aclk (192MHz -> 200MHz, 400MHz in the kernel), pmu_pclk
    (99MHz -> 96.57MHz) and i2c0_src (198MHz -> 338MHz, leading to an
    effective I2C0 change 399193Hz -> 398584Hz).
    
    BRANCH=gru
    BUG=chrome-os-partner:59139
    TEST=Booted Kevin, sanity checking display and beep. Instrumented
    rockchip_rk3399_pll_set_params() in the kernel and confirmed that GPLL,
    PPLL and CPLL do not get reinitialized anymore (with additional kernel
    patch to ignore frac divider when it's not used). Also confirmed that
    /sys/kernel/debug/clk_summary now shows pclk_pmu_src 96571429 because
    the kernel doesn't even bother to reinitialize the divisor.
    
    Change-Id: Ib44d872a7b7f177fb2e60ccc6992f888835365eb
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 9b82056037be5a5aebf146784ffb246780013c96
    Original-Change-Id: Ie112104035b01166217a8c5b5586972b4d7ca6ec
    Original-Signed-off-by: Julius Werner <jwerner at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/405785
    Original-Commit-Ready: Xing Zheng <zhengxing at rock-chips.com>
    Original-Tested-by: Xing Zheng <zhengxing at rock-chips.com>
    Original-Reviewed-by: Xing Zheng <zhengxing at rock-chips.com>
    Original-Reviewed-by: Douglas Anderson <dianders at chromium.org>
---
 src/soc/rockchip/common/i2c.c               | 11 +++++---
 src/soc/rockchip/rk3399/clock.c             | 43 ++++++++++++++---------------
 src/soc/rockchip/rk3399/display.c           |  2 +-
 src/soc/rockchip/rk3399/include/soc/clock.h |  6 ++--
 4 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/src/soc/rockchip/common/i2c.c b/src/soc/rockchip/common/i2c.c
index 1bd88bb..a00d538 100644
--- a/src/soc/rockchip/common/i2c.c
+++ b/src/soc/rockchip/common/i2c.c
@@ -273,16 +273,19 @@ void i2c_init(unsigned int bus, unsigned int hz)
 	unsigned int divl;
 	unsigned int divh;
 	unsigned int i2c_src_clk;
+	unsigned int i2c_clk;
 	struct rk_i2c_regs *regs = (struct rk_i2c_regs *)(i2c_bus[bus]);
 
 	i2c_src_clk = rkclk_i2c_clock_for_bus(bus);
 
-	/*SCL Divisor = 8*(CLKDIVL + 1 + CLKDIVH + 1)
-	  SCL = PCLK/ SCLK Divisor
-	*/
+	/* SCL Divisor = 8*(CLKDIVL + 1 + CLKDIVH + 1)
+	   SCL = PCLK / SCLK Divisor */
 	clk_div = div_round_up(i2c_src_clk, hz * 8);
 	divh = clk_div * 3 / 7 - 1;
 	divl = clk_div - divh - 2;
-	assert((divh < 65536) && (divl < 65536));
+	i2c_clk = i2c_src_clk / (8 * (divl + 1 + divh + 1));
+	printk(BIOS_DEBUG, "I2C bus %u: %uHz (divh = %u, divl = %u)\n",
+	       bus, i2c_clk, divh, divl);
+	assert((divh < 65536) && (divl < 65536) && hz - i2c_clk < 10*KHz);
 	write32(&regs->i2c_clkdiv, (divh << 16) | (divl << 0));
 }
diff --git a/src/soc/rockchip/rk3399/clock.c b/src/soc/rockchip/rk3399/clock.c
index 2596853..ced78b3 100644
--- a/src/soc/rockchip/rk3399/clock.c
+++ b/src/soc/rockchip/rk3399/clock.c
@@ -40,12 +40,12 @@ struct pll_div {
 	.postdiv1 = _postdiv1, .postdiv2 = _postdiv2, .freq = hz};\
 	_Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
 			 OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
-			 #hz "Hz cannot be hit with PLL "\
+			 STRINGIFY(hz) " Hz cannot be hit with PLL "\
 			 "divisors on line " STRINGIFY(__LINE__))
 
-static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
-static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
-static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 3, 1);
+static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 3, 2, 1);
 
 static const struct pll_div apll_1512_cfg = PLL_DIVISORS(1512*MHz, 1, 1, 1);
 static const struct pll_div apll_600_cfg = PLL_DIVISORS(600*MHz, 1, 3, 1);
@@ -402,7 +402,8 @@ void rkclk_init(void)
 
 	/* configure pmu pclk */
 	pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
-	assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div <= 0x1f);
+	assert((unsigned int)(PPLL_HZ - (pclk_div + 1) * PMU_PCLK_HZ) <= pclk_div
+	       && pclk_div <= 0x1f);
 	write32(&pmucru_ptr->pmucru_clksel[0],
 		RK_CLRSETBITS(PMU_PCLK_DIV_CON_MASK << PMU_PCLK_DIV_CON_SHIFT,
 			      pclk_div << PMU_PCLK_DIV_CON_SHIFT));
@@ -631,15 +632,20 @@ void rkclk_configure_spi(unsigned int bus, unsigned int hz)
 		RK_CLRSETBITS(I2C_DIV_CON_MASK << I2C ##bus## _DIV_CON_SHIFT, \
 			      (clk_div - 1) << I2C ##bus## _DIV_CON_SHIFT)
 
-static void rkclk_configure_i2c(unsigned int bus, unsigned int hz)
+uint32_t rkclk_i2c_clock_for_bus(unsigned int bus)
 {
-	int src_clk_div;
-	int pll;
-
-	/* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
-	pll = (bus == 0 || bus == 4 || bus == 8) ? PPLL_HZ : GPLL_HZ;
-	src_clk_div = pll / hz;
-	assert((src_clk_div - 1 <= 127) && (src_clk_div * hz == pll));
+	int src_clk_div, pll, freq;
+
+	/* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll */
+	if (bus == 0 || bus == 4 || bus == 8) {
+		pll = PPLL_HZ;
+		freq = 338*MHz;
+	} else {
+		pll = GPLL_HZ;
+		freq = 198*MHz;
+	}
+	src_clk_div = pll / freq;
+	assert((src_clk_div - 1 <= 127) && (src_clk_div * freq == pll));
 
 	switch (bus) {
 	case 0:
@@ -679,15 +685,8 @@ static void rkclk_configure_i2c(unsigned int bus, unsigned int hz)
 			PMU_I2C_CLK_REG_VALUE(8, src_clk_div));
 		break;
 	default:
-		printk(BIOS_ERR, "do not support this i2c bus\n");
+		die("unknown i2c bus\n");
 	}
-}
-
-uint32_t rkclk_i2c_clock_for_bus(unsigned bus)
-{
-	uint32_t freq = 198 * 1000 * 1000;
-
-	rkclk_configure_i2c(bus, freq);
 
 	return freq;
 }
@@ -724,7 +723,7 @@ void rkclk_configure_i2s(unsigned int hz)
 	v = clk_gcd(CPLL_HZ, hz);
 	n = (CPLL_HZ / v) & (0xffff);
 	d = (hz / v) & (0xffff);
-	assert(hz == CPLL_HZ / n * d);
+	assert(hz == (u64)CPLL_HZ * d / n);
 	write32(&cru_ptr->clksel_con[96], d << 16 | n);
 
 	/**
diff --git a/src/soc/rockchip/rk3399/display.c b/src/soc/rockchip/rk3399/display.c
index 5b88478..671e518 100644
--- a/src/soc/rockchip/rk3399/display.c
+++ b/src/soc/rockchip/rk3399/display.c
@@ -52,7 +52,7 @@ void rk_display_init(device_t dev)
 		/* try EDP first, then HDMI */
 	case VOP_MODE_EDP:
 		printk(BIOS_DEBUG, "Attempting to set up EDP display.\n");
-		rkclk_configure_vop_aclk(vop_id, 192 * MHz);
+		rkclk_configure_vop_aclk(vop_id, 200 * MHz);
 
 		/* select edp signal from vop0 */
 		write32(&rk3399_grf->soc_con20, RK_CLRBITS(1 << 5));
diff --git a/src/soc/rockchip/rk3399/include/soc/clock.h b/src/soc/rockchip/rk3399/include/soc/clock.h
index 5926051..82bf215 100644
--- a/src/soc/rockchip/rk3399/include/soc/clock.h
+++ b/src/soc/rockchip/rk3399/include/soc/clock.h
@@ -74,10 +74,10 @@ static struct rk3399_cru_reg * const cru_ptr = (void *)CRU_BASE;
 
 #define OSC_HZ		(24*MHz)
 #define GPLL_HZ		(594*MHz)
-#define CPLL_HZ		(384*MHz)
-#define PPLL_HZ		(594*MHz)
+#define CPLL_HZ		(800*MHz)
+#define PPLL_HZ		(676*MHz)
 
-#define PMU_PCLK_HZ	(99*MHz)
+#define PMU_PCLK_HZ	96571428
 
 #define ACLKM_CORE_HZ	(300*MHz)
 #define ATCLK_CORE_HZ	(300*MHz)



More information about the coreboot-gerrit mailing list