OMAPDSS: Use WB fifo for GFX overlay
OMAP4's GFX overlay has smaller fifo than the rest of the overlays
(including writeback "overlay"). This seems to be the reason for
underflows in some more demanding scenarios.
We can avoid the problems by using the WB fifo for GFX overlay, and vice
versa. WB usage is not supported yet, but when it will, it should
perform just fine with smaller fifo as there are no hard realtime
constraints with WB.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index dc0f372..d512c38 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -95,6 +95,9 @@
unsigned long (*calc_core_clk) (enum omap_channel channel,
u16 width, u16 height, u16 out_width, u16 out_height);
u8 num_fifos;
+
+ /* swap GFX & WB fifos */
+ bool gfx_fifo_workaround:1;
};
#define DISPC_MAX_NR_FIFOS 5
@@ -1088,6 +1091,29 @@
*/
dispc.fifo_assignment[fifo] = fifo;
}
+
+ /*
+ * The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo
+ * causes problems with certain use cases, like using the tiler in 2D
+ * mode. The below hack swaps the fifos of GFX and WB planes, thus
+ * giving GFX plane a larger fifo. WB but should work fine with a
+ * smaller fifo.
+ */
+ if (dispc.feat->gfx_fifo_workaround) {
+ u32 v;
+
+ v = dispc_read_reg(DISPC_GLOBAL_BUFFER);
+
+ v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */
+ v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */
+ v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */
+ v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */
+
+ dispc_write_reg(DISPC_GLOBAL_BUFFER, v);
+
+ dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
+ dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
+ }
}
static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
@@ -3780,6 +3806,7 @@
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
+ .gfx_fifo_workaround = true,
};
static int __init dispc_init_features(struct device *dev)