rk3288: cpu frequency up to 1.8GHz
before the rkclk_init(), we must set rk808
buck1 voltage up to 1300mv
BUG=chrome-os-partner:32716, chrome-os-partner:31896
TEST=Boot on veyron_pinky rev2,check the rk808 buck1 voltage 1300mv
and check the cpu frequency up to 1.8GHz
Change-Id: I6a8c6e35bd7cc6017f2def72876a9170977f206e
Signed-off-by: huang lin <hl@rock-chips.com>
Reviewed-on: https://chromium-review.googlesource.com/222957
Reviewed-by: Doug Anderson <dianders@chromium.org>
diff --git a/src/mainboard/google/veyron_pinky/bootblock.c b/src/mainboard/google/veyron_pinky/bootblock.c
index 3ed8e27..a66d748 100644
--- a/src/mainboard/google/veyron_pinky/bootblock.c
+++ b/src/mainboard/google/veyron_pinky/bootblock.c
@@ -22,11 +22,24 @@
#include <bootblock_common.h>
#include <soc/rockchip/rk3288/grf.h>
#include <soc/rockchip/rk3288/spi.h>
+#include <soc/rockchip/rk3288/rk808.h>
+#include <soc/rockchip/rk3288/clock.h>
+#include <soc/rockchip/rk3288/pmu.h>
+#include <soc/rockchip/rk3288/i2c.h>
#include <vendorcode/google/chromeos/chromeos.h>
+#include "board.h"
+
void bootblock_mainboard_init(void)
{
- /* i2c1 for tpm*/
+ /* cpu frequency will up to 1.8GHz, so the buck1 must up to 1.3v */
+ setbits_le32(&rk3288_pmu->iomux_i2c0scl, IOMUX_I2C0SCL);
+ setbits_le32(&rk3288_pmu->iomux_i2c0sda, IOMUX_I2C0SDA);
+ i2c_init(PMIC_BUS, 400*KHz);
+ rk808_configure_buck(PMIC_BUS, 1, 1300);
+ rkclk_configure_cpu();
+
+ /* i2c1 for tpm */
writel(IOMUX_I2C1, &rk3288_grf->iomux_i2c1);
/* spi2 for firmware ROM */
diff --git a/src/soc/rockchip/rk3288/Makefile.inc b/src/soc/rockchip/rk3288/Makefile.inc
index cde5d46..5c52f2e 100644
--- a/src/soc/rockchip/rk3288/Makefile.inc
+++ b/src/soc/rockchip/rk3288/Makefile.inc
@@ -31,6 +31,7 @@
bootblock-y += media.c
bootblock-y += gpio.c
bootblock-y += i2c.c
+bootblock-y += rk808.c
verstage-y += monotonic_timer.c
verstage-y += spi.c
diff --git a/src/soc/rockchip/rk3288/clock.c b/src/soc/rockchip/rk3288/clock.c
index 0fa8b70..bdfe079 100644
--- a/src/soc/rockchip/rk3288/clock.c
+++ b/src/soc/rockchip/rk3288/clock.c
@@ -245,49 +245,24 @@
u32 pclk_div;
/* pll enter slow-mode */
- writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_SLOW)
- | RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_SLOW)
+ writel(RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_SLOW)
| RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_SLOW),
&cru_ptr->cru_mode_con);
/* init pll */
- rkclk_set_pll(&cru_ptr->cru_apll_con[0], &apll_init_cfg);
rkclk_set_pll(&cru_ptr->cru_gpll_con[0], &gpll_init_cfg);
rkclk_set_pll(&cru_ptr->cru_cpll_con[0], &cpll_init_cfg);
/* waiting for pll lock */
while (1) {
if ((readl(&rk3288_grf->soc_status[1])
- & (SOCSTS_APLL_LOCK | SOCSTS_CPLL_LOCK
- | SOCSTS_GPLL_LOCK))
- == (SOCSTS_APLL_LOCK | SOCSTS_CPLL_LOCK
- | SOCSTS_GPLL_LOCK))
+ & (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+ == (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
break;
udelay(1);
}
/*
- * core clock pll source selection and
- * set up dependent divisors for MPAXI/M0AXI and ARM clocks.
- * core clock select apll, apll clk = 816MHz
- * arm clk = 816MHz, mpclk = 204MHz, m0clk = 408MHz
- */
- writel(RK_CLRBITS(CORE_SEL_PLL_MSK)
- | RK_CLRSETBITS(A12_DIV_MSK, 0 << A12_DIV_SHIFT)
- | RK_CLRSETBITS(MP_DIV_MSK, 3 << MP_DIV_SHIFT)
- | RK_CLRSETBITS(M0_DIV_MSK, 1 << 0),
- &cru_ptr->cru_clksel_con[0]);
-
- /*
- * set up dependent divisors for L2RAM/ATCLK and PCLK clocks.
- * l2ramclk = 408MHz, atclk = 204MHz, pclk_dbg = 204MHz
- */
- writel(RK_CLRSETBITS(L2_DIV_MSK, 1 << 0)
- | RK_CLRSETBITS(ATCLK_DIV_MSK, (3 << ATCLK_DIV_SHIFT))
- | RK_CLRSETBITS(PCLK_DBG_DIV_MSK, (3 << PCLK_DBG_DIV_SHIFT)),
- &cru_ptr->cru_clksel_con[37]);
-
- /*
* pd_bus clock pll source selection and
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
@@ -336,13 +311,53 @@
&cru_ptr->cru_clksel_con[10]);
/* PLL enter normal-mode */
- writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_NORM)
- | RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_NORM)
+ writel(RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_NORM)
| RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_NORM),
&cru_ptr->cru_mode_con);
}
+void rkclk_configure_cpu()
+{
+ /* pll enter slow-mode */
+ writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_SLOW),
+ &cru_ptr->cru_mode_con);
+
+ rkclk_set_pll(&cru_ptr->cru_apll_con[0], &apll_init_cfg);
+
+ /* waiting for pll lock */
+ while (1) {
+ if (readl(&rk3288_grf->soc_status[1]) & SOCSTS_APLL_LOCK)
+ break;
+ udelay(1);
+ }
+
+ /*
+ * core clock pll source selection and
+ * set up dependent divisors for MPAXI/M0AXI and ARM clocks.
+ * core clock select apll, apll clk = 1800MHz
+ * arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz
+ */
+ writel(RK_CLRBITS(CORE_SEL_PLL_MSK)
+ | RK_CLRSETBITS(A12_DIV_MSK, 0 << A12_DIV_SHIFT)
+ | RK_CLRSETBITS(MP_DIV_MSK, 3 << MP_DIV_SHIFT)
+ | RK_CLRSETBITS(M0_DIV_MSK, 1 << 0),
+ &cru_ptr->cru_clksel_con[0]);
+
+ /*
+ * set up dependent divisors for L2RAM/ATCLK and PCLK clocks.
+ * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz
+ */
+ writel(RK_CLRSETBITS(L2_DIV_MSK, 1 << 0)
+ | RK_CLRSETBITS(ATCLK_DIV_MSK, (3 << ATCLK_DIV_SHIFT))
+ | RK_CLRSETBITS(PCLK_DBG_DIV_MSK, (3 << PCLK_DBG_DIV_SHIFT)),
+ &cru_ptr->cru_clksel_con[37]);
+
+ /* PLL enter normal-mode */
+ writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_NORM),
+ &cru_ptr->cru_mode_con);
+}
+
void rkclk_configure_ddr(unsigned int hz)
{
struct pll_div dpll_cfg;
diff --git a/src/soc/rockchip/rk3288/clock.h b/src/soc/rockchip/rk3288/clock.h
index 71f2a5b..e767459 100644
--- a/src/soc/rockchip/rk3288/clock.h
+++ b/src/soc/rockchip/rk3288/clock.h
@@ -24,7 +24,7 @@
#define OSC_HZ (24*MHz)
-#define APLL_HZ (816*MHz)
+#define APLL_HZ (1800*MHz)
#define GPLL_HZ (594*MHz)
#define CPLL_HZ (384*MHz)
@@ -42,4 +42,5 @@
void rkclk_ddr_phy_ctl_reset(u32 ch, u32 n);
void rkclk_configure_ddr(unsigned int hz);
void rkclk_configure_i2s(unsigned int hz);
+void rkclk_configure_cpu(void);
#endif /* __SOC_ROCKCHIP_RK3288_CLOCK_H__ */
diff --git a/src/soc/rockchip/rk3288/rk808.c b/src/soc/rockchip/rk3288/rk808.c
index 50df96d..48cfa86 100644
--- a/src/soc/rockchip/rk3288/rk808.c
+++ b/src/soc/rockchip/rk3288/rk808.c
@@ -22,12 +22,15 @@
#include <device/i2c.h>
#include <stdint.h>
#include <stdlib.h>
+#include <delay.h>
#include "rk808.h"
#define RK808_ADDR 0x1b
#define DCDC_EN 0x23
#define LDO_EN 0x24
+#define BUCK1SEL 0x2f
+#define BUCK4SEL 0x38
#define LDO_ONSEL(i) (0x39 + 2 * i)
#define LDO_SLPSEL(i) (0x3a + 2 * i)
@@ -56,12 +59,12 @@
case 4:
case 5:
case 8:
- vsel = millivolts / 100 - 18;
+ vsel = div_round_up(millivolts, 100) - 18;
break;
case 3:
case 6:
case 7:
- vsel = millivolts / 100 - 8;
+ vsel = div_round_up(millivolts, 100) - 8;
break;
default:
die("Unknown LDO index!");
@@ -71,3 +74,29 @@
rk808_clrsetbits(bus, LDO_ONSEL(ldo), 0x1f, vsel);
rk808_clrsetbits(bus, LDO_EN, 0, 1 << (ldo - 1));
}
+
+void rk808_configure_buck(uint8_t bus, int buck, int millivolts)
+{
+ uint8_t vsel;
+ uint8_t buck_reg;
+
+ switch (buck) {
+ case 1:
+ case 2:
+ /*base on 725mv, use 25mv step */
+ vsel = (div_round_up(millivolts, 25) - 29) * 2 + 1;
+ assert(vsel <= 0x3f);
+ buck_reg = BUCK1SEL + 4 * (buck - 1);
+ break;
+ case 4:
+ vsel = div_round_up(millivolts, 100) - 18;
+ assert(vsel <= 0xf);
+ buck_reg = BUCK4SEL;
+ break;
+ default:
+ die("fault buck index!");
+ }
+ rk808_clrsetbits(bus, buck_reg, 0x3f, vsel);
+ rk808_clrsetbits(bus, DCDC_EN, 0, 1 << (buck - 1));
+ udelay(225);/* Must wait for voltage to stabilize */
+}
diff --git a/src/soc/rockchip/rk3288/rk808.h b/src/soc/rockchip/rk3288/rk808.h
index 0052075..e03ace8 100644
--- a/src/soc/rockchip/rk3288/rk808.h
+++ b/src/soc/rockchip/rk3288/rk808.h
@@ -22,5 +22,6 @@
void rk808_configure_switch(uint8_t bus, int sw, int enabled);
void rk808_configure_ldo(uint8_t bus, int ldo, int millivolts);
+void rk808_configure_buck(uint8_t bus, int buck, int millivolts);
#endif