diff options
Diffstat (limited to 'drivers/gpu/drm/sti/sti_hqvdp.c')
-rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index f88130f2eb48..66f843148ef7 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -332,6 +332,7 @@ struct sti_hqvdp_cmd { * @hqvdp_cmd_paddr: physical address of hqvdp_cmd * @vtg: vtg for main data path * @xp70_initialized: true if xp70 is already initialized + * @vtg_registered: true if registered to VTG */ struct sti_hqvdp { struct device *dev; @@ -347,6 +348,7 @@ struct sti_hqvdp { u32 hqvdp_cmd_paddr; struct sti_vtg *vtg; bool xp70_initialized; + bool vtg_registered; }; #define to_sti_hqvdp(x) container_of(x, struct sti_hqvdp, plane) @@ -771,7 +773,7 @@ static void sti_hqvdp_disable(struct sti_hqvdp *hqvdp) DRM_ERROR("XP70 could not revert to idle\n"); hqvdp->plane.status = STI_PLANE_DISABLED; - hqvdp->xp70_initialized = false; + hqvdp->vtg_registered = false; } /** @@ -1035,9 +1037,9 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, src_w = state->src_w >> 16; src_h = state->src_h >> 16; - if (!sti_hqvdp_check_hw_scaling(hqvdp, mode, - src_w, src_h, - dst_w, dst_h)) { + if (mode->clock && !sti_hqvdp_check_hw_scaling(hqvdp, mode, + src_w, src_h, + dst_w, dst_h)) { DRM_ERROR("Scaling beyond HW capabilities\n"); return -EINVAL; } @@ -1064,10 +1066,11 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, return -EINVAL; } - if (!hqvdp->xp70_initialized) { + if (!hqvdp->xp70_initialized) /* Start HQVDP XP70 coprocessor */ sti_hqvdp_start_xp70(hqvdp); + if (!hqvdp->vtg_registered) { /* Prevent VTG shutdown */ if (clk_prepare_enable(hqvdp->clk_pix_main)) { DRM_ERROR("Failed to prepare/enable pix main clk\n"); @@ -1081,6 +1084,7 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, DRM_ERROR("Cannot register VTG notifier\n"); return -EINVAL; } + hqvdp->vtg_registered = true; } DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n", @@ -1113,6 +1117,21 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane, if (!crtc || !fb) return; + if ((oldstate->fb == state->fb) && + (oldstate->crtc_x == state->crtc_x) && + (oldstate->crtc_y == state->crtc_y) && + (oldstate->crtc_w == state->crtc_w) && + (oldstate->crtc_h == state->crtc_h) && + (oldstate->src_x == state->src_x) && + (oldstate->src_y == state->src_y) && + (oldstate->src_w == state->src_w) && + (oldstate->src_h == state->src_h)) { + /* No change since last update, do not post cmd */ + DRM_DEBUG_DRIVER("No change, not posting cmd\n"); + plane->status = STI_PLANE_UPDATED; + return; + } + mode = &crtc->mode; dst_x = state->crtc_x; dst_y = state->crtc_y; @@ -1147,7 +1166,7 @@ static void sti_hqvdp_atomic_update(struct drm_plane *drm_plane, cma_obj = drm_fb_cma_get_gem_obj(fb, 0); DRM_DEBUG_DRIVER("drm FB:%d format:%.4s phys@:0x%lx\n", fb->base.id, - (char *)&fb->pixel_format, + (char *)&fb->format->format, (unsigned long)cma_obj->paddr); /* Buffer planes address */ |