Hi Suraj,

I agree with overall approach, but I suggest that we use num of vdsc engines per pipe to avoid changes in future.

This would perhaps need a small patch first to get num of vdsc engines per pipe though, more details inline for the case:

On 7/20/2023 1:37 PM, Suraj Kandpal wrote:
Add function to read any PPS register based on the
intel_dsc_pps enum provided. Add a function which will call the
new pps read function and place it in crtc state. Only PPS0 and
PPS1 are readout the rest of the registers will be read in upcoming
patches.

--v2
-Changes in read function as PPS enum is removed
-Initialize pps_val as 0 in pps_read func itself [Jani]
-Create a function that gets the required register and call that
in the common read function [Jani]
-Move the drm_WARN_ON one abstraction layer above [Jani]

--v3
-Send both reg values regardless of dsc engine no [Jani]
-Don't use num_vdsc_instances stick to dsc_split field [Ankit]

--v4
-Manipulate the reg values instead of creating MACRO to change
name of pps [Ankit]

Signed-off-by: Suraj Kandpal <suraj.kand...@intel.com>
---
  drivers/gpu/drm/i915/display/intel_vdsc.c     | 103 ++++++++++++------
  .../gpu/drm/i915/display/intel_vdsc_regs.h    |  12 ++
  2 files changed, 82 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c 
b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 9196329d998d..58eb19f8d35b 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -303,6 +303,25 @@ 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(struct intel_crtc_state *crtc_state, int pps,
+                                 i915_reg_t *dsc_reg0, i915_reg_t *dsc_reg1)

It would be good if we can send *dsc_reg, num_vdsc in the function.

IMHO lets calculate the num of vdsc engines in dsc_get_config and pass it from there to the other functions :intel_dsc_read_and_verify_pps_reg and all.


+{
+       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);
+
+       if (pipe_dsc) {
+               *dsc_reg0 = ICL_DSC0_PPS_REG(pipe, pps);
+               *dsc_reg1 = ICL_DSC1_PPS_REG(pipe, pps);
+       } else {
+               *dsc_reg0 = DSCA_PPS_REG(pps);
+               *dsc_reg1 = DSCC_PPS_REG(pps);
+       }
+}
+
  static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
  {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -930,16 +949,63 @@ 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);
+       bool dsc_split = crtc_state->dsc.dsc_split;
+       i915_reg_t dsc_reg0, dsc_reg1;
+       u32 pps_temp;
+
+       *pps_val = 0;
+
+       intel_dsc_get_pps_reg(crtc_state, pps, &dsc_reg0, &dsc_reg1);
+       *pps_val = intel_de_read(i915, dsc_reg0);
+       if (dsc_split) {
+               pps_temp = intel_de_read(i915, dsc_reg1);
+               if (*pps_val != pps_temp)
+                       return false;
+       }


With the num of vdsc engines available we can have a loop something like:

intel_dsc_get_pps_reg(crtc_state, pps, &dsc_reg, num);

for (i=0; i < num; i++) {
    pps_val[i] = intel_de_read(i915, dsc_reg[i]);
    if (i > 0)
        if (pps_val[i] != pps_val[i-1])
            return false;
}

return true;

+       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);
+       bool is_dsc_eq;
+
+       is_dsc_eq = intel_dsc_read_pps_reg(crtc_state, pps, pps_val);
+       drm_WARN_ON(&i915->drm, !is_dsc_eq);
+}
+
+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;
+
+       /* 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 = 0, pps_temp1 = 
1;
+       u32 dss_ctl1, dss_ctl2;
if (!intel_dsc_source_support(crtc_state))
                return;
@@ -960,36 +1026,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 */


We are still reading 2 PPS only so lets retain this line in the patch.


Regards,

Ankit


-
-       /* PPS0 & PPS1 */
-       if (!is_pipe_dsc(crtc, cpu_transcoder)) {
-               pps1 = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
-               if (crtc_state->dsc.dsc_split) {
-                       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 (crtc_state->dsc.dsc_split) {
-                       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 785ede31116e..862dc708c5fc 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_REG(pps)                      _MMIO(DSCA_PPS_0 + (pps) * 4)
+#define DSCC_PPS_REG(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_REG(pipe, pps)           _MMIO(ICL_DSC0_PPS_0(pipe) + 
((pps) * 4))
+#define  ICL_DSC1_PPS_REG(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)

Reply via email to