From patchwork Tue Oct 22 09:59:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sharma, Shashank" X-Patchwork-Id: 11204109 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 848AA913 for ; Tue, 22 Oct 2019 10:01:22 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6D04C2064B for ; Tue, 22 Oct 2019 10:01:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6D04C2064B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4C5E56E512; Tue, 22 Oct 2019 10:01:20 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 77C636E514; Tue, 22 Oct 2019 10:01:18 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Oct 2019 03:01:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,326,1566889200"; d="scan'208";a="196388709" Received: from sharmash-desk1.iind.intel.com ([10.99.66.206]) by fmsmga008.fm.intel.com with ESMTP; 22 Oct 2019 03:01:16 -0700 From: Shashank Sharma To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Date: Tue, 22 Oct 2019 15:29:44 +0530 Message-Id: <20191022095946.29354-2-shashank.sharma@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022095946.29354-1-shashank.sharma@intel.com> References: <20191022095946.29354-1-shashank.sharma@intel.com> Subject: [Intel-gfx] [PATCH 1/3] drm: Introduce scaling filter mode property X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" This patch adds a scaling filter mode porperty to allow: - A driver/HW to showcase it's scaling filter capabilities. - A userspace to pick a desired effect while scaling. This option will be particularly useful in the scenarios where Integer mode scaling is possible, and a UI client wants to pick filters like Nearest-neighbor applied for non-blurry outputs. There was a RFC patch series published, to discus the request to enable Integer mode scaling by some of the gaming communities, which can be found here: https://patchwork.freedesktop.org/series/66175/ Signed-off-by: Shashank Sharma --- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++++ include/drm/drm_crtc.h | 26 ++++++++++++++++++++++++++ include/drm/drm_mode_config.h | 6 ++++++ 3 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 0d466d3b0809..883329453a86 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -435,6 +435,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, return ret; } else if (property == config->prop_vrr_enabled) { state->vrr_enabled = val; + } else if (property == config->scaling_filter_property) { + state->scaling_filter = val; } else if (property == config->degamma_lut_property) { ret = drm_atomic_replace_property_blob_from_id(dev, &state->degamma_lut, @@ -503,6 +505,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; else if (property == config->prop_out_fence_ptr) *val = 0; + else if (property == config->scaling_filter_property) + *val = state->scaling_filter; else if (crtc->funcs->atomic_get_property) return crtc->funcs->atomic_get_property(crtc, state, property, val); else diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 5e9b15a0e8c5..94c5509474a8 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -58,6 +58,25 @@ struct device_node; struct dma_fence; struct edid; +enum drm_scaling_filters { + DRM_SCALING_FILTER_DEFAULT, + DRM_SCALING_FILTER_MEDIUM, + DRM_SCALING_FILTER_BILINEAR, + DRM_SCALING_FILTER_NN, + DRM_SCALING_FILTER_NN_IS_ONLY, + DRM_SCALING_FILTER_EDGE_ENHANCE, + DRM_SCALING_FILTER_INVALID, +}; + +static const struct drm_prop_enum_list drm_scaling_filter_enum_list[] = { + { DRM_SCALING_FILTER_DEFAULT, "Default" }, + { DRM_SCALING_FILTER_MEDIUM, "Medium" }, + { DRM_SCALING_FILTER_BILINEAR, "Bilinear" }, + { DRM_SCALING_FILTER_NN, "Nearest Neighbor" }, + { DRM_SCALING_FILTER_NN_IS_ONLY, "Integer Mode Scaling" }, + { DRM_SCALING_FILTER_INVALID, "Invalid" }, +}; + static inline int64_t U642I64(uint64_t val) { return (int64_t)*((int64_t *)&val); @@ -283,6 +302,13 @@ struct drm_crtc_state { */ u32 target_vblank; + /** + * @scaling_filter: + * + * Scaling filter mode to be applied + */ + u32 scaling_filter; + /** * @async_flip: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 3bcbe30339f0..efd6fd55770f 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -914,6 +914,12 @@ struct drm_mode_config { */ struct drm_property *modifiers_property; + /** + * @scaling_filter_property: CRTC property to apply a particular filter + * while scaling in panel fitter mode. + */ + struct drm_property *scaling_filter_property; + /* cursor size */ uint32_t cursor_width, cursor_height; From patchwork Tue Oct 22 09:59:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sharma, Shashank" X-Patchwork-Id: 11204113 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D27C41515 for ; Tue, 22 Oct 2019 10:01:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BADD12064B for ; Tue, 22 Oct 2019 10:01:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BADD12064B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B2F246E513; Tue, 22 Oct 2019 10:01:23 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id ABAAF6E513; Tue, 22 Oct 2019 10:01:20 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Oct 2019 03:01:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,326,1566889200"; d="scan'208";a="196388717" Received: from sharmash-desk1.iind.intel.com ([10.99.66.206]) by fmsmga008.fm.intel.com with ESMTP; 22 Oct 2019 03:01:18 -0700 From: Shashank Sharma To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Date: Tue, 22 Oct 2019 15:29:45 +0530 Message-Id: <20191022095946.29354-3-shashank.sharma@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022095946.29354-1-shashank.sharma@intel.com> References: <20191022095946.29354-1-shashank.sharma@intel.com> Subject: [Intel-gfx] [PATCH 2/3] drm/i915: Add support for scaling filters X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" This patch does the following: - Creates the CRTC property for scaling filter mode (for GEN11 and +). - Applies the chosen filter value while enabling the panel fitter. - Adds CRTC state readouts and comparisons. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/display/intel_display.c | 59 +++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1a533ccdb54f..21993f9fd2ae 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5615,11 +5615,35 @@ static void skylake_scaler_disable(struct intel_crtc *crtc) skl_detach_scaler(crtc, i); } +static u32 +icelake_get_scaler_filter(const struct intel_crtc_state *crtc_state) +{ + const struct drm_crtc_state *state = &crtc_state->base; + + switch (state->scaling_filter) { + case DRM_SCALING_FILTER_BILINEAR: + return PS_FILTER_BILINEAR; + case DRM_SCALING_FILTER_EDGE_ENHANCE: + return PS_FILTER_EDGE_ENHANCE; + case DRM_SCALING_FILTER_NN: + case DRM_SCALING_FILTER_NN_IS_ONLY: + return PS_FILTER_PROGRAMMED; + case DRM_SCALING_FILTER_INVALID: + DRM_ERROR("Ignoring invalid scaler filter mode\n"); + return PS_FILTER_MEDIUM; + case DRM_SCALING_FILTER_DEFAULT: + case DRM_SCALING_FILTER_MEDIUM: + default: + return PS_FILTER_MEDIUM; + } +} + static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; + u32 scaler_filter; const struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; @@ -5640,9 +5664,11 @@ static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state) uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false); uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); + scaler_filter = icelake_get_scaler_filter(crtc_state); + id = scaler_state->scaler_id; I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | - PS_FILTER_MEDIUM | scaler_state->scalers[id].mode); + scaler_filter | scaler_state->scalers[id].mode); I915_WRITE_FW(SKL_PS_VPHASE(pipe, id), PS_Y_PHASE(0) | PS_UV_RGB_PHASE(uv_rgb_vphase)); I915_WRITE_FW(SKL_PS_HPHASE(pipe, id), @@ -12192,6 +12218,10 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config, pipe_config->scaler_state.scaler_users, pipe_config->scaler_state.scaler_id); + if (INTEL_GEN(dev_priv) >= 11) + DRM_DEBUG_KMS("scaling_filter: %d\n", + pipe_config->base.scaling_filter); + if (HAS_GMCH(dev_priv)) DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n", pipe_config->gmch_pfit.control, @@ -12858,6 +12888,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, } PIPE_CONF_CHECK_I(scaler_state.scaler_id); + PIPE_CONF_CHECK_I(base.scaling_filter); PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate); PIPE_CONF_CHECK_X(gamma_mode); @@ -14996,6 +15027,29 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, return ERR_PTR(ret); } +static void icl_create_scaler_filter_property(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state) +{ + struct drm_property *prop; + struct drm_device *dev = crtc->base.dev; + struct drm_mode_config *mode_config = &dev->mode_config; + u8 size; + + if (mode_config->scaling_filter_property) + return; + + size = ARRAY_SIZE(drm_scaling_filter_enum_list); + prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, + "SCALING_FILTERS", + drm_scaling_filter_enum_list, size); + if (!prop) { + DRM_ERROR("Failed to create scaling filter property\n"); + return; + } + + dev->mode_config.scaling_filter_property = prop; +} + static void intel_crtc_init_scalers(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { @@ -15016,6 +15070,9 @@ static void intel_crtc_init_scalers(struct intel_crtc *crtc, } scaler_state->scaler_id = -1; + + if (INTEL_GEN(dev_priv) >= 11) + icl_create_scaler_filter_property(crtc, crtc_state); } #define INTEL_CRTC_FUNCS \ From patchwork Tue Oct 22 09:59:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sharma, Shashank" X-Patchwork-Id: 11204115 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AFB8B913 for ; Tue, 22 Oct 2019 10:01:26 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 97ECA2064B for ; Tue, 22 Oct 2019 10:01:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 97ECA2064B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7AFE16E516; Tue, 22 Oct 2019 10:01:24 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id CC13B6E516; Tue, 22 Oct 2019 10:01:22 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Oct 2019 03:01:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,326,1566889200"; d="scan'208";a="196388726" Received: from sharmash-desk1.iind.intel.com ([10.99.66.206]) by fmsmga008.fm.intel.com with ESMTP; 22 Oct 2019 03:01:20 -0700 From: Shashank Sharma To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Date: Tue, 22 Oct 2019 15:29:46 +0530 Message-Id: <20191022095946.29354-4-shashank.sharma@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022095946.29354-1-shashank.sharma@intel.com> References: <20191022095946.29354-1-shashank.sharma@intel.com> Subject: [Intel-gfx] [PATCH 3/3] drm/i915: Handle nearest-neighbor scaling filter X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" This patch adds support to handle nearest-neighbor(NN) filter option for the panel fitter / pipe scaler. Nearest-neighbor filter, when applied for integer upscaling ratios, can produce sharp and blurless outputs. This is pretty useful while upscaling the old games to higher resolution displays. To enable NN: - we need to set the scaler filter select value to "programmed" - and then we need to program specific values to the scaler data registers. Naturally, this patch also handles the Integer scaling scenarios. If the user selects scaler filter value as "DRM_SCALING_FILTER_NN_IS_ONLY", this means user wants to enable NN filter only when the upscaling ratios are complete integer. PS: There are two 80 char warnings in this patch, which is left deliberately for the better readibility of register definision and to maintain the existing formatting of the file. Maintainers can suggest. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/display/intel_display.c | 102 ++++++++++++++++++ .../drm/i915/display/intel_display_types.h | 3 + drivers/gpu/drm/i915/i915_reg.h | 31 ++++++ 3 files changed, 136 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 21993f9fd2ae..b882e9886fde 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5411,6 +5411,17 @@ u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited) #define SKL_MIN_YUV_420_SRC_W 16 #define SKL_MIN_YUV_420_SRC_H 16 +static inline bool +scaling_ratio_is_integer(int src_w, int dst_w, int src_h, int dst_h) +{ + /* Integer mode scaling is applicable only for upscaling scenarios */ + if (dst_w < src_w || dst_h < src_h) + return false; + if (dst_w % src_w == 0 && dst_h % src_h == 0) + return true; + return false; +} + static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, unsigned int scaler_user, int *scaler_id, @@ -5445,6 +5456,15 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, return -EINVAL; } + /* + * If we are upscaling, and the scaling ratios are integer, we can + * pick nearest-neighbour method in HW for scaling, which produces + * blurless outputs in such scenarios. + */ + if (INTEL_GEN(dev_priv) >= 11 && + scaling_ratio_is_integer(src_w, dst_w, src_h, dst_h)) + scaler_state->integer_scaling = true; + /* * if plane is being disabled or scaler is no more required or force detach * - free scaler binded to this plane/crtc @@ -5615,6 +5635,86 @@ static void skylake_scaler_disable(struct intel_crtc *crtc) skl_detach_scaler(crtc, i); } +static void +icl_setup_nearest_neighbor_filter(const struct intel_crtc_state *crtc_state) +{ + int count; + int phase; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + int scaler_id = crtc_state->scaler_state.scaler_id; + enum pipe pipe = crtc->pipe; + + /* + * To setup nearest-neighbor integer scaling mode: + * Write 60 dwords: represnting 119 coefficients. + * + * Seven basic Coefficients are named from An......Gn. + * Value of every D'th coefficent must be 1, all others to be 0. + * + * 17 such phases of 7 such coefficients = 119 coefficients. + * Arrange these 119 coefficients in 60 dwords, 2 coefficient + * per dword, in the sequence shown below: + * + *+------------+--------------+ + *| B0 | A0 | + *+---------------------------+ + *| D0 = 1 | C0 | + *+---------------------------+ + *| F0 | E0 | + *+---------------------------+ + *| A1 | G0 | + *+---------------------------+ + *| C1 | B1 | + *+---------------------------+ + *| E1 | D1 = 1 | + *+---------------------------+ + *| ..... | ..... | + *+---------------------------+ + *| ...... | ...... | + *+---------------------------+ + *| Res | G16 | + *+------------+--------------+ + * + */ + + for (phase = 0; phase < 17; phase++) { + for (count = 0; count < 7; count++) { + u32 val = 0; + + /* Every D'th entry needs to be 1 */ + if (count == 3) + (phase % 2) ? (val = 1) : (val = (1 << 16)); + + I915_WRITE_FW(SKL_PS_COEF_INDEX_SET0(pipe, scaler_id), + phase * 17 + count); + I915_WRITE_FW(SKL_PS_COEF_DATA_SET0(pipe, scaler_id), + val); + + I915_WRITE_FW(SKL_PS_COEF_INDEX_SET1(pipe, scaler_id), + phase * 17 + count); + I915_WRITE_FW(SKL_PS_COEF_DATA_SET1(pipe, scaler_id), + val); + } + } +} + +static u32 icl_program_pfit_filter(const struct intel_crtc_state *crtc_state) +{ + const struct drm_crtc_state *state = &crtc_state->base; + const struct intel_crtc_scaler_state *scaler_state = + &crtc_state->scaler_state; + + if (state->scaling_filter == DRM_SCALING_FILTER_NN_IS_ONLY && + !scaler_state->integer_scaling) { + DRM_DEBUG_DRIVER("Scaling ratio not integer, not picking NN\n"); + return PS_FILTER_MEDIUM; + } + + icl_setup_nearest_neighbor_filter(crtc_state); + return PS_FILTER_PROGRAMMED; +} + static u32 icelake_get_scaler_filter(const struct intel_crtc_state *crtc_state) { @@ -5665,6 +5765,8 @@ static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state) uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); scaler_filter = icelake_get_scaler_filter(crtc_state); + if (scaler_filter == PS_FILTER_PROGRAMMED) + scaler_filter = icl_program_pfit_filter(crtc_state); id = scaler_state->scaler_id; I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 40390d855815..8da499031bc2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -620,6 +620,9 @@ struct intel_crtc_scaler_state { /* scaler used by crtc for panel fitting purpose */ int scaler_id; + + /* indicate if scaling ratio is integer, to apply scaling filters */ + bool integer_scaling; }; /* drm_mode->private_flags */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1dc067fc57ab..f1ed5aa96ffd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7114,6 +7114,7 @@ enum { #define PS_PLANE_SEL(plane) (((plane) + 1) << 25) #define PS_FILTER_MASK (3 << 23) #define PS_FILTER_MEDIUM (0 << 23) +#define PS_FILTER_PROGRAMMED (1 << 23) #define PS_FILTER_EDGE_ENHANCE (2 << 23) #define PS_FILTER_BILINEAR (3 << 23) #define PS_VERT3TAP (1 << 21) @@ -7190,6 +7191,24 @@ enum { #define _PS_ECC_STAT_2B 0x68AD0 #define _PS_ECC_STAT_1C 0x691D0 +#define _PS_COEF_SET0_INDEX_1A 0x68198 +#define _PS_COEF_SET0_INDEX_2A 0x68298 +#define _PS_COEF_SET0_INDEX_1B 0x68998 +#define _PS_COEF_SET0_INDEX_2B 0x68A98 +#define _PS_COEF_SET1_INDEX_1A 0x681A0 +#define _PS_COEF_SET1_INDEX_2A 0x682A0 +#define _PS_COEF_SET1_INDEX_1B 0x689A0 +#define _PS_COEF_SET1_INDEX_2B 0x68AA0 + +#define _PS_COEF_SET0_DATA_1A 0x6819C +#define _PS_COEF_SET0_DATA_2A 0x6829C +#define _PS_COEF_SET0_DATA_1B 0x6899C +#define _PS_COEF_SET0_DATA_2B 0x68A9C +#define _PS_COEF_SET1_DATA_1A 0x681A4 +#define _PS_COEF_SET1_DATA_2A 0x682A4 +#define _PS_COEF_SET1_DATA_1B 0x689A4 +#define _PS_COEF_SET1_DATA_2B 0x68AA4 + #define _ID(id, a, b) _PICK_EVEN(id, a, b) #define SKL_PS_CTRL(pipe, id) _MMIO_PIPE(pipe, \ _ID(id, _PS_1A_CTRL, _PS_2A_CTRL), \ @@ -7218,6 +7237,18 @@ enum { #define SKL_PS_ECC_STAT(pipe, id) _MMIO_PIPE(pipe, \ _ID(id, _PS_ECC_STAT_1A, _PS_ECC_STAT_2A), \ _ID(id, _PS_ECC_STAT_1B, _PS_ECC_STAT_2B)) +#define SKL_PS_COEF_DATA_SET0(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_COEF_SET0_DATA_1A, _PS_COEF_SET0_DATA_2A), \ + _ID(id, _PS_COEF_SET0_DATA_1B, _PS_COEF_SET0_DATA_1B)) +#define SKL_PS_COEF_DATA_SET1(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_COEF_SET1_DATA_1A, _PS_COEF_SET1_DATA_2A), \ + _ID(id, _PS_COEF_SET1_DATA_1B, _PS_COEF_SET1_DATA_1B)) +#define SKL_PS_COEF_INDEX_SET0(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_COEF_SET0_INDEX_1A, _PS_COEF_SET0_INDEX_2A), \ + _ID(id, _PS_COEF_SET0_INDEX_1B, _PS_COEF_SET0_INDEX_1B)) +#define SKL_PS_COEF_INDEX_SET1(pipe, id) _MMIO_PIPE(pipe, \ + _ID(id, _PS_COEF_SET1_INDEX_1A, _PS_COEF_SET1_INDEX_2A), \ + _ID(id, _PS_COEF_SET1_INDEX_1B, _PS_COEF_SET1_INDEX_1B)) /* legacy palette */ #define _LGC_PALETTE_A 0x4a000