rk3288: set 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

Original-Change-Id: I6a8c6e35bd7cc6017f2def72876a9170977f206e
Original-Signed-off-by: huang lin <hl@rock-chips.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/222957
Original-Reviewed-by: Doug Anderson <dianders@chromium.org>

(cherry picked from commit 2e7e7c265691250d4a1b3ff94fe70b0a05f23e16)
Signed-off-by: Aaron Durbin <adurbin@chromium.org>

Change-Id: Iff89d959456dd4d36f4293435caf7b4f7bdaf6fd
Reviewed-on: http://review.coreboot.org/9260
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.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 95d72c9..d41919b 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 0ce3f94..37d366f 100644
--- a/src/soc/rockchip/rk3288/clock.c
+++ b/src/soc/rockchip/rk3288/clock.c
@@ -235,49 +235,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.
 	 */
@@ -326,13 +301,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 7a1dba0..e767459 100644
--- a/src/soc/rockchip/rk3288/clock.h
+++ b/src/soc/rockchip/rk3288/clock.h
@@ -22,7 +22,9 @@
 
 #include "addressmap.h"
 
-#define APLL_HZ		(816*MHz)
+#define OSC_HZ		(24*MHz)
+
+#define APLL_HZ		(1800*MHz)
 #define GPLL_HZ		(594*MHz)
 #define CPLL_HZ		(384*MHz)
 
@@ -40,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