[PATCH 2/5] drm/i915/display: Compute the scaler filter coefficients
Nemesa Garg
nemesa.garg at intel.com
Fri Sep 13 08:22:38 UTC 2024
The sharpness property requires the use of one of the scaler
so need to set the sharpness scaler coefficient values.
These values are based on experiments and vary for different
tap value/win size. These values are normalized by taking the
sum of all values and then dividing each value with a sum.
--v4: fix ifndef header naming issue reported by kernel test robot
Signed-off-by: Nemesa Garg <nemesa.garg at intel.com>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/display/intel_display.c | 2 +
.../drm/i915/display/intel_display_types.h | 2 +
.../drm/i915/display/intel_sharpness_filter.c | 106 ++++++++++++++++++
.../drm/i915/display/intel_sharpness_filter.h | 36 ++++++
drivers/gpu/drm/i915/i915_reg.h | 2 +
drivers/gpu/drm/xe/Makefile | 1 +
7 files changed, 150 insertions(+)
create mode 100644 drivers/gpu/drm/i915/display/intel_sharpness_filter.c
create mode 100644 drivers/gpu/drm/i915/display/intel_sharpness_filter.h
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c63fa2133ccb..28e5f3b95371 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -280,6 +280,7 @@ i915-y += \
display/intel_pmdemand.o \
display/intel_psr.o \
display/intel_quirks.o \
+ display/intel_sharpness_filter.o \
display/intel_sprite.o \
display/intel_sprite_uapi.o \
display/intel_tc.o \
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b4ec9bf12aa7..61ef03e3d002 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -5919,6 +5919,8 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
if (ret)
return ret;
+ intel_sharpness_scaler_compute_config(new_crtc_state);
+
/*
* On some platforms the number of active planes affects
* the planes' minimum cdclk calculation. Add such planes
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 000ab373c887..a3a862a180d9 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -49,6 +49,7 @@
#include "intel_display_power.h"
#include "intel_dpll_mgr.h"
#include "intel_wm_types.h"
+#include "intel_sharpness_filter.h"
struct cec_notifier;
struct drm_printer;
@@ -945,6 +946,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_sharpness_filter casf_params;
} hw;
/* actual state of LUTs */
diff --git a/drivers/gpu/drm/i915/display/intel_sharpness_filter.c b/drivers/gpu/drm/i915/display/intel_sharpness_filter.c
new file mode 100644
index 000000000000..cfb2b02501e4
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_sharpness_filter.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ *
+ */
+
+#include "i915_reg.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "skl_scaler.h"
+
+#define MAX_NUM_UNIQUE_COEF_FOR_SHARPNESS_FILTER 7
+#define SCALER_FILTER_NUM_TAPS 7
+#define SCALER_FILTER_NUM_PHASES 17
+#define FILTER_COEFF_0_125 125
+#define FILTER_COEFF_0_25 250
+#define FILTER_COEFF_0_5 500
+#define FILTER_COEFF_1_0 1000
+#define FILTER_COEFF_0_0 0
+
+const u16 filtercoeff_1[] = {FILTER_COEFF_0_0, FILTER_COEFF_0_0,
+FILTER_COEFF_0_5, FILTER_COEFF_1_0, FILTER_COEFF_0_5, FILTER_COEFF_0_0, FILTER_COEFF_0_0};
+
+const u16 filtercoeff_2[] = {FILTER_COEFF_0_0, FILTER_COEFF_0_25,
+FILTER_COEFF_0_5, FILTER_COEFF_1_0, FILTER_COEFF_0_5, FILTER_COEFF_0_25, FILTER_COEFF_0_0};
+
+const u16 filtercoeff_3[] = {FILTER_COEFF_0_125, FILTER_COEFF_0_25,
+FILTER_COEFF_0_5, FILTER_COEFF_1_0, FILTER_COEFF_0_5, FILTER_COEFF_0_25, FILTER_COEFF_0_125};
+
+void intel_sharpness_filter_enable(struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ int id = crtc_state->scaler_state.scaler_id;
+
+ intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(crtc->pipe, id, 0),
+ PS_COEF_INDEX_AUTO_INC);
+
+ intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(crtc->pipe, id, 1),
+ PS_COEF_INDEX_AUTO_INC);
+
+ for (int index = 0; index < 60; index++) {
+ intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 0),
+ crtc_state->hw.casf_params.scaler_coefficient[index]);
+ intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 1),
+ crtc_state->hw.casf_params. scaler_coefficient[index]);
+ }
+}
+
+static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff,
+ u16 coefficient)
+{
+ if (coefficient < 25) {
+ coeff->mantissa = (coefficient * 2048) / 100;
+ coeff->exp = 3;
+ } else if (coefficient < 50) {
+ coeff->mantissa = (coefficient * 1024) / 100;
+ coeff->exp = 2;
+ } else if (coefficient < 100) {
+ coeff->mantissa = (coefficient * 512) / 100;
+ coeff->exp = 1;
+ } else {
+ coeff->mantissa = (coefficient * 256) / 100;
+ coeff->exp = 0;
+ }
+}
+
+static void intel_sharpness_filter_coeff(struct intel_crtc_state *crtc_state)
+{
+ const u16 *filtercoeff;
+ u16 filter_coeff[MAX_NUM_UNIQUE_COEF_FOR_SHARPNESS_FILTER];
+ u16 sumcoeff = 0;
+ u8 i;
+
+ if (crtc_state->hw.casf_params.win_size == 0)
+ filtercoeff = filtercoeff_1;
+ else if (crtc_state->hw.casf_params.win_size == 1)
+ filtercoeff = filtercoeff_2;
+ else
+ filtercoeff = filtercoeff_3;
+
+ for (i = 0; i < MAX_NUM_UNIQUE_COEF_FOR_SHARPNESS_FILTER; i++)
+ sumcoeff += *(filtercoeff + i);
+
+ for (i = 0; i < MAX_NUM_UNIQUE_COEF_FOR_SHARPNESS_FILTER; i++) {
+ filter_coeff[i] = (*(filtercoeff +i) * 100 / sumcoeff);
+ convert_sharpness_coef_binary(&crtc_state->hw.casf_params.coeff[i],
+ filter_coeff[i]);
+ }
+}
+
+void intel_sharpness_scaler_compute_config(struct intel_crtc_state *crtc_state)
+{
+ u16 phase, tapindex, phaseoffset;
+ u16 *coeff = (u16 *)crtc_state->hw.casf_params.scaler_coefficient;
+
+ intel_sharpness_filter_coeff(crtc_state);
+
+ for (phase = 0; phase < SCALER_FILTER_NUM_PHASES; phase++) {
+ phaseoffset = SCALER_FILTER_NUM_TAPS * phase;
+ for (tapindex = 0; tapindex < SCALER_FILTER_NUM_TAPS; tapindex++) {
+ coeff[phaseoffset + tapindex] =
+ SHARP_COEFF_TO_REG_FORMAT(crtc_state->hw.casf_params.coeff[tapindex]);
+ }
+ }
+}
diff --git a/drivers/gpu/drm/i915/display/intel_sharpness_filter.h b/drivers/gpu/drm/i915/display/intel_sharpness_filter.h
new file mode 100644
index 000000000000..ca396cf5647b
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_sharpness_filter.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_SHARPNESS_FILTER_H__
+#define __INTEL_SHARPNESS_FILTER_H__
+
+#include <linux/types.h>
+
+#define SHARP_COEFF_TO_REG_FORMAT(coefficient) ((u16)(coefficient.sign << 15 | \
+ coefficient.exp << 12 | coefficient.mantissa << 3))
+
+struct intel_crtc;
+struct intel_crtc_state;
+struct intel_atomic_state;
+
+struct scaler_filter_coeff {
+ u16 sign;
+ u16 exp;
+ u16 mantissa;
+};
+
+struct intel_sharpness_filter {
+#define SCALER_FILTER_NUM_TAPS 7
+#define SCLAER_FILTER_COEFF 119
+ struct scaler_filter_coeff coeff[7];
+ u32 scaler_coefficient[119];
+ bool strength_changed;
+ u8 win_size;
+};
+
+void intel_sharpness_filter_enable(struct intel_crtc_state *crtc_state);
+void intel_sharpness_scaler_compute_config(struct intel_crtc_state *crtc_state);
+
+#endif /* __INTEL_SHARPEN_FILTER_H__ */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 41f4350a7c6c..84b05b57ad52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2257,6 +2257,8 @@
#define PS_VERT_INT_INVERT_FIELD REG_BIT(20)
#define PS_PROG_SCALE_FACTOR REG_BIT(19) /* tgl+ */
#define PS_PWRUP_PROGRESS REG_BIT(17)
+#define PS_BYPASS_ARMING REG_BIT(10)
+#define PS_DB_STALL REG_BIT(9)
#define PS_V_FILTER_BYPASS REG_BIT(8)
#define PS_VADAPT_EN REG_BIT(7) /* skl/bxt */
#define PS_VADAPT_MODE_MASK REG_GENMASK(6, 5) /* skl/bxt */
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index edfd812e0f41..d5edc7eface6 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -253,6 +253,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_psr.o \
i915-display/intel_qp_tables.o \
i915-display/intel_quirks.o \
+ i915-display/intel_sharpness_filter.o \
i915-display/intel_snps_phy.o \
i915-display/intel_tc.o \
i915-display/intel_vblank.o \
--
2.25.1
More information about the Intel-gfx-trybot
mailing list