Commit 1c96d673 authored by Imre Deak's avatar Imre Deak Committed by Juha Yrjola

ARM: OMAP: DISPC: DMA underflow for high graphics bandwith

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: default avatarImre Deak <imre.deak@solidboot.com>
Signed-off-by: default avatarJuha Yrjola <juha.yrjola@solidboot.com>
parent 6a9f264c
...@@ -244,7 +244,7 @@ void omap_dispc_set_digit_size(int x, int y) ...@@ -244,7 +244,7 @@ void omap_dispc_set_digit_size(int x, int y)
} }
EXPORT_SYMBOL(omap_dispc_set_digit_size); 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, const u32 ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD, DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD,
...@@ -252,16 +252,22 @@ static void setup_plane_fifo(int plane) ...@@ -252,16 +252,22 @@ static void setup_plane_fifo(int plane)
const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS, const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS, DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS,
DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS }; DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS };
int low, high;
u32 l; u32 l;
BUG_ON(plane > 2); BUG_ON(plane > 2);
l = dispc_read_reg(fsz_reg[plane]); l = dispc_read_reg(fsz_reg[plane]);
l &= FLD_MASK(0, 9); 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), 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) void omap_dispc_enable_lcd_out(int enable)
...@@ -1095,9 +1101,9 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, ...@@ -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(16, 8), 1 << 16);
MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(0, 8), 2 << 0); MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(0, 8), 2 << 0);
setup_plane_fifo(0); setup_plane_fifo(0, ext_mode);
setup_plane_fifo(1); setup_plane_fifo(1, ext_mode);
setup_plane_fifo(2); setup_plane_fifo(2, ext_mode);
setup_color_conv_coef(); setup_color_conv_coef();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment