Replace the use of mode->private_flags with a truly private bitmaks
in our own crtc state. We also need a copy in the crtc itself so the
vblank code can get at it. We already have scanline_offset in there
for a similar reason, as well as the vblank->hwmode which is assigned
via drm_calc_timestamping_constants(). Fortunately we now have a
nice place for doing the crtc_state->crtc copy in
intel_crtc_update_active_timings() which gets called both for
modesets and init/resume readout.
The one slightly iffy spot is the INHERITED flag which we want to
preserve until userspace/fb_helper does the first proper commit after
actually calling .detecti() on the connectors. Otherwise we don't have
the full sink capabilities (audio,infoframes,etc.) when .compute_config()
gets called and thus we will fail to enable those features when the
first userspace commit happens. The only internal commit we do prior to
that should be from intel_initial_commit() and there we can simply
preserve the INHERITED flag from the readout.
v2: Deal with INHERITED in sanitize_watermarks() as well
CC: Sam Ravnborg <sam@ravnborg.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Emil Velikov <emil.l.velikov@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200429103904.11727-1-ville.syrjala@linux.intel.com
 
        pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc);
 
        if (gen11_dsi_is_periodic_cmd_mode(intel_dsi))
-               pipe_config->hw.adjusted_mode.private_flags |=
-                                       I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
+               pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
 }
 
 static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
 
        pipe_config->port_clock = afe_clk(encoder, pipe_config) / 5;
 
-       /* We would not operate in periodic command mode */
-       pipe_config->hw.adjusted_mode.private_flags &=
-                                       ~I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
-
        /*
         * In case of TE GATE cmd mode, we
         * receive TE from the slave if
         */
        if (is_cmd_mode(intel_dsi)) {
                if (intel_dsi->ports == (BIT(PORT_B) | BIT(PORT_A)))
-                       pipe_config->hw.adjusted_mode.private_flags |=
+                       pipe_config->mode_flags |=
                                                I915_MODE_FLAG_DSI_USE_TE1 |
                                                I915_MODE_FLAG_DSI_USE_TE0;
                else if (intel_dsi->ports == BIT(PORT_B))
-                       pipe_config->hw.adjusted_mode.private_flags |=
+                       pipe_config->mode_flags |=
                                                I915_MODE_FLAG_DSI_USE_TE1;
                else
-                       pipe_config->hw.adjusted_mode.private_flags |=
+                       pipe_config->mode_flags |=
                                                I915_MODE_FLAG_DSI_USE_TE0;
        }
 
 
        crtc_state->fb_bits = 0;
        crtc_state->update_planes = 0;
        crtc_state->dsb = NULL;
+       crtc_state->mode_flags &= ~I915_MODE_FLAG_INHERITED;
 
        return &crtc_state->uapi;
 }
 
         * forcibly enable IPS on the first fastset.
         */
        if (new_crtc_state->update_pipe &&
-           old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
+           old_crtc_state->mode_flags & I915_MODE_FLAG_INHERITED)
                return true;
 
        return !old_crtc_state->ips_enabled;
        bool ret = true;
        u32 bp_gamma = 0;
        bool fixup_inherited = fastset &&
-               (current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
-               !(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
+               (current_config->mode_flags & I915_MODE_FLAG_INHERITED) &&
+               !(pipe_config->mode_flags & I915_MODE_FLAG_INHERITED);
 
        if (fixup_inherited && !fastboot_enabled(dev_priv)) {
                drm_dbg_kms(&dev_priv->drm,
 
        drm_calc_timestamping_constants(&crtc->base, adjusted_mode);
 
+       crtc->mode_flags = crtc_state->mode_flags;
+
        /*
         * The scanline counter increments at the leading edge of hsync.
         *
        /* Catch I915_MODE_FLAG_INHERITED */
        for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
                                            new_crtc_state, i) {
-               if (new_crtc_state->uapi.mode.private_flags !=
-                   old_crtc_state->uapi.mode.private_flags)
+               if (new_crtc_state->mode_flags != old_crtc_state->mode_flags)
                        new_crtc_state->uapi.mode_changed = true;
        }
 
         * of enabling them on the CRTC's first fastset.
         */
        if (new_crtc_state->update_pipe && !modeset &&
-           old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
+           old_crtc_state->mode_flags & I915_MODE_FLAG_INHERITED)
                intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
 static int sanitize_watermarks_add_affected(struct drm_atomic_state *state)
 {
        struct drm_plane *plane;
-       struct drm_crtc *crtc;
+       struct intel_crtc *crtc;
 
-       drm_for_each_crtc(crtc, state->dev) {
-               struct drm_crtc_state *crtc_state;
+       for_each_intel_crtc(state->dev, crtc) {
+               struct intel_crtc_state *crtc_state;
 
-               crtc_state = drm_atomic_get_crtc_state(state, crtc);
+               crtc_state = intel_atomic_get_crtc_state(state, crtc);
                if (IS_ERR(crtc_state))
                        return PTR_ERR(crtc_state);
+
+               if (crtc_state->hw.active) {
+                       /*
+                        * Preserve the inherited flag to avoid
+                        * taking the full modeset path.
+                        */
+                       crtc_state->mode_flags |= I915_MODE_FLAG_INHERITED;
+               }
        }
 
        drm_for_each_plane(plane, state->dev) {
                }
 
                if (crtc_state->hw.active) {
+                       /*
+                        * We've not yet detected sink capabilities
+                        * (audio,infoframes,etc.) and thus we don't want to
+                        * force a full state recomputation yet. We want that to
+                        * happen only for the first real commit from userspace.
+                        * So preserve the inherited flag for the time being.
+                        */
+                       crtc_state->mode_flags |= I915_MODE_FLAG_INHERITED;
+
                        ret = drm_atomic_add_affected_planes(state, &crtc->base);
                        if (ret)
                                goto out;
                         * set a flag to indicate that a full recalculation is
                         * needed on the next commit.
                         */
-                       mode->private_flags = I915_MODE_FLAG_INHERITED;
+                       crtc_state->mode_flags |= I915_MODE_FLAG_INHERITED;
 
                        intel_crtc_compute_pixel_rate(crtc_state);
 
 
        int scaler_id;
 };
 
-/* drm_mode->private_flags */
+/* {crtc,crtc_state}->mode_flags */
 #define I915_MODE_FLAG_INHERITED (1<<0)
 /* Flag to get scanline using frame time stamps */
 #define I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP (1<<1)
        /* Used by SDVO (and if we ever fix it, HDMI). */
        unsigned pixel_multiplier;
 
+       /* I915_MODE_FLAG_* */
+       u8 mode_flags;
+
        u8 lane_count;
 
        /*
         */
        bool active;
        u8 plane_ids_mask;
+
+       /* I915_MODE_FLAG_* */
+       u8 mode_flags;
+
        unsigned long long enabled_power_domains;
        struct intel_overlay *overlay;
 
 
 
        /* pixel counter doesn't work on i965gm TV output */
        if (IS_I965GM(dev_priv))
-               adjusted_mode->private_flags |=
+               pipe_config->mode_flags |=
                        I915_MODE_FLAG_USE_SCANLINE_COUNTER;
 }
 
 
        /* pixel counter doesn't work on i965gm TV output */
        if (IS_I965GM(dev_priv))
-               adjusted_mode->private_flags |=
+               pipe_config->mode_flags |=
                        I915_MODE_FLAG_USE_SCANLINE_COUNTER;
 
        return 0;
 
 
        if (IS_GEN9_LP(dev_priv)) {
                /* Enable Frame time stamp based scanline reporting */
-               adjusted_mode->private_flags |=
+               pipe_config->mode_flags |=
                        I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP;
 
                /* Dual link goes to DSI transcoder A. */
        pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc);
 
        /* Enable Frame time stamo based scanline reporting */
-       adjusted_mode->private_flags |=
-                       I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP;
+       pipe_config->mode_flags |=
+               I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP;
 
        /* In terms of pixels */
        adjusted_mode->crtc_hdisplay =
 
        vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
        mode = &vblank->hwmode;
 
-       if (mode->private_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP)
+       if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP)
                return __intel_get_crtc_scanline_from_timestamp(crtc);
 
        vtotal = mode->crtc_vtotal;
        unsigned long irqflags;
        bool use_scanline_counter = INTEL_GEN(dev_priv) >= 5 ||
                IS_G4X(dev_priv) || IS_GEN(dev_priv, 2) ||
-               mode->private_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;
+               crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;
 
        if (drm_WARN_ON(&dev_priv->drm, !mode->crtc_clock)) {
                drm_dbg(&dev_priv->drm,