diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index e3e6f81593c0..46d932bc7678 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -455,7 +455,7 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) if (work) armada_drm_crtc_complete_frame_work(dcrtc, work); - wake_up(&dcrtc->frame_wait); + wake_up(&drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait); } } @@ -571,7 +571,8 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, adj->crtc_vtotal, tm, bm); /* Wait for pending flips to complete */ - wait_event(dcrtc->frame_wait, !dcrtc->frame_work); + wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait, + !dcrtc->frame_work); drm_crtc_vblank_off(crtc); @@ -688,7 +689,8 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, armada_reg_queue_end(regs, i); /* Wait for pending flips to complete */ - wait_event(dcrtc->frame_wait, !dcrtc->frame_work); + wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait, + !dcrtc->frame_work); /* Take a reference to the new fb as we're using it */ drm_framebuffer_reference(crtc->primary->fb); @@ -1096,6 +1098,13 @@ static const struct drm_plane_funcs armada_primary_plane_funcs = { .destroy = drm_primary_helper_destroy, }; +int armada_drm_plane_init(struct armada_plane *plane) +{ + init_waitqueue_head(&plane->frame_wait); + + return 0; +} + static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = { { CSC_AUTO, "Auto" }, { CSC_YUV_CCIR601, "CCIR601" }, @@ -1166,7 +1175,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, spin_lock_init(&dcrtc->irq_lock); dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR; INIT_LIST_HEAD(&dcrtc->vbl_list); - init_waitqueue_head(&dcrtc->frame_wait); /* Initialize some registers which we don't otherwise set */ writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV); @@ -1208,6 +1216,12 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, if (!primary) return -ENOMEM; + ret = armada_drm_plane_init(primary); + if (ret) { + kfree(primary); + return ret; + } + ret = drm_universal_plane_init(drm, &primary->base, 0, &armada_primary_plane_funcs, armada_primary_formats, diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index 500ce0f43f64..3ec5101e13f7 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h @@ -36,9 +36,12 @@ struct armada_variant; struct armada_plane { struct drm_plane base; + wait_queue_head_t frame_wait; }; #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base) +int armada_drm_plane_init(struct armada_plane *plane); + struct armada_crtc { struct drm_crtc crtc; const struct armada_variant *variant; @@ -71,7 +74,6 @@ struct armada_crtc { uint32_t dumb_ctrl; uint32_t spu_iopad_ctrl; - wait_queue_head_t frame_wait; struct armada_frame_work *frame_work; spinlock_t irq_lock; diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 6ec42eb85981..9a5bab765085 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -39,7 +39,6 @@ struct armada_ovl_plane { struct { struct armada_vbl_event update; struct armada_regs regs[13]; - wait_queue_head_t wait; } vbl; struct armada_ovl_plane_properties prop; }; @@ -90,7 +89,7 @@ static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data) armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs); armada_ovl_retire_fb(dplane, NULL); - wake_up(&dplane->vbl.wait); + wake_up(&dplane->base.frame_wait); } static int @@ -163,7 +162,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, dcrtc->base + LCD_SPU_SRAM_PARA1); } - wait_event_timeout(dplane->vbl.wait, + wait_event_timeout(dplane->base.frame_wait, list_empty(&dplane->vbl.update.node), HZ/25); @@ -451,7 +450,12 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) if (!dplane) return -ENOMEM; - init_waitqueue_head(&dplane->vbl.wait); + ret = armada_drm_plane_init(&dplane->base); + if (ret) { + kfree(dplane); + return ret; + } + armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl, dplane);