Commit 5e881f6b authored by Thierry Reding's avatar Thierry Reding
Browse files

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: default avatarThierry Reding <treding@nvidia.com>
parent acf6b77c
Loading
Loading
Loading
Loading
+29 −18
Original line number Diff line number Diff line
@@ -691,23 +691,28 @@ int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
	if (err < 0)
		return err;

	if (output->panel) {
		enum drm_connector_status status;

		timeout = jiffies + msecs_to_jiffies(250);

		while (time_before(jiffies, timeout)) {
		enum drm_connector_status status;

			status = drm_dp_aux_detect(aux);
		if (status == connector_status_connected) {
			enable_irq(dpaux->irq);
			return 0;
		}

			if (status == connector_status_connected)
				break;

			usleep_range(1000, 2000);
		}

		if (status != connector_status_connected)
			return -ETIMEDOUT;
	}

	enable_irq(dpaux->irq);
	return 0;
}

int drm_dp_aux_detach(struct drm_dp_aux *aux)
{
	struct tegra_dpaux *dpaux = to_dpaux(aux);
@@ -720,21 +725,27 @@ int drm_dp_aux_detach(struct drm_dp_aux *aux)
	if (err < 0)
		return err;

	if (dpaux->output->panel) {
		enum drm_connector_status status;

		timeout = jiffies + msecs_to_jiffies(250);

		while (time_before(jiffies, timeout)) {
		enum drm_connector_status status;

			status = drm_dp_aux_detect(aux);
		if (status == connector_status_disconnected) {
			dpaux->output = NULL;
			return 0;
		}

			if (status == connector_status_disconnected)
				break;

			usleep_range(1000, 2000);
		}

		if (status != connector_status_disconnected)
			return -ETIMEDOUT;

		dpaux->output = NULL;
	}

	return 0;
}

enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)