if (drm_WARN_ON(&dev_priv->drm, crtc->active))
                return;
 
-       if (!new_crtc_state->bigjoiner) {
+       if (!new_crtc_state->bigjoiner_pipes) {
                intel_encoders_pre_pll_enable(state, crtc);
 
                if (new_crtc_state->shared_dpll)
 static void intel_bigjoiner_adjust_timings(const struct intel_crtc_state *crtc_state,
                                           struct drm_display_mode *mode)
 {
-       if (!crtc_state->bigjoiner)
+       if (!crtc_state->bigjoiner_pipes)
                return;
 
        mode->crtc_clock /= 2;
        /* Populate the "user" mode with full numbers */
        drm_mode_copy(mode, pipe_mode);
        intel_mode_from_crtc_timings(mode, mode);
-       mode->hdisplay = drm_rect_width(&crtc_state->pipe_src) << crtc_state->bigjoiner;
+       mode->hdisplay = drm_rect_width(&crtc_state->pipe_src) << !!crtc_state->bigjoiner_pipes;
        mode->vdisplay = drm_rect_height(&crtc_state->pipe_src);
 
        /* Derive per-pipe timings in case bigjoiner is used */
 {
        int width, height;
 
-       if (!crtc_state->bigjoiner)
+       if (!crtc_state->bigjoiner_pipes)
                return;
 
        width = drm_rect_width(&crtc_state->pipe_src);
        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);
                intel_atomic_get_new_crtc_state(state, master_crtc);
        struct intel_crtc_state *saved_state;
 
+       WARN_ON(master_crtc_state->bigjoiner_pipes !=
+               slave_crtc_state->bigjoiner_pipes);
+
        saved_state = kmemdup(master_crtc_state, sizeof(*saved_state), GFP_KERNEL);
        if (!saved_state)
                return -ENOMEM;
        slave_crtc_state->uapi.connectors_changed = master_crtc_state->uapi.connectors_changed;
        slave_crtc_state->uapi.active_changed = master_crtc_state->uapi.active_changed;
 
+       WARN_ON(master_crtc_state->bigjoiner_pipes !=
+               slave_crtc_state->bigjoiner_pipes);
+
        return 0;
 }
 
 
        PIPE_CONF_CHECK_X(sync_mode_slaves_mask);
        PIPE_CONF_CHECK_I(master_transcoder);
-       PIPE_CONF_CHECK_BOOL(bigjoiner);
        PIPE_CONF_CHECK_X(bigjoiner_pipes);
 
        PIPE_CONF_CHECK_I(dsc.compression_enable);
        struct intel_crtc_state *master_crtc_state =
                intel_atomic_get_new_crtc_state(state, master_crtc);
        struct intel_crtc *slave_crtc;
-       u8 slave_pipes;
-
-       /*
-        * 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)
+       if (!master_crtc_state->bigjoiner_pipes)
                return 0;
 
-       slave_pipes = BIT(master_crtc->pipe + 1);
+       /* sanity check */
+       if (drm_WARN_ON(&i915->drm,
+                       master_crtc->pipe != bigjoiner_master_pipe(master_crtc_state)))
+               return -EINVAL;
 
-       if (slave_pipes & ~bigjoiner_pipes(i915)) {
+       if (master_crtc_state->bigjoiner_pipes & ~bigjoiner_pipes(i915)) {
                drm_dbg_kms(&i915->drm,
                            "[CRTC:%d:%s] Cannot act as big joiner master "
-                           "(need 0x%x as slave pipes, only 0x%x possible)\n",
+                           "(need 0x%x as pipes, only 0x%x possible)\n",
                            master_crtc->base.base.id, master_crtc->base.name,
-                           slave_pipes, bigjoiner_pipes(i915));
+                           master_crtc_state->bigjoiner_pipes, bigjoiner_pipes(i915));
                return -EINVAL;
        }
 
-       for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, slave_pipes) {
+       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;
                int ret;
 
                            slave_crtc->base.base.id, slave_crtc->base.name,
                            master_crtc->base.base.id, master_crtc->base.name);
 
-               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);
+                       master_crtc_state->bigjoiner_pipes;
 
                ret = copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
                if (ret)
                struct intel_crtc_state *slave_crtc_state =
                        intel_atomic_get_new_crtc_state(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;
 }
 
                        }
                }
 
-               if (new_crtc_state->bigjoiner) {
+               if (new_crtc_state->bigjoiner_pipes) {
                        if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes)) {
                                new_crtc_state->uapi.mode_changed = true;
                                new_crtc_state->update_pipe = false;
                        intel_encoder_get_config(encoder, crtc_state);
 
                        /* read out to slave crtc as well for bigjoiner */
-                       if (crtc_state->bigjoiner) {
+                       if (crtc_state->bigjoiner_pipes) {
                                struct intel_crtc *slave_crtc;
 
                                /* encoder should read be linked to bigjoiner master */
 
                                                    pipe_config->lane_count,
                                                    adjusted_mode->crtc_clock,
                                                    adjusted_mode->crtc_hdisplay,
-                                                   pipe_config->bigjoiner,
+                                                   pipe_config->bigjoiner_pipes,
                                                    pipe_bpp);
                dsc_dp_slice_count =
                        intel_dp_dsc_get_slice_count(intel_dp,
                                                     adjusted_mode->crtc_clock,
                                                     adjusted_mode->crtc_hdisplay,
-                                                    pipe_config->bigjoiner);
+                                                    pipe_config->bigjoiner_pipes);
                if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
                        drm_dbg_kms(&dev_priv->drm,
                                    "Compressed BPP/Slice Count not supported\n");
         * then we need to use 2 VDSC instances.
         */
        if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
-           pipe_config->bigjoiner) {
+           pipe_config->bigjoiner_pipes) {
                if (pipe_config->dsc.slice_count < 2) {
                        drm_dbg_kms(&dev_priv->drm,
                                    "Cannot split stream to use 2 VDSC instances\n");
                             struct drm_connector_state *conn_state)
 {
        struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
        const struct drm_display_mode *adjusted_mode =
                &pipe_config->hw.adjusted_mode;
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
        if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,
                                    adjusted_mode->crtc_clock))
-               pipe_config->bigjoiner = true;
+               pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
 
        /*
         * Optimize for slow and wide for everything, because there are some
         * onwards pipe joiner can be enabled without compression.
         */
        drm_dbg_kms(&i915->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en);
-       if (ret || intel_dp->force_dsc_en || (DISPLAY_VER(i915) < 13 &&
-                                             pipe_config->bigjoiner)) {
+       if (ret || intel_dp->force_dsc_en ||
+           (DISPLAY_VER(i915) < 13 && pipe_config->bigjoiner_pipes)) {
                ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
                                                  conn_state, &limits);
                if (ret < 0)
 
        u8 num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;
        int i = 0;
 
-       if (crtc_state->bigjoiner)
+       if (crtc_state->bigjoiner_pipes)
                num_vdsc_instances *= 2;
 
        /* Populate PICTURE_PARAMETER_SET_0 registers */
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 dss_ctl1_val = 0;
 
-       if (crtc_state->bigjoiner && !crtc_state->dsc.compression_enable) {
+       if (crtc_state->bigjoiner_pipes && !crtc_state->dsc.compression_enable) {
                if (intel_crtc_is_bigjoiner_slave(crtc_state))
                        dss_ctl1_val |= UNCOMPRESSED_JOINER_SLAVE;
                else
                dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
                dss_ctl1_val |= JOINER_ENABLE;
        }
-       if (crtc_state->bigjoiner) {
+       if (crtc_state->bigjoiner_pipes) {
                dss_ctl1_val |= BIG_JOINER_ENABLE;
                if (!intel_crtc_is_bigjoiner_slave(crtc_state))
                        dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
 
        /* Disable only if either of them is enabled */
        if (old_crtc_state->dsc.compression_enable ||
-           old_crtc_state->bigjoiner) {
+           old_crtc_state->bigjoiner_pipes) {
                intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
                intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
        }