From 4941f35b48f7f329bdf2ccad17d6fdb2190f8d34 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Sat, 21 Dec 2019 14:05:43 +0200 Subject: [PATCH] drm/i915: Make sure CCS YUV semiplanar format checks work MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For CCS formats, the current DRM core check for YUV semiplanar formats doesn't work; use an i915 specific function for that. v2: Fix checkpatch warnings. Cc: Dhinakaran Pandiyan Cc: Ville Syrjälä Cc: Mika Kahola Signed-off-by: Imre Deak Reviewed-by: Mika Kahola Link: https://patchwork.freedesktop.org/patch/msgid/20191221120543.22816-11-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_atomic_plane.c | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 25 +++++++++++++++++------ drivers/gpu/drm/i915/display/intel_display.h | 4 ++++ drivers/gpu/drm/i915/display/intel_sprite.c | 9 ++++---- drivers/gpu/drm/i915/intel_pm.c | 7 ++++--- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 9429b8e..3e97af6 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -250,7 +250,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ new_crtc_state->active_planes |= BIT(plane->id); if (new_plane_state->uapi.visible && - drm_format_info_is_yuv_semiplanar(fb->format)) + intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) new_crtc_state->nv12_planes |= BIT(plane->id); if (new_plane_state->uapi.visible && diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e1a01e6..6fcf3d8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1986,6 +1986,14 @@ intel_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane) return 1; } +bool +intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info, + uint64_t modifier) +{ + return info->is_yuv && + info->num_planes == (is_ccs_modifier(modifier) ? 4 : 2); +} + static unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) { @@ -3862,7 +3870,8 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state) * Handle the AUX surface first since * the main surface setup depends on it. */ - if (drm_format_info_is_yuv_semiplanar(fb->format)) { + if (intel_format_info_is_yuv_semiplanar(fb->format, + fb->modifier)) { ret = skl_check_nv12_aux_surface(plane_state); if (ret) return ret; @@ -5791,7 +5800,8 @@ static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, unsigned int scaler_user, int *scaler_id, int src_w, int src_h, int dst_w, int dst_h, - const struct drm_format_info *format, bool need_scaler) + const struct drm_format_info *format, + u64 modifier, bool need_scaler) { struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; @@ -5845,7 +5855,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, return 0; } - if (format && drm_format_info_is_yuv_semiplanar(format) && + if (format && intel_format_info_is_yuv_semiplanar(format, modifier) && (src_h < SKL_MIN_YUV_420_SRC_H || src_w < SKL_MIN_YUV_420_SRC_W)) { DRM_DEBUG_KMS("Planar YUV: src dimensions not met\n"); return -EINVAL; @@ -5897,7 +5907,8 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) &state->scaler_state.scaler_id, state->pipe_src_w, state->pipe_src_h, adjusted_mode->crtc_hdisplay, - adjusted_mode->crtc_vdisplay, NULL, need_scaler); + adjusted_mode->crtc_vdisplay, NULL, 0, + need_scaler); } /** @@ -5922,7 +5933,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, /* Pre-gen11 and SDR planes always need a scaler for planar formats. */ if (!icl_is_hdr_plane(dev_priv, intel_plane->id) && - fb && drm_format_info_is_yuv_semiplanar(fb->format)) + fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) need_scaler = true; ret = skl_update_scaler(crtc_state, force_detach, @@ -5932,7 +5943,9 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, drm_rect_height(&plane_state->uapi.src) >> 16, drm_rect_width(&plane_state->uapi.dst), drm_rect_height(&plane_state->uapi.dst), - fb ? fb->format : NULL, need_scaler); + fb ? fb->format : NULL, + fb ? fb->modifier : 0, + need_scaler); if (ret || plane_state->scaler_id < 0) return ret; diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index ff496cf..0fef926 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -601,6 +601,10 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv); void intel_display_print_error_state(struct drm_i915_error_state_buf *e, struct intel_display_error_state *error); +bool +intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info, + uint64_t modifier); + /* modesetting */ void intel_modeset_init_hw(struct drm_i915_private *i915); int intel_modeset_init(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 0a29866..3f7b8f2 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -417,7 +417,7 @@ skl_program_scaler(struct intel_plane *plane, 0, INT_MAX); /* TODO: handle sub-pixel coordinates */ - if (drm_format_info_is_yuv_semiplanar(fb->format) && + if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && !icl_is_hdr_plane(dev_priv, plane->id)) { y_hphase = skl_scaler_calc_phase(1, hscale, false); y_vphase = skl_scaler_calc_phase(1, vscale, false); @@ -2151,7 +2151,8 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s int src_w = drm_rect_width(&plane_state->uapi.src) >> 16; /* Display WA #1106 */ - if (drm_format_info_is_yuv_semiplanar(fb->format) && src_w & 3 && + if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && + src_w & 3 && (rotation == DRM_MODE_ROTATE_270 || rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); @@ -2171,7 +2172,7 @@ static int skl_plane_max_scale(struct drm_i915_private *dev_priv, * FIXME need to properly check this later. */ if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) || - !drm_format_info_is_yuv_semiplanar(fb->format)) + !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) return 0x30000 - 1; else return 0x20000 - 1; @@ -2233,7 +2234,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, plane_state->color_ctl = glk_plane_color_ctl(crtc_state, plane_state); - if (drm_format_info_is_yuv_semiplanar(fb->format) && + if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && icl_is_hdr_plane(dev_priv, plane->id)) /* Enable and use MPEG-2 chroma siting */ plane_state->cus_ctl = PLANE_CUS_ENABLE | diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 00f9f51..d690f71 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4135,7 +4135,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, return 0; if (color_plane == 1 && - !drm_format_info_is_yuv_semiplanar(fb->format)) + !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) return 0; /* @@ -4559,7 +4559,8 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, u32 interm_pbpl; /* only planar format has two planes */ - if (color_plane == 1 && !drm_format_info_is_yuv_semiplanar(format)) { + if (color_plane == 1 && + !intel_format_info_is_yuv_semiplanar(format, modifier)) { DRM_DEBUG_KMS("Non planar format have single plane\n"); return -EINVAL; } @@ -4571,7 +4572,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED; wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS || modifier == I915_FORMAT_MOD_Yf_TILED_CCS; - wp->is_planar = drm_format_info_is_yuv_semiplanar(format); + wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier); wp->width = width; if (color_plane == 1 && wp->is_planar) -- 2.7.4