aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-08-22 09:57:02 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-07 13:02:13 -0400
commit66a0f9e4ac46144fb86ebe90f58ce6f416a55cd5 (patch)
tree4e692f659edf5992a27b743c885c381a00d0140d
parent42a6961cf6d23632b8b5c64bd8711aef33e89518 (diff)
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>
-rw-r--r--drivers/video/omap2/dss/dispc.c27
-rw-r--r--drivers/video/omap2/dss/dispc.h4
-rw-r--r--include/video/omapdss.h1
3 files changed, 32 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index dc0f372c6b22..d512c389741e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -95,6 +95,9 @@ struct dispc_features {
95 unsigned long (*calc_core_clk) (enum omap_channel channel, 95 unsigned long (*calc_core_clk) (enum omap_channel channel,
96 u16 width, u16 height, u16 out_width, u16 out_height); 96 u16 width, u16 height, u16 out_width, u16 out_height);
97 u8 num_fifos; 97 u8 num_fifos;
98
99 /* swap GFX & WB fifos */
100 bool gfx_fifo_workaround:1;
98}; 101};
99 102
100#define DISPC_MAX_NR_FIFOS 5 103#define DISPC_MAX_NR_FIFOS 5
@@ -1088,6 +1091,29 @@ static void dispc_init_fifos(void)
1088 */ 1091 */
1089 dispc.fifo_assignment[fifo] = fifo; 1092 dispc.fifo_assignment[fifo] = fifo;
1090 } 1093 }
1094
1095 /*
1096 * The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo
1097 * causes problems with certain use cases, like using the tiler in 2D
1098 * mode. The below hack swaps the fifos of GFX and WB planes, thus
1099 * giving GFX plane a larger fifo. WB but should work fine with a
1100 * smaller fifo.
1101 */
1102 if (dispc.feat->gfx_fifo_workaround) {
1103 u32 v;
1104
1105 v = dispc_read_reg(DISPC_GLOBAL_BUFFER);
1106
1107 v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */
1108 v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */
1109 v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */
1110 v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */
1111
1112 dispc_write_reg(DISPC_GLOBAL_BUFFER, v);
1113
1114 dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
1115 dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
1116 }
1091} 1117}
1092 1118
1093static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) 1119static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
@@ -3780,6 +3806,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
3780 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3806 .calc_scaling = dispc_ovl_calc_scaling_44xx,
3781 .calc_core_clk = calc_core_clk_44xx, 3807 .calc_core_clk = calc_core_clk_44xx,
3782 .num_fifos = 5, 3808 .num_fifos = 5,
3809 .gfx_fifo_workaround = true,
3783}; 3810};
3784 3811
3785static int __init dispc_init_features(struct device *dev) 3812static int __init dispc_init_features(struct device *dev)
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 92d8a9be86fc..42e56cc7cdbc 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,7 @@
36#define DISPC_CONTROL2 0x0238 36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620 37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804 38#define DISPC_DIVISOR 0x0804
39#define DISPC_GLOBAL_BUFFER 0x0800
39#define DISPC_CONTROL3 0x0848 40#define DISPC_CONTROL3 0x0848
40#define DISPC_CONFIG3 0x084C 41#define DISPC_CONFIG3 0x084C
41 42
@@ -355,6 +356,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
355 return 0x014C; 356 return 0x014C;
356 case OMAP_DSS_VIDEO3: 357 case OMAP_DSS_VIDEO3:
357 return 0x0300; 358 return 0x0300;
359 case OMAP_DSS_WB:
360 return 0x0500;
358 default: 361 default:
359 BUG(); 362 BUG();
360 return 0; 363 return 0;
@@ -517,6 +520,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
517 case OMAP_DSS_VIDEO2: 520 case OMAP_DSS_VIDEO2:
518 return 0x0018; 521 return 0x0018;
519 case OMAP_DSS_VIDEO3: 522 case OMAP_DSS_VIDEO3:
523 case OMAP_DSS_WB:
520 return 0x0088; 524 return 0x0088;
521 default: 525 default:
522 BUG(); 526 BUG();
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 24a7fa196651..ac2e4cca5a23 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -73,6 +73,7 @@ enum omap_plane {
73 OMAP_DSS_VIDEO1 = 1, 73 OMAP_DSS_VIDEO1 = 1,
74 OMAP_DSS_VIDEO2 = 2, 74 OMAP_DSS_VIDEO2 = 2,
75 OMAP_DSS_VIDEO3 = 3, 75 OMAP_DSS_VIDEO3 = 3,
76 OMAP_DSS_WB = 4,
76}; 77};
77 78
78enum omap_channel { 79enum omap_channel {