Message ID | 20181119134413.60300-1-christoph.muellner@theobroma-systems.com |
---|---|
State | Superseded |
Delegated to: | Philipp Tomsich |
Headers | show |
Series | [U-Boot] rockchip: rk3399: Initialize CPU B clock. | expand |
> 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. > > 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(-) > Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> 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. 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
> 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
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); + + 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.
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. 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(-)