diff options
Diffstat (limited to 'drivers/clk/rockchip')
-rw-r--r-- | drivers/clk/rockchip/clk_rk3188.c | 63 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk_rk3399.c | 13 |
2 files changed, 74 insertions, 2 deletions
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c index 459649f724..d36cf8f3f2 100644 --- a/drivers/clk/rockchip/clk_rk3188.c +++ b/drivers/clk/rockchip/clk_rk3188.c @@ -168,6 +168,65 @@ static int rkclk_configure_ddr(struct rk3188_cru *cru, struct rk3188_grf *grf, return 0; } +static int rkclk_configure_cpu(struct rk3188_cru *cru, struct rk3188_grf *grf, + unsigned int hz, bool has_bwadj) +{ + static const struct pll_div apll_cfg[] = { + {.nf = 50, .nr = 1, .no = 2}, + {.nf = 67, .nr = 1, .no = 1}, + }; + int div_core_peri, div_aclk_core, cfg; + + /* + * We support two possible frequencies, the safe 600MHz + * which will work with default pmic settings and will + * be set in SPL to get away from the 24MHz default and + * the maximum of 1.6Ghz, which boards can set if they + * were able to get pmic support for it. + */ + switch (hz) { + case APLL_SAFE_HZ: + cfg = 0; + div_core_peri = 1; + div_aclk_core = 3; + break; + case APLL_HZ: + cfg = 1; + div_core_peri = 2; + div_aclk_core = 3; + break; + default: + debug("Unsupported ARMCLK frequency"); + return -EINVAL; + } + + /* pll enter slow-mode */ + rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK << APLL_MODE_SHIFT, + APLL_MODE_SLOW << APLL_MODE_SHIFT); + + rkclk_set_pll(cru, CLK_ARM, &apll_cfg[cfg], has_bwadj); + + /* waiting for pll lock */ + while (!(readl(&grf->soc_status0) & SOCSTS_APLL_LOCK)) + udelay(1); + + /* Set divider for peripherals attached to the cpu core. */ + rk_clrsetreg(&cru->cru_clksel_con[0], + CORE_PERI_DIV_MASK << CORE_PERI_DIV_SHIFT, + div_core_peri << CORE_PERI_DIV_SHIFT); + + /* set up dependent divisor for aclk_core */ + rk_clrsetreg(&cru->cru_clksel_con[1], + CORE_ACLK_DIV_MASK << CORE_ACLK_DIV_SHIFT, + div_aclk_core << CORE_ACLK_DIV_SHIFT); + + /* PLL enter normal-mode */ + rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK << APLL_MODE_SHIFT, + APLL_MODE_NORMAL << APLL_MODE_SHIFT); + + return hz; +} + /* Get pll rate by id */ static uint32_t rkclk_pll_get_rate(struct rk3188_cru *cru, enum rk_clk_id clk_id) @@ -435,6 +494,10 @@ static ulong rk3188_clk_set_rate(struct clk *clk, ulong rate) ulong new_rate; switch (clk->id) { + case PLL_APLL: + new_rate = rkclk_configure_cpu(priv->cru, priv->grf, rate, + priv->has_bwadj); + break; case CLK_DDR: new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate, priv->has_bwadj); diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 922ce7e549..ff3cc37af3 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -47,9 +47,12 @@ struct pll_div { .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2}; +#if defined(CONFIG_SPL_BUILD) 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); +#else static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1); +#endif static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1); static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1); @@ -664,7 +667,7 @@ static ulong rk3399_mmc_get_clk(struct rk3399_cru *cru, uint clk_id) if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT == CLK_EMMC_PLL_SEL_24M) - return DIV_TO_RATE(24*1024*1024, div); + return DIV_TO_RATE(24*1000*1000, div); else return DIV_TO_RATE(GPLL_HZ, div); } @@ -682,7 +685,7 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru, if (src_clk_div > 127) { /* use 24MHz source for 400KHz clock */ - src_clk_div = 24*1024*1024 / set_rate; + src_clk_div = 24*1000*1000 / set_rate; rk_clrsetreg(&cru->clksel_con[16], CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | @@ -799,6 +802,10 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) case SCLK_EMMC: ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate); break; + case SCLK_MAC: + /* nothing to do, as this is an external clock */ + ret = rate; + break; case SCLK_I2C1: case SCLK_I2C2: case SCLK_I2C3: @@ -1009,7 +1016,9 @@ static void pmuclk_init(struct rk3399_pmucru *pmucru) static int rk3399_pmuclk_probe(struct udevice *dev) { +#if CONFIG_IS_ENABLED(OF_PLATDATA) || !defined(CONFIG_SPL_BUILD) struct rk3399_pmuclk_priv *priv = dev_get_priv(dev); +#endif #if CONFIG_IS_ENABLED(OF_PLATDATA) struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev); |