[U-Boot] [PATCH v3 40/66] rockchip: clk: rk3368: do not change CPLL/GPLL before returning to BROM

Philipp Tomsich
2017-07-28T19:22:12Z

The RK3368 has a somewhat temperamental BootROM (which I learned the
hard way) when it comes to reconfiguring the CPLL and GPLL (in fact,
experiments show that changing the GPLL broke things for me, while
changing the CPLL seems to be more benign). These should not be
modified by the SPL stage, if we intend to return to the BootROM for
chain booting the next stage.

This commit changes the clock initialisation to not change CPLL/GPLL
before returning to the BootROM (i.e. in TPL). As it's safe to change
these settings if we no longer intend to return to U-Boot, we'll run
the full PLL setup a little later (i.e. in SPL).

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>

Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

drivers/clk/rockchip/clk_rk3368.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk_rk3368.c b/drivers/clk/rockchip/clk_rk3368.c
index 809ad19..d05be72 100644
--- a/drivers/clk/rockchip/clk_rk3368.c
+++ b/drivers/clk/rockchip/clk_rk3368.c
@@ -50,10 +50,14 @@ struct pll_div {
(_nr * _no) == hz, #hz "Hz cannot be hit with PLL " \
"divisors on line " __stringify(__LINE__));

+#if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD)
static const struct pll_div apll_l_init_cfg = PLL_DIVISORS(APLL_L_HZ, 12, 2);
static const struct pll_div apll_b_init_cfg = PLL_DIVISORS(APLL_B_HZ, 1, 2);
+#if !defined(CONFIG_TPL_BUILD)
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 2);
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 6);
+#endif
+#endif

/* Get pll rate by id */
static uint32_t rkclk_pll_get_rate(struct rk3368_cru *cru,
@@ -82,6 +86,7 @@ static uint32_t rkclk_pll_get_rate(struct rk3368_cru *cru,
}
}

+#if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD)
static int rkclk_set_pll(struct rk3368_cru *cru, enum rk3368_pll_id pll_id,
const struct pll_div *div)
{
@@ -121,15 +126,23 @@ static int rkclk_set_pll(struct rk3368_cru *cru, enum rk3368_pll_id pll_id,

return 0;
}
+#endif

+#if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD)
static void rkclk_init(struct rk3368_cru *cru)
{
u32 apllb, aplll, dpll, cpll, gpll;

rkclk_set_pll(cru, APLLB, &apll_b_init_cfg);
rkclk_set_pll(cru, APLLL, &apll_l_init_cfg);
+#if !defined(CONFIG_TPL_BUILD)
+ /*
+ * If we plan to return to the boot ROM, we can't increase the
+ * GPLL rate from the SPL stage.
+ */
rkclk_set_pll(cru, GPLL, &gpll_init_cfg);
rkclk_set_pll(cru, CPLL, &cpll_init_cfg);
+#endif

apllb = rkclk_pll_get_rate(cru, APLLB);
aplll = rkclk_pll_get_rate(cru, APLLL);
@@ -140,6 +153,7 @@ static void rkclk_init(struct rk3368_cru *cru)
debug("%s apllb(%d) apll(%d) dpll(%d) cpll(%d) gpll(%d)\n",
__func__, apllb, aplll, dpll, cpll, gpll);
}
+#endif

static ulong rk3368_mmc_get_clk(struct rk3368_cru *cru, uint clk_id)
{
@@ -261,13 +275,15 @@ static struct clk_ops rk3368_clk_ops = {

static int rk3368_clk_probe(struct udevice *dev)
{
- struct rk3368_clk_priv *priv = dev_get_priv(dev);
+ struct rk3368_clk_priv __maybe_unused *priv = dev_get_priv(dev);
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3368_clk_plat *plat = dev_get_platdata(dev);

priv->cru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
#endif
+#if IS_ENABLED(CONFIG_SPL_BUILD) || IS_ENABLED(CONFIG_TPL_BUILD)
rkclk_init(priv->cru);
+#endif

return 0;
}
--
2.1.4