aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2017-07-08 05:22:31 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2017-12-08 07:20:57 -0500
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,
136 if (format->num_planes == 1 && state.src.x1 >> 16 & (format->hsub - 1)) 136 if (format->num_planes == 1 && state.src.x1 >> 16 & (format->hsub - 1))
137 ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV); 137 ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
138 138
139 fb_changed = plane->fb != fb || 139 if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
140 dplane->base.state.src_x != state.src.x1 >> 16 ||
141 dplane->base.state.src_y != state.src.y1 >> 16;
142
143 /* FIXME: overlay on an interlaced display */
144 /* Just updating the position/size? */
145 if (!fb_changed && dplane->base.state.ctrl0 == ctrl0) {
146 val = (drm_rect_height(&state.src) & 0xffff0000) |
147 drm_rect_width(&state.src) >> 16;
148 dplane->base.state.src_hw = val;
149 writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN);
150
151 val = drm_rect_height(&state.dst) << 16 |
152 drm_rect_width(&state.dst);
153 dplane->base.state.dst_hw = val;
154 writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN);
155
156 val = state.dst.y1 << 16 | state.dst.x1;
157 dplane->base.state.dst_yx = val;
158 writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN);
159
160 return 0;
161 } else if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
162 /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ 140 /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */
163 armada_reg_queue_mod(work->regs, idx, 141 armada_reg_queue_mod(work->regs, idx,
164 0, CFG_PDWN16x66 | CFG_PDWN32x66, 142 0, CFG_PDWN16x66 | CFG_PDWN32x66,
165 LCD_SPU_SRAM_PARA1); 143 LCD_SPU_SRAM_PARA1);
166 } 144 }
167 145
168 if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0) 146 fb_changed = plane->fb != fb ||
169 armada_drm_plane_work_cancel(dcrtc, &dplane->base); 147 dplane->base.state.src_x != state.src.x1 >> 16 ||
170 148 dplane->base.state.src_y != state.src.y1 >> 16;
171 if (!dcrtc->plane) {
172 dcrtc->plane = plane;
173 armada_ovl_update_attr(&dplane->prop, dcrtc);
174 }
175 149
150 /* FIXME: overlay on an interlaced display */
176 if (fb_changed) { 151 if (fb_changed) {
177 u32 addrs[3]; 152 u32 addrs[3];
178 153
@@ -243,6 +218,23 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
243 CFG_YUV2RGB) | CFG_DMA_ENA, 218 CFG_YUV2RGB) | CFG_DMA_ENA,
244 LCD_SPU_DMA_CTRL0); 219 LCD_SPU_DMA_CTRL0);
245 } 220 }
221
222 /* Just updating the position/size? */
223 if (!fb_changed && dplane->base.state.ctrl0 == ctrl0) {
224 armada_reg_queue_end(work->regs, idx);
225 armada_ovl_plane_work(dcrtc, work);
226 return 0;
227 }
228
229 /* Wait for pending work to complete */
230 if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
231 armada_drm_plane_work_cancel(dcrtc, &dplane->base);
232
233 if (!dcrtc->plane) {
234 dcrtc->plane = plane;
235 armada_ovl_update_attr(&dplane->prop, dcrtc);
236 }
237
246 if (idx) { 238 if (idx) {
247 armada_reg_queue_end(work->regs, idx); 239 armada_reg_queue_end(work->regs, idx);
248 /* Queue it for update on the next interrupt if we are enabled */ 240 /* Queue it for update on the next interrupt if we are enabled */