|
Takashi Iwai |
429927 |
From ca871659ec1606d33b1e76de8d4cf924cf627e34 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
429927 |
From: Brian Norris <briannorris@chromium.org>
|
|
Takashi Iwai |
429927 |
Date: Mon, 28 Feb 2022 12:25:31 -0800
|
|
Takashi Iwai |
429927 |
Subject: [PATCH] drm/bridge: analogix_dp: Support PSR-exit to disable transition
|
|
Takashi Iwai |
429927 |
Git-commit: ca871659ec1606d33b1e76de8d4cf924cf627e34
|
|
Takashi Iwai |
429927 |
Patch-mainline: v5.19-rc2
|
|
Takashi Iwai |
429927 |
References: git-fixes
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
Most eDP panel functions only work correctly when the panel is not in
|
|
Takashi Iwai |
429927 |
self-refresh. In particular, analogix_dp_bridge_disable() tends to hit
|
|
Takashi Iwai |
429927 |
AUX channel errors if the panel is in self-refresh.
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
Given the above, it appears that so far, this driver assumes that we are
|
|
Takashi Iwai |
429927 |
never in self-refresh when it comes time to fully disable the bridge.
|
|
Takashi Iwai |
429927 |
Prior to commit 846c7dfc1193 ("drm/atomic: Try to preserve the crtc
|
|
Takashi Iwai |
429927 |
enabled state in drm_atomic_remove_fb, v2."), this tended to be true,
|
|
Takashi Iwai |
429927 |
because we would automatically disable the pipe when framebuffers were
|
|
Takashi Iwai |
429927 |
removed, and so we'd typically disable the bridge shortly after the last
|
|
Takashi Iwai |
429927 |
display activity.
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
However, that is not guaranteed: an idle (self-refresh) display pipe may
|
|
Takashi Iwai |
429927 |
be disabled, e.g., when switching CRTCs. We need to exit PSR first.
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
Stable notes: this is definitely a bugfix, and the bug has likely
|
|
Takashi Iwai |
429927 |
existed in some form for quite a while. It may predate the "PSR helpers"
|
|
Takashi Iwai |
429927 |
refactor, but the code looked very different before that, and it's
|
|
Takashi Iwai |
429927 |
probably not worth rewriting the fix.
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
Cc: <stable@vger.kernel.org>
|
|
Takashi Iwai |
429927 |
Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR")
|
|
Takashi Iwai |
429927 |
Signed-off-by: Brian Norris <briannorris@chromium.org>
|
|
Takashi Iwai |
429927 |
Reviewed-by: Sean Paul <seanpaul@chromium.org>
|
|
Takashi Iwai |
429927 |
Signed-off-by: Douglas Anderson <dianders@chromium.org>
|
|
Takashi Iwai |
429927 |
Link: https://patchwork.freedesktop.org/patch/msgid/20220228122522.v2.1.I161904be17ba14526f78536ccd78b85818449b51@changeid
|
|
Takashi Iwai |
429927 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
---
|
|
Takashi Iwai |
429927 |
.../drm/bridge/analogix/analogix_dp_core.c | 42 +++++++++++++++++--
|
|
Takashi Iwai |
429927 |
1 file changed, 38 insertions(+), 4 deletions(-)
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
|
|
Takashi Iwai |
429927 |
index eb590fb8e8d0..0300f670a4fd 100644
|
|
Takashi Iwai |
429927 |
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
|
|
Takashi Iwai |
429927 |
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
|
|
Takashi Iwai |
429927 |
@@ -1268,6 +1268,25 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
|
|
Takashi Iwai |
429927 |
return 0;
|
|
Takashi Iwai |
429927 |
}
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
+static
|
|
Takashi Iwai |
429927 |
+struct drm_crtc *analogix_dp_get_old_crtc(struct analogix_dp_device *dp,
|
|
Takashi Iwai |
429927 |
+ struct drm_atomic_state *state)
|
|
Takashi Iwai |
429927 |
+{
|
|
Takashi Iwai |
429927 |
+ struct drm_encoder *encoder = dp->encoder;
|
|
Takashi Iwai |
429927 |
+ struct drm_connector *connector;
|
|
Takashi Iwai |
429927 |
+ struct drm_connector_state *conn_state;
|
|
Takashi Iwai |
429927 |
+
|
|
Takashi Iwai |
429927 |
+ connector = drm_atomic_get_old_connector_for_encoder(state, encoder);
|
|
Takashi Iwai |
429927 |
+ if (!connector)
|
|
Takashi Iwai |
429927 |
+ return NULL;
|
|
Takashi Iwai |
429927 |
+
|
|
Takashi Iwai |
429927 |
+ conn_state = drm_atomic_get_old_connector_state(state, connector);
|
|
Takashi Iwai |
429927 |
+ if (!conn_state)
|
|
Takashi Iwai |
429927 |
+ return NULL;
|
|
Takashi Iwai |
429927 |
+
|
|
Takashi Iwai |
429927 |
+ return conn_state->crtc;
|
|
Takashi Iwai |
429927 |
+}
|
|
Takashi Iwai |
429927 |
+
|
|
Takashi Iwai |
429927 |
static
|
|
Takashi Iwai |
429927 |
struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp,
|
|
Takashi Iwai |
429927 |
struct drm_atomic_state *state)
|
|
Takashi Iwai |
429927 |
@@ -1448,14 +1467,16 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
|
Takashi Iwai |
429927 |
{
|
|
Takashi Iwai |
429927 |
struct drm_atomic_state *old_state = old_bridge_state->base.state;
|
|
Takashi Iwai |
429927 |
struct analogix_dp_device *dp = bridge->driver_private;
|
|
Takashi Iwai |
429927 |
- struct drm_crtc *crtc;
|
|
Takashi Iwai |
429927 |
+ struct drm_crtc *old_crtc, *new_crtc;
|
|
Takashi Iwai |
429927 |
+ struct drm_crtc_state *old_crtc_state = NULL;
|
|
Takashi Iwai |
429927 |
struct drm_crtc_state *new_crtc_state = NULL;
|
|
Takashi Iwai |
429927 |
+ int ret;
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
- crtc = analogix_dp_get_new_crtc(dp, old_state);
|
|
Takashi Iwai |
429927 |
- if (!crtc)
|
|
Takashi Iwai |
429927 |
+ new_crtc = analogix_dp_get_new_crtc(dp, old_state);
|
|
Takashi Iwai |
429927 |
+ if (!new_crtc)
|
|
Takashi Iwai |
429927 |
goto out;
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
- new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc);
|
|
Takashi Iwai |
429927 |
+ new_crtc_state = drm_atomic_get_new_crtc_state(old_state, new_crtc);
|
|
Takashi Iwai |
429927 |
if (!new_crtc_state)
|
|
Takashi Iwai |
429927 |
goto out;
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
@@ -1464,6 +1485,19 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge,
|
|
Takashi Iwai |
429927 |
return;
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
out:
|
|
Takashi Iwai |
429927 |
+ old_crtc = analogix_dp_get_old_crtc(dp, old_state);
|
|
Takashi Iwai |
429927 |
+ if (old_crtc) {
|
|
Takashi Iwai |
429927 |
+ old_crtc_state = drm_atomic_get_old_crtc_state(old_state,
|
|
Takashi Iwai |
429927 |
+ old_crtc);
|
|
Takashi Iwai |
429927 |
+
|
|
Takashi Iwai |
429927 |
+ /* When moving from PSR to fully disabled, exit PSR first. */
|
|
Takashi Iwai |
429927 |
+ if (old_crtc_state && old_crtc_state->self_refresh_active) {
|
|
Takashi Iwai |
429927 |
+ ret = analogix_dp_disable_psr(dp);
|
|
Takashi Iwai |
429927 |
+ if (ret)
|
|
Takashi Iwai |
429927 |
+ DRM_ERROR("Failed to disable psr (%d)\n", ret);
|
|
Takashi Iwai |
429927 |
+ }
|
|
Takashi Iwai |
429927 |
+ }
|
|
Takashi Iwai |
429927 |
+
|
|
Takashi Iwai |
429927 |
analogix_dp_bridge_disable(bridge);
|
|
Takashi Iwai |
429927 |
}
|
|
Takashi Iwai |
429927 |
|
|
Takashi Iwai |
429927 |
--
|
|
Takashi Iwai |
429927 |
2.35.3
|
|
Takashi Iwai |
429927 |
|