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);
        }
 }
 
+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;
        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);
 }
 
 /* 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
 #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)