[U-Boot,4/8] rockchip: clk: rk3188: Allow configuration of the armclk

Message ID 20170320114036.21475-5-heiko@sntech.de
State Accepted
Commit f785357073be1563b2f668a1b4bb5847bfaa96f9
Delegated to: Simon Glass
Headers show

Commit Message

Heiko Stuebner March 20, 2017, 11:40 a.m.
The armclk starts in slow mode (24MHz) on the rk3188, which makes the whole
startup take a lot of time. We therefore want to at least move to the safe
600MHz value we can use with default pmic settings.
This is also the freqency the proprietary sdram-init leaves the cpu at.

For boards that have pmic control later in u-boot, we also add the option
to set the maximum frequency of 1.6GHz, if they so desire.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/include/asm/arch-rockchip/cru_rk3188.h |  1 +
 drivers/clk/rockchip/clk_rk3188.c               | 63 +++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

Comments

Simon Glass March 24, 2017, 3:27 a.m. | #1
On 20 March 2017 at 05:40, Heiko Stuebner <heiko@sntech.de> wrote:
> The armclk starts in slow mode (24MHz) on the rk3188, which makes the whole
> startup take a lot of time. We therefore want to at least move to the safe
> 600MHz value we can use with default pmic settings.
> This is also the freqency the proprietary sdram-init leaves the cpu at.
>
> For boards that have pmic control later in u-boot, we also add the option
> to set the maximum frequency of 1.6GHz, if they so desire.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>  arch/arm/include/asm/arch-rockchip/cru_rk3188.h |  1 +
>  drivers/clk/rockchip/clk_rk3188.c               | 63 +++++++++++++++++++++++++
>  2 files changed, 64 insertions(+)

Acked-by: Simon Glass <sjg@chromium.org>
Simon Glass March 26, 2017, 2:42 a.m. | #2
On 23 March 2017 at 21:27, Simon Glass <sjg@chromium.org> wrote:
> On 20 March 2017 at 05:40, Heiko Stuebner <heiko@sntech.de> wrote:
>> The armclk starts in slow mode (24MHz) on the rk3188, which makes the whole
>> startup take a lot of time. We therefore want to at least move to the safe
>> 600MHz value we can use with default pmic settings.
>> This is also the freqency the proprietary sdram-init leaves the cpu at.
>>
>> For boards that have pmic control later in u-boot, we also add the option
>> to set the maximum frequency of 1.6GHz, if they so desire.
>>
>> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
>> ---
>>  arch/arm/include/asm/arch-rockchip/cru_rk3188.h |  1 +
>>  drivers/clk/rockchip/clk_rk3188.c               | 63 +++++++++++++++++++++++++
>>  2 files changed, 64 insertions(+)
>
> Acked-by: Simon Glass <sjg@chromium.org>

Applied to u-boot-rockchip, thanks!

Patch

diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3188.h b/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
index 74f0fedcc6..f5d6420d04 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
@@ -9,6 +9,7 @@ 
 #define OSC_HZ		(24 * 1000 * 1000)
 
 #define APLL_HZ		(1608 * 1000000)
+#define APLL_SAFE_HZ	(600 * 1000000)
 #define GPLL_HZ		(594 * 1000000)
 #define CPLL_HZ		(384 * 1000000)
 
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);