Ultrajoiner mode has some new bits and states to be
read out from the hw. Lets make changes accordingly.

SIgned-off-by: Stanislav Lisovskiy <stanislav.lisovs...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 56 +++++++++++++++----
 .../gpu/drm/i915/display/intel_vdsc_regs.h    |  2 +
 2 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index c390b79a43d6..0dc5349712f6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3537,12 +3537,14 @@ static bool transcoder_ddi_func_is_enabled(struct 
drm_i915_private *dev_priv,
 }
 
 static void enabled_joiner_pipes(struct drm_i915_private *dev_priv,
-                                   u8 *master_pipes, u8 *slave_pipes)
+                                   u8 *master_pipes, u8 *slave_pipes,
+                                   bool *ultrajoiner_used)
 {
        struct intel_crtc *crtc;
 
        *master_pipes = 0;
        *slave_pipes = 0;
+       *ultrajoiner_used = false;
 
        for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc,
                                         joiner_pipes(dev_priv)) {
@@ -3557,6 +3559,20 @@ static void enabled_joiner_pipes(struct drm_i915_private 
*dev_priv,
                        if (!(tmp & BIG_JOINER_ENABLE))
                                continue;
 
+                       if (tmp & ULTRA_JOINER_ENABLE)
+                               *ultrajoiner_used = true;
+
+                       /*
+                        * As of now we always assume primary master to be PIPE 
A.
+                        * Otherwise we need a new field in crtc_state to track
+                        * primary master as well.
+                        */
+                       drm_WARN(&dev_priv->drm,
+                                (tmp & MASTER_ULTRA_JOINER_ENABLE) && 
crtc->pipe != PIPE_A,
+                                "Ultrajoiner primary master isn't PIPE A(pipe 
%c)",
+                                pipe_name(crtc->pipe));
+
+
                        if (tmp & MASTER_BIG_JOINER_ENABLE)
                                *master_pipes |= BIT(pipe);
                        else
@@ -3583,7 +3599,8 @@ static void enabled_joiner_pipes(struct drm_i915_private 
*dev_priv,
                 *master_pipes, *slave_pipes);
 }
 
-static enum pipe get_joiner_master_pipe(enum pipe pipe, u8 master_pipes, u8 
slave_pipes)
+static enum pipe get_joiner_master_pipe(enum pipe pipe, u8 master_pipes,
+                                       u8 slave_pipes, bool ultrajoiner_used)
 {
        if ((slave_pipes & BIT(pipe)) == 0)
                return pipe;
@@ -3591,15 +3608,22 @@ static enum pipe get_joiner_master_pipe(enum pipe pipe, 
u8 master_pipes, u8 slav
        /* ignore everything above our pipe */
        master_pipes &= ~GENMASK(7, pipe);
 
-       /* highest remaining bit should be our master pipe */
-       return fls(master_pipes) - 1;
+       if (!ultrajoiner_used) {
+               /* highest remaining bit should be our master pipe */
+               return fls(master_pipes) - 1;
+       } else {
+               /* lowest remaining bit should be our primary master pipe */
+               return ffs(master_pipes) - 1;
+       }
 }
 
-static u8 get_joiner_slave_pipes(enum pipe pipe, u8 master_pipes, u8 
slave_pipes)
+static u8 get_joiner_slave_pipes(enum pipe pipe, u8 master_pipes,
+                                u8 slave_pipes, bool ultrajoiner_used)
 {
        enum pipe master_pipe, next_master_pipe;
 
-       master_pipe = get_joiner_master_pipe(pipe, master_pipes, slave_pipes);
+       master_pipe = get_joiner_master_pipe(pipe, master_pipes,
+                                            slave_pipes, ultrajoiner_used);
 
        if ((master_pipes & BIT(master_pipe)) == 0)
                return 0;
@@ -3611,7 +3635,10 @@ static u8 get_joiner_slave_pipes(enum pipe pipe, u8 
master_pipes, u8 slave_pipes
        /* lowest remaining bit should be the next master pipe */
        next_master_pipe = ffs(master_pipes) - 1;
 
-       return slave_pipes & GENMASK(next_master_pipe - 1, master_pipe);
+       if (!ultrajoiner_used)
+               return slave_pipes & GENMASK(next_master_pipe - 1, master_pipe);
+       else
+               return (slave_pipes | master_pipes) & ~BIT(master_pipe);
 }
 
 static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
@@ -3632,6 +3659,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
        enum transcoder cpu_transcoder;
        u8 master_pipes, slave_pipes;
        u8 enabled_transcoders = 0;
+       bool ultrajoiner_used;
 
        /*
         * XXX: Do intel_display_power_get_if_enabled before reading this (for
@@ -3682,10 +3710,11 @@ static u8 hsw_enabled_transcoders(struct intel_crtc 
*crtc)
                enabled_transcoders |= BIT(cpu_transcoder);
 
        /* joiner slave -> consider the master pipe's transcoder as well */
-       enabled_joiner_pipes(dev_priv, &master_pipes, &slave_pipes);
+       enabled_joiner_pipes(dev_priv, &master_pipes, &slave_pipes, 
&ultrajoiner_used);
        if (slave_pipes & BIT(crtc->pipe)) {
                cpu_transcoder = (enum transcoder)
-                       get_joiner_master_pipe(crtc->pipe, master_pipes, 
slave_pipes);
+                       get_joiner_master_pipe(crtc->pipe, master_pipes,
+                                              slave_pipes, ultrajoiner_used);
                if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
                        enabled_transcoders |= BIT(cpu_transcoder);
        }
@@ -3816,15 +3845,18 @@ static void intel_joiner_get_config(struct 
intel_crtc_state *crtc_state)
        struct drm_i915_private *i915 = to_i915(crtc->base.dev);
        u8 master_pipes, slave_pipes;
        enum pipe pipe = crtc->pipe;
+       bool ultrajoiner_used;
 
-       enabled_joiner_pipes(i915, &master_pipes, &slave_pipes);
+       enabled_joiner_pipes(i915, &master_pipes, &slave_pipes, 
&ultrajoiner_used);
 
        if (((master_pipes | slave_pipes) & BIT(pipe)) == 0)
                return;
 
        crtc_state->joiner_pipes =
-               BIT(get_joiner_master_pipe(pipe, master_pipes, slave_pipes)) |
-               get_joiner_slave_pipes(pipe, master_pipes, slave_pipes);
+               BIT(get_joiner_master_pipe(pipe, master_pipes,
+                                          slave_pipes, ultrajoiner_used)) |
+                       get_joiner_slave_pipes(pipe, master_pipes,
+                                              slave_pipes, ultrajoiner_used);
 }
 
 static bool hsw_get_pipe_config(struct intel_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h 
b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
index 8b21dc8e26d5..b3d91c0a17a6 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
@@ -37,6 +37,8 @@
 #define  SPLITTER_CONFIGURATION_MASK           REG_GENMASK(26, 25)
 #define  SPLITTER_CONFIGURATION_2_SEGMENT      
REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 0)
 #define  SPLITTER_CONFIGURATION_4_SEGMENT      
REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 1)
+#define  ULTRA_JOINER_ENABLE                    (1 << 23)
+#define  MASTER_ULTRA_JOINER_ENABLE             (1 << 22)
 #define  UNCOMPRESSED_JOINER_MASTER            (1 << 21)
 #define  UNCOMPRESSED_JOINER_SLAVE             (1 << 20)
 
-- 
2.37.3

Reply via email to