On Thu, Feb 03, 2022 at 08:38:23PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <[email protected]>
> 
> Get rid of the inflexible bigjoiner_linked_crtc pointer thing
> and just track things as a bitmask of pipes instead. We can
> also nuke the bigjoiner_slave boolean as the role of the pipe
> can be determined from its position in the bitmask.
> 
> It might be possible to nuke the bigjoiner boolean as well
> if we make encoder.compute_config() do the bitmask assignment
> directly for the master pipe. But for now I left that alone so
> that encoer.compute_config() will just flag the state as needing
> bigjoiner, and the intel_atomic_check_bigjoiner() is still
> responsible for determining the bitmask. But that may have to change
> as the encoder may be in the best position to determine how
> exactly we should populate the bitmask.
> 
> Most places that just looked at the single bigjoiner_linked_crtc
> now iterate over the whole bitmask, eliminating the singular
> slave pipe assumption.

Okay so trying to understand the design here:
For Pipe A + B Bigjoiner and C + D bigjoiner for example,
bitmasks will be as below:

A : 0011
B:  0011

C: 1100
D: 1100

Is this correct understanding? Because we would mark both the master pipe and 
slave pipe in a bitmask right?

> 
> Signed-off-by: Ville Syrjälä <[email protected]>
> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c |   5 +-
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  12 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 305 ++++++++++++------
>  drivers/gpu/drm/i915/display/intel_display.h  |   2 +
>  .../drm/i915/display/intel_display_debugfs.c  |   5 +-
>  .../drm/i915/display/intel_display_types.h    |   7 +-
>  .../drm/i915/display/intel_plane_initial.c    |   7 -
>  drivers/gpu/drm/i915/display/intel_vdsc.c     |  43 ---
>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   1 -
>  9 files changed, 227 insertions(+), 160 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
> b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 41d52889dfce..0e15fe908855 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -404,9 +404,10 @@ int intel_plane_atomic_check(struct intel_atomic_state 
> *state,
>               intel_atomic_get_new_crtc_state(state, crtc);
>  
>       if (new_crtc_state && intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
> +             struct intel_crtc *master_crtc =
> +                     intel_master_crtc(new_crtc_state);
>               struct intel_plane *master_plane =
> -                     
> intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
> -                                          plane->id);
> +                     intel_crtc_get_plane(master_crtc, plane->id);
>  
>               new_master_plane_state =
>                       intel_atomic_get_new_plane_state(state, master_plane);
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 3f0e1e127595..9dee12986991 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2703,6 +2703,7 @@ static void intel_ddi_post_disable(struct 
> intel_atomic_state *state,
>       struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
>       enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
>       bool is_tc_port = intel_phy_is_tc(dev_priv, phy);
> +     struct intel_crtc *slave_crtc;
>  
>       if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
>               intel_crtc_vblank_off(old_crtc_state);
> @@ -2721,9 +2722,8 @@ static void intel_ddi_post_disable(struct 
> intel_atomic_state *state,
>                       ilk_pfit_disable(old_crtc_state);
>       }
>  
> -     if (old_crtc_state->bigjoiner_linked_crtc) {
> -             struct intel_crtc *slave_crtc =
> -                     old_crtc_state->bigjoiner_linked_crtc;
> +     for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc,
> +                                      
> intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) {
>               const struct intel_crtc_state *old_slave_crtc_state =
>                       intel_atomic_get_old_crtc_state(state, slave_crtc);
>  
> @@ -3041,6 +3041,7 @@ intel_ddi_update_prepare(struct intel_atomic_state 
> *state,
>                        struct intel_encoder *encoder,
>                        struct intel_crtc *crtc)
>  {
> +     struct drm_i915_private *i915 = to_i915(state->base.dev);
>       struct intel_crtc_state *crtc_state =
>               crtc ? intel_atomic_get_new_crtc_state(state, crtc) : NULL;
>       int required_lanes = crtc_state ? crtc_state->lane_count : 1;
> @@ -3050,11 +3051,12 @@ intel_ddi_update_prepare(struct intel_atomic_state 
> *state,
>       intel_tc_port_get_link(enc_to_dig_port(encoder),
>                              required_lanes);
>       if (crtc_state && crtc_state->hw.active) {
> -             struct intel_crtc *slave_crtc = 
> crtc_state->bigjoiner_linked_crtc;
> +             struct intel_crtc *slave_crtc;
>  
>               intel_update_active_dpll(state, crtc, encoder);
>  
> -             if (slave_crtc)
> +             for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
> +                                              
> intel_crtc_bigjoiner_slave_pipes(crtc_state))
>                       intel_update_active_dpll(state, slave_crtc, encoder);
>       }
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 34b6b4ab3a1b..f5fc283f8f73 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -337,20 +337,38 @@ is_trans_port_sync_mode(const struct intel_crtc_state 
> *crtc_state)
>               is_trans_port_sync_slave(crtc_state);
>  }
>  
> +static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state 
> *crtc_state)
> +{
> +     return ffs(crtc_state->bigjoiner_pipes) - 1;

Here we have both master and slave pipe bits set in a bitmask: This would 
result in ffs(0011) -1 = 2 which wouldnt be correct?

> +}
> +
> +u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state 
> *crtc_state)
> +{
> +     return crtc_state->bigjoiner_pipes & 
> ~BIT(bigjoiner_master_pipe(crtc_state));
> +}
> +
>  bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state)
>  {
> -     return crtc_state->bigjoiner_slave;
> +     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> +     return crtc_state->bigjoiner_pipes &&
> +             crtc->pipe != bigjoiner_master_pipe(crtc_state);
>  }
>  
>  bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state 
> *crtc_state)
>  {
> -     return crtc_state->bigjoiner && !crtc_state->bigjoiner_slave;
> +     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> +     return crtc_state->bigjoiner_pipes &&
> +             crtc->pipe == bigjoiner_master_pipe(crtc_state);
>  }
>  
> -static struct intel_crtc *intel_master_crtc(const struct intel_crtc_state 
> *crtc_state)
> +struct intel_crtc *intel_master_crtc(const struct intel_crtc_state 
> *crtc_state)
>  {
> +     struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> +
>       if (intel_crtc_is_bigjoiner_slave(crtc_state))
> -             return crtc_state->bigjoiner_linked_crtc;
> +             return intel_crtc_for_pipe(i915, 
> bigjoiner_master_pipe(crtc_state));
>       else
>               return to_intel_crtc(crtc_state->uapi.crtc);
>  }
> @@ -4111,6 +4129,37 @@ static void enabled_bigjoiner_pipes(struct 
> drm_i915_private *dev_priv,
>                *master_pipes, *slave_pipes);
>  }
>  
> +static enum pipe get_bigjoiner_master_pipe(enum pipe pipe, u8 master_pipes, 
> u8 slave_pipes)
> +{
> +     if ((slave_pipes & BIT(pipe)) == 0)
> +             return pipe;
> +
> +     /* ignore everything above our pipe */
> +     master_pipes &= ~GENMASK(7, pipe);
> +
> +     /* highest remaining bit should be our master pipe */
> +     return fls(master_pipes) - 1;
> +}
> +
> +static u8 get_bigjoiner_slave_pipes(enum pipe pipe, u8 master_pipes, u8 
> slave_pipes)
> +{
> +     enum pipe master_pipe, next_master_pipe;
> +
> +     master_pipe = get_bigjoiner_master_pipe(pipe, master_pipes, 
> slave_pipes);
> +
> +     if ((master_pipes & BIT(master_pipe)) == 0)
> +             return 0;
> +
> +     /* ignore our master pipe and everything below it */
> +     master_pipes &= ~GENMASK(master_pipe, 0);
> +     /* make sure a high bit is set for the ffs() */
> +     master_pipes |= BIT(7);
> +     /* 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);
> +}
> +
>  static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
>  {
>       u8 panel_transcoder_mask = BIT(TRANSCODER_EDP);
> @@ -4181,7 +4230,8 @@ static u8 hsw_enabled_transcoders(struct intel_crtc 
> *crtc)
>       /* bigjoiner slave -> consider the master pipe's transcoder as well */
>       enabled_bigjoiner_pipes(dev_priv, &master_pipes, &slave_pipes);
>       if (slave_pipes & BIT(crtc->pipe)) {
> -             cpu_transcoder = (enum transcoder) crtc->pipe - 1;
> +             cpu_transcoder = (enum transcoder)
> +                     get_bigjoiner_master_pipe(crtc->pipe, master_pipes, 
> slave_pipes);
>               if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
>                       enabled_transcoders |= BIT(cpu_transcoder);
>       }
> @@ -4306,6 +4356,24 @@ static bool bxt_get_dsi_transcoder_state(struct 
> intel_crtc *crtc,
>       return transcoder_is_dsi(pipe_config->cpu_transcoder);
>  }
>  
> +static void intel_bigjoiner_get_config(struct intel_crtc_state *crtc_state)
> +{
> +     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +     struct drm_i915_private *i915 = to_i915(crtc->base.dev);
> +     u8 master_pipes, slave_pipes;
> +     enum pipe pipe = crtc->pipe;
> +
> +     enabled_bigjoiner_pipes(i915, &master_pipes, &slave_pipes);
> +
> +     if (((master_pipes | slave_pipes) & BIT(pipe)) == 0)
> +             return;
> +
> +     crtc_state->bigjoiner = true;
> +     crtc_state->bigjoiner_pipes =
> +             BIT(get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes)) 
> |
> +             get_bigjoiner_slave_pipes(pipe, master_pipes, slave_pipes);
> +}
> +
>  static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>                               struct intel_crtc_state *pipe_config)
>  {
> @@ -4332,8 +4400,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>               goto out;
>  
>       intel_dsc_get_config(pipe_config);
> -     if (DISPLAY_VER(dev_priv) >= 13 && !pipe_config->dsc.compression_enable)
> -             intel_uncompressed_joiner_get_config(pipe_config);
> +     intel_bigjoiner_get_config(pipe_config);
>  
>       if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>           DISPLAY_VER(dev_priv) >= 11)
> @@ -5615,9 +5682,10 @@ static void intel_dump_pipe_config(const struct 
> intel_crtc_state *pipe_config,
>                   transcoder_name(pipe_config->master_transcoder),
>                   pipe_config->sync_mode_slaves_mask);
>  
> -     drm_dbg_kms(&dev_priv->drm, "bigjoiner: %s\n",
> +     drm_dbg_kms(&dev_priv->drm, "bigjoiner: %s, pipes: 0x%x\n",
>                   intel_crtc_is_bigjoiner_slave(pipe_config) ? "slave" :
> -                 intel_crtc_is_bigjoiner_master(pipe_config) ? "master" : 
> "no");
> +                 intel_crtc_is_bigjoiner_master(pipe_config) ? "master" : 
> "no",
> +                 pipe_config->bigjoiner_pipes);
>  
>       drm_dbg_kms(&dev_priv->drm, "splitter: %s, link count %d, overlap %d\n",
>                   enableddisabled(pipe_config->splitter.enable),
> @@ -6699,8 +6767,7 @@ intel_pipe_config_compare(const struct intel_crtc_state 
> *current_config,
>       PIPE_CONF_CHECK_X(sync_mode_slaves_mask);
>       PIPE_CONF_CHECK_I(master_transcoder);
>       PIPE_CONF_CHECK_BOOL(bigjoiner);
> -     PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
> -     PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
> +     PIPE_CONF_CHECK_X(bigjoiner_pipes);
>  
>       PIPE_CONF_CHECK_I(dsc.compression_enable);
>       PIPE_CONF_CHECK_I(dsc.dsc_split);
> @@ -7486,20 +7553,25 @@ static int intel_crtc_add_bigjoiner_planes(struct 
> intel_atomic_state *state,
>  
>  static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state 
> *state)
>  {
> +     struct drm_i915_private *i915 = to_i915(state->base.dev);
>       const struct intel_crtc_state *crtc_state;
>       struct intel_crtc *crtc;
>       int i;
>  
>       for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -             int ret;
> +             struct intel_crtc *other;
>  
> -             if (!crtc_state->bigjoiner)
> -                     continue;
> +             for_each_intel_crtc_in_pipe_mask(&i915->drm, other,
> +                                              crtc_state->bigjoiner_pipes) {
> +                     int ret;
>  
> -             ret = intel_crtc_add_bigjoiner_planes(state, crtc,
> -                                                   
> crtc_state->bigjoiner_linked_crtc);
> -             if (ret)
> -                     return ret;
> +                     if (crtc == other)
> +                             continue;
> +
> +                     ret = intel_crtc_add_bigjoiner_planes(state, crtc, 
> other);
> +                     if (ret)
> +                             return ret;
> +             }
>       }
>  
>       return 0;
> @@ -7601,84 +7673,123 @@ static bool 
> intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
>       return false;
>  }
>  
> +static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
> +                                  u8 pipes)
> +{
> +     const struct intel_crtc_state *new_crtc_state;
> +     struct intel_crtc *crtc;
> +     int i;
> +
> +     for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> +             if (new_crtc_state->hw.enable &&
> +                 pipes & BIT(crtc->pipe) &&
> +                 intel_crtc_needs_modeset(new_crtc_state))
> +                     return true;
> +     }
> +
> +     return false;
> +}
> +
>  static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
>                                       struct intel_crtc *master_crtc)
>  {
>       struct drm_i915_private *i915 = to_i915(state->base.dev);
>       struct intel_crtc_state *master_crtc_state =
>               intel_atomic_get_new_crtc_state(state, master_crtc);
> -     struct intel_crtc_state *slave_crtc_state;
>       struct intel_crtc *slave_crtc;
> +     u8 slave_pipes;
>  
> -     WARN_ON(master_crtc_state->bigjoiner_linked_crtc);
> -     WARN_ON(intel_crtc_is_bigjoiner_slave(master_crtc_state));
> +     /*
> +      * TODO: encoder.compute_config() may be the best
> +      * place to populate the bitmask for the master crtc.
> +      * For now encoder.compute_config() just flags things
> +      * as needing bigjoiner and we populate the bitmask
> +      * here.
> +      */
> +     WARN_ON(master_crtc_state->bigjoiner_pipes);
>  
>       if (!master_crtc_state->bigjoiner)
>               return 0;
>  
> -     slave_crtc = intel_dsc_get_bigjoiner_secondary(master_crtc);
> -     if (!slave_crtc) {
> +     slave_pipes = BIT(master_crtc->pipe + 1);
> +
> +     if (slave_pipes & ~bigjoiner_pipes(i915)) {
>               drm_dbg_kms(&i915->drm,
> -                         "[CRTC:%d:%s] Big joiner configuration requires "
> -                         "CRTC + 1 to be used, doesn't exist\n",
> +                         "[CRTC:%d:%s] Cannot act as big joiner master "
> +                         "(need 0x%x as slave pipes, only 0x%x possible)\n",
> +                         master_crtc->base.base.id, master_crtc->base.name,
> +                         slave_pipes, bigjoiner_pipes(i915));
> +             return -EINVAL;

I dont get how we are checking for the invalid slave pipe here?
slave_pipes = BIT(1) = 0010
bigjoiner_pipes = 0000 (since we havents et anything in compute config)
so slave_pipes & ~bigjoiner_pipes = 0010 & 1111 = 0010 so the condition will be 
true
And then we are flagging it as error why?

Manasi

> +     }
> +
> +     for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, slave_pipes) {
> +             struct intel_crtc_state *slave_crtc_state;
> +             int ret;
> +
> +             slave_crtc_state = intel_atomic_get_crtc_state(&state->base, 
> slave_crtc);
> +             if (IS_ERR(slave_crtc_state))
> +                     return PTR_ERR(slave_crtc_state);
> +
> +             /* master being enabled, slave was already configured? */
> +             if (slave_crtc_state->uapi.enable) {
> +                     drm_dbg_kms(&i915->drm,
> +                                 "[CRTC:%d:%s] Slave is enabled as normal 
> CRTC, but "
> +                                 "[CRTC:%d:%s] claiming this CRTC for 
> bigjoiner.\n",
> +                                 slave_crtc->base.base.id, 
> slave_crtc->base.name,
> +                                 master_crtc->base.base.id, 
> master_crtc->base.name);
> +                     return -EINVAL;
> +             }
> +
> +             /*
> +              * The state copy logic assumes the master crtc gets processed
> +              * before the slave crtc during the main compute_config loop.
> +              * This works because the crtcs are created in pipe order,
> +              * and the hardware requires master pipe < slave pipe as well.
> +              * Should that change we need to rethink the logic.
> +              */
> +             if (WARN_ON(drm_crtc_index(&master_crtc->base) >
> +                         drm_crtc_index(&slave_crtc->base)))
> +                     return -EINVAL;
> +
> +             drm_dbg_kms(&i915->drm,
> +                         "[CRTC:%d:%s] Used as slave for big joiner master 
> [CRTC:%d:%s]\n",
> +                         slave_crtc->base.base.id, slave_crtc->base.name,
>                           master_crtc->base.base.id, master_crtc->base.name);
> -             return -EINVAL;
> +
> +             master_crtc_state->bigjoiner_pipes =
> +                     BIT(master_crtc->pipe) | BIT(slave_crtc->pipe);
> +             slave_crtc_state->bigjoiner_pipes =
> +                     BIT(master_crtc->pipe) | BIT(slave_crtc->pipe);
> +
> +             ret = copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
> +             if (ret)
> +                     return ret;
>       }
>  
> -     slave_crtc_state = intel_atomic_get_crtc_state(&state->base, 
> slave_crtc);
> -     if (IS_ERR(slave_crtc_state))
> -             return PTR_ERR(slave_crtc_state);
> -
> -     /* master being enabled, slave was already configured? */
> -     if (slave_crtc_state->uapi.enable)
> -             goto claimed;
> -
> -     /*
> -      * The state copy logic assumes the master crtc gets processed
> -      * before the slave crtc during the main compute_config loop.
> -      * This works because the crtcs are created in pipe order,
> -      * and the hardware requires master pipe < slave pipe as well.
> -      * Should that change we need to rethink the logic.
> -      */
> -     if (WARN_ON(drm_crtc_index(&master_crtc->base) > 
> drm_crtc_index(&slave_crtc->base)))
> -             return -EINVAL;
> -
> -     drm_dbg_kms(&i915->drm,
> -                 "[CRTC:%d:%s] Used as slave for big joiner master 
> [CRTC:%d:%s]\n",
> -                 slave_crtc->base.base.id, slave_crtc->base.name,
> -                 master_crtc->base.base.id, master_crtc->base.name);
> -
> -     master_crtc_state->bigjoiner_linked_crtc = slave_crtc;
> -     master_crtc_state->bigjoiner_slave = false;
> -
> -     slave_crtc_state->bigjoiner_linked_crtc = master_crtc;
> -     slave_crtc_state->bigjoiner_slave = true;
> -
> -     return copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
> -
> -claimed:
> -     drm_dbg_kms(&i915->drm,
> -                 "[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
> -                 "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
> -                 slave_crtc->base.base.id, slave_crtc->base.name,
> -                 master_crtc->base.base.id, master_crtc->base.name);
> -     return -EINVAL;
> +     return 0;
>  }
>  
>  static void kill_bigjoiner_slave(struct intel_atomic_state *state,
>                                struct intel_crtc *master_crtc)
>  {
> +     struct drm_i915_private *i915 = to_i915(state->base.dev);
>       struct intel_crtc_state *master_crtc_state =
>               intel_atomic_get_new_crtc_state(state, master_crtc);
> -     struct intel_crtc *slave_crtc = 
> master_crtc_state->bigjoiner_linked_crtc;
> -     struct intel_crtc_state *slave_crtc_state =
> -             intel_atomic_get_new_crtc_state(state, slave_crtc);
> +     struct intel_crtc *slave_crtc;
>  
> -     slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
> -     slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave 
> = false;
> -     slave_crtc_state->bigjoiner_linked_crtc = 
> master_crtc_state->bigjoiner_linked_crtc = NULL;
> +     for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
> +                                      
> intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
> +             struct intel_crtc_state *slave_crtc_state =
> +                     intel_atomic_get_new_crtc_state(state, slave_crtc);
>  
> -     intel_crtc_copy_uapi_to_hw_state_modeset(state, slave_crtc);
> +             slave_crtc_state->bigjoiner = false;
> +             slave_crtc_state->bigjoiner_pipes = 0;
> +
> +             intel_crtc_copy_uapi_to_hw_state_modeset(state, slave_crtc);
> +     }
> +
> +     master_crtc_state->bigjoiner = false;
> +     master_crtc_state->bigjoiner_pipes = 0;
>  }
>  
>  /**
> @@ -7828,34 +7939,37 @@ static int intel_atomic_check_async(struct 
> intel_atomic_state *state, struct int
>  
>  static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state 
> *state)
>  {
> +     struct drm_i915_private *i915 = to_i915(state->base.dev);
>       struct intel_crtc_state *crtc_state;
>       struct intel_crtc *crtc;
> +     u8 affected_pipes = 0;
> +     u8 modeset_pipes = 0;
>       int i;
>  
>       for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -             struct intel_crtc_state *linked_crtc_state;
> -             struct intel_crtc *linked_crtc;
> +             affected_pipes |= crtc_state->bigjoiner_pipes;
> +             if (intel_crtc_needs_modeset(crtc_state))
> +                     modeset_pipes |= crtc_state->bigjoiner_pipes;
> +     }
> +
> +     for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, affected_pipes) {
> +             crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
> +             if (IS_ERR(crtc_state))
> +                     return PTR_ERR(crtc_state);
> +     }
> +
> +     for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, modeset_pipes) {
>               int ret;
>  
> -             if (!crtc_state->bigjoiner)
> -                     continue;
> +             crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>  
> -             linked_crtc = crtc_state->bigjoiner_linked_crtc;
> -             linked_crtc_state = intel_atomic_get_crtc_state(&state->base, 
> linked_crtc);
> -             if (IS_ERR(linked_crtc_state))
> -                     return PTR_ERR(linked_crtc_state);
> +             crtc_state->uapi.mode_changed = true;
>  
> -             if (!intel_crtc_needs_modeset(crtc_state))
> -                     continue;
> -
> -             linked_crtc_state->uapi.mode_changed = true;
> -
> -             ret = drm_atomic_add_affected_connectors(&state->base,
> -                                                      &linked_crtc->base);
> +             ret = drm_atomic_add_affected_connectors(&state->base, 
> &crtc->base);
>               if (ret)
>                       return ret;
>  
> -             ret = intel_atomic_add_affected_planes(state, linked_crtc);
> +             ret = intel_atomic_add_affected_planes(state, crtc);
>               if (ret)
>                       return ret;
>       }
> @@ -7985,10 +8099,7 @@ static int intel_atomic_check(struct drm_device *dev,
>               }
>  
>               if (new_crtc_state->bigjoiner) {
> -                     struct intel_crtc_state *linked_crtc_state =
> -                             intel_atomic_get_new_crtc_state(state, 
> new_crtc_state->bigjoiner_linked_crtc);
> -
> -                     if (intel_crtc_needs_modeset(linked_crtc_state)) {
> +                     if (intel_pipes_need_modeset(state, 
> new_crtc_state->bigjoiner_pipes)) {
>                               new_crtc_state->uapi.mode_changed = true;
>                               new_crtc_state->update_pipe = false;
>                       }
> @@ -10390,12 +10501,18 @@ static void intel_modeset_readout_hw_state(struct 
> drm_device *dev)
>  
>                       /* read out to slave crtc as well for bigjoiner */
>                       if (crtc_state->bigjoiner) {
> +                             struct intel_crtc *slave_crtc;
> +
>                               /* encoder should read be linked to bigjoiner 
> master */
>                               
> WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
>  
> -                             crtc = crtc_state->bigjoiner_linked_crtc;
> -                             crtc_state = 
> to_intel_crtc_state(crtc->base.state);
> -                             intel_encoder_get_config(encoder, crtc_state);
> +                             
> for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc,
> +                                                              
> intel_crtc_bigjoiner_slave_pipes(crtc_state)) {
> +                                     struct intel_crtc_state 
> *slave_crtc_state;
> +
> +                                     slave_crtc_state = 
> to_intel_crtc_state(slave_crtc->base.state);
> +                                     intel_encoder_get_config(encoder, 
> slave_crtc_state);
> +                             }
>                       }
>               } else {
>                       encoder->base.crtc = NULL;
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h 
> b/drivers/gpu/drm/i915/display/intel_display.h
> index fe9eb3acee65..d8c5c507f54b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -557,6 +557,8 @@ enum phy intel_port_to_phy(struct drm_i915_private *i915, 
> enum port port);
>  bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
>  bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state 
> *crtc_state);
>  bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state 
> *crtc_state);
> +u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state 
> *crtc_state);
> +struct intel_crtc *intel_master_crtc(const struct intel_crtc_state 
> *crtc_state);
>  
>  void intel_plane_destroy(struct drm_plane *plane);
>  void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
> b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index 053c74afe721..1738a4050773 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -936,9 +936,8 @@ static void intel_crtc_info(struct seq_file *m, struct 
> intel_crtc *crtc)
>       }
>  
>       if (crtc_state->bigjoiner)
> -             seq_printf(m, "\tLinked to [CRTC:%d:%s] as a %s\n",
> -                        crtc_state->bigjoiner_linked_crtc->base.base.id,
> -                        crtc_state->bigjoiner_linked_crtc->base.name,
> +             seq_printf(m, "\tLinked to 0x%x pipes as a %s\n",
> +                        crtc_state->bigjoiner_pipes,
>                          intel_crtc_is_bigjoiner_slave(crtc_state) ? "slave" 
> : "master");
>  
>       for_each_intel_encoder_mask(&dev_priv->drm, encoder,
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 60e15226a8cb..641ecae42198 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1202,11 +1202,8 @@ struct intel_crtc_state {
>       /* enable pipe big joiner? */
>       bool bigjoiner;
>  
> -     /* big joiner slave crtc? */
> -     bool bigjoiner_slave;
> -
> -     /* linked crtc for bigjoiner, either slave or master */
> -     struct intel_crtc *bigjoiner_linked_crtc;
> +     /* big joiner pipe bitmask */
> +     u8 bigjoiner_pipes;
>  
>       /* Display Stream compression state */
>       struct {
> diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c 
> b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> index e4186a0b8edb..542227d6d2f9 100644
> --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
> +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> @@ -165,8 +165,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
>  {
>       struct drm_device *dev = crtc->base.dev;
>       struct drm_i915_private *dev_priv = to_i915(dev);
> -     struct intel_crtc_state *crtc_state =
> -             to_intel_crtc_state(crtc->base.state);
>       struct intel_plane *plane =
>               to_intel_plane(crtc->base.primary);
>       struct intel_plane_state *plane_state =
> @@ -203,11 +201,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
>        * pretend the BIOS never had it enabled.
>        */
>       intel_plane_disable_noatomic(crtc, plane);
> -     if (crtc_state->bigjoiner) {
> -             struct intel_crtc *slave =
> -                     crtc_state->bigjoiner_linked_crtc;
> -             intel_plane_disable_noatomic(slave, 
> to_intel_plane(slave->base.primary));
> -     }
>  
>       return;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c 
> b/drivers/gpu/drm/i915/display/intel_vdsc.c
> index b83b59cf2b78..545eff5bf158 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -1107,18 +1107,6 @@ static i915_reg_t dss_ctl2_reg(struct intel_crtc 
> *crtc, enum transcoder cpu_tran
>               ICL_PIPE_DSS_CTL2(crtc->pipe) : DSS_CTL2;
>  }
>  
> -struct intel_crtc *
> -intel_dsc_get_bigjoiner_secondary(const struct intel_crtc *primary_crtc)
> -{
> -     return intel_crtc_for_pipe(to_i915(primary_crtc->base.dev), 
> primary_crtc->pipe + 1);
> -}
> -
> -static struct intel_crtc *
> -intel_dsc_get_bigjoiner_primary(const struct intel_crtc *secondary_crtc)
> -{
> -     return intel_crtc_for_pipe(to_i915(secondary_crtc->base.dev), 
> secondary_crtc->pipe - 1);
> -}
> -
>  void intel_uncompressed_joiner_enable(const struct intel_crtc_state 
> *crtc_state)
>  {
>       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> @@ -1174,25 +1162,6 @@ void intel_dsc_disable(const struct intel_crtc_state 
> *old_crtc_state)
>       }
>  }
>  
> -void intel_uncompressed_joiner_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);
> -     u32 dss_ctl1;
> -
> -     dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, 
> crtc_state->cpu_transcoder));
> -     if (dss_ctl1 & UNCOMPRESSED_JOINER_MASTER) {
> -             crtc_state->bigjoiner = true;
> -             crtc_state->bigjoiner_linked_crtc = 
> intel_dsc_get_bigjoiner_secondary(crtc);
> -             drm_WARN_ON(&dev_priv->drm, !crtc_state->bigjoiner_linked_crtc);
> -     } else if (dss_ctl1 & UNCOMPRESSED_JOINER_SLAVE) {
> -             crtc_state->bigjoiner = true;
> -             crtc_state->bigjoiner_slave = true;
> -             crtc_state->bigjoiner_linked_crtc = 
> intel_dsc_get_bigjoiner_primary(crtc);
> -             drm_WARN_ON(&dev_priv->drm, !crtc_state->bigjoiner_linked_crtc);
> -     }
> -}
> -
>  void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
>  {
>       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> @@ -1223,18 +1192,6 @@ 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);
>  
> -     if (dss_ctl1 & BIG_JOINER_ENABLE) {
> -             crtc_state->bigjoiner = true;
> -
> -             if (!(dss_ctl1 & MASTER_BIG_JOINER_ENABLE)) {
> -                     crtc_state->bigjoiner_slave = true;
> -                     crtc_state->bigjoiner_linked_crtc = 
> intel_dsc_get_bigjoiner_primary(crtc);
> -             } else {
> -                     crtc_state->bigjoiner_linked_crtc = 
> intel_dsc_get_bigjoiner_secondary(crtc);
> -             }
> -             drm_WARN_ON(&dev_priv->drm, !crtc_state->bigjoiner_linked_crtc);
> -     }
> -
>       /* FIXME: add more state readout as needed */
>  
>       /* PPS1 */
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h 
> b/drivers/gpu/drm/i915/display/intel_vdsc.h
> index 4ec75f715986..8763f00fa7e2 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -18,7 +18,6 @@ void intel_uncompressed_joiner_enable(const struct 
> intel_crtc_state *crtc_state)
>  void intel_dsc_enable(const struct intel_crtc_state *crtc_state);
>  void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
>  int intel_dsc_compute_params(struct intel_crtc_state *pipe_config);
> -void intel_uncompressed_joiner_get_config(struct intel_crtc_state 
> *crtc_state);
>  void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
>  enum intel_display_power_domain
>  intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder 
> cpu_transcoder);
> -- 
> 2.34.1
> 

Reply via email to