drm/exynos: check for pending fb before finish update
The current code was ignoring the end of update for all overlay planes, caring only for the primary plane update in case of pageflip. This change adds a change to start to check for pending updates for all planes through exynos_plane->pending_fb. At the start of plane update the pending_fb is set with the fb to be shown on the screen. Then only when to fb is already presented in the screen we set pending_fb to NULL to signal that the update was finished. Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Inki Dae <inki.dae@samsung.com> fixup! drm/exynos: check for pending fb before finish update
This commit is contained in:
Родитель
ce3ff36be9
Коммит
822f6dfd71
|
@ -542,13 +542,21 @@ static irqreturn_t decon_lcd_sys_irq_handler(int irq, void *dev_id)
|
|||
{
|
||||
struct decon_context *ctx = dev_id;
|
||||
u32 val;
|
||||
int win;
|
||||
|
||||
if (!test_bit(BIT_CLKS_ENABLED, &ctx->enabled))
|
||||
goto out;
|
||||
|
||||
val = readl(ctx->addr + DECON_VIDINTCON1);
|
||||
if (val & VIDINTCON1_INTFRMDONEPEND) {
|
||||
exynos_drm_crtc_finish_pageflip(ctx->crtc);
|
||||
for (win = 0 ; win < WINDOWS_NR ; win++) {
|
||||
struct exynos_drm_plane *plane = &ctx->planes[win];
|
||||
|
||||
if (!plane->pending_fb)
|
||||
continue;
|
||||
|
||||
exynos_drm_crtc_finish_update(ctx->crtc, plane);
|
||||
}
|
||||
|
||||
/* clear */
|
||||
writel(VIDINTCON1_INTFRMDONEPEND,
|
||||
|
|
|
@ -623,6 +623,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
|
|||
{
|
||||
struct decon_context *ctx = (struct decon_context *)dev_id;
|
||||
u32 val, clear_bit;
|
||||
int win;
|
||||
|
||||
val = readl(ctx->regs + VIDINTCON1);
|
||||
|
||||
|
@ -636,7 +637,14 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
|
|||
|
||||
if (!ctx->i80_if) {
|
||||
drm_crtc_handle_vblank(&ctx->crtc->base);
|
||||
exynos_drm_crtc_finish_pageflip(ctx->crtc);
|
||||
for (win = 0 ; win < WINDOWS_NR ; win++) {
|
||||
struct exynos_drm_plane *plane = &ctx->planes[win];
|
||||
|
||||
if (!plane->pending_fb)
|
||||
continue;
|
||||
|
||||
exynos_drm_crtc_finish_update(ctx->crtc, plane);
|
||||
}
|
||||
|
||||
/* set wait vsync event to zero and wake up queue. */
|
||||
if (atomic_read(&ctx->wait_vsync_event)) {
|
||||
|
|
|
@ -197,18 +197,19 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe)
|
|||
exynos_crtc->ops->disable_vblank(exynos_crtc);
|
||||
}
|
||||
|
||||
void exynos_drm_crtc_finish_pageflip(struct exynos_drm_crtc *exynos_crtc)
|
||||
void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
|
||||
struct exynos_drm_plane *exynos_plane)
|
||||
{
|
||||
struct drm_crtc *crtc = &exynos_crtc->base;
|
||||
unsigned long flags;
|
||||
|
||||
exynos_plane->pending_fb = NULL;
|
||||
|
||||
spin_lock_irqsave(&crtc->dev->event_lock, flags);
|
||||
if (exynos_crtc->event) {
|
||||
|
||||
drm_crtc_send_vblank_event(crtc, exynos_crtc->event);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
wake_up(&exynos_crtc->pending_flip_queue);
|
||||
|
||||
}
|
||||
|
||||
exynos_crtc->event = NULL;
|
||||
|
|
|
@ -25,7 +25,8 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
|
|||
void *context);
|
||||
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
|
||||
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
|
||||
void exynos_drm_crtc_finish_pageflip(struct exynos_drm_crtc *exynos_crtc);
|
||||
void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
|
||||
struct exynos_drm_plane *exynos_plane);
|
||||
void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
|
||||
|
||||
/* This function gets pipe value to crtc device matched with out_type. */
|
||||
|
|
|
@ -74,6 +74,7 @@ struct exynos_drm_plane {
|
|||
unsigned int v_ratio;
|
||||
dma_addr_t dma_addr[MAX_FB_BUFFER];
|
||||
unsigned int zpos;
|
||||
struct drm_framebuffer *pending_fb;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -896,6 +896,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
|||
{
|
||||
struct fimd_context *ctx = (struct fimd_context *)dev_id;
|
||||
u32 val, clear_bit;
|
||||
int win;
|
||||
|
||||
val = readl(ctx->regs + VIDINTCON1);
|
||||
|
||||
|
@ -910,7 +911,14 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
|||
if (!ctx->i80_if)
|
||||
drm_crtc_handle_vblank(&ctx->crtc->base);
|
||||
|
||||
exynos_drm_crtc_finish_pageflip(ctx->crtc);
|
||||
for (win = 0 ; win < WINDOWS_NR ; win++) {
|
||||
struct exynos_drm_plane *plane = &ctx->planes[win];
|
||||
|
||||
if (!plane->pending_fb)
|
||||
continue;
|
||||
|
||||
exynos_drm_crtc_finish_update(ctx->crtc, plane);
|
||||
}
|
||||
|
||||
if (ctx->i80_if) {
|
||||
/* Exits triggering mode */
|
||||
|
|
|
@ -168,6 +168,8 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
|
|||
state->src_x >> 16, state->src_y >> 16,
|
||||
state->src_w >> 16, state->src_h >> 16);
|
||||
|
||||
exynos_plane->pending_fb = state->fb;
|
||||
|
||||
if (exynos_crtc->ops->update_plane)
|
||||
exynos_crtc->ops->update_plane(exynos_crtc, exynos_plane);
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
|
|||
{
|
||||
struct vidi_context *ctx = container_of(work, struct vidi_context,
|
||||
work);
|
||||
int win;
|
||||
|
||||
if (ctx->pipe < 0)
|
||||
return;
|
||||
|
@ -197,7 +198,14 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
|
|||
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
||||
exynos_drm_crtc_finish_pageflip(ctx->crtc);
|
||||
for (win = 0 ; win < WINDOWS_NR ; win++) {
|
||||
struct exynos_drm_plane *plane = &ctx->planes[win];
|
||||
|
||||
if (!plane->pending_fb)
|
||||
continue;
|
||||
|
||||
exynos_drm_crtc_finish_update(ctx->crtc, plane);
|
||||
}
|
||||
}
|
||||
|
||||
static int vidi_show_connection(struct device *dev,
|
||||
|
|
|
@ -716,6 +716,7 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
|||
struct mixer_context *ctx = arg;
|
||||
struct mixer_resources *res = &ctx->mixer_res;
|
||||
u32 val, base, shadow;
|
||||
int win;
|
||||
|
||||
spin_lock(&res->reg_slock);
|
||||
|
||||
|
@ -742,7 +743,14 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
|||
}
|
||||
|
||||
drm_crtc_handle_vblank(&ctx->crtc->base);
|
||||
exynos_drm_crtc_finish_pageflip(ctx->crtc);
|
||||
for (win = 0 ; win < MIXER_WIN_NR ; win++) {
|
||||
struct exynos_drm_plane *plane = &ctx->planes[win];
|
||||
|
||||
if (!plane->pending_fb)
|
||||
continue;
|
||||
|
||||
exynos_drm_crtc_finish_update(ctx->crtc, plane);
|
||||
}
|
||||
|
||||
/* set wait vsync event to zero and wake up queue. */
|
||||
if (atomic_read(&ctx->wait_vsync_event)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче