summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2023-12-21 13:55:48 -0800
committerDouglas Anderson <dianders@chromium.org>2024-01-08 13:57:33 -0800
commit024b32db43a359e0ded3fcc6cd86247cbbed4224 (patch)
treecb242cf1b8607faa73c5e6500f2694cc462a512a
parent11f9eb899ecc8c02b769cf8d2532ba12786a7af7 (diff)
downloadlinux-stable-024b32db43a359e0ded3fcc6cd86247cbbed4224.tar.gz
linux-stable-024b32db43a359e0ded3fcc6cd86247cbbed4224.tar.bz2
linux-stable-024b32db43a359e0ded3fcc6cd86247cbbed4224.zip
drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer
Unlike what is claimed in commit f5aa7d46b0ee ("drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct drm_dp_aux"), if someone manually tries to do an AUX transfer (like via `i2cdump ${bus} 0x50 i`) while the panel is off we don't just get a simple transfer error. Instead, the whole ps8640 gets thrown for a loop and goes into a bad state. Let's put the function to wait for the HPD (and the magical 50 ms after first reset) back in when we're doing an AUX transfer. This shouldn't actually make things much slower (assuming the panel is on) because we should immediately poll and see the HPD high. Mostly this is just an extra i2c transfer to the bridge. Fixes: f5aa7d46b0ee ("drm/bridge: parade-ps8640: Provide wait_hpd_asserted() in struct drm_dp_aux") Tested-by: Pin-yen Lin <treapking@chromium.org> Reviewed-by: Pin-yen Lin <treapking@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20231221135548.1.I10f326a9305d57ad32cee7f8d9c60518c8be20fb@changeid
-rw-r--r--drivers/gpu/drm/bridge/parade-ps8640.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
index 541e4f5afc4c..fb5e9ae9ad81 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -346,6 +346,11 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
int ret;
pm_runtime_get_sync(dev);
+ ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
+ if (ret) {
+ pm_runtime_put_sync_suspend(dev);
+ return ret;
+ }
ret = ps8640_aux_transfer_msg(aux, msg);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);