diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/sunxi_mmc.c | 21 | ||||
-rw-r--r-- | drivers/video/bridge/video-bridge-uclass.c | 16 | ||||
-rw-r--r-- | drivers/video/sunxi/lcdc.c | 22 |
3 files changed, 45 insertions, 14 deletions
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 39f15eb423..147eb9b4d5 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -99,11 +99,16 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) { unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly; bool new_mode = false; + bool calibrate = false; u32 val = 0; if (IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && (priv->mmc_no == 2)) new_mode = true; +#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) + calibrate = true; +#endif + /* * The MMC clock has an extra /2 post-divider when operating in the new * mode. @@ -174,7 +179,11 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) val = CCM_MMC_CTRL_MODE_SEL_NEW; setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW); #endif - } else { + } else if (!calibrate) { + /* + * Use hardcoded delay values if controller doesn't support + * calibration + */ val = CCM_MMC_CTRL_OCLK_DLY(oclk_dly) | CCM_MMC_CTRL_SCLK_DLY(sclk_dly); } @@ -228,6 +237,16 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc) rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; writel(rval, &priv->reg->clkcr); +#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) + /* A64 supports calibration of delays on MMC controller and we + * have to set delay of zero before starting calibration. + * Allwinner BSP driver sets a delay only in the case of + * using HS400 which is not supported by mainline U-Boot or + * Linux at the moment + */ + writel(SUNXI_MMC_CAL_DL_SW_EN, &priv->reg->samp_dl); +#endif + /* Re-enable Clock */ rval |= SUNXI_MMC_CLK_ENABLE; writel(rval, &priv->reg->clkcr); diff --git a/drivers/video/bridge/video-bridge-uclass.c b/drivers/video/bridge/video-bridge-uclass.c index cd4959cc71..5fecb4cfd5 100644 --- a/drivers/video/bridge/video-bridge-uclass.c +++ b/drivers/video/bridge/video-bridge-uclass.c @@ -106,13 +106,19 @@ static int video_bridge_pre_probe(struct udevice *dev) int video_bridge_set_active(struct udevice *dev, bool active) { struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev); - int ret; + int ret = 0; debug("%s: %d\n", __func__, active); - ret = dm_gpio_set_value(&uc_priv->sleep, !active); - if (ret) - return ret; - if (active) { + if (uc_priv->sleep.dev) { + ret = dm_gpio_set_value(&uc_priv->sleep, !active); + if (ret) + return ret; + } + + if (!active) + return 0; + + if (uc_priv->reset.dev) { ret = dm_gpio_set_value(&uc_priv->reset, true); if (ret) return ret; diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index 63c47bf1bc..4cf3a0eb75 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -211,11 +211,17 @@ void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, int *clk_div, int *clk_double, bool is_composite) { - int value, n, m, min_m, max_m, diff; + int value, n, m, min_m, max_m, diff, step; int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF; int best_double = 0; bool use_mipi_pll = false; +#ifdef CONFIG_SUNXI_DE2 + step = 6000; +#else + step = 3000; +#endif + if (tcon == 0) { #if defined(CONFIG_VIDEO_LCD_IF_PARALLEL) || defined(CONFIG_SUNXI_DE2) min_m = 6; @@ -237,10 +243,10 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, */ for (m = min_m; m <= max_m; m++) { #ifndef CONFIG_SUNXI_DE2 - n = (m * dotclock) / 3000; + n = (m * dotclock) / step; if ((n >= 9) && (n <= 127)) { - value = (3000 * n) / m; + value = (step * n) / m; diff = dotclock - value; if (diff < best_diff) { best_diff = diff; @@ -256,9 +262,9 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, #endif /* No double clock on DE2 */ - n = (m * dotclock) / 6000; + n = (m * dotclock) / (step * 2); if ((n >= 9) && (n <= 127)) { - value = (6000 * n) / m; + value = (step * 2 * n) / m; diff = dotclock - value; if (diff < best_diff) { best_diff = diff; @@ -287,11 +293,11 @@ void lcdc_pll_set(struct sunxi_ccm_reg *ccm, int tcon, int dotclock, } else #endif { - clock_set_pll3(best_n * 3000000); - debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n", + clock_set_pll3(best_n * step * 1000); + debug("dotclock: %dkHz = %dkHz: (%d * %dkHz * %d) / %d\n", dotclock, (best_double + 1) * clock_get_pll3() / best_m / 1000, - best_double + 1, best_n, best_m); + best_double + 1, step, best_n, best_m); } if (tcon == 0) { |