
On 30.11.2018, at 19:37, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Christoph Muellner christoph.muellner@theobroma-systems.com Date: Mon, 19 Nov 2018 14:44:13 +0100
This patch sets the PLL of CPU cluster B (BPLL) to 600 MHz. This decreases the boot time of Linux 4.19 by about 8%.
The 600 MHz are inspired by the 600 MHz used for LPLL initialization (came in with commit 9f636a249c1).
Tested on RK3399-Q7 on Haikou base board.
Hi Christoph,
Philipp's reviewed-by reminded me that I wanted to check this diff to see whether it has the same bug as the firmware that came with my board. Unfortunately I think it does...
Signed-off-by: Christoph Muellner christoph.muellner@theobroma-systems.com
arch/arm/include/asm/arch-rockchip/cru_rk3399.h | 22 +++++-- drivers/clk/rockchip/clk_rk3399.c | 79 ++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 13 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h index b18de9f7c2e..15eeb9c4407 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h @@ -69,16 +69,21 @@ check_member(rk3399_cru, sdio1_con[1], 0x594); #define MHz 1000000 #define KHz 1000 #define OSC_HZ (24*MHz) -#define APLL_HZ (600*MHz) +#define LPLL_HZ (600*MHz) +#define BPLL_HZ (600*MHz) #define GPLL_HZ (594*MHz) #define CPLL_HZ (384*MHz) #define PPLL_HZ (676*MHz)
#define PMU_PCLK_HZ (48*MHz)
-#define ACLKM_CORE_HZ (300*MHz) -#define ATCLK_CORE_HZ (300*MHz) -#define PCLK_DBG_HZ (100*MHz) +#define ACLKM_CORE_L_HZ (300*MHz) +#define ATCLK_CORE_L_HZ (300*MHz) +#define PCLK_DBG_L_HZ (100*MHz)
+#define ACLKM_CORE_B_HZ (300*MHz) +#define ATCLK_CORE_B_HZ (300*MHz) +#define PCLK_DBG_B_HZ (100*MHz)
#define PERIHP_ACLK_HZ (148500*KHz) #define PERIHP_HCLK_HZ (148500*KHz) @@ -98,4 +103,13 @@ enum apll_l_frequencies { APLL_L_600_MHZ, };
+enum apll_b_frequencies {
- APLL_B_600_MHZ,
+};
+void rk3399_configure_cpu_l(struct rk3399_cru *cru,
enum apll_l_frequencies apll_l_freq);
+void rk3399_configure_cpu_b(struct rk3399_cru *cru,
enum apll_b_frequencies apll_b_freq);
#endif /* __ASM_ARCH_CRU_RK3399_H_ */ diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 26faf88116b..0a8178466dc 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -61,6 +61,11 @@ static const struct pll_div *apll_l_cfgs[] = { [APLL_L_600_MHZ] = &apll_l_600_cfg, };
+static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1); +static const struct pll_div *apll_b_cfgs[] = {
- [APLL_B_600_MHZ] = &apll_b_600_cfg,
+};
enum { /* PLL_CON0 */ PLL_FBDIV_MASK = 0xfff, @@ -128,6 +133,24 @@ enum { ATCLK_CORE_L_DIV_SHIFT = 0, ATCLK_CORE_L_DIV_MASK = 0x1f << ATCLK_CORE_L_DIV_SHIFT,
- /* CLKSEL_CON2 */
- ACLKM_CORE_B_DIV_CON_SHIFT = 8,
- ACLKM_CORE_B_DIV_CON_MASK = 0x1f << ACLKM_CORE_B_DIV_CON_SHIFT,
- CLK_CORE_B_PLL_SEL_SHIFT = 6,
- CLK_CORE_B_PLL_SEL_MASK = 3 << CLK_CORE_B_PLL_SEL_SHIFT,
- CLK_CORE_B_PLL_SEL_ALPLL = 0x0,
- CLK_CORE_B_PLL_SEL_ABPLL = 0x1,
- CLK_CORE_B_PLL_SEL_DPLL = 0x10,
- CLK_CORE_B_PLL_SEL_GPLL = 0x11,
- CLK_CORE_B_DIV_MASK = 0x1f,
- CLK_CORE_B_DIV_SHIFT = 0,
- /* CLKSEL_CON3 */
- PCLK_DBG_B_DIV_SHIFT = 0x8,
- PCLK_DBG_B_DIV_MASK = 0x1f << PCLK_DBG_B_DIV_SHIFT,
- ATCLK_CORE_B_DIV_SHIFT = 0,
- ATCLK_CORE_B_DIV_MASK = 0x1f << ATCLK_CORE_B_DIV_SHIFT,
- /* CLKSEL_CON14 */ PCLK_PERIHP_DIV_CON_SHIFT = 12, PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
@@ -395,25 +418,26 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div) return 0; }
-void rk3399_configure_cpu(struct rk3399_cru *cru,
enum apll_l_frequencies apll_l_freq)
+void rk3399_configure_cpu_l(struct rk3399_cru *cru,
enum apll_l_frequencies apll_l_freq)
{ u32 aclkm_div; u32 pclk_dbg_div; u32 atclk_div;
- /* Setup cluster L */ rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]);
- aclkm_div = APLL_HZ / ACLKM_CORE_HZ - 1;
- assert((aclkm_div + 1) * ACLKM_CORE_HZ == APLL_HZ &&
- aclkm_div = LPLL_HZ / ACLKM_CORE_L_HZ - 1;
- assert((aclkm_div + 1) * ACLKM_CORE_L_HZ == LPLL_HZ && aclkm_div < 0x1f);
- pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ - 1;
- assert((pclk_dbg_div + 1) * PCLK_DBG_HZ == APLL_HZ &&
- pclk_dbg_div = LPLL_HZ / PCLK_DBG_L_HZ - 1;
- assert((pclk_dbg_div + 1) * PCLK_DBG_L_HZ == LPLL_HZ && pclk_dbg_div < 0x1f);
- atclk_div = APLL_HZ / ATCLK_CORE_HZ - 1;
- assert((atclk_div + 1) * ATCLK_CORE_HZ == APLL_HZ &&
atclk_div = LPLL_HZ / ATCLK_CORE_L_HZ - 1;
assert((atclk_div + 1) * ATCLK_CORE_L_HZ == LPLL_HZ && atclk_div < 0x1f);
rk_clrsetreg(&cru->clksel_con[0],
@@ -428,6 +452,42 @@ void rk3399_configure_cpu(struct rk3399_cru *cru, pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT | atclk_div << ATCLK_CORE_L_DIV_SHIFT); }
+void rk3399_configure_cpu_b(struct rk3399_cru *cru,
enum apll_b_frequencies apll_b_freq)
+{
- u32 aclkm_div;
- u32 pclk_dbg_div;
- u32 atclk_div;
- /* Setup cluster B */
- rkclk_set_pll(&cru->apll_b_con[0], apll_b_cfgs[apll_b_freq]);
- aclkm_div = BPLL_HZ / ACLKM_CORE_B_HZ - 1;
- assert((aclkm_div + 1) * ACLKM_CORE_B_HZ == BPLL_HZ &&
aclkm_div < 0x1f);
- pclk_dbg_div = BPLL_HZ / PCLK_DBG_B_HZ - 1;
- assert((pclk_dbg_div + 1) * PCLK_DBG_B_HZ == BPLL_HZ &&
pclk_dbg_div < 0x1f);
- atclk_div = BPLL_HZ / ATCLK_CORE_B_HZ - 1;
- assert((atclk_div + 1) * ATCLK_CORE_B_HZ == BPLL_HZ &&
atclk_div < 0x1f);
- rk_clrsetreg(&cru->clksel_con[2],
ACLKM_CORE_B_DIV_CON_MASK | CLK_CORE_B_PLL_SEL_MASK |
CLK_CORE_B_DIV_MASK,
aclkm_div << ACLKM_CORE_B_DIV_CON_SHIFT |
CLK_CORE_B_PLL_SEL_ALPLL << CLK_CORE_B_PLL_SEL_SHIFT |
0 << CLK_CORE_B_DIV_SHIFT);
...since this sets the parent of the CPU clock for the B cluster to LPLL. I'm pretty sure you should use CLK_CORE_B_PLL_SEL_ABPLL here.
Hi Mark,
you are indeed right here (I just double checked with the TRM). I guess I never encountered a problem, because Linux sets this right later on (before clocking LPLL up). Anyways, we want to run from BPLL after setting it up.
Thanks, Christoph
With LPLL as the parent, running OpenBSD on the board didn't work very well since changing the clock of the L cluster would also change the clock of the B cluster, but without changing the voltage of the B cluster...
- rk_clrsetreg(&cru->clksel_con[3],
PCLK_DBG_B_DIV_MASK | ATCLK_CORE_B_DIV_MASK,
pclk_dbg_div << PCLK_DBG_B_DIV_SHIFT |
atclk_div << ATCLK_CORE_B_DIV_SHIFT);
+}
#define I2C_CLK_REG_MASK(bus) \ (I2C_DIV_CON_MASK << \ CLK_I2C ##bus## _DIV_CON_SHIFT | \ @@ -1026,7 +1086,8 @@ static void rkclk_init(struct rk3399_cru *cru) u32 hclk_div; u32 pclk_div;
- rk3399_configure_cpu(cru, APLL_L_600_MHZ);
- rk3399_configure_cpu_l(cru, APLL_L_600_MHZ);
- rk3399_configure_cpu_b(cru, APLL_B_600_MHZ); /*
- some cru registers changed by bootrom, we'd better reset them to
- reset/default values described in TRM to avoid confusion in kernel.
-- 2.11.0
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot