diff options
-rw-r--r-- | drivers/gpu/drm/bridge/samsung-dsim.c | 27 | ||||
-rw-r--r-- | include/drm/bridge/samsung-dsim.h | 2 |
2 files changed, 27 insertions, 2 deletions
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 71fc0a8766ff..60d5ab2e0989 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -410,6 +410,8 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = { .num_bits_resol = 11, .pll_p_offset = 13, .reg_values = reg_values, + .pll_fin_min = 6, + .pll_fin_max = 12, .m_min = 41, .m_max = 125, .min_freq = 500, @@ -427,6 +429,8 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { .num_bits_resol = 11, .pll_p_offset = 13, .reg_values = reg_values, + .pll_fin_min = 6, + .pll_fin_max = 12, .m_min = 41, .m_max = 125, .min_freq = 500, @@ -442,6 +446,8 @@ static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = { .num_bits_resol = 11, .pll_p_offset = 13, .reg_values = reg_values, + .pll_fin_min = 6, + .pll_fin_max = 12, .m_min = 41, .m_max = 125, .min_freq = 500, @@ -457,6 +463,8 @@ static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = { .num_bits_resol = 12, .pll_p_offset = 13, .reg_values = exynos5433_reg_values, + .pll_fin_min = 6, + .pll_fin_max = 12, .m_min = 41, .m_max = 125, .min_freq = 500, @@ -472,6 +480,8 @@ static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = { .num_bits_resol = 12, .pll_p_offset = 13, .reg_values = exynos5422_reg_values, + .pll_fin_min = 6, + .pll_fin_max = 12, .m_min = 41, .m_max = 125, .min_freq = 500, @@ -491,6 +501,8 @@ static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = { */ .pll_p_offset = 14, .reg_values = imx8mm_dsim_reg_values, + .pll_fin_min = 2, + .pll_fin_max = 30, .m_min = 64, .m_max = 1023, .min_freq = 1050, @@ -614,10 +626,21 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi, u16 m; u32 reg; - if (dsi->pll_clk) + if (dsi->pll_clk) { + /* + * Ensure that the reference clock is generated with a power of + * two divider from its parent, but close to the PLLs upper + * limit. + */ + fin = clk_get_rate(clk_get_parent(dsi->pll_clk)); + while (fin > driver_data->pll_fin_max * MHZ) + fin /= 2; + clk_set_rate(dsi->pll_clk, fin); + fin = clk_get_rate(dsi->pll_clk); - else + } else { fin = dsi->pll_clk_rate; + } dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin); fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s); diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h index 757f87337fe5..e0c105051246 100644 --- a/include/drm/bridge/samsung-dsim.h +++ b/include/drm/bridge/samsung-dsim.h @@ -61,6 +61,8 @@ struct samsung_dsim_driver_data { unsigned int num_bits_resol; unsigned int pll_p_offset; const unsigned int *reg_values; + unsigned int pll_fin_min; + unsigned int pll_fin_max; u16 m_min; u16 m_max; }; |