]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/display: Add CASF strength and winsize
authorNemesa Garg <nemesa.garg@intel.com>
Tue, 28 Oct 2025 12:07:39 +0000 (17:37 +0530)
committerJani Nikula <jani.nikula@intel.com>
Thu, 30 Oct 2025 13:41:18 +0000 (15:41 +0200)
Add register definitions for sharpness strength and
filter window size used by CASF. Provide functions to
read and write these fields.

The sharpness strength value is determined by user input,
while the winsize is based on the resolution. The casf_enable
flag should be set if the platform supports sharpness adjustments
and the user API strength is not zero. Once sharpness is
enabled, update the strength bit of the register whenever
the user changes the strength value, as the enable bit and
winsize bit remain constant.

Introduce helper to enable, disable and update strength.
Add relavant strength and winsize in both enable and disable.

v2: Introduce get_config for casf[Ankit]
v3: Replace 0 with FILTER_STRENGTH_MASK[Ankit]
v4: After updating strength add win_sz register
v5: Replace u16 with u32 for total_pixel
v6: Add casf logging
v7: Add helper for enable and disable casf

Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Link: https://patch.msgid.link/20251028120747.3027332-4-ankit.k.nautiyal@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/display/intel_casf.c [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_casf.h [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_casf_regs.h [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/skl_scaler.c
drivers/gpu/drm/xe/Makefile

index 47bac9b2c611bb52d5f5781841b96e3522fe4430..be439fb45cca7a3d5eb5d22ea5b1a969a01f8271 100644 (file)
@@ -234,6 +234,7 @@ i915-y += \
        display/intel_bios.o \
        display/intel_bo.o \
        display/intel_bw.o \
+       display/intel_casf.o \
        display/intel_cdclk.o \
        display/intel_cmtg.o \
        display/intel_color.o \
diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c
new file mode 100644 (file)
index 0000000..4949774
--- /dev/null
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: MIT
+/* Copyright © 2025 Intel Corporation */
+
+#include <drm/drm_print.h>
+
+#include "i915_reg.h"
+#include "intel_casf.h"
+#include "intel_casf_regs.h"
+#include "intel_de.h"
+#include "intel_display_regs.h"
+#include "intel_display_types.h"
+
+#define MAX_PIXELS_FOR_3_TAP_FILTER (1920 * 1080)
+#define MAX_PIXELS_FOR_5_TAP_FILTER (3840 * 2160)
+
+/**
+ * DOC: Content Adaptive Sharpness Filter (CASF)
+ *
+ * Starting from LNL the display engine supports an
+ * adaptive sharpening filter, enhancing the image
+ * quality. The display hardware utilizes the second
+ * pipe scaler for implementing CASF.
+ * If sharpness is being enabled then pipe scaling
+ * cannot be used.
+ * This filter operates on a region of pixels based
+ * on the tap size. Coefficients are used to generate
+ * an alpha value which blends the sharpened image to
+ * original image.
+ */
+
+void intel_casf_update_strength(struct intel_crtc_state *crtc_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       int win_size;
+
+       intel_de_rmw(display, SHARPNESS_CTL(crtc->pipe), FILTER_STRENGTH_MASK,
+                    FILTER_STRENGTH(crtc_state->hw.casf_params.strength));
+
+       win_size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, 1));
+
+       intel_de_write_fw(display, SKL_PS_WIN_SZ(crtc->pipe, 1), win_size);
+}
+
+static void intel_casf_compute_win_size(struct intel_crtc_state *crtc_state)
+{
+       const struct drm_display_mode *mode = &crtc_state->hw.adjusted_mode;
+       u32 total_pixels = mode->hdisplay * mode->vdisplay;
+
+       if (total_pixels <= MAX_PIXELS_FOR_3_TAP_FILTER)
+               crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_3X3;
+       else if (total_pixels <= MAX_PIXELS_FOR_5_TAP_FILTER)
+               crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_5X5;
+       else
+               crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_7X7;
+}
+
+int intel_casf_compute_config(struct intel_crtc_state *crtc_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+
+       if (!HAS_CASF(display))
+               return 0;
+
+       if (crtc_state->uapi.sharpness_strength == 0) {
+               crtc_state->hw.casf_params.casf_enable = false;
+               crtc_state->hw.casf_params.strength = 0;
+               return 0;
+       }
+
+       crtc_state->hw.casf_params.casf_enable = true;
+
+       /*
+        * HW takes a value in form (1.0 + strength) in 4.4 fixed format.
+        * Strength is from 0.0-14.9375 ie from 0-239.
+        * User can give value from 0-255 but is clamped to 239.
+        * Ex. User gives 85 which is 5.3125 and adding 1.0 gives 6.3125.
+        * 6.3125 in 4.4 format is b01100101 which is equal to 101.
+        * Also 85 + 16 = 101.
+        */
+       crtc_state->hw.casf_params.strength =
+               min(crtc_state->uapi.sharpness_strength, 0xEF) + 0x10;
+
+       intel_casf_compute_win_size(crtc_state);
+
+       return 0;
+}
+
+void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       u32 sharp;
+
+       sharp = intel_de_read(display, SHARPNESS_CTL(crtc->pipe));
+       if (sharp & FILTER_EN) {
+               if (drm_WARN_ON(display->drm,
+                               REG_FIELD_GET(FILTER_STRENGTH_MASK, sharp) < 16))
+                       crtc_state->hw.casf_params.strength = 0;
+               else
+                       crtc_state->hw.casf_params.strength =
+                               REG_FIELD_GET(FILTER_STRENGTH_MASK, sharp);
+               crtc_state->hw.casf_params.casf_enable = true;
+               crtc_state->hw.casf_params.win_size =
+                       REG_FIELD_GET(FILTER_SIZE_MASK, sharp);
+       }
+}
+
+void intel_casf_enable(struct intel_crtc_state *crtc_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       u32 sharpness_ctl;
+
+       sharpness_ctl = FILTER_EN | FILTER_STRENGTH(crtc_state->hw.casf_params.strength);
+
+       sharpness_ctl |= crtc_state->hw.casf_params.win_size;
+
+       intel_de_write(display, SHARPNESS_CTL(crtc->pipe), sharpness_ctl);
+}
+
+void intel_casf_disable(const struct intel_crtc_state *crtc_state)
+{
+       struct intel_display *display = to_intel_display(crtc_state);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+       intel_de_write(display, SHARPNESS_CTL(crtc->pipe), 0);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_casf.h b/drivers/gpu/drm/i915/display/intel_casf.h
new file mode 100644 (file)
index 0000000..7538718
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#ifndef __INTEL_CASF_H__
+#define __INTEL_CASF_H__
+
+#include <linux/types.h>
+
+struct intel_crtc_state;
+
+int intel_casf_compute_config(struct intel_crtc_state *crtc_state);
+void intel_casf_update_strength(struct intel_crtc_state *new_crtc_state);
+void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state);
+void intel_casf_enable(struct intel_crtc_state *crtc_state);
+void intel_casf_disable(const struct intel_crtc_state *crtc_state);
+
+#endif /* __INTEL_CASF_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_casf_regs.h b/drivers/gpu/drm/i915/display/intel_casf_regs.h
new file mode 100644 (file)
index 0000000..bd763ef
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#ifndef __INTEL_CASF_REGS_H__
+#define __INTEL_CASF_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _SHARPNESS_CTL_A               0x682B0
+#define _SHARPNESS_CTL_B               0x68AB0
+#define SHARPNESS_CTL(pipe)            _MMIO_PIPE(pipe, _SHARPNESS_CTL_A, _SHARPNESS_CTL_B)
+#define   FILTER_EN                    REG_BIT(31)
+#define   FILTER_STRENGTH_MASK         REG_GENMASK(15, 8)
+#define   FILTER_STRENGTH(x)           REG_FIELD_PREP(FILTER_STRENGTH_MASK, (x))
+#define   FILTER_SIZE_MASK             REG_GENMASK(1, 0)
+#define   SHARPNESS_FILTER_SIZE_3X3    REG_FIELD_PREP(FILTER_SIZE_MASK, 0)
+#define   SHARPNESS_FILTER_SIZE_5X5    REG_FIELD_PREP(FILTER_SIZE_MASK, 1)
+#define   SHARPNESS_FILTER_SIZE_7X7    REG_FIELD_PREP(FILTER_SIZE_MASK, 2)
+
+#endif /* __INTEL_CASF_REGS__ */
index e6f300dbb5eebc9ca89e9cb435f6d95862a017bf..c2a6217c22622dc173b2eef0801d9680dde84328 100644 (file)
@@ -372,6 +372,11 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
 
        intel_vdsc_state_dump(&p, 0, pipe_config);
 
+       drm_printf(&p, "sharpness strength: %d, sharpness tap size: %d, sharpness enable: %d\n",
+                  pipe_config->hw.casf_params.strength,
+                  pipe_config->hw.casf_params.win_size,
+                  pipe_config->hw.casf_params.casf_enable);
+
 dump_planes:
        if (!state)
                return;
index 5ae66b7444b68c450b0cb12e7f88024395419997..2afb346249ef24616077a6663947a972b53b0aa7 100644 (file)
@@ -961,6 +961,12 @@ enum intel_panel_replay_dsc_support {
        INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE,
 };
 
+struct intel_casf {
+       u8 strength;
+       u8 win_size;
+       bool casf_enable;
+};
+
 struct intel_crtc_state {
        /*
         * uapi (drm) state. This is the software state shown to userspace.
@@ -997,6 +1003,7 @@ struct intel_crtc_state {
                struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
                struct drm_display_mode mode, pipe_mode, adjusted_mode;
                enum drm_scaling_filter scaling_filter;
+               struct intel_casf casf_params;
        } hw;
 
        /* actual state of LUTs */
index d29efcbf2319fe65cc48a7d0edba95b7a05e025b..dbe1c4a63ec7fbfc616af4ad3e472ec69dc4c72f 100644 (file)
@@ -6,6 +6,7 @@
 #include <drm/drm_print.h>
 
 #include "i915_utils.h"
+#include "intel_casf_regs.h"
 #include "intel_de.h"
 #include "intel_display_regs.h"
 #include "intel_display_trace.h"
index 5d6e80d541e09a59f1b78f7faccbe638f72fd9e9..58e1d68e495b71560ab2e4479c2edbabbcfa9c6b 100644 (file)
@@ -231,6 +231,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
        i915-display/intel_backlight.o \
        i915-display/intel_bios.o \
        i915-display/intel_bw.o \
+       i915-display/intel_casf.o \
        i915-display/intel_cdclk.o \
        i915-display/intel_cmtg.o \
        i915-display/intel_color.o \