aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonard Crestez <leonard.crestez@nxp.com>2018-09-17 09:42:12 -0400
committerStefan Agner <stefan@agner.ch>2018-09-26 16:07:40 -0400
commit2dc3620eac2df1545bc4a4b9110dcc7961c24a50 (patch)
treeea718c68775cb44af5648c47fa0d278669ac1fc1
parent626a2c52f1050b4581a0ffcd71245505b24315a2 (diff)
drm/mxsfb: Fix initial corrupt frame when activating display
LCDIF will repeatedly display data from CUR_BUF and set CUR_BUF to NEXT_BUF when done. Since we are only ever writing to NEXT_BUF the display will show an initial corrupt frame. Fix by writing the FB paddr to both CUR_BUF and NEXT_BUF when activating the CRTC. Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Stefan Agner <stefan@agner.ch> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Stefan Agner <stefan@agner.ch> Link: https://patchwork.freedesktop.org/patch/msgid/7cdac9c064cc2b8a3d237934f186da98cefe6cb3.1537191359.git.leonard.crestez@nxp.com
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_crtc.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
index e4fcbb65b969..24b1f0c1432e 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
@@ -193,6 +193,21 @@ static int mxsfb_reset_block(void __iomem *reset_addr)
193 return clear_poll_bit(reset_addr, MODULE_CLKGATE); 193 return clear_poll_bit(reset_addr, MODULE_CLKGATE);
194} 194}
195 195
196static dma_addr_t mxsfb_get_fb_paddr(struct mxsfb_drm_private *mxsfb)
197{
198 struct drm_framebuffer *fb = mxsfb->pipe.plane.state->fb;
199 struct drm_gem_cma_object *gem;
200
201 if (!fb)
202 return 0;
203
204 gem = drm_fb_cma_get_gem_obj(fb, 0);
205 if (!gem)
206 return 0;
207
208 return gem->paddr;
209}
210
196static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) 211static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
197{ 212{
198 struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode; 213 struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
@@ -269,8 +284,18 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
269 284
270void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb) 285void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
271{ 286{
287 dma_addr_t paddr;
288
272 mxsfb_enable_axi_clk(mxsfb); 289 mxsfb_enable_axi_clk(mxsfb);
273 mxsfb_crtc_mode_set_nofb(mxsfb); 290 mxsfb_crtc_mode_set_nofb(mxsfb);
291
292 /* Write cur_buf as well to avoid an initial corrupt frame */
293 paddr = mxsfb_get_fb_paddr(mxsfb);
294 if (paddr) {
295 writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf);
296 writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
297 }
298
274 mxsfb_enable_controller(mxsfb); 299 mxsfb_enable_controller(mxsfb);
275} 300}
276 301
@@ -285,12 +310,8 @@ void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
285{ 310{
286 struct drm_simple_display_pipe *pipe = &mxsfb->pipe; 311 struct drm_simple_display_pipe *pipe = &mxsfb->pipe;
287 struct drm_crtc *crtc = &pipe->crtc; 312 struct drm_crtc *crtc = &pipe->crtc;
288 struct drm_framebuffer *fb = pipe->plane.state->fb;
289 struct drm_pending_vblank_event *event; 313 struct drm_pending_vblank_event *event;
290 struct drm_gem_cma_object *gem; 314 dma_addr_t paddr;
291
292 if (!crtc)
293 return;
294 315
295 spin_lock_irq(&crtc->dev->event_lock); 316 spin_lock_irq(&crtc->dev->event_lock);
296 event = crtc->state->event; 317 event = crtc->state->event;
@@ -305,12 +326,10 @@ void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
305 } 326 }
306 spin_unlock_irq(&crtc->dev->event_lock); 327 spin_unlock_irq(&crtc->dev->event_lock);
307 328
308 if (!fb) 329 paddr = mxsfb_get_fb_paddr(mxsfb);
309 return; 330 if (paddr) {
310 331 mxsfb_enable_axi_clk(mxsfb);
311 gem = drm_fb_cma_get_gem_obj(fb, 0); 332 writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
312 333 mxsfb_disable_axi_clk(mxsfb);
313 mxsfb_enable_axi_clk(mxsfb); 334 }
314 writel(gem->paddr, mxsfb->base + mxsfb->devdata->next_buf);
315 mxsfb_disable_axi_clk(mxsfb);
316} 335}