OSDN Git Service

drm/i915: Perform correct cpu_transcoder readout for bigjoiner
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 22 Oct 2021 10:33:02 +0000 (13:33 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 27 Oct 2021 11:00:54 +0000 (14:00 +0300)
Read out cpu_transcoder correctly for the bigjoiner slave pipes.

Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211022103304.24164-8-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/intel_display.c

index 6a8da98..753f443 100644 (file)
@@ -4064,6 +4064,16 @@ out:
        return ret;
 }
 
+static u8 bigjoiner_pipes(struct drm_i915_private *i915)
+{
+       if (DISPLAY_VER(i915) >= 12)
+               return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
+       else if (DISPLAY_VER(i915) >= 11)
+               return BIT(PIPE_B) | BIT(PIPE_C);
+       else
+               return 0;
+}
+
 static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
                                           enum transcoder cpu_transcoder)
 {
@@ -4079,6 +4089,54 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
        return tmp & TRANS_DDI_FUNC_ENABLE;
 }
 
+static u8 enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv)
+{
+       u8 master_pipes = 0, slave_pipes = 0;
+       struct intel_crtc *crtc;
+
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
+               enum intel_display_power_domain power_domain;
+               enum pipe pipe = crtc->pipe;
+               intel_wakeref_t wakeref;
+
+               if ((bigjoiner_pipes(dev_priv) & BIT(pipe)) == 0)
+                       continue;
+
+               power_domain = intel_dsc_power_domain(crtc, (enum transcoder) pipe);
+               with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
+                       u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
+
+                       if (!(tmp & BIG_JOINER_ENABLE))
+                               continue;
+
+                       if (tmp & MASTER_BIG_JOINER_ENABLE)
+                               master_pipes |= BIT(pipe);
+                       else
+                               slave_pipes |= BIT(pipe);
+               }
+
+               if (DISPLAY_VER(dev_priv) < 13)
+                       continue;
+
+               power_domain = POWER_DOMAIN_PIPE(pipe);
+               with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
+                       u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
+
+                       if (tmp & UNCOMPRESSED_JOINER_MASTER)
+                               master_pipes |= BIT(pipe);
+                       if (tmp & UNCOMPRESSED_JOINER_SLAVE)
+                               slave_pipes |= BIT(pipe);
+               }
+       }
+
+       /* Bigjoiner pipes should always be consecutive master and slave */
+       drm_WARN(&dev_priv->drm, slave_pipes != master_pipes << 1,
+                "Bigjoiner misconfigured (master pipes 0x%x, slave pipes 0x%x)\n",
+                master_pipes, slave_pipes);
+
+       return slave_pipes;
+}
+
 static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
 {
        u8 panel_transcoder_mask = BIT(TRANSCODER_EDP);
@@ -4140,10 +4198,18 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
                        enabled_transcoders |= BIT(cpu_transcoder);
        }
 
+       /* single pipe or bigjoiner master */
        cpu_transcoder = (enum transcoder) crtc->pipe;
        if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
                enabled_transcoders |= BIT(cpu_transcoder);
 
+       /* bigjoiner slave -> consider the master pipe's transcoder as well */
+       if (enabled_bigjoiner_pipes(dev_priv) & BIT(crtc->pipe)) {
+               cpu_transcoder = (enum transcoder) crtc->pipe - 1;
+               if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
+                       enabled_transcoders |= BIT(cpu_transcoder);
+       }
+
        return enabled_transcoders;
 }