From bdd06de15d3edc1398db72591f1a173fee5befab Mon Sep 17 00:00:00 2001
From: Lin Huang <hl@rock-chips.com>
Date: Tue, 28 Jun 2016 15:21:20 +0800
Subject: rockchip/rk3399: initialize apll_b

coreboot boots from the little core, and doesn't use the big core for
now, but if apll_b is set to the default 24MHz, it will take a long time
to enable the big core.  This will cause a watchdog crash, so apll_b
initialization to 600MHz needs to be done in coreboot.

BRANCH=none
BUG=chrome-os-partner:54817
TEST=Pick CL:353762 and see big CPU clocks look right
TEST=Boot from Gru and see no cpufreq warnings

Change-Id: Ie45cd2271555942e4321e9a9e523dc10f63d8107
Signed-off-by: Martin Roth <martinroth@chromium.org>
Original-Commit-Id:
Original-Change-Id: I20b8b591db3171e27740d85edce11f9e8797d849
Original-Signed-off-by: Martin Roth <martinroth@chromium.org>
Original-Original-Commit-Id: 16bc916174042620bebe19ae73d241002491aecc
Original-Original-Change-Id: Id3487138b383b6643ba7e3ce1eae501a6622da10
Original-Original-Signed-off-by: Lin Huang <hl@rock-chips.com>
Original-Original-Signed-off-by: Douglas Anderson <dianders@chromium.org>
Original-Original-Reviewed-on: https://chromium-review.googlesource.com/356399
Original-Original-Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Original-Tested-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://review.coreboot.org/15583
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan@google.com>
---
 src/soc/rockchip/rk3399/bootblock.c         |  2 +-
 src/soc/rockchip/rk3399/clock.c             | 81 ++++++++++++++++-------------
 src/soc/rockchip/rk3399/include/soc/clock.h |  2 +-
 3 files changed, 47 insertions(+), 38 deletions(-)

(limited to 'src/soc/rockchip')

diff --git a/src/soc/rockchip/rk3399/bootblock.c b/src/soc/rockchip/rk3399/bootblock.c
index 3e95a17267..4f85e94ff4 100644
--- a/src/soc/rockchip/rk3399/bootblock.c
+++ b/src/soc/rockchip/rk3399/bootblock.c
@@ -22,7 +22,7 @@
 void bootblock_soc_init(void)
 {
 	rkclk_init();
-	rkclk_configure_cpu(APLL_600_MHZ);
+	rkclk_configure_cpu(APLL_600_MHZ, false);
 
 	/* all ddr range non-secure */
 	write32(&rk3399_pmusgrf->ddr_rgn_con[16], 0xff << 16 | 0);
diff --git a/src/soc/rockchip/rk3399/clock.c b/src/soc/rockchip/rk3399/clock.c
index 9388487672..cfe363c681 100644
--- a/src/soc/rockchip/rk3399/clock.c
+++ b/src/soc/rockchip/rk3399/clock.c
@@ -104,23 +104,23 @@ enum {
 	/* PMUCRU_CLKSEL_CON3 */
 	I2C4_DIV_CON_SHIFT		= 0,
 
-	/* CLKSEL_CON0 */
-	ACLKM_CORE_L_DIV_CON_MASK	= 0x1f,
-	ACLKM_CORE_L_DIV_CON_SHIFT	= 8,
-	CLK_CORE_L_PLL_SEL_MASK		= 3,
-	CLK_CORE_L_PLL_SEL_SHIFT	= 6,
-	CLK_CORE_L_PLL_SEL_ALPLL	= 0x0,
-	CLK_CORE_L_PLL_SEL_ABPLL	= 0x1,
-	CLK_CORE_L_PLL_SEL_DPLL		= 0x10,
-	CLK_CORE_L_PLL_SEL_GPLL		= 0x11,
-	CLK_CORE_L_DIV_MASK		= 0x1f,
-	CLK_CORE_L_DIV_SHIFT		= 0,
-
-	/* CLKSEL_CON1 */
-	PCLK_DBG_L_DIV_MASK		= 0x1f,
-	PCLK_DBG_L_DIV_SHIFT		= 0x8,
-	ATCLK_CORE_L_DIV_MASK		= 0x1f,
-	ATCLK_CORE_L_DIV_SHIFT		= 0,
+	/* CLKSEL_CON0 / CLKSEL_CON2 */
+	ACLKM_CORE_DIV_CON_MASK	= 0x1f,
+	ACLKM_CORE_DIV_CON_SHIFT	= 8,
+	CLK_CORE_PLL_SEL_MASK		= 3,
+	CLK_CORE_PLL_SEL_SHIFT		= 6,
+	CLK_CORE_PLL_SEL_ALPLL		= 0x0,
+	CLK_CORE_PLL_SEL_ABPLL		= 0x1,
+	CLK_CORE_PLL_SEL_DPLL		= 0x10,
+	CLK_CORE_PLL_SEL_GPLL		= 0x11,
+	CLK_CORE_DIV_MASK		= 0x1f,
+	CLK_CORE_DIV_SHIFT		= 0,
+
+	/* CLKSEL_CON1 / CLKSEL_CON3 */
+	PCLK_DBG_DIV_MASK		= 0x1f,
+	PCLK_DBG_DIV_SHIFT		= 0x8,
+	ATCLK_CORE_DIV_MASK		= 0x1f,
+	ATCLK_CORE_DIV_SHIFT		= 0,
 
 	/* CLKSEL_CON14 */
 	PCLK_PERIHP_DIV_CON_MASK	= 0x7,
@@ -411,6 +411,13 @@ void rkclk_init(void)
 	rkclk_set_pll(&cru_ptr->gpll_con[0], &gpll_init_cfg);
 	rkclk_set_pll(&cru_ptr->cpll_con[0], &cpll_init_cfg);
 
+	/*
+	 * coreboot boot from little core, but it seem if apll_b use defalut
+	 * 24MHz it will take a long time to enable big core, and will cause
+	 * a watchdog crash, so we should do apll_b initialization here
+	 */
+	rkclk_configure_cpu(APLL_600_MHZ, true);
+
 	/* configure perihp aclk, hclk, pclk */
 	aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
 	assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
@@ -487,16 +494,20 @@ void rkclk_init(void)
 						HCLK_PERILP1_PLL_SEL_SHIFT));
 }
 
-void rkclk_configure_cpu(enum apll_frequencies apll_l_freq)
+void rkclk_configure_cpu(enum apll_frequencies apll_freq, bool is_big)
 {
 	u32 aclkm_div;
 	u32 pclk_dbg_div;
 	u32 atclk_div;
 	u32 apll_l_hz;
+	int con_base = is_big ? 2 : 0;
+	int parent = is_big ? CLK_CORE_PLL_SEL_ABPLL : CLK_CORE_PLL_SEL_ALPLL;
+	u32 *pll_con = is_big ? &cru_ptr->apll_b_con[0] :
+				&cru_ptr->apll_l_con[0];
 
-	apll_l_hz = apll_cfgs[apll_l_freq]->freq;
+	apll_l_hz = apll_cfgs[apll_freq]->freq;
 
-	rkclk_set_pll(&cru_ptr->apll_l_con[0], apll_cfgs[apll_l_freq]);
+	rkclk_set_pll(pll_con, apll_cfgs[apll_freq]);
 
 	aclkm_div = div_round_up(apll_l_hz, ACLKM_CORE_HZ) - 1;
 
@@ -504,22 +515,20 @@ void rkclk_configure_cpu(enum apll_frequencies apll_l_freq)
 
 	atclk_div = div_round_up(apll_l_hz, ATCLK_CORE_HZ) - 1;
 
-	write32(&cru_ptr->clksel_con[0],
-		RK_CLRSETBITS(ACLKM_CORE_L_DIV_CON_MASK <<
-						ACLKM_CORE_L_DIV_CON_SHIFT |
-			      CLK_CORE_L_PLL_SEL_MASK <<
-						CLK_CORE_L_PLL_SEL_SHIFT |
-			      CLK_CORE_L_DIV_MASK << CLK_CORE_L_DIV_SHIFT,
-			      aclkm_div << ACLKM_CORE_L_DIV_CON_SHIFT |
-			      CLK_CORE_L_PLL_SEL_ALPLL <<
-						CLK_CORE_L_PLL_SEL_SHIFT |
-			      0 << CLK_CORE_L_DIV_SHIFT));
-
-	write32(&cru_ptr->clksel_con[1],
-		RK_CLRSETBITS(PCLK_DBG_L_DIV_MASK << PCLK_DBG_L_DIV_SHIFT |
-			      ATCLK_CORE_L_DIV_MASK << ATCLK_CORE_L_DIV_SHIFT,
-			      pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT |
-			      atclk_div << ATCLK_CORE_L_DIV_SHIFT));
+	write32(&cru_ptr->clksel_con[con_base],
+		RK_CLRSETBITS(ACLKM_CORE_DIV_CON_MASK <<
+						ACLKM_CORE_DIV_CON_SHIFT |
+			      CLK_CORE_PLL_SEL_MASK << CLK_CORE_PLL_SEL_SHIFT |
+			      CLK_CORE_DIV_MASK << CLK_CORE_DIV_SHIFT,
+			      aclkm_div << ACLKM_CORE_DIV_CON_SHIFT |
+			      parent << CLK_CORE_PLL_SEL_SHIFT |
+			      0 << CLK_CORE_DIV_SHIFT));
+
+	write32(&cru_ptr->clksel_con[con_base + 1],
+		RK_CLRSETBITS(PCLK_DBG_DIV_MASK << PCLK_DBG_DIV_SHIFT |
+			      ATCLK_CORE_DIV_MASK << ATCLK_CORE_DIV_SHIFT,
+			      pclk_dbg_div << PCLK_DBG_DIV_SHIFT |
+			      atclk_div << ATCLK_CORE_DIV_SHIFT));
 }
 
 void rkclk_configure_ddr(unsigned int hz)
diff --git a/src/soc/rockchip/rk3399/include/soc/clock.h b/src/soc/rockchip/rk3399/include/soc/clock.h
index 70b819a374..19e315b8da 100644
--- a/src/soc/rockchip/rk3399/include/soc/clock.h
+++ b/src/soc/rockchip/rk3399/include/soc/clock.h
@@ -103,7 +103,7 @@ enum apll_frequencies {
 
 void rkclk_init(void);
 int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz);
-void rkclk_configure_cpu(enum apll_frequencies apll_l_freq);
+void rkclk_configure_cpu(enum apll_frequencies apll_freq, bool is_big);
 void rkclk_configure_ddr(unsigned int hz);
 void rkclk_configure_emmc(void);
 void rkclk_configure_i2s(unsigned int hz);
-- 
cgit v1.2.3