From: Maarten Lankhorst Date: Thu, 18 Oct 2018 11:51:33 +0000 (+0200) Subject: drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3. X-Git-Tag: v5.4-rc1~1388^2~28^2~426 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e364f9008a7cdf603ac394948ba7152b2842849;p=platform%2Fkernel%2Flinux-rpi.git drm/i915/gen11: Program the Y and UV plane for planar mode correctly, v3. The UV plane is the master plane that does all color correction etc. It needs to be programmed with the dimensions for color plane 1 (UV). The Y plane just feeds the Y pixels to it. Program the scaler from the master only, and set PLANE_CTL_YUV420_Y_PLANE on the slave plane. Changes since v1: - Make a common skl_program_plane, and use it for both plane updates. Changes since v2: - Make color_plane explicit, to clarify skl_update_plane(). (Ville) Signed-off-by: Maarten Lankhorst Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181018115134.9061-8-maarten.lankhorst@linux.intel.com --- diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 57068ae..69eb573 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6499,6 +6499,7 @@ enum { #define PLANE_CTL_KEY_ENABLE_DESTINATION (2 << 21) #define PLANE_CTL_ORDER_BGRX (0 << 20) #define PLANE_CTL_ORDER_RGBX (1 << 20) +#define PLANE_CTL_YUV420_Y_PLANE (1 << 19) #define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 (1 << 18) #define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) #define PLANE_CTL_YUV422_YUYV (0 << 16) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 95d9405..efb2701 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -362,22 +362,22 @@ skl_program_scaler(struct drm_i915_private *dev_priv, } static void -skl_update_plane(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state) +skl_program_plane(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state, + int color_plane, bool slave, u32 plane_ctl) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; - u32 plane_ctl = plane_state->ctl; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; - u32 surf_addr = plane_state->color_plane[0].offset; - u32 stride = skl_plane_stride(plane_state, 0); + u32 surf_addr = plane_state->color_plane[color_plane].offset; + u32 stride = skl_plane_stride(plane_state, color_plane); u32 aux_stride = skl_plane_stride(plane_state, 1); int crtc_x = plane_state->base.dst.x1; int crtc_y = plane_state->base.dst.y1; - uint32_t x = plane_state->color_plane[0].x; - uint32_t y = plane_state->color_plane[0].y; + uint32_t x = plane_state->color_plane[color_plane].x; + uint32_t y = plane_state->color_plane[color_plane].y; uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; struct intel_plane *linked = plane_state->linked_plane; @@ -441,7 +441,9 @@ skl_update_plane(struct intel_plane *plane, /* program plane scaler */ if (plane_state->scaler_id >= 0) { - skl_program_scaler(dev_priv, plane, crtc_state, plane_state); + if (!slave) + skl_program_scaler(dev_priv, plane, + crtc_state, plane_state); I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0); } else { @@ -456,7 +458,32 @@ skl_update_plane(struct intel_plane *plane, spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); } +void +skl_update_plane(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) +{ + int color_plane = 0; + + if (plane_state->linked_plane) { + /* Program the UV plane */ + color_plane = 1; + } + + skl_program_plane(plane, crtc_state, plane_state, + color_plane, false, plane_state->ctl); +} + static void +icl_update_slave(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) +{ + skl_program_plane(plane, crtc_state, plane_state, 0, true, + plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE); +} + +void skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); @@ -1934,6 +1961,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->disable_plane = skl_disable_plane; plane->get_hw_state = skl_plane_get_hw_state; plane->check_plane = skl_plane_check; + if (icl_is_nv12_y_plane(plane_id)) + plane->update_slave = icl_update_slave; if (skl_plane_has_planar(dev_priv, pipe, plane_id)) { formats = skl_planar_formats;