rockchip: spl: Support full-speed CPU in SPL
authorSimon Glass <sjg@chromium.org>
Fri, 22 Jan 2016 02:45:17 +0000 (19:45 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 22 Jan 2016 03:42:37 +0000 (20:42 -0700)
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>
arch/arm/dts/rk3288-veyron.dtsi
arch/arm/include/asm/arch-rockchip/clock.h
arch/arm/include/asm/arch-rockchip/cru_rk3288.h
arch/arm/mach-rockchip/rk3288/Kconfig
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c
configs/chromebook_jerry_defconfig
drivers/clk/clk_rk3288.c
include/configs/chromebook_jerry.h

index c201e855de7d99bc031646dffb478af29ca2dfc8..421d21290ca8efdef76acd196cb9ce6301e89bcb 100644 (file)
        clock-frequency = <400000>;
        i2c-scl-falling-time-ns = <50>;         /* 2.5ns measured */
        i2c-scl-rising-time-ns = <100>;         /* 45ns measured */
+       u-boot,dm-pre-reloc;
 
        rk808: pmic@1b {
                compatible = "rockchip,rk808";
                rockchip,system-power-controller;
                wakeup-source;
                #clock-cells = <1>;
+               u-boot,dm-pre-reloc;
 
                vcc1-supply = <&vcc33_sys>;
                vcc2-supply = <&vcc33_sys>;
index a9ea2689c7462bc3f6815bc59a89859eeb1b9377..d66b26f18ef32369b1475204617f468d578856cc 100644 (file)
@@ -74,4 +74,9 @@ void *rockchip_get_cru(void);
  */
 int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp);
 
+struct rk3288_cru;
+struct rk3288_grf;
+
+void rkclk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf);
+
 #endif
index b0dea7060a73b9863f1681fadf056f1198777dc5..d2690c77886bee5395e81e71d67cd1dc4571c2b6 100644 (file)
@@ -109,6 +109,18 @@ enum {
        SPI0_DIV_MASK           = 0x7f,
 };
 
+/* CRU_CLKSEL37_CON */
+enum {
+       PCLK_CORE_DBG_DIV_SHIFT = 9,
+       PCLK_CORE_DBG_DIV_MASK  = 0x1f,
+
+       ATCLK_CORE_DIV_CON_SHIFT = 4,
+       ATCLK_CORE_DIV_CON_MASK = 0x1f,
+
+       CLK_L2RAM_DIV_SHIFT     = 0,
+       CLK_L2RAM_DIV_MASK      = 7,
+};
+
 /* CRU_CLKSEL39_CON */
 enum {
        ACLK_HEVC_PLL_SHIFT     = 0xe,
index d0a72767c88075ba78846bb2631313f02e0d789c..ed89c3e0774d8a05f3dff4a3b4bbcb29195c8dd4 100644 (file)
@@ -16,6 +16,15 @@ config TARGET_CHROMEBOOK_JERRY
          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"
 
index 074cf518709cd8560febe43bb86d640e30ef32aa..e9e2211c824aa974c3eb99c6e2c6ada8f4d38523 100644 (file)
@@ -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 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
 }
 
 #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);
@@ -791,6 +819,14 @@ static int setup_sdram(struct udevice *dev)
                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);
 }
 #endif
index b2672b868d470db47d520c4d8b7f57214791d7de..526306f32d25ee9de5468f0f069a705db76745e9 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_ARCH_ROCKCHIP=y
 CONFIG_SYS_MALLOC_F_LEN=0x2000
 CONFIG_ROCKCHIP_RK3288=y
 CONFIG_TARGET_CHROMEBOOK_JERRY=y
+CONFIG_ROCKCHIP_FAST_SPL=y
 CONFIG_SPL_STACK_R_ADDR=0x80000
 CONFIG_DM_KEYBOARD=y
 CONFIG_DEFAULT_DEVICE_TREE="rk3288-jerry"
index 8ef68fe0cd2b761b39188daac18f1f00d839bd43..2a85e93a6cc3f534ac165e17343de18344c43619 100644 (file)
@@ -59,6 +59,16 @@ enum {
        /* PLL CON3 */
        PLL_RESET_SHIFT         = 5,
 
+       /* CLKSEL0 */
+       CORE_SEL_PLL_MASK       = 1,
+       CORE_SEL_PLL_SHIFT      = 15,
+       A17_DIV_MASK            = 0x1f,
+       A17_DIV_SHIFT           = 8,
+       MP_DIV_MASK             = 0xf,
+       MP_DIV_SHIFT            = 4,
+       M0_DIV_MASK             = 0xf,
+       M0_DIV_SHIFT            = 0,
+
        /* CLKSEL1: pd bus clk pll sel: codec or general */
        PD_BUS_SEL_PLL_MASK     = 15,
        PD_BUS_SEL_CPLL         = 0,
@@ -438,6 +448,52 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
 }
 #endif
 
+void rkclk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
+{
+       /* 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_init_cfg);
+
+       /* waiting for pll lock */
+       while (!(readl(&grf->soc_status[1]) & SOCSTS_APLL_LOCK))
+               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
+        */
+       rk_clrsetreg(&cru->cru_clksel_con[0],
+                    CORE_SEL_PLL_MASK << CORE_SEL_PLL_SHIFT |
+                    A17_DIV_MASK << A17_DIV_SHIFT |
+                    MP_DIV_MASK << MP_DIV_SHIFT |
+                    M0_DIV_MASK << M0_DIV_SHIFT,
+                    0 << A17_DIV_SHIFT |
+                    3 << MP_DIV_SHIFT |
+                    1 << M0_DIV_SHIFT);
+
+       /*
+        * set up dependent divisors for L2RAM/ATCLK and PCLK clocks.
+        * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz
+        */
+       rk_clrsetreg(&cru->cru_clksel_con[37],
+                    CLK_L2RAM_DIV_MASK << CLK_L2RAM_DIV_SHIFT |
+                    ATCLK_CORE_DIV_CON_MASK << ATCLK_CORE_DIV_CON_SHIFT |
+                    PCLK_CORE_DBG_DIV_MASK >> PCLK_CORE_DBG_DIV_SHIFT,
+                    1 << CLK_L2RAM_DIV_SHIFT |
+                    3 << ATCLK_CORE_DIV_CON_SHIFT |
+                    3 << PCLK_CORE_DBG_DIV_SHIFT);
+
+       /* PLL enter normal-mode */
+       rk_clrsetreg(&cru->cru_mode_con,
+                    APLL_MODE_MASK << APLL_MODE_SHIFT,
+                    APLL_MODE_NORMAL << APLL_MODE_SHIFT);
+}
+
 /* Get pll rate by id */
 static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru,
                                   enum rk_clk_id clk_id)
index 6e32f2ccad4d3c1b830c57b502909ae498f09c8d..e07d05764a1062373379f5498551da8a5afd9b23 100644 (file)
@@ -24,4 +24,7 @@
 
 #define CONFIG_KEYBOARD
 
+#define CONFIG_SPL_POWER_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+
 #endif