diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 6f2ca74238d1..19bdb32dbc9a 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -413,6 +413,7 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = { .m_min = 41, .m_max = 125, .min_freq = 500, + .has_broken_fifoctrl_emptyhdr = 1, }; static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { @@ -429,6 +430,7 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { .m_min = 41, .m_max = 125, .min_freq = 500, + .has_broken_fifoctrl_emptyhdr = 1, }; static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = { @@ -1010,8 +1012,20 @@ static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi) do { u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG); - if (reg & DSIM_SFR_HEADER_EMPTY) - return 0; + if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) { + if (reg & DSIM_SFR_HEADER_EMPTY) + return 0; + } else { + if (!(reg & DSIM_SFR_HEADER_FULL)) { + /* + * Wait a little bit, so the pending data can + * actually leave the FIFO to avoid overflow. + */ + if (!cond_resched()) + usleep_range(950, 1050); + return 0; + } + } if (!cond_resched()) usleep_range(950, 1050); diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h index 05100e91ecb9..6fc9bb2979e4 100644 --- a/include/drm/bridge/samsung-dsim.h +++ b/include/drm/bridge/samsung-dsim.h @@ -53,6 +53,7 @@ struct samsung_dsim_driver_data { unsigned int plltmr_reg; unsigned int has_freqband:1; unsigned int has_clklane_stop:1; + unsigned int has_broken_fifoctrl_emptyhdr:1; unsigned int num_clks; unsigned int min_freq; unsigned int max_freq;