Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/display: Compute the scaler coefficients

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.

Add helper to compute and set the scaler coefficients.

v2: Fix ifndef header naming issue reported by kernel test robot
v3: Rename file name[Arun]
Replace array size number with macro[Arun]
v4: Correct the register format[Jani]
Add brief comment and expalin about file[Jani]
Remove coefficient value from crtc_state[Jani]
v5: Fix build issue
v6: Add new function for writing coefficients[Ankit]
v7: Add cooments and add a scaler id check [Ankit]
v8: Remove casf_enable from here[Ankit]
v9: Removed REG and use shift operator[Jani]
v10: Remove filter macros
v11: Add casf_write_coeff function to casf_enable

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-6-ankit.k.nautiyal@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

authored by

Nemesa Garg and committed by
Jani Nikula
76f51cdc 515d1c89

+108
+99
drivers/gpu/drm/i915/display/intel_casf.c
··· 130 130 131 131 intel_casf_compute_win_size(crtc_state); 132 132 133 + intel_casf_scaler_compute_config(crtc_state); 134 + 133 135 return 0; 134 136 } 135 137 ··· 155 153 } 156 154 } 157 155 156 + static int casf_coeff_tap(int i) 157 + { 158 + return i % SCALER_FILTER_NUM_TAPS; 159 + } 160 + 161 + static u32 casf_coeff(struct intel_crtc_state *crtc_state, int t) 162 + { 163 + struct scaler_filter_coeff value; 164 + u32 coeff; 165 + 166 + value = crtc_state->hw.casf_params.coeff[t]; 167 + value.sign = 0; 168 + 169 + coeff = value.sign << 15 | value.exp << 12 | value.mantissa << 3; 170 + return coeff; 171 + } 172 + 173 + /* 174 + * 17 phase of 7 taps requires 119 coefficients in 60 dwords per set. 175 + * To enable casf: program scaler coefficients with the coeffients 176 + * that are calculated and stored in hw.casf_params.coeff as per 177 + * SCALER_COEFFICIENT_FORMAT 178 + */ 179 + static void intel_casf_write_coeff(struct intel_crtc_state *crtc_state) 180 + { 181 + struct intel_display *display = to_intel_display(crtc_state); 182 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 183 + int id = crtc_state->scaler_state.scaler_id; 184 + int i; 185 + 186 + if (id != 1) { 187 + drm_WARN(display->drm, 0, "Second scaler not enabled\n"); 188 + return; 189 + } 190 + 191 + intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(crtc->pipe, id, 0), 192 + PS_COEF_INDEX_AUTO_INC); 193 + 194 + for (i = 0; i < 17 * SCALER_FILTER_NUM_TAPS; i += 2) { 195 + u32 tmp; 196 + int t; 197 + 198 + t = casf_coeff_tap(i); 199 + tmp = casf_coeff(crtc_state, t); 200 + 201 + t = casf_coeff_tap(i + 1); 202 + tmp |= casf_coeff(crtc_state, t) << 16; 203 + 204 + intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 0), 205 + tmp); 206 + } 207 + } 208 + 209 + static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff, 210 + u16 coefficient) 211 + { 212 + if (coefficient < 25) { 213 + coeff->mantissa = (coefficient * 2048) / 100; 214 + coeff->exp = 3; 215 + } else if (coefficient < 50) { 216 + coeff->mantissa = (coefficient * 1024) / 100; 217 + coeff->exp = 2; 218 + } else if (coefficient < 100) { 219 + coeff->mantissa = (coefficient * 512) / 100; 220 + coeff->exp = 1; 221 + } else { 222 + coeff->mantissa = (coefficient * 256) / 100; 223 + coeff->exp = 0; 224 + } 225 + } 226 + 227 + void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state) 228 + { 229 + const u16 *filtercoeff; 230 + u16 filter_coeff[SCALER_FILTER_NUM_TAPS]; 231 + u16 sumcoeff = 0; 232 + int i; 233 + 234 + if (crtc_state->hw.casf_params.win_size == 0) 235 + filtercoeff = filtercoeff_1; 236 + else if (crtc_state->hw.casf_params.win_size == 1) 237 + filtercoeff = filtercoeff_2; 238 + else 239 + filtercoeff = filtercoeff_3; 240 + 241 + for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) 242 + sumcoeff += *(filtercoeff + i); 243 + 244 + for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) { 245 + filter_coeff[i] = (*(filtercoeff + i) * 100 / sumcoeff); 246 + convert_sharpness_coef_binary(&crtc_state->hw.casf_params.coeff[i], 247 + filter_coeff[i]); 248 + } 249 + } 250 + 158 251 void intel_casf_enable(struct intel_crtc_state *crtc_state) 159 252 { 160 253 struct intel_display *display = to_intel_display(crtc_state); ··· 257 160 u32 sharpness_ctl; 258 161 259 162 intel_casf_filter_lut_load(crtc, crtc_state); 163 + 164 + intel_casf_write_coeff(crtc_state); 260 165 261 166 sharpness_ctl = FILTER_EN | FILTER_STRENGTH(crtc_state->hw.casf_params.strength); 262 167
+1
drivers/gpu/drm/i915/display/intel_casf.h
··· 15 15 void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state); 16 16 void intel_casf_enable(struct intel_crtc_state *crtc_state); 17 17 void intel_casf_disable(const struct intel_crtc_state *crtc_state); 18 + void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state); 18 19 19 20 #endif /* __INTEL_CASF_H__ */
+8
drivers/gpu/drm/i915/display/intel_display_types.h
··· 961 961 INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE, 962 962 }; 963 963 964 + struct scaler_filter_coeff { 965 + u16 sign; 966 + u16 exp; 967 + u16 mantissa; 968 + }; 969 + 964 970 struct intel_casf { 971 + #define SCALER_FILTER_NUM_TAPS 7 972 + struct scaler_filter_coeff coeff[SCALER_FILTER_NUM_TAPS]; 965 973 u8 strength; 966 974 u8 win_size; 967 975 bool casf_enable;