From 422f04b68f59a8348428a6a5628a00a5689d0168 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:15 -0600 Subject: power: regulator: Add more debugging and fix a missing newline This file does not report a few possible errors and one message is missing a newline. Fix these. Signed-off-by: Simon Glass Reviewed-by: Jaehoon Chung --- drivers/power/regulator/regulator-uclass.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index a42f80bb2b3..0a1d1b36c06 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -146,8 +146,10 @@ int regulator_get_by_platname(const char *plat_name, struct udevice **devp) for (ret = uclass_find_first_device(UCLASS_REGULATOR, &dev); dev; ret = uclass_find_next_device(&dev)) { - if (ret) + if (ret) { + debug("regulator %s, ret=%d\n", dev->name, ret); continue; + } uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata || strcmp(plat_name, uc_pdata->name)) @@ -156,7 +158,7 @@ int regulator_get_by_platname(const char *plat_name, struct udevice **devp) return uclass_get_device_tail(dev, 0, devp); } - debug("%s: can't find: %s\n", __func__, plat_name); + debug("%s: can't find: %s, ret=%d\n", __func__, plat_name, ret); return -ENODEV; } @@ -219,7 +221,7 @@ int regulator_autoset_by_name(const char *platname, struct udevice **devp) if (devp) *devp = dev; if (ret) { - debug("Can get the regulator: %s!", platname); + debug("Can get the regulator: %s (err=%d)\n", platname, ret); return ret; } -- cgit v1.2.3 From 4a7b9ee15ee0c5aa38bce0e32263fbb11572b475 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:18 -0600 Subject: tegra: spi: Wait a little after setting the clocks For devices that need a delay between SPI transactions we seem to need an additional delay before the first one if the CPU is running at full speed. Add this, under control of the existing setting. At present it will only be enabled with the Chrome OS EC. Signed-off-by: Simon Glass --- drivers/spi/tegra114_spi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index 802117eb49f..91659349a3d 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -152,6 +152,7 @@ static int tegra114_spi_probe(struct udevice *bus) bus->name, priv->freq, rate); } } + udelay(plat->deactivate_delay_us); /* Clear stale status here */ setbits_le32(®s->fifo_status, -- cgit v1.2.3 From 505907a4677786dc179d7edd3d71bb5f273425cf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:20 -0600 Subject: tegra: video: Don't power up the SOR twice If U-Boot is the secondary boot loader, or has been run from itself, the SOR may already be powered up. Powering it up again causes a hang, so detect this situation and skip it. Signed-off-by: Simon Glass Acked-by: Anatolij Gustschin --- drivers/video/tegra124/sor.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/video/tegra124/sor.c b/drivers/video/tegra124/sor.c index 5e4140ff532..4324071cdc8 100644 --- a/drivers/video/tegra124/sor.c +++ b/drivers/video/tegra124/sor.c @@ -466,11 +466,20 @@ void tegra_dc_sor_set_lane_count(struct udevice *dev, u8 lane_count) static int tegra_dc_sor_power_up(struct udevice *dev, int is_lvds) { struct tegra_dc_sor_data *sor = dev_get_priv(dev); + u32 reg; int ret; if (sor->power_is_up) return 0; + /* + * If for some reason it is already powered up, don't do it again. + * This can happen if U-Boot is the secondary boot loader. + */ + reg = tegra_sor_readl(sor, DP_PADCTL(sor->portnum)); + if (reg & DP_PADCTL_PD_TXD_0_NO) + return 0; + /* Set link bw */ tegra_dc_sor_set_link_bandwidth(dev, is_lvds ? CLK_CNTRL_DP_LINK_SPEED_LVDS : -- cgit v1.2.3 From 385105983abf428de55eab9a1c2464889e94cc1b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:25 -0600 Subject: rockchip: Setup default PWM flags At present if the Signed-off-by: Simon Glass Fixes: 874ee59 (rockchip: pwm: implement pwm_set_invert()) --- drivers/pwm/rk_pwm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pwm/rk_pwm.c b/drivers/pwm/rk_pwm.c index 59eae0956e6..28de62d7161 100644 --- a/drivers/pwm/rk_pwm.c +++ b/drivers/pwm/rk_pwm.c @@ -92,6 +92,7 @@ static int rk_pwm_probe(struct udevice *dev) return -EINVAL; } priv->freq = clk_get_rate(&clk); + priv->enable_conf = PWM_DUTY_POSTIVE | PWM_INACTIVE_POSTIVE; return 0; } -- cgit v1.2.3 From f418676e9ab8b7ec5496fc83fe8ab2b92b26a58e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:28 -0600 Subject: rockchip: video: Add remove() methods Add remove() methods for EDP and VOP so that U-Boot can shut down the video on exit. This avoids leaving DMA running while booting Linux which can cause problems if Linux uses the frame buffer for something else. It also makes it clear what is needed to shut down video. While we are here, make rkvop_enable() static. Signed-off-by: Simon Glass Acked-by: Anatolij Gustschin Squashed in 'rockchip: video: fix taking the VOP device out of standby': Signed-off-by: Philipp Tomsich --- drivers/video/rockchip/rk3288_vop.c | 14 ++++++++++++++ drivers/video/rockchip/rk_edp.c | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/rockchip/rk3288_vop.c b/drivers/video/rockchip/rk3288_vop.c index e3e1ec728c0..3a5740a6cb8 100644 --- a/drivers/video/rockchip/rk3288_vop.c +++ b/drivers/video/rockchip/rk3288_vop.c @@ -70,6 +70,19 @@ static int rk3288_vop_probe(struct udevice *dev) return rk_vop_probe(dev); } +static int rk_vop_remove(struct udevice *dev) +{ + struct rk_vop_priv *priv = dev_get_priv(dev); + struct rk3288_vop *regs = priv->regs; + + setbits_le32(®s->sys_ctrl, V_STANDBY_EN(1)); + + /* wait frame complete (60Hz) to enter standby */ + mdelay(17); + + return 0; +} + struct rkvop_driverdata rk3288_driverdata = { .features = VOP_FEATURE_OUTPUT_10BIT, .set_pin_polarity = rk3288_set_pin_polarity, @@ -91,5 +104,6 @@ U_BOOT_DRIVER(rk_vop) = { .ops = &rk3288_vop_ops, .bind = rk_vop_bind, .probe = rk3288_vop_probe, + .remove = rk_vop_remove, .priv_auto_alloc_size = sizeof(struct rk_vop_priv), }; diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c index 4e2030e8e4b..1527f96eca2 100644 --- a/drivers/video/rockchip/rk_edp.c +++ b/drivers/video/rockchip/rk_edp.c @@ -1004,7 +1004,20 @@ static int rk_edp_ofdata_to_platdata(struct udevice *dev) return 0; } -int rk_edp_probe(struct udevice *dev) +static int rk_edp_remove(struct udevice *dev) +{ + struct rk_edp_priv *priv = dev_get_priv(dev); + struct rk3288_edp *regs = priv->regs; + + setbits_le32(®s->video_ctl_1, VIDEO_MUTE); + clrbits_le32(®s->video_ctl_1, VIDEO_EN); + clrbits_le32(®s->sys_ctl_3, F_HPD | HPD_CTRL); + setbits_le32(®s->func_en_1, SW_FUNC_EN_N); + + return 0; +} + +static int rk_edp_probe(struct udevice *dev) { struct display_plat *uc_plat = dev_get_uclass_platdata(dev); struct rk_edp_priv *priv = dev_get_priv(dev); @@ -1080,5 +1093,6 @@ U_BOOT_DRIVER(dp_rockchip) = { .ops = &dp_rockchip_ops, .ofdata_to_platdata = rk_edp_ofdata_to_platdata, .probe = rk_edp_probe, + .remove = rk_edp_remove, .priv_auto_alloc_size = sizeof(struct rk_edp_priv), }; -- cgit v1.2.3 From 6b5a09aa385693f5921a96d93197f5c40e7f37f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:29 -0600 Subject: rockchip: video: Take the vop device out of standby On reset the standby bit is clear, but if U-Boot is chain-loaded from another boot loader it may be set. Clear it before starting up video so that it works correctly. Signed-off-by: Simon Glass Acked-by: Anatolij Gustschin Squashed in 'rockchip: video: fix taking the VOP device out of standby': Signed-off-by: Philipp Tomsich --- drivers/video/rockchip/rk_vop.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c index 93437964b22..c979049b5ba 100644 --- a/drivers/video/rockchip/rk_vop.c +++ b/drivers/video/rockchip/rk_vop.c @@ -105,6 +105,9 @@ static void rkvop_enable_output(struct udevice *dev, enum vop_modes mode) struct rk_vop_priv *priv = dev_get_priv(dev); struct rk3288_vop *regs = priv->regs; + /* remove from standby */ + clrbits_le32(®s->sys_ctrl, V_STANDBY_EN(1)); + switch (mode) { case VOP_MODE_HDMI: clrsetbits_le32(®s->sys_ctrl, M_ALL_OUT_EN, -- cgit v1.2.3 From b223c1aeade5b29c13347354edd1ce4e66f60b7f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:31 -0600 Subject: rockchip: rk3288: Convert clock driver to use shifted masks Shifted masks are the standard approach with rockchip since it allows use of the mask without shifting it each time. Update the definitions and the driver to match. Signed-off-by: Simon Glass --- drivers/clk/rockchip/clk_rk3288.c | 121 ++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c index 14851ca5aa2..f6ef7ecd7a1 100644 --- a/drivers/clk/rockchip/clk_rk3288.c +++ b/drivers/clk/rockchip/clk_rk3288.c @@ -59,14 +59,14 @@ enum { PLL_RESET_SHIFT = 5, /* CLKSEL0 */ - CORE_SEL_PLL_MASK = 1, CORE_SEL_PLL_SHIFT = 15, - A17_DIV_MASK = 0x1f, + CORE_SEL_PLL_MASK = 1 << CORE_SEL_PLL_SHIFT, A17_DIV_SHIFT = 8, - MP_DIV_MASK = 0xf, + A17_DIV_MASK = 0x1f << A17_DIV_SHIFT, MP_DIV_SHIFT = 4, - M0_DIV_MASK = 0xf, + MP_DIV_MASK = 0xf << MP_DIV_SHIFT, M0_DIV_SHIFT = 0, + M0_DIV_MASK = 0xf << M0_DIV_SHIFT, /* CLKSEL1: pd bus clk pll sel: codec or general */ PD_BUS_SEL_PLL_MASK = 15, @@ -75,41 +75,41 @@ enum { /* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */ PD_BUS_PCLK_DIV_SHIFT = 12, - PD_BUS_PCLK_DIV_MASK = 7, + PD_BUS_PCLK_DIV_MASK = 7 << PD_BUS_PCLK_DIV_SHIFT, /* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */ PD_BUS_HCLK_DIV_SHIFT = 8, - PD_BUS_HCLK_DIV_MASK = 3, + PD_BUS_HCLK_DIV_MASK = 3 << PD_BUS_HCLK_DIV_SHIFT, /* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */ PD_BUS_ACLK_DIV0_SHIFT = 3, - PD_BUS_ACLK_DIV0_MASK = 0x1f, + PD_BUS_ACLK_DIV0_MASK = 0x1f << PD_BUS_ACLK_DIV0_SHIFT, PD_BUS_ACLK_DIV1_SHIFT = 0, - PD_BUS_ACLK_DIV1_MASK = 0x7, + PD_BUS_ACLK_DIV1_MASK = 0x7 << PD_BUS_ACLK_DIV1_SHIFT, /* * CLKSEL10 * peripheral bus pclk div: * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1 */ - PERI_SEL_PLL_MASK = 1, PERI_SEL_PLL_SHIFT = 15, + PERI_SEL_PLL_MASK = 1 << PERI_SEL_PLL_SHIFT, PERI_SEL_CPLL = 0, PERI_SEL_GPLL, PERI_PCLK_DIV_SHIFT = 12, - PERI_PCLK_DIV_MASK = 3, + PERI_PCLK_DIV_MASK = 3 << PERI_PCLK_DIV_SHIFT, /* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */ PERI_HCLK_DIV_SHIFT = 8, - PERI_HCLK_DIV_MASK = 3, + PERI_HCLK_DIV_MASK = 3 << PERI_HCLK_DIV_SHIFT, /* * peripheral bus aclk div: * aclk_periph = periph_clk_src / (peri_aclk_div_con + 1) */ PERI_ACLK_DIV_SHIFT = 0, - PERI_ACLK_DIV_MASK = 0x1f, + PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT, SOCSTS_DPLL_LOCK = 1 << 5, SOCSTS_APLL_LOCK = 1 << 6, @@ -154,8 +154,7 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, /* enter reset */ rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT); - rk_clrsetreg(&pll->con0, - CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK, + rk_clrsetreg(&pll->con0, CLKR_MASK | PLL_OD_MASK, ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1)); rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1); rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1); @@ -198,7 +197,7 @@ static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf, } /* pll enter slow-mode */ - rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT, + rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK, DPLL_MODE_SLOW << DPLL_MODE_SHIFT); rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]); @@ -208,7 +207,7 @@ static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf, udelay(1); /* PLL enter normal-mode */ - rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT, + rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK, DPLL_MODE_NORMAL << DPLL_MODE_SHIFT); return 0; @@ -296,7 +295,7 @@ static int rockchip_mac_set_clk(struct rk3288_cru *cru, { /* Assuming mac_clk is fed by an external clock */ rk_clrsetreg(&cru->cru_clksel_con[21], - RMII_EXTCLK_MASK << RMII_EXTCLK_SHIFT, + RMII_EXTCLK_MASK, RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT); return 0; @@ -313,7 +312,7 @@ static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf, if (ret) return ret; - rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT, + rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK, NPLL_MODE_SLOW << NPLL_MODE_SHIFT); rkclk_set_pll(cru, CLK_NEW, &npll_config); @@ -324,7 +323,7 @@ static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf, udelay(1); } - rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT, + rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK, NPLL_MODE_NORMAL << NPLL_MODE_SHIFT); /* vop dclk source clk: npll,dclk_div: 1 */ @@ -352,8 +351,7 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) /* pll enter slow-mode */ rk_clrsetreg(&cru->cru_mode_con, - GPLL_MODE_MASK << GPLL_MODE_SHIFT | - CPLL_MODE_MASK << CPLL_MODE_SHIFT, + GPLL_MODE_MASK | CPLL_MODE_MASK, GPLL_MODE_SLOW << GPLL_MODE_SHIFT | CPLL_MODE_SLOW << CPLL_MODE_SHIFT); @@ -382,10 +380,8 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) PD_BUS_ACLK_HZ && pclk_div < 0x7); rk_clrsetreg(&cru->cru_clksel_con[1], - PD_BUS_PCLK_DIV_MASK << PD_BUS_PCLK_DIV_SHIFT | - PD_BUS_HCLK_DIV_MASK << PD_BUS_HCLK_DIV_SHIFT | - PD_BUS_ACLK_DIV0_MASK << PD_BUS_ACLK_DIV0_SHIFT | - PD_BUS_ACLK_DIV1_MASK << PD_BUS_ACLK_DIV1_SHIFT, + PD_BUS_PCLK_DIV_MASK | PD_BUS_HCLK_DIV_MASK | + PD_BUS_ACLK_DIV0_MASK | PD_BUS_ACLK_DIV1_MASK, pclk_div << PD_BUS_PCLK_DIV_SHIFT | hclk_div << PD_BUS_HCLK_DIV_SHIFT | aclk_div << PD_BUS_ACLK_DIV0_SHIFT | @@ -407,9 +403,8 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) PERI_ACLK_HZ && (pclk_div < 0x4)); rk_clrsetreg(&cru->cru_clksel_con[10], - PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT | - PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT | - PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT, + PERI_PCLK_DIV_MASK | PERI_HCLK_DIV_MASK | + PERI_ACLK_DIV_MASK, PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT | pclk_div << PERI_PCLK_DIV_SHIFT | hclk_div << PERI_HCLK_DIV_SHIFT | @@ -417,8 +412,7 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) /* PLL enter normal-mode */ rk_clrsetreg(&cru->cru_mode_con, - GPLL_MODE_MASK << GPLL_MODE_SHIFT | - CPLL_MODE_MASK << CPLL_MODE_SHIFT, + GPLL_MODE_MASK | CPLL_MODE_MASK, GPLL_MODE_NORMAL << GPLL_MODE_SHIFT | CPLL_MODE_NORMAL << CPLL_MODE_SHIFT); } @@ -427,8 +421,7 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) void rk3288_clk_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, + rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK, APLL_MODE_SLOW << APLL_MODE_SHIFT); rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); @@ -444,10 +437,8 @@ void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf) * 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, + CORE_SEL_PLL_MASK | A17_DIV_MASK | MP_DIV_MASK | + M0_DIV_MASK, 0 << A17_DIV_SHIFT | 3 << MP_DIV_SHIFT | 1 << M0_DIV_SHIFT); @@ -457,16 +448,14 @@ void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf) * 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, + CLK_L2RAM_DIV_MASK | ATCLK_CORE_DIV_CON_MASK | + PCLK_CORE_DBG_DIV_MASK, 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, + rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK, APLL_MODE_NORMAL << APLL_MODE_SHIFT); } @@ -486,16 +475,16 @@ static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru, con = readl(&cru->cru_mode_con); shift = clk_shift[clk_id]; - switch ((con >> shift) & APLL_MODE_MASK) { + switch ((con >> shift) & CRU_MODE_MASK) { case APLL_MODE_SLOW: return OSC_HZ; case APLL_MODE_NORMAL: /* normal mode */ con = readl(&pll->con0); - no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1; - nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1; + no = ((con & CLKOD_MASK) >> CLKOD_SHIFT) + 1; + nr = ((con & CLKR_MASK) >> CLKR_SHIFT) + 1; con = readl(&pll->con1); - nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1; + nf = ((con & CLKF_MASK) >> CLKF_SHIFT) + 1; return (24 * nf / (nr * no)) * 1000000; case APLL_MODE_DEEP: @@ -515,20 +504,20 @@ static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate, case HCLK_EMMC: case SCLK_EMMC: con = readl(&cru->cru_clksel_con[12]); - mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK; - div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK; + mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT; + div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT; break; case HCLK_SDMMC: case SCLK_SDMMC: con = readl(&cru->cru_clksel_con[11]); - mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK; - div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK; + mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT; + div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT; break; case HCLK_SDIO0: case SCLK_SDIO0: con = readl(&cru->cru_clksel_con[12]); - mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK; - div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK; + mux = (con & SDIO0_PLL_MASK) >> SDIO0_PLL_SHIFT; + div = (con & SDIO0_DIV_MASK) >> SDIO0_DIV_SHIFT; break; default: return -EINVAL; @@ -561,24 +550,21 @@ static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate, case HCLK_EMMC: case SCLK_EMMC: rk_clrsetreg(&cru->cru_clksel_con[12], - EMMC_PLL_MASK << EMMC_PLL_SHIFT | - EMMC_DIV_MASK << EMMC_DIV_SHIFT, + EMMC_PLL_MASK | EMMC_DIV_MASK, mux << EMMC_PLL_SHIFT | (src_clk_div - 1) << EMMC_DIV_SHIFT); break; case HCLK_SDMMC: case SCLK_SDMMC: rk_clrsetreg(&cru->cru_clksel_con[11], - MMC0_PLL_MASK << MMC0_PLL_SHIFT | - MMC0_DIV_MASK << MMC0_DIV_SHIFT, + MMC0_PLL_MASK | MMC0_DIV_MASK, mux << MMC0_PLL_SHIFT | (src_clk_div - 1) << MMC0_DIV_SHIFT); break; case HCLK_SDIO0: case SCLK_SDIO0: rk_clrsetreg(&cru->cru_clksel_con[12], - SDIO0_PLL_MASK << SDIO0_PLL_SHIFT | - SDIO0_DIV_MASK << SDIO0_DIV_SHIFT, + SDIO0_PLL_MASK | SDIO0_DIV_MASK, mux << SDIO0_PLL_SHIFT | (src_clk_div - 1) << SDIO0_DIV_SHIFT); break; @@ -598,18 +584,18 @@ static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate, switch (periph) { case SCLK_SPI0: con = readl(&cru->cru_clksel_con[25]); - mux = (con >> SPI0_PLL_SHIFT) & SPI0_PLL_MASK; - div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK; + mux = (con & SPI0_PLL_MASK) >> SPI0_PLL_SHIFT; + div = (con & SPI0_DIV_MASK) >> SPI0_DIV_SHIFT; break; case SCLK_SPI1: con = readl(&cru->cru_clksel_con[25]); - mux = (con >> SPI1_PLL_SHIFT) & SPI1_PLL_MASK; - div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK; + mux = (con & SPI1_PLL_MASK) >> SPI1_PLL_SHIFT; + div = (con & SPI1_DIV_MASK) >> SPI1_DIV_SHIFT; break; case SCLK_SPI2: con = readl(&cru->cru_clksel_con[39]); - mux = (con >> SPI2_PLL_SHIFT) & SPI2_PLL_MASK; - div = (con >> SPI2_DIV_SHIFT) & SPI2_DIV_MASK; + mux = (con & SPI2_PLL_MASK) >> SPI2_PLL_SHIFT; + div = (con & SPI2_DIV_MASK) >> SPI2_DIV_SHIFT; break; default: return -EINVAL; @@ -629,22 +615,19 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate, switch (periph) { case SCLK_SPI0: rk_clrsetreg(&cru->cru_clksel_con[25], - SPI0_PLL_MASK << SPI0_PLL_SHIFT | - SPI0_DIV_MASK << SPI0_DIV_SHIFT, + SPI0_PLL_MASK | SPI0_DIV_MASK, SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT | src_clk_div << SPI0_DIV_SHIFT); break; case SCLK_SPI1: rk_clrsetreg(&cru->cru_clksel_con[25], - SPI1_PLL_MASK << SPI1_PLL_SHIFT | - SPI1_DIV_MASK << SPI1_DIV_SHIFT, + SPI1_PLL_MASK | SPI1_DIV_MASK, SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT | src_clk_div << SPI1_DIV_SHIFT); break; case SCLK_SPI2: rk_clrsetreg(&cru->cru_clksel_con[39], - SPI2_PLL_MASK << SPI2_PLL_SHIFT | - SPI2_DIV_MASK << SPI2_DIV_SHIFT, + SPI2_PLL_MASK | SPI2_DIV_MASK, SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT | src_clk_div << SPI2_DIV_SHIFT); break; -- cgit v1.2.3 From d3cb46aa8c41e85b07ccf494ca90f3a7fe19373d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 May 2017 17:57:32 -0600 Subject: rockchip: Init clocks again when chain-loading Detect with a previous boot loader has already set up the clocks and set them up again so that U-Boot gets what it expects. Signed-off-by: Simon Glass --- drivers/clk/rockchip/clk_rk3288.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c index f6ef7ecd7a1..792ee76509f 100644 --- a/drivers/clk/rockchip/clk_rk3288.c +++ b/drivers/clk/rockchip/clk_rk3288.c @@ -131,10 +131,8 @@ enum { /* Keep divisors as low as possible to reduce jitter and power usage */ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1); -#ifdef CONFIG_SPL_BUILD static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2); static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2); -#endif static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, const struct pll_div *div) @@ -340,9 +338,8 @@ static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf, return 0; } -#endif +#endif /* CONFIG_SPL_BUILD */ -#ifdef CONFIG_SPL_BUILD static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) { u32 aclk_div; @@ -416,7 +413,6 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) GPLL_MODE_NORMAL << GPLL_MODE_SHIFT | CPLL_MODE_NORMAL << CPLL_MODE_SHIFT); } -#endif void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf) { @@ -786,6 +782,7 @@ static int rk3288_clk_ofdata_to_platdata(struct udevice *dev) static int rk3288_clk_probe(struct udevice *dev) { struct rk3288_clk_priv *priv = dev_get_priv(dev); + bool init_clocks = false; priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); if (IS_ERR(priv->grf)) @@ -796,8 +793,24 @@ static int rk3288_clk_probe(struct udevice *dev) priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]); #endif - rkclk_init(priv->cru, priv->grf); + init_clocks = true; #endif + if (!(gd->flags & GD_FLG_RELOC)) { + u32 reg; + + /* + * Init clocks in U-Boot proper if the NPLL is runnning. This + * indicates that a previous boot loader set up the clocks, so + * we need to redo it. U-Boot's SPL does not set this clock. + */ + reg = readl(&priv->cru->cru_mode_con); + if (((reg & NPLL_MODE_MASK) >> NPLL_MODE_SHIFT) == + NPLL_MODE_NORMAL) + init_clocks = true; + } + + if (init_clocks) + rkclk_init(priv->cru, priv->grf); return 0; } -- cgit v1.2.3