diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c index bd63fdafb898..ee24e5957d3d 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.c +++ b/drivers/gpu/drm/i915/display/intel_casf.c @@ -130,6 +130,8 @@ int intel_casf_compute_config(struct intel_crtc_state *crtc_state) intel_casf_compute_win_size(crtc_state); + intel_casf_scaler_compute_config(crtc_state); + return 0; } @@ -153,6 +155,101 @@ void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state) } } +static int casf_coeff_tap(int i) +{ + return i % SCALER_FILTER_NUM_TAPS; +} + +static u32 casf_coeff(struct intel_crtc_state *crtc_state, int t) +{ + struct scaler_filter_coeff value; + u32 coeff; + + value = crtc_state->hw.casf_params.coeff[t]; + value.sign = 0; + + coeff = value.sign << 15 | value.exp << 12 | value.mantissa << 3; + return coeff; +} + +/* + * 17 phase of 7 taps requires 119 coefficients in 60 dwords per set. + * To enable casf: program scaler coefficients with the coeffients + * that are calculated and stored in hw.casf_params.coeff as per + * SCALER_COEFFICIENT_FORMAT + */ +static void intel_casf_write_coeff(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 id = crtc_state->scaler_state.scaler_id; + int i; + + if (id != 1) { + drm_WARN(display->drm, 0, "Second scaler not enabled\n"); + return; + } + + intel_de_write_fw(display, GLK_PS_COEF_INDEX_SET(crtc->pipe, id, 0), + PS_COEF_INDEX_AUTO_INC); + + for (i = 0; i < 17 * SCALER_FILTER_NUM_TAPS; i += 2) { + u32 tmp; + int t; + + t = casf_coeff_tap(i); + tmp = casf_coeff(crtc_state, t); + + t = casf_coeff_tap(i + 1); + tmp |= casf_coeff(crtc_state, t) << 16; + + intel_de_write_fw(display, GLK_PS_COEF_DATA_SET(crtc->pipe, id, 0), + tmp); + } +} + +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; + } +} + +void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state) +{ + const u16 *filtercoeff; + u16 filter_coeff[SCALER_FILTER_NUM_TAPS]; + u16 sumcoeff = 0; + int 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 < SCALER_FILTER_NUM_TAPS; i++) + sumcoeff += *(filtercoeff + i); + + for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) { + filter_coeff[i] = (*(filtercoeff + i) * 100 / sumcoeff); + convert_sharpness_coef_binary(&crtc_state->hw.casf_params.coeff[i], + filter_coeff[i]); + } +} + void intel_casf_enable(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -161,6 +258,8 @@ void intel_casf_enable(struct intel_crtc_state *crtc_state) intel_casf_filter_lut_load(crtc, crtc_state); + intel_casf_write_coeff(crtc_state); + sharpness_ctl = FILTER_EN | FILTER_STRENGTH(crtc_state->hw.casf_params.strength); sharpness_ctl |= crtc_state->hw.casf_params.win_size; diff --git a/drivers/gpu/drm/i915/display/intel_casf.h b/drivers/gpu/drm/i915/display/intel_casf.h index 753871880279..203a5587921c 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.h +++ b/drivers/gpu/drm/i915/display/intel_casf.h @@ -15,5 +15,6 @@ 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); +void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state); #endif /* __INTEL_CASF_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 2afb346249ef..00600134bda0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -961,7 +961,15 @@ enum intel_panel_replay_dsc_support { INTEL_DP_PANEL_REPLAY_DSC_SELECTIVE_UPDATE, }; +struct scaler_filter_coeff { + u16 sign; + u16 exp; + u16 mantissa; +}; + struct intel_casf { + #define SCALER_FILTER_NUM_TAPS 7 + struct scaler_filter_coeff coeff[SCALER_FILTER_NUM_TAPS]; u8 strength; u8 win_size; bool casf_enable;