aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra/dpaux.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-08-03 14:08:34 +0200
committerThierry Reding <treding@nvidia.com>2019-10-28 11:18:43 +0100
commit5e881f6b29fe69726d0aa11f846c438a5cb7ddb0 (patch)
treedf9f5b887100d71397d4a42d221294093b66a997 /drivers/gpu/drm/tegra/dpaux.c
parentdrm/tegra: gem: Use sg_alloc_table_from_pages() (diff)
downloadlinux-dev-5e881f6b29fe69726d0aa11f846c438a5cb7ddb0.tar.xz
linux-dev-5e881f6b29fe69726d0aa11f846c438a5cb7ddb0.zip
drm/tegra: dpaux: Support monitor hotplugging
The dpaux driver has a quirk built-in that will delay initialization of the display driver for a short while, trying to detect an eDP panel. The reason for this quirk is that the panel may not report as connected until after the display driver has initialized, at which point the fbdev emulation will have fallen back to 1024x768 as default resolution, which will likely not be the eDP panel's native resolution. With upcoming DisplayPort support, the code needs to be able to cope with hotpluggable monitors as well. Waiting for a panel to show up is no longer going to work because the monitor may not be attached on boot. If the output runs in DisplayPort mode, skip waiting for the panel to show up. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dpaux.c')
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 1144605c9737..4a35a6e0e2aa 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -691,21 +691,26 @@ int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
if (err < 0)
return err;
- timeout = jiffies + msecs_to_jiffies(250);
-
- while (time_before(jiffies, timeout)) {
+ if (output->panel) {
enum drm_connector_status status;
- status = drm_dp_aux_detect(aux);
- if (status == connector_status_connected) {
- enable_irq(dpaux->irq);
- return 0;
+ timeout = jiffies + msecs_to_jiffies(250);
+
+ while (time_before(jiffies, timeout)) {
+ status = drm_dp_aux_detect(aux);
+
+ if (status == connector_status_connected)
+ break;
+
+ usleep_range(1000, 2000);
}
- usleep_range(1000, 2000);
+ if (status != connector_status_connected)
+ return -ETIMEDOUT;
}
- return -ETIMEDOUT;
+ enable_irq(dpaux->irq);
+ return 0;
}
int drm_dp_aux_detach(struct drm_dp_aux *aux)
@@ -720,21 +725,27 @@ int drm_dp_aux_detach(struct drm_dp_aux *aux)
if (err < 0)
return err;
- timeout = jiffies + msecs_to_jiffies(250);
-
- while (time_before(jiffies, timeout)) {
+ if (dpaux->output->panel) {
enum drm_connector_status status;
- status = drm_dp_aux_detect(aux);
- if (status == connector_status_disconnected) {
- dpaux->output = NULL;
- return 0;
+ timeout = jiffies + msecs_to_jiffies(250);
+
+ while (time_before(jiffies, timeout)) {
+ status = drm_dp_aux_detect(aux);
+
+ if (status == connector_status_disconnected)
+ break;
+
+ usleep_range(1000, 2000);
}
- usleep_range(1000, 2000);
+ if (status != connector_status_disconnected)
+ return -ETIMEDOUT;
+
+ dpaux->output = NULL;
}
- return -ETIMEDOUT;
+ return 0;
}
enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)