diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index fbe8ce9fe1ab36e0fdbfaee4f7bd8e412a770aaf..f90424efeb56b87f2f681f279be2ab4a5327f264 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -371,6 +371,28 @@ int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state) return num_vdsc_instances; } +static void intel_dsc_get_pps_reg(const struct intel_crtc_state *crtc_state, int pps, + i915_reg_t *dsc_reg, int vdsc_per_pipe) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + enum pipe pipe = crtc->pipe; + bool pipe_dsc; + + pipe_dsc = is_pipe_dsc(crtc, cpu_transcoder); + + switch (vdsc_per_pipe) { + case 2: + dsc_reg[1] = pipe_dsc ? ICL_DSC1_PPS(pipe, pps) : DSCC_PPS(pps); + fallthrough; + case 1: + dsc_reg[0] = pipe_dsc ? ICL_DSC0_PPS(pipe, pps) : DSCA_PPS(pps); + break; + default: + MISSING_CASE(vdsc_per_pipe); + } +} + static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -1000,17 +1022,72 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) } } +static bool intel_dsc_read_pps_reg(struct intel_crtc_state *crtc_state, + int pps, u32 *pps_val) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + const int vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state); + i915_reg_t dsc_reg[2]; + int i; + + *pps_val = 0; + drm_WARN_ON_ONCE(&i915->drm, ARRAY_SIZE(dsc_reg) < vdsc_per_pipe); + + intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, vdsc_per_pipe); + + for (i = 0; i < min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe); i++) { + u32 pps_temp; + + pps_temp = intel_de_read(i915, dsc_reg[i]); + + if (i == 0) + *pps_val = pps_temp; + else if (pps_temp != *pps_val) + return false; + } + + return true; +} + +static void intel_dsc_read_and_verify_pps_reg(struct intel_crtc_state *crtc_state, + int pps, u32 *pps_val) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + int ret; + + ret = intel_dsc_read_pps_reg(crtc_state, pps, pps_val); + drm_WARN_ON(&i915->drm, !ret); +} + +static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state) +{ + struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; + u32 pps_temp1, pps_temp2; + + /* FIXME: add more state readout as needed */ + + /* Readout PPS_0 and PPS_1 registers */ + intel_dsc_read_and_verify_pps_reg(crtc_state, 0, &pps_temp1); + intel_dsc_read_and_verify_pps_reg(crtc_state, 1, &pps_temp2); + + vdsc_cfg->bits_per_pixel = pps_temp2; + + if (pps_temp1 & DSC_NATIVE_420_ENABLE) + vdsc_cfg->bits_per_pixel >>= 1; + + crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4; +} + void intel_dsc_get_config(struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - enum pipe pipe = crtc->pipe; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; - u32 dss_ctl1, dss_ctl2, pps0 = 0, pps1 = 0, pps_temp0, pps_temp1; - int vdsc_instances_per_pipe; + u32 dss_ctl1, dss_ctl2; if (!intel_dsc_source_support(crtc_state)) return; @@ -1031,38 +1108,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) && (dss_ctl1 & JOINER_ENABLE); - /* FIXME: add more state readout as needed */ - - vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state); - - /* PPS0 & PPS1 */ - if (!is_pipe_dsc(crtc, cpu_transcoder)) { - pps1 = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1); - if (vdsc_instances_per_pipe > 1) { - pps_temp1 = intel_de_read(dev_priv, DSCC_PICTURE_PARAMETER_SET_1); - drm_WARN_ON(&dev_priv->drm, pps1 != pps_temp1); - } - } else { - pps0 = intel_de_read(dev_priv, - ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe)); - pps1 = intel_de_read(dev_priv, - ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe)); - if (vdsc_instances_per_pipe > 1) { - pps_temp0 = intel_de_read(dev_priv, - ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe)); - pps_temp1 = intel_de_read(dev_priv, - ICL_DSC1_PICTURE_PARAMETER_SET_1(pipe)); - drm_WARN_ON(&dev_priv->drm, pps0 != pps_temp0); - drm_WARN_ON(&dev_priv->drm, pps1 != pps_temp1); - } - } - - vdsc_cfg->bits_per_pixel = pps1; - - if (pps0 & DSC_NATIVE_420_ENABLE) - vdsc_cfg->bits_per_pixel >>= 1; - - crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4; + intel_dsc_get_pps_config(crtc_state); out: intel_display_power_put(dev_priv, power_domain, wakeref); } diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h index 785ede31116e65b3f5dc3d98badd9e32e0959b38..a4dbe576b755fc8fe257644e2215e4132eea8ceb 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h @@ -78,6 +78,10 @@ /* Icelake Display Stream Compression Registers */ #define DSCA_PICTURE_PARAMETER_SET_0 _MMIO(0x6B200) #define DSCC_PICTURE_PARAMETER_SET_0 _MMIO(0x6BA00) +#define _DSCA_PPS_0 0x6B200 +#define _DSCC_PPS_0 0x6BA00 +#define DSCA_PPS(pps) _MMIO(_DSCA_PPS_0 + (pps) * 4) +#define DSCC_PPS(pps) _MMIO(_DSCC_PPS_0 + (pps) * 4) #define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB 0x78270 #define _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB 0x78370 #define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC 0x78470 @@ -88,6 +92,14 @@ #define ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB, \ _ICL_DSC1_PICTURE_PARAMETER_SET_0_PC) +#define _ICL_DSC0_PPS_0(pipe) _PICK_EVEN((pipe) - PIPE_B, \ + _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB, \ + _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC) +#define _ICL_DSC1_PPS_0(pipe) _PICK_EVEN((pipe) - PIPE_B, \ + _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB, \ + _ICL_DSC1_PICTURE_PARAMETER_SET_0_PC) +#define ICL_DSC0_PPS(pipe, pps) _MMIO(_ICL_DSC0_PPS_0(pipe) + ((pps) * 4)) +#define ICL_DSC1_PPS(pipe, pps) _MMIO(_ICL_DSC1_PPS_0(pipe) + ((pps) * 4)) #define DSC_NATIVE_422_ENABLE BIT(23) #define DSC_NATIVE_420_ENABLE BIT(22) #define DSC_ALT_ICH_SEL (1 << 20)