[PATCH 36/36] drm/i915: Clean up skl_update_scaler()
Ville Syrjala
ville.syrjala at linux.intel.com
Wed Dec 18 16:10:53 UTC 2019
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
Move all the "do we need scaling?" checks into the callers where
it's easier to differentiate between the plane vs. pfit cases.
And this also allows us to plumb drm_rects all the way down.
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/i915/display/intel_display.c | 174 +++++++++----------
1 file changed, 78 insertions(+), 96 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8d1eb587ab07..9db05a1ccfaf 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5582,41 +5582,34 @@ static int skl_scaler_max_vscale(const struct intel_crtc_state *crtc_state,
static int skl_scaler_check_scaling(const struct intel_crtc_state *crtc_state,
unsigned int scaler_user,
- int src_w, int src_h,
- int dst_w, int dst_h,
+ const struct drm_rect *src,
+ const struct drm_rect *dst,
const struct drm_format_info *format)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_rect src = {
- .x2 = src_w << 16,
- .y2 = src_h << 16,
- };
- struct drm_rect dst = {
- .x2 = dst_w,
- .y2 = dst_h,
- };
int ret, hscale, vscale, max_hscale, max_vscale;
+ int src_w = drm_rect_width(src) >> 16;
max_hscale = skl_scaler_max_hscale(crtc_state, format);
- ret = drm_rect_calc_hscale(&src, &dst, 0, max_hscale, &hscale);
+ ret = drm_rect_calc_hscale(src, dst, 0, max_hscale, &hscale);
if (ret) {
DRM_DEBUG_KMS("[CRTC:%d:%s] scaler_user %u: horizontal downscaling (" DRM_RECT_FP_FMT
" -> " DRM_RECT_FMT ") (" DRM_FP_FMT ") exceeds max (" DRM_FP_FMT ")\n",
crtc->base.base.id, crtc->base.name, scaler_user,
- DRM_RECT_FP_ARG(&src), DRM_RECT_ARG(&dst),
+ DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst),
DRM_FP_ARG(hscale), DRM_FP_ARG(max_hscale));
return ret;
}
max_vscale = skl_scaler_max_vscale(crtc_state, src_w, format);
- ret = drm_rect_calc_vscale(&src, &dst, 0, max_vscale, &vscale);
+ ret = drm_rect_calc_vscale(src, dst, 0, max_vscale, &vscale);
if (ret) {
DRM_DEBUG_KMS("[CRTC:%d:%s] scaler_user %u: vertical downscaling (" DRM_RECT_FP_FMT
" -> " DRM_RECT_FMT ") (" DRM_FP_FMT ") exceeds max (" DRM_FP_FMT ")\n",
crtc->base.base.id, crtc->base.name, scaler_user,
- DRM_RECT_FP_ARG(&src), DRM_RECT_ARG(&dst),
+ DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst),
DRM_FP_ARG(vscale), DRM_FP_ARG(max_vscale));
return ret;
}
@@ -5655,9 +5648,11 @@ static void skl_scaler_min_src_size(const struct drm_format_info *format,
static int skl_scaler_check_src_size(struct intel_crtc *crtc,
unsigned int scaler_user,
- int src_w, int src_h,
+ const struct drm_rect *src,
const struct drm_format_info *format)
{
+ int src_w = drm_rect_width(src) >> 16;
+ int src_h = drm_rect_height(src) >> 16;
int min_w, min_h, max_w, max_h;
skl_scaler_min_src_size(format, &min_w, &min_h);
@@ -5708,40 +5703,19 @@ static int skl_scaler_check_pipe_src_size(const struct intel_crtc_state *crtc_st
}
static int
-skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
+skl_update_scaler(struct intel_crtc_state *crtc_state,
unsigned int scaler_user, enum scaler *scaler_id,
- int src_w, int src_h, int dst_w, int dst_h,
+ const struct drm_rect *src,
+ const struct drm_rect *dst,
const struct drm_format_info *format, bool need_scaler)
{
struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
- struct intel_crtc *intel_crtc =
- to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int ret;
- /*
- * Src coordinates are already rotated by 270 degrees for
- * the 90/270 degree plane rotation cases (to match the
- * GTT mapping), hence no need to account for rotation here.
- */
- if (src_w != dst_w || src_h != dst_h)
- need_scaler = true;
-
- /*
- * Scaling/fitting not supported in IF-ID mode in GEN9+
- * TODO: Interlace fetch mode doesn't support YUV420 planar formats.
- * Once NV12 is enabled, handle it here while allocating scaler
- * for NV12.
- */
- if (INTEL_GEN(dev_priv) >= 9 && crtc_state->hw.enable &&
- need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
- DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
- return -EINVAL;
- }
-
/*
* if plane is being disabled or scaler is no more required or force detach
* - free scaler binded to this plane/crtc
@@ -5752,22 +5726,28 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
* update to free the scaler is done in plane/panel-fit programming.
* For this purpose crtc/plane_state->scaler isn't reset here.
*/
- if (force_detach || !need_scaler) {
+ if (!need_scaler) {
if (*scaler_id != INVALID_SCALER) {
scaler_state->scaler_users &= ~BIT(scaler_user);
scaler_state->scalers[*scaler_id].in_use = false;
- DRM_DEBUG_KMS("scaler_user index %u.%u: "
- "Staged freeing scaler id %d scaler_users = 0x%x\n",
- intel_crtc->pipe, scaler_user, *scaler_id,
- scaler_state->scaler_users);
+ DRM_DEBUG_KMS("[CRTC:%d:%s] scaler_user %u: "
+ "Staged freeing scaler id %d scaler_users = 0x%x\n",
+ crtc->base.base.id, crtc->base.name,
+ scaler_user, *scaler_id,
+ scaler_state->scaler_users);
*scaler_id = INVALID_SCALER;
}
return 0;
}
- ret = skl_scaler_check_src_size(intel_crtc, scaler_user,
- src_w, src_h, format);
+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ DRM_DEBUG_KMS("[CRTC:%d:%s] Pipe/Plane scaling not supported with IF-ID mode\n",
+ crtc->base.base.id, crtc->base.name);
+ return -EINVAL;
+ }
+
+ ret = skl_scaler_check_src_size(crtc, scaler_user, src, format);
if (ret)
return ret;
@@ -5776,42 +5756,64 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
return ret;
ret = skl_scaler_check_scaling(crtc_state, scaler_user,
- src_w, src_h, dst_w, dst_h, format);
+ src, dst, format);
if (ret)
return ret;
/* mark this pipe/plane as a scaler user in crtc_state */
scaler_state->scaler_users |= BIT(scaler_user);
- DRM_DEBUG_KMS("scaler_user index %u.%u: "
- "staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n",
- intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h,
- scaler_state->scaler_users);
+ DRM_DEBUG_KMS("[CRTC:%d:%s] scaler_user %u: "
+ "staged scaling request for " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT " scaler_users = 0x%x\n",
+ crtc->base.base.id, crtc->base.name,
+ scaler_user, DRM_RECT_FP_ARG(src),
+ DRM_RECT_ARG(dst), scaler_state->scaler_users);
return 0;
}
static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state)
{
- const struct drm_display_mode *adjusted_mode =
- &crtc_state->hw.adjusted_mode;
- int width, height;
-
- if (crtc_state->pch_pfit.enabled) {
- width = drm_rect_width(&crtc_state->pch_pfit.dst);
- height = drm_rect_height(&crtc_state->pch_pfit.dst);
- } else {
- width = adjusted_mode->crtc_hdisplay;
- height = adjusted_mode->crtc_vdisplay;
- }
+ struct drm_rect src = {
+ .x2 = crtc_state->pipe_src_w << 16,
+ .y2 = crtc_state->pipe_src_h << 16,
+ };
- return skl_update_scaler(crtc_state, !crtc_state->hw.active,
+ return skl_update_scaler(crtc_state,
intel_crtc_scaler_user(),
&crtc_state->pch_pfit.scaler_id,
- crtc_state->pipe_src_w, crtc_state->pipe_src_h,
- width, height, NULL,
+ &src, &crtc_state->pch_pfit.dst, NULL,
+ crtc_state->hw.enable &&
crtc_state->pch_pfit.enabled);
}
+static bool intel_plane_is_scaled(const struct intel_plane_state *plane_state)
+{
+ int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
+ int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
+ int dst_w = drm_rect_width(&plane_state->uapi.dst);
+ int dst_h = drm_rect_height(&plane_state->uapi.dst);
+
+ return plane_state->uapi.visible &&
+ (src_w != dst_w || src_h != dst_h);
+}
+
+static bool skl_plane_needs_scaler(struct intel_plane_state *plane_state)
+{
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
+
+ if (!plane_state->uapi.visible)
+ return false;
+
+ /* Pre-gen11 and SDR planes always need a scaler for planar formats. */
+ if (!icl_is_hdr_plane(dev_priv, plane->id) &&
+ drm_format_info_is_yuv_semiplanar(fb->format))
+ return true;
+
+ return intel_plane_is_scaled(plane_state);
+}
+
/**
* skl_update_scaler_plane - Stages update to scaler state for a given plane.
* @crtc_state: crtc's scaler state
@@ -5824,26 +5826,16 @@ static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state)
static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
- struct intel_plane *intel_plane =
- to_intel_plane(plane_state->uapi.plane);
- struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
- struct drm_framebuffer *fb = plane_state->hw.fb;
- bool force_detach = !fb || !plane_state->uapi.visible;
- bool need_scaler = false;
-
- /* 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))
- need_scaler = true;
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
- return skl_update_scaler(crtc_state, force_detach,
- intel_plane_scaler_user(intel_plane),
+ return skl_update_scaler(crtc_state,
+ intel_plane_scaler_user(plane),
&plane_state->scaler_id,
- drm_rect_width(&plane_state->uapi.src) >> 16,
- 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);
+ &plane_state->uapi.src,
+ &plane_state->uapi.dst,
+ fb ? fb->format : NULL,
+ skl_plane_needs_scaler(plane_state));
}
void skylake_scaler_disable(const struct intel_crtc_state *old_crtc_state)
@@ -11845,16 +11837,6 @@ static bool intel_wm_need_update(const struct intel_plane_state *cur,
return false;
}
-static bool needs_scaling(const struct intel_plane_state *state)
-{
- int src_w = drm_rect_width(&state->uapi.src) >> 16;
- int src_h = drm_rect_height(&state->uapi.src) >> 16;
- int dst_w = drm_rect_width(&state->uapi.dst);
- int dst_h = drm_rect_height(&state->uapi.dst);
-
- return (src_w != dst_w || src_h != dst_h);
-}
-
int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *crtc_state,
const struct intel_plane_state *old_plane_state,
@@ -11971,8 +11953,8 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
if (plane->id != PLANE_CURSOR &&
(IS_GEN_RANGE(dev_priv, 5, 6) ||
IS_IVYBRIDGE(dev_priv)) &&
- (turn_on || (!needs_scaling(old_plane_state) &&
- needs_scaling(plane_state))))
+ (turn_on || (!intel_plane_is_scaled(old_plane_state) &&
+ intel_plane_is_scaled(plane_state))))
crtc_state->disable_lp_wm = true;
return 0;
--
2.23.0
More information about the Intel-gfx-trybot
mailing list