drm/tilcdc: Get rid of complex ping-pong mechanism
Get rid of complex ping-pong mechanism and replace it with simpler single buffer flipping code. The LCDC HW appears to be designed mainly static framebuffers in mind. There are two modes of operation, either static single buffer, or ping pong double buffering with two static buffers switching back and forth. Luckily the framebuffer start address is fetched only in the beginning of the frame and changing the address after that only takes effect after the next vertical blank. The page flipping code can simply write the address of the new framebuffer and the page is flipped automatically after the next vertical blank. Using the ping pong double buffering makes the flipping code way more complex and it does not provide any benefit, so it is better to switch to single buffer operation. There is still one problem in updating the framebuffer dma address on the fly. There are two registers defining the framebuffer dma area and things may break if the dma address is fetched in while the registers are are being updated. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> [Added description to the patch] Signed-off-by: Jyri Sarha <jsarha@ti.com>
This commit is contained in:

committed by
Jyri Sarha

parent
317aae738b
commit
2b2080d7e9
@@ -381,6 +381,7 @@ static int tilcdc_irq_postinstall(struct drm_device *dev)
|
||||
else
|
||||
tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG,
|
||||
LCDC_V2_UNDERFLOW_INT_ENA |
|
||||
LCDC_V2_END_OF_FRAME0_INT_ENA |
|
||||
LCDC_FRAME_DONE);
|
||||
|
||||
return 0;
|
||||
@@ -398,41 +399,19 @@ static void tilcdc_irq_uninstall(struct drm_device *dev)
|
||||
} else {
|
||||
tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG,
|
||||
LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA |
|
||||
LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_V2_END_OF_FRAME1_INT_ENA |
|
||||
LCDC_V2_END_OF_FRAME0_INT_ENA |
|
||||
LCDC_FRAME_DONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void enable_vblank(struct drm_device *dev, bool enable)
|
||||
{
|
||||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
u32 reg, mask;
|
||||
|
||||
if (priv->rev == 1) {
|
||||
reg = LCDC_DMA_CTRL_REG;
|
||||
mask = LCDC_V1_END_OF_FRAME_INT_ENA;
|
||||
} else {
|
||||
reg = LCDC_INT_ENABLE_SET_REG;
|
||||
mask = LCDC_V2_END_OF_FRAME0_INT_ENA |
|
||||
LCDC_V2_END_OF_FRAME1_INT_ENA;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
tilcdc_set(dev, reg, mask);
|
||||
else
|
||||
tilcdc_clear(dev, reg, mask);
|
||||
}
|
||||
|
||||
static int tilcdc_enable_vblank(struct drm_device *dev, unsigned int pipe)
|
||||
{
|
||||
enable_vblank(dev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tilcdc_disable_vblank(struct drm_device *dev, unsigned int pipe)
|
||||
{
|
||||
enable_vblank(dev, false);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PM_SLEEP)
|
||||
|
Reference in New Issue
Block a user