struct armada_plane_work work;
struct drm_pending_vblank_event *event;
struct armada_regs regs[4];
- struct drm_framebuffer *old_fb;
};
enum csc_mode {
void (*fn)(struct armada_crtc *, struct armada_plane_work *))
{
struct armada_plane *dplane = drm_to_armada_plane(work->plane);
+ struct drm_framebuffer *fb = work->old_fb;
if (fn)
fn(dcrtc, work);
drm_crtc_vblank_put(&dcrtc->crtc);
+ /* Finally, queue the process-half of the cleanup. */
+ if (fb)
+ armada_drm_queue_unref_work(dcrtc->crtc.dev, fb);
+
wake_up(&dplane->frame_wait);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
}
- /* Finally, queue the process-half of the cleanup. */
- __armada_drm_queue_unref_work(dcrtc->crtc.dev, fwork->old_fb);
kfree(fwork);
}
work = armada_drm_crtc_alloc_frame_work(dcrtc->crtc.primary);
if (work) {
- work->old_fb = fb;
+ work->work.old_fb = fb;
if (armada_drm_plane_work_queue(dcrtc, &work->work) == 0)
return;
return -ENOMEM;
work->event = event;
- work->old_fb = dcrtc->crtc.primary->fb;
+ work->work.old_fb = dcrtc->crtc.primary->fb;
i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs,
dcrtc->interlaced);
struct armada_ovl_plane {
struct armada_plane base;
- struct drm_framebuffer *old_fb;
struct {
struct armada_plane_work work;
struct armada_regs regs[13];
spin_unlock_irq(&dcrtc->irq_lock);
}
-static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
- struct drm_framebuffer *fb)
-{
- struct drm_framebuffer *old_fb;
-
- old_fb = xchg(&dplane->old_fb, fb);
-
- if (old_fb)
- armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
-}
-
/* === Plane support === */
static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
struct armada_plane_work *work)
spin_lock_irqsave(&dcrtc->irq_lock, flags);
armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-
- armada_ovl_retire_fb(dplane, NULL);
}
static int
*/
drm_framebuffer_get(fb);
- if (plane->fb)
- armada_ovl_retire_fb(dplane, plane->fb);
+ dplane->vbl.work.old_fb = plane->fb;
dplane->base.state.src_y = src_y = src.y1 >> 16;
dplane->base.state.src_x = src_x = src.x1 >> 16;
val = fb->pitches[1] << 16 | fb->pitches[2];
armada_reg_queue_set(dplane->vbl.regs, idx, val,
LCD_SPU_DMA_PITCH_UV);
+ } else {
+ dplane->vbl.work.old_fb = NULL;
}
val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16;
static int armada_ovl_plane_disable(struct drm_plane *plane,
struct drm_modeset_acquire_ctx *ctx)
{
- struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
- struct drm_framebuffer *fb;
-
armada_drm_plane_disable(plane, ctx);
- if (dplane->base.base.crtc)
- drm_to_armada_crtc(dplane->base.base.crtc)->plane = NULL;
-
- fb = xchg(&dplane->old_fb, NULL);
- if (fb)
- drm_framebuffer_put(fb);
+ if (plane->crtc)
+ drm_to_armada_crtc(plane->crtc)->plane = NULL;
return 0;
}