From 0aaf29b35f93f68128f92ea826ebfee8df9ab1ef Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 21 Sep 2018 16:44:37 +0200 Subject: drm/i915: Clean up scaler setup, v2. On skylake we can switch to a high quality scaler mode when only 1 out of 2 scalers are used, but on GLK and later bit 28 has a different meaning. Don't set it, and make clear the distinction between SKL and later PS values. Changes since v1: - Add missing break statement. Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper [mlankhorst: Remove extra newline] Link: https://patchwork.freedesktop.org/patch/msgid/20180921144437.20037-1-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic.c | 108 ++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 47 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_atomic.c') diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index b04952bacf77..760758ad21c1 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -203,6 +203,62 @@ intel_crtc_destroy_state(struct drm_crtc *crtc, drm_atomic_helper_crtc_destroy_state(crtc, state); } +static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, + int num_scalers_need, struct intel_crtc *intel_crtc, + const char *name, int idx, + struct intel_plane_state *plane_state, + int *scaler_id) +{ + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); + int j; + u32 mode; + + if (*scaler_id < 0) { + /* find a free scaler */ + for (j = 0; j < intel_crtc->num_scalers; j++) { + if (scaler_state->scalers[j].in_use) + continue; + + *scaler_id = j; + scaler_state->scalers[*scaler_id].in_use = 1; + break; + } + } + + if (WARN(*scaler_id < 0, "Cannot find scaler for %s:%d\n", name, idx)) + return; + + /* set scaler mode */ + if (plane_state && plane_state->base.fb && + plane_state->base.fb->format->is_yuv && + plane_state->base.fb->format->num_planes > 1) { + if (INTEL_GEN(dev_priv) == 9 && + !IS_GEMINILAKE(dev_priv)) + mode = SKL_PS_SCALER_MODE_NV12; + else + mode = PS_SCALER_MODE_PLANAR; + + } else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) { + mode = PS_SCALER_MODE_PACKED; + } else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) { + /* + * when only 1 scaler is in use on a pipe with 2 scalers + * scaler 0 operates in high quality (HQ) mode. + * In this case use scaler 0 to take advantage of HQ mode + */ + scaler_state->scalers[*scaler_id].in_use = 0; + *scaler_id = 0; + scaler_state->scalers[0].in_use = 1; + mode = SKL_PS_SCALER_MODE_HQ; + } else { + mode = SKL_PS_SCALER_MODE_DYN; + } + + DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n", + intel_crtc->pipe, *scaler_id, name, idx); + scaler_state->scalers[*scaler_id].mode = mode; +} + /** * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests * @dev_priv: i915 device @@ -232,7 +288,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, struct drm_atomic_state *drm_state = crtc_state->base.state; struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state); int num_scalers_need; - int i, j; + int i; num_scalers_need = hweight32(scaler_state->scaler_users); @@ -304,59 +360,17 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, idx = plane->base.id; /* plane on different crtc cannot be a scaler user of this crtc */ - if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) { + if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) continue; - } plane_state = intel_atomic_get_new_plane_state(intel_state, intel_plane); scaler_id = &plane_state->scaler_id; } - if (*scaler_id < 0) { - /* find a free scaler */ - for (j = 0; j < intel_crtc->num_scalers; j++) { - if (!scaler_state->scalers[j].in_use) { - scaler_state->scalers[j].in_use = 1; - *scaler_id = j; - DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n", - intel_crtc->pipe, *scaler_id, name, idx); - break; - } - } - } - - if (WARN_ON(*scaler_id < 0)) { - DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n", name, idx); - continue; - } - - /* set scaler mode */ - if ((INTEL_GEN(dev_priv) >= 9) && - plane_state && plane_state->base.fb && - plane_state->base.fb->format->format == - DRM_FORMAT_NV12) { - if (INTEL_GEN(dev_priv) == 9 && - !IS_GEMINILAKE(dev_priv) && - !IS_SKYLAKE(dev_priv)) - scaler_state->scalers[*scaler_id].mode = - SKL_PS_SCALER_MODE_NV12; - else - scaler_state->scalers[*scaler_id].mode = - PS_SCALER_MODE_PLANAR; - } else if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) { - /* - * when only 1 scaler is in use on either pipe A or B, - * scaler 0 operates in high quality (HQ) mode. - * In this case use scaler 0 to take advantage of HQ mode - */ - *scaler_id = 0; - scaler_state->scalers[0].in_use = 1; - scaler_state->scalers[0].mode = PS_SCALER_MODE_HQ; - scaler_state->scalers[1].in_use = 0; - } else { - scaler_state->scalers[*scaler_id].mode = PS_SCALER_MODE_DYN; - } + intel_atomic_setup_scaler(scaler_state, num_scalers_need, + intel_crtc, name, idx, + plane_state, scaler_id); } return 0; -- cgit From b1554e23ccb6d8e611c5d54ca94bb2dfc54cae72 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 18 Oct 2018 13:51:31 +0200 Subject: drm/i915/gen11: Program the scalers correctly for planar formats, v3. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first 3 planes (primary, sprite 0 and 1) have a dedicated chroma upsampler to upscale YUV420 to YUV444 and the scaler should only be used for upscaling. Because of this we shouldn't program the scalers in planar mode if NV12 and the chroma upsampler are used. Instead program the scalers like on normal planes. Sprite 2 and 3 have no dedicated scaler, and need to program the selected Y plane in the scaler mode. Changes since v1: - Make the comment less confusing. Changes since v2: - Fix checkpatch warning (Matt) - gen10- -> Pre-gen11 (Ville) - PS_SCALER_MODE_PACKED -> PS_SCALER_MODE_NORMAL. (Matt) - Add comment about scaler mode in intel_atomic_setup_scaler(). (Matt) - Rename need_scaling to need_scaler. (Matt) - Move the crtc need_scaling check to skl_update_scaler_crtc(). Signed-off-by: Maarten Lankhorst Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181018115134.9061-6-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_atomic.c') diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 760758ad21c1..08b1472d26b8 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -233,13 +233,23 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta plane_state->base.fb->format->is_yuv && plane_state->base.fb->format->num_planes > 1) { if (INTEL_GEN(dev_priv) == 9 && - !IS_GEMINILAKE(dev_priv)) + !IS_GEMINILAKE(dev_priv)) { mode = SKL_PS_SCALER_MODE_NV12; - else + } else if (icl_is_hdr_plane(to_intel_plane(plane_state->base.plane))) { + /* + * On gen11+'s HDR planes we only use the scaler for + * scaling. They have a dedicated chroma upsampler, so + * we don't need the scaler to upsample the UV plane. + */ + mode = PS_SCALER_MODE_NORMAL; + } else { mode = PS_SCALER_MODE_PLANAR; + if (plane_state->linked_plane) + mode |= PS_PLANE_Y_SEL(plane_state->linked_plane->id); + } } else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) { - mode = PS_SCALER_MODE_PACKED; + mode = PS_SCALER_MODE_NORMAL; } else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) { /* * when only 1 scaler is in use on a pipe with 2 scalers -- cgit From 9e7833758b9feebc37b9988d13b017534c90a4a2 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 26 Oct 2018 12:51:42 -0700 Subject: drm/i915: Prefer IS_GEN check with bitmask. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whenever possible we should stick with IS_GEN checks. Bitmaks has been introduced on commit ae7617f0ef18 ("drm/i915: Allow optimized platform checks") for efficiency. Let's stick with it whenever possible. This patch was generated with coccinelle: spatch -sp_file is_gen.cocci *{c,h} --in-place is_gen.cocci: @gen2@ expression e; @@ -INTEL_GEN(e) == 2 +IS_GEN2(e) @gen3@ expression e; @@ -INTEL_GEN(e) == 3 +IS_GEN3(e) @gen4@ expression e; @@ -INTEL_GEN(e) == 4 +IS_GEN4(e) @gen5@ expression e; @@ -INTEL_GEN(e) == 5 +IS_GEN5(e) @gen6@ expression e; @@ -INTEL_GEN(e) == 6 +IS_GEN6(e) @gen7@ expression e; @@ -INTEL_GEN(e) == 7 +IS_GEN7(e) @gen8@ expression e; @@ -INTEL_GEN(e) == 8 +IS_GEN8(e) @gen9@ expression e; @@ -INTEL_GEN(e) == 9 +IS_GEN9(e) @gen10@ expression e; @@ -INTEL_GEN(e) == 10 +IS_GEN10(e) @gen11@ expression e; @@ -INTEL_GEN(e) == 11 +IS_GEN11(e) Cc: Tvrtko Ursulin Signed-off-by: Rodrigo Vivi Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20181026195143.20353-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_atomic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_atomic.c') diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 08b1472d26b8..a5a2c8fe58a7 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -232,7 +232,7 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta if (plane_state && plane_state->base.fb && plane_state->base.fb->format->is_yuv && plane_state->base.fb->format->num_planes > 1) { - if (INTEL_GEN(dev_priv) == 9 && + if (IS_GEN9(dev_priv) && !IS_GEMINILAKE(dev_priv)) { mode = SKL_PS_SCALER_MODE_NV12; } else if (icl_is_hdr_plane(to_intel_plane(plane_state->base.plane))) { -- cgit