summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2017-07-08 10:22:31 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2017-12-08 12:20:57 +0000
commitd19f6ee5051be073939b6a013455355711708215 (patch)
treef0edf673fa6849ebce117df79bf4c28e8055c272
parent890ca8df5a75b3bfdab86bec03aa60cff90a573e (diff)
drm/armada: re-organise overlay register update generation
Re-organise overlay register generation so that we do not have to wait for the previous update to complete while creating the new state. This allows the update to be fully prepared before queueing it for the next interrupt. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c52
1 files changed, 22 insertions, 30 deletions
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 0fe3f2db8ff5..00da2c58701c 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -136,43 +136,18 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
if (format->num_planes == 1 && state.src.x1 >> 16 & (format->hsub - 1))
ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
- fb_changed = plane->fb != fb ||
- dplane->base.state.src_x != state.src.x1 >> 16 ||
- dplane->base.state.src_y != state.src.y1 >> 16;
-
- /* FIXME: overlay on an interlaced display */
- /* Just updating the position/size? */
- if (!fb_changed && dplane->base.state.ctrl0 == ctrl0) {
- val = (drm_rect_height(&state.src) & 0xffff0000) |
- drm_rect_width(&state.src) >> 16;
- dplane->base.state.src_hw = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN);
-
- val = drm_rect_height(&state.dst) << 16 |
- drm_rect_width(&state.dst);
- dplane->base.state.dst_hw = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN);
-
- val = state.dst.y1 << 16 | state.dst.x1;
- dplane->base.state.dst_yx = val;
- writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN);
-
- return 0;
- } else if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
+ if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
/* Power up the Y/U/V FIFOs on ENA 0->1 transitions */
armada_reg_queue_mod(work->regs, idx,
0, CFG_PDWN16x66 | CFG_PDWN32x66,
LCD_SPU_SRAM_PARA1);
}
- if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
- armada_drm_plane_work_cancel(dcrtc, &dplane->base);
-
- if (!dcrtc->plane) {
- dcrtc->plane = plane;
- armada_ovl_update_attr(&dplane->prop, dcrtc);
- }
+ fb_changed = plane->fb != fb ||
+ dplane->base.state.src_x != state.src.x1 >> 16 ||
+ dplane->base.state.src_y != state.src.y1 >> 16;
+ /* FIXME: overlay on an interlaced display */
if (fb_changed) {
u32 addrs[3];
@@ -243,6 +218,23 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
CFG_YUV2RGB) | CFG_DMA_ENA,
LCD_SPU_DMA_CTRL0);
}
+
+ /* Just updating the position/size? */
+ if (!fb_changed && dplane->base.state.ctrl0 == ctrl0) {
+ armada_reg_queue_end(work->regs, idx);
+ armada_ovl_plane_work(dcrtc, work);
+ return 0;
+ }
+
+ /* Wait for pending work to complete */
+ if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
+ armada_drm_plane_work_cancel(dcrtc, &dplane->base);
+
+ if (!dcrtc->plane) {
+ dcrtc->plane = plane;
+ armada_ovl_update_attr(&dplane->prop, dcrtc);
+ }
+
if (idx) {
armada_reg_queue_end(work->regs, idx);
/* Queue it for update on the next interrupt if we are enabled */