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>
This commit is contained in:
Simon Glass 2016-01-21 19:45:17 -07:00
parent 318922b30f
commit dae594f210
8 changed files with 124 additions and 0 deletions

View File

@ -332,6 +332,7 @@
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";
@ -344,6 +345,7 @@
rockchip,system-power-controller;
wakeup-source;
#clock-cells = <1>;
u-boot,dm-pre-reloc;
vcc1-supply = <&vcc33_sys>;
vcc2-supply = <&vcc33_sys>;

View 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

View 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,

View 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"

View 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

View 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"

View 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)

View File

@ -24,4 +24,7 @@
#define CONFIG_KEYBOARD
#define CONFIG_SPL_POWER_SUPPORT
#define CONFIG_SPL_I2C_SUPPORT
#endif