Commit 4941f35b authored by Imre Deak's avatar Imre Deak

drm/i915: Make sure CCS YUV semiplanar format checks work

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 <dhinakaran.pandiyan@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarMika Kahola <mika.kahola@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191221120543.22816-11-imre.deak@intel.com
parent 320625aa
...@@ -250,7 +250,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ ...@@ -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); new_crtc_state->active_planes |= BIT(plane->id);
if (new_plane_state->uapi.visible && 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); new_crtc_state->nv12_planes |= BIT(plane->id);
if (new_plane_state->uapi.visible && if (new_plane_state->uapi.visible &&
......
...@@ -1986,6 +1986,14 @@ intel_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane) ...@@ -1986,6 +1986,14 @@ intel_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
return 1; 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 static unsigned int
intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane) 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) ...@@ -3862,7 +3870,8 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
* Handle the AUX surface first since * Handle the AUX surface first since
* the main surface setup depends on it. * 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); ret = skl_check_nv12_aux_surface(plane_state);
if (ret) if (ret)
return ret; return ret;
...@@ -5791,7 +5800,8 @@ static int ...@@ -5791,7 +5800,8 @@ static int
skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
unsigned int scaler_user, int *scaler_id, unsigned int scaler_user, int *scaler_id,
int src_w, int src_h, int dst_w, int dst_h, 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 = struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state; &crtc_state->scaler_state;
...@@ -5845,7 +5855,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, ...@@ -5845,7 +5855,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
return 0; 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)) { (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"); DRM_DEBUG_KMS("Planar YUV: src dimensions not met\n");
return -EINVAL; return -EINVAL;
...@@ -5897,7 +5907,8 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) ...@@ -5897,7 +5907,8 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
&state->scaler_state.scaler_id, &state->scaler_state.scaler_id,
state->pipe_src_w, state->pipe_src_h, state->pipe_src_w, state->pipe_src_h,
adjusted_mode->crtc_hdisplay, 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, ...@@ -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. */ /* Pre-gen11 and SDR planes always need a scaler for planar formats. */
if (!icl_is_hdr_plane(dev_priv, intel_plane->id) && 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; need_scaler = true;
ret = skl_update_scaler(crtc_state, force_detach, ret = skl_update_scaler(crtc_state, force_detach,
...@@ -5932,7 +5943,9 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, ...@@ -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_height(&plane_state->uapi.src) >> 16,
drm_rect_width(&plane_state->uapi.dst), drm_rect_width(&plane_state->uapi.dst),
drm_rect_height(&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) if (ret || plane_state->scaler_id < 0)
return ret; return ret;
......
...@@ -601,6 +601,10 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv); ...@@ -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, void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
struct intel_display_error_state *error); struct intel_display_error_state *error);
bool
intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info,
uint64_t modifier);
/* modesetting */ /* modesetting */
void intel_modeset_init_hw(struct drm_i915_private *i915); void intel_modeset_init_hw(struct drm_i915_private *i915);
int intel_modeset_init(struct drm_i915_private *i915); int intel_modeset_init(struct drm_i915_private *i915);
......
...@@ -417,7 +417,7 @@ skl_program_scaler(struct intel_plane *plane, ...@@ -417,7 +417,7 @@ skl_program_scaler(struct intel_plane *plane,
0, INT_MAX); 0, INT_MAX);
/* TODO: handle sub-pixel coordinates */ /* 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)) { !icl_is_hdr_plane(dev_priv, plane->id)) {
y_hphase = skl_scaler_calc_phase(1, hscale, false); y_hphase = skl_scaler_calc_phase(1, hscale, false);
y_vphase = skl_scaler_calc_phase(1, vscale, 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 ...@@ -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; int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
/* Display WA #1106 */ /* 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_ROTATE_270 ||
rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) { rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n"); 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, ...@@ -2171,7 +2172,7 @@ static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
* FIXME need to properly check this later. * FIXME need to properly check this later.
*/ */
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) || 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; return 0x30000 - 1;
else else
return 0x20000 - 1; return 0x20000 - 1;
...@@ -2233,7 +2234,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state, ...@@ -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->color_ctl = glk_plane_color_ctl(crtc_state,
plane_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)) icl_is_hdr_plane(dev_priv, plane->id))
/* Enable and use MPEG-2 chroma siting */ /* Enable and use MPEG-2 chroma siting */
plane_state->cus_ctl = PLANE_CUS_ENABLE | plane_state->cus_ctl = PLANE_CUS_ENABLE |
......
...@@ -4135,7 +4135,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, ...@@ -4135,7 +4135,7 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
return 0; return 0;
if (color_plane == 1 && if (color_plane == 1 &&
!drm_format_info_is_yuv_semiplanar(fb->format)) !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
return 0; return 0;
/* /*
...@@ -4559,7 +4559,8 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, ...@@ -4559,7 +4559,8 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
u32 interm_pbpl; u32 interm_pbpl;
/* only planar format has two planes */ /* 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"); DRM_DEBUG_KMS("Non planar format have single plane\n");
return -EINVAL; return -EINVAL;
} }
...@@ -4571,7 +4572,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, ...@@ -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->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS || wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
modifier == I915_FORMAT_MOD_Yf_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; wp->width = width;
if (color_plane == 1 && wp->is_planar) if (color_plane == 1 && wp->is_planar)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment