rockchip: spl: Support full-speed CPU in SPL

Add a feature which speeds up the CPU to full speed in SPL to minimise
boot time. This is only supported for certain boards (at present only
jerry).

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index d0a7276..ed89c3e 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -16,6 +16,15 @@
 	  WiFi. It includes a Chrome OS EC (Cortex-M3) to provide access to
 	  the keyboard and battery functions.
 
+config ROCKCHIP_FAST_SPL
+	bool "Change the CPU to full speed in SPL"
+	depends on TARGET_CHROMEBOOK_JERRY
+	help
+	  Some boards want to boot as fast as possible. We can increase the
+	  CPU frequency in SPL if the power supply is configured to the correct
+	  voltage. This option is only available on boards which support it
+	  and have the required PMIC code.
+
 config SYS_SOC
 	default "rockchip"
 
diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
index 074cf518..e9e2211 100644
--- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
@@ -22,6 +22,8 @@
 #include <asm/arch/pmu_rk3288.h>
 #include <asm/arch/sdram.h>
 #include <linux/err.h>
+#include <power/regulator.h>
+#include <power/rk808_pmic.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -748,6 +750,32 @@
 }
 
 #ifdef CONFIG_SPL_BUILD
+# ifdef CONFIG_ROCKCHIP_FAST_SPL
+static int veyron_init(struct dram_info *priv)
+{
+	struct udevice *pmic;
+	int ret;
+
+	ret = uclass_first_device(UCLASS_PMIC, &pmic);
+	if (ret)
+		return ret;
+
+	/* Slowly raise to max CPU voltage to prevent overshoot */
+	ret = rk808_spl_configure_buck(pmic, 1, 1200000);
+	if (ret)
+		return ret;
+	udelay(175);/* Must wait for voltage to stabilize, 2mV/us */
+	ret = rk808_spl_configure_buck(pmic, 1, 1400000);
+	if (ret)
+		return ret;
+	udelay(100);/* Must wait for voltage to stabilize, 2mV/us */
+
+	rkclk_configure_cpu(priv->cru, priv->grf);
+
+	return 0;
+}
+# endif
+
 static int setup_sdram(struct udevice *dev)
 {
 	struct dram_info *priv = dev_get_priv(dev);
@@ -790,6 +818,14 @@
 		debug("%s: Cannot read rockchip,sdram-params\n", __func__);
 		return -EINVAL;
 	}
+
+# ifdef CONFIG_ROCKCHIP_FAST_SPL
+	if (!fdt_node_check_compatible(blob, 0, "google,veyron")) {
+		ret = veyron_init(priv);
+		if (ret)
+			return ret;
+	}
+# endif
 
 	return sdram_init(priv, &params);
 }