summaryrefslogtreecommitdiff
path: root/drivers/clk/rockchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/rockchip')
-rw-r--r--drivers/clk/rockchip/clk_rk3188.c63
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c13
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);