]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: DISPC: DMA underflow for high graphics bandwith
authorImre Deak <imre.deak@solidboot.com>
Wed, 12 Jul 2006 11:18:57 +0000 (14:18 +0300)
committerJuha Yrjola <juha.yrjola@solidboot.com>
Mon, 24 Jul 2006 12:11:14 +0000 (15:11 +0300)
DISPC DMA can, in certain conditions, underflow which will trigger an error
condition and halt the graphics pipeline. The only way to recover from
this would be to reset the related HW modules, which would abort the
current transfer and cause unwanted visual side-effects. The problem
arises mainly when enabling multiple planes with higher resolutions.

The arbitration priority of the DISPC DMA cannot be raised higher, thus -
so far - the only workaround is to keep the DMA FIFO full as much as
possible to minimize the risk of it being totally drained. The patch does
this for external LCD controllers connected to RFBI, where the new FIFO
setting doesn't degrade power consumption significantly.

Signed-off-by: Imre Deak <imre.deak@solidboot.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
drivers/video/omap/dispc.c

index 67201d2fb773bc65df822a2bcee7e14af3a7d35d..4693bbf07a45135071948028c6aff3a85b6c6013 100644 (file)
@@ -244,7 +244,7 @@ void omap_dispc_set_digit_size(int x, int y)
 }
 EXPORT_SYMBOL(omap_dispc_set_digit_size);
 
-static void setup_plane_fifo(int plane)
+static void setup_plane_fifo(int plane, int ext_mode)
 {
        const u32 ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
                                DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD,
@@ -252,16 +252,22 @@ static void setup_plane_fifo(int plane)
        const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
                                DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS,
                                DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS };
-
+       int low, high;
        u32 l;
 
        BUG_ON(plane > 2);
 
        l = dispc_read_reg(fsz_reg[plane]);
        l &= FLD_MASK(0, 9);
-       /* HIGH=3/4 LOW=1/4 */
+       if (ext_mode) {
+               low = l * 3 / 4;
+               high = l;
+       } else {
+               low = l / 4;
+               high = l * 3 / 4;
+       }
        MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 9) | FLD_MASK(0, 9),
-                       ((l * 3 / 4) << 16) | (l / 4));
+                       (high << 16) | low);
 }
 
 void omap_dispc_enable_lcd_out(int enable)
@@ -1095,9 +1101,9 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
                MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(16, 8), 1 << 16);
                MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(0, 8), 2 << 0);
 
-               setup_plane_fifo(0);
-               setup_plane_fifo(1);
-               setup_plane_fifo(2);
+               setup_plane_fifo(0, ext_mode);
+               setup_plane_fifo(1, ext_mode);
+               setup_plane_fifo(2, ext_mode);
 
                setup_color_conv_coef();