diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-09 18:51:02 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-09-13 06:29:11 -0400 |
commit | 7b334fcb45b757ffb093696ca3de1b0c8b4a33f1 (patch) | |
tree | fe56259639b9f1c993d742e27468087c46e51f05 /drivers/gpu/drm/i915 | |
parent | 27849044ca6ff9c52f63271b511282acf6d1c251 (diff) |
drm: Use a nondestructive mode for output detect when polling
Destructive load-detection is very expensive and due to failings
elsewhere can trigger system wide stalls of up to 600ms. A simple
first step to correcting this is not to invoke such an expensive
and destructive load-detection operation automatically.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29536
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16265
Reported-by: Bruno Prémont <bonbons@linux-vserver.org>
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 12 |
7 files changed, 29 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4b7735196cd5..0350e5d711f8 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -400,7 +400,9 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
400 | return status; | 400 | return status; |
401 | } | 401 | } |
402 | 402 | ||
403 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) | 403 | static enum drm_connector_status |
404 | intel_crt_detect(struct drm_connector *connector, | ||
405 | bool nondestructive) | ||
404 | { | 406 | { |
405 | struct drm_device *dev = connector->dev; | 407 | struct drm_device *dev = connector->dev; |
406 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 408 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
@@ -419,6 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
419 | if (intel_crt_detect_ddc(encoder)) | 421 | if (intel_crt_detect_ddc(encoder)) |
420 | return connector_status_connected; | 422 | return connector_status_connected; |
421 | 423 | ||
424 | if (nondestructive) | ||
425 | return connector->status; | ||
426 | |||
422 | /* for pre-945g platforms use load detect */ | 427 | /* for pre-945g platforms use load detect */ |
423 | if (encoder->crtc && encoder->crtc->enabled) { | 428 | if (encoder->crtc && encoder->crtc->enabled) { |
424 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); | 429 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 51d142939a26..e1a2a05fb838 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1386,7 +1386,8 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1386 | * \return false if DP port is disconnected. | 1386 | * \return false if DP port is disconnected. |
1387 | */ | 1387 | */ |
1388 | static enum drm_connector_status | 1388 | static enum drm_connector_status |
1389 | intel_dp_detect(struct drm_connector *connector) | 1389 | intel_dp_detect(struct drm_connector *connector, |
1390 | bool nondestructive) | ||
1390 | { | 1391 | { |
1391 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1392 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1392 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1393 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a399f4b2c1c5..f0de1addf8a4 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -221,7 +221,9 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
221 | * | 221 | * |
222 | * Unimplemented. | 222 | * Unimplemented. |
223 | */ | 223 | */ |
224 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 224 | static enum drm_connector_status |
225 | intel_dvo_detect(struct drm_connector *connector, | ||
226 | bool nondestructive) | ||
225 | { | 227 | { |
226 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 228 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
227 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | 229 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index ccd4c97e6524..2ea123d8d22b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -139,7 +139,8 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | static enum drm_connector_status | 141 | static enum drm_connector_status |
142 | intel_hdmi_detect(struct drm_connector *connector) | 142 | intel_hdmi_detect(struct drm_connector *connector, |
143 | bool nondestructive) | ||
143 | { | 144 | { |
144 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 145 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 146 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4fbb0165b26f..fb1bed8f4071 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -445,7 +445,9 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
445 | * connected and closed means disconnected. We also send hotplug events as | 445 | * connected and closed means disconnected. We also send hotplug events as |
446 | * needed, using lid status notification from the input layer. | 446 | * needed, using lid status notification from the input layer. |
447 | */ | 447 | */ |
448 | static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) | 448 | static enum drm_connector_status |
449 | intel_lvds_detect(struct drm_connector *connector, | ||
450 | bool nondestructive) | ||
449 | { | 451 | { |
450 | struct drm_device *dev = connector->dev; | 452 | struct drm_device *dev = connector->dev; |
451 | enum drm_connector_status status = connector_status_connected; | 453 | enum drm_connector_status status = connector_status_connected; |
@@ -540,7 +542,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
540 | * the LID nofication event. | 542 | * the LID nofication event. |
541 | */ | 543 | */ |
542 | if (connector) | 544 | if (connector) |
543 | connector->status = connector->funcs->detect(connector); | 545 | connector->status = connector->funcs->detect(connector, |
546 | true); | ||
547 | |||
544 | /* Don't force modeset on machines where it causes a GPU lockup */ | 548 | /* Don't force modeset on machines where it causes a GPU lockup */ |
545 | if (dmi_check_system(intel_no_modeset_on_lid)) | 549 | if (dmi_check_system(intel_no_modeset_on_lid)) |
546 | return NOTIFY_OK; | 550 | return NOTIFY_OK; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e3b7a7ee39cb..db6b6d4b8fae 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1417,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1417 | if (!analog_connector) | 1417 | if (!analog_connector) |
1418 | return false; | 1418 | return false; |
1419 | 1419 | ||
1420 | if (analog_connector->funcs->detect(analog_connector) == | 1420 | if (analog_connector->funcs->detect(analog_connector, true) == |
1421 | connector_status_disconnected) | 1421 | connector_status_disconnected) |
1422 | return false; | 1422 | return false; |
1423 | 1423 | ||
@@ -1486,7 +1486,9 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1486 | return status; | 1486 | return status; |
1487 | } | 1487 | } |
1488 | 1488 | ||
1489 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1489 | static enum drm_connector_status |
1490 | intel_sdvo_detect(struct drm_connector *connector, | ||
1491 | bool nondestructive) | ||
1490 | { | 1492 | { |
1491 | uint16_t response; | 1493 | uint16_t response; |
1492 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1494 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index c671f60ce80b..d20b550c0f55 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1341,7 +1341,8 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1341 | * we have a pipe programmed in order to probe the TV. | 1341 | * we have a pipe programmed in order to probe the TV. |
1342 | */ | 1342 | */ |
1343 | static enum drm_connector_status | 1343 | static enum drm_connector_status |
1344 | intel_tv_detect(struct drm_connector *connector) | 1344 | intel_tv_detect(struct drm_connector *connector, |
1345 | bool nondestructive) | ||
1345 | { | 1346 | { |
1346 | struct drm_display_mode mode; | 1347 | struct drm_display_mode mode; |
1347 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1348 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
@@ -1353,7 +1354,7 @@ intel_tv_detect(struct drm_connector *connector) | |||
1353 | 1354 | ||
1354 | if (encoder->crtc && encoder->crtc->enabled) { | 1355 | if (encoder->crtc && encoder->crtc->enabled) { |
1355 | type = intel_tv_detect_type(intel_tv); | 1356 | type = intel_tv_detect_type(intel_tv); |
1356 | } else { | 1357 | } else if (nondestructive) { |
1357 | struct drm_crtc *crtc; | 1358 | struct drm_crtc *crtc; |
1358 | int dpms_mode; | 1359 | int dpms_mode; |
1359 | 1360 | ||
@@ -1364,10 +1365,9 @@ intel_tv_detect(struct drm_connector *connector) | |||
1364 | intel_release_load_detect_pipe(&intel_tv->base, connector, | 1365 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
1365 | dpms_mode); | 1366 | dpms_mode); |
1366 | } else | 1367 | } else |
1367 | type = -1; | 1368 | return connector_status_unknown; |
1368 | } | 1369 | } else |
1369 | 1370 | return connector->status; | |
1370 | intel_tv->type = type; | ||
1371 | 1371 | ||
1372 | if (type < 0) | 1372 | if (type < 0) |
1373 | return connector_status_disconnected; | 1373 | return connector_status_disconnected; |