drm/i915/display: Force the state compute phase once to enable PSR
authorJosé Roberto de Souza <jose.souza@intel.com>
Mon, 6 Jan 2020 15:21:28 +0000 (07:21 -0800)
committerJosé Roberto de Souza <jose.souza@intel.com>
Wed, 8 Jan 2020 16:12:01 +0000 (08:12 -0800)
Recent improvements in the state tracking in i915 caused PSR to not be
enabled when reusing firmware/BIOS modeset, this is due to all initial
commits returning ealier in intel_atomic_check() as needs_modeset()
is always false.

To fix that here forcing the state compute phase in CRTC that is
driving the eDP that supports PSR once. Enable or disable PSR do not
require a fullmodeset, so user will still experience glitch free boot
process plus the power savings that PSR brings.

It was tried to set mode_changed in intel_initial_commit() but at
this point the connectors are not registered causing a crash when
computing encoder state.

v2:
- removed function return
- change arguments to match intel_hdcp_atomic_check

v3:
- replaced drm includes in intel_psr.h by forward declaration(Jani)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112253
Reported-by: <s.zharkoff@gmail.com>
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200106152128.195171-1-jose.souza@intel.com
drivers/gpu/drm/i915/display/intel_atomic.c
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/display/intel_psr.h
drivers/gpu/drm/i915/i915_drv.h

index 0eb973f..c362eec 100644 (file)
@@ -37,6 +37,7 @@
 #include "intel_atomic.h"
 #include "intel_display_types.h"
 #include "intel_hdcp.h"
+#include "intel_psr.h"
 #include "intel_sprite.h"
 
 /**
@@ -129,6 +130,7 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn,
        struct drm_crtc_state *crtc_state;
 
        intel_hdcp_atomic_check(conn, old_state, new_state);
+       intel_psr_atomic_check(conn, old_state, new_state);
 
        if (!new_state->crtc)
                return 0;
index 16e9ff4..e3fd5f1 100644 (file)
@@ -1523,3 +1523,27 @@ bool intel_psr_enabled(struct intel_dp *intel_dp)
 
        return ret;
 }
+
+void intel_psr_atomic_check(struct drm_connector *connector,
+                           struct drm_connector_state *old_state,
+                           struct drm_connector_state *new_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(connector->dev);
+       struct intel_connector *intel_connector;
+       struct intel_digital_port *dig_port;
+       struct drm_crtc_state *crtc_state;
+
+       if (!CAN_PSR(dev_priv) || !new_state->crtc ||
+           dev_priv->psr.initially_probed)
+               return;
+
+       intel_connector = to_intel_connector(connector);
+       dig_port = enc_to_dig_port(&intel_connector->encoder->base);
+       if (dev_priv->psr.dp != &dig_port->dp)
+               return;
+
+       crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
+                                                  new_state->crtc);
+       crtc_state->mode_changed = true;
+       dev_priv->psr.initially_probed = true;
+}
index 46e4de8..c58a1d4 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "intel_frontbuffer.h"
 
+struct drm_connector;
+struct drm_connector_state;
 struct drm_i915_private;
 struct intel_crtc_state;
 struct intel_dp;
@@ -35,5 +37,8 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp);
 int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
                            u32 *out_value);
 bool intel_psr_enabled(struct intel_dp *intel_dp);
+void intel_psr_atomic_check(struct drm_connector *connector,
+                           struct drm_connector_state *old_state,
+                           struct drm_connector_state *new_state);
 
 #endif /* __INTEL_PSR_H__ */
index 5018111..1025d78 100644 (file)
@@ -505,6 +505,7 @@ struct i915_psr {
        bool dc3co_enabled;
        u32 dc3co_exit_delay;
        struct delayed_work idle_work;
+       bool initially_probed;
 };
 
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)