diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a75972250a2..374c987038a 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1072,13 +1072,33 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, */ unsigned buf_unit = dss_feat_get_buffer_size_unit(); - unsigned fifo_size, burst_size; + unsigned ovl_fifo_size, total_fifo_size, burst_size; + int i; burst_size = dispc_ovl_get_burst_size(plane); - fifo_size = dispc_ovl_get_fifo_size(plane); + ovl_fifo_size = dispc_ovl_get_fifo_size(plane); - *fifo_low = fifo_size - burst_size; - *fifo_high = fifo_size - buf_unit; + if (use_fifomerge) { + total_fifo_size = 0; + for (i = 0; i < omap_dss_get_num_overlays(); ++i) + total_fifo_size += dispc_ovl_get_fifo_size(i); + } else { + total_fifo_size = ovl_fifo_size; + } + + /* + * We use the same low threshold for both fifomerge and non-fifomerge + * cases, but for fifomerge we calculate the high threshold using the + * combined fifo size + */ + + if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { + *fifo_low = ovl_fifo_size - burst_size * 2; + *fifo_high = total_fifo_size - burst_size; + } else { + *fifo_low = ovl_fifo_size - burst_size; + *fifo_high = total_fifo_size - buf_unit; + } } static void dispc_ovl_set_fir(enum omap_plane plane, diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index c2456c5bcd3..419419ad049 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -370,7 +370,8 @@ static const struct omap_dss_features omap3430_dss_features = { FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | + FEAT_OMAP3_DSI_FIFO_BUG, .num_mgrs = 2, .num_ovls = 3, @@ -394,7 +395,8 @@ static const struct omap_dss_features omap3630_dss_features = { FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | + FEAT_OMAP3_DSI_FIFO_BUG, .num_mgrs = 2, .num_ovls = 3, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 50caee9192a..5f9b8215677 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -59,6 +59,8 @@ enum dss_feat_id { FEAT_ALPHA_FIXED_ZORDER = 1 << 26, FEAT_ALPHA_FREE_ZORDER = 1 << 27, FEAT_FIFO_MERGE = 1 << 28, + /* An unknown HW bug causing the normal FIFO thresholds not to work */ + FEAT_OMAP3_DSI_FIFO_BUG = 1 << 29, }; /* DSS register field id */