diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3da9c0f9e948..248128126422 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -15415,16 +15415,45 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc, | |||
15415 | } | 15415 | } |
15416 | } | 15416 | } |
15417 | 15417 | ||
15418 | static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state) | ||
15419 | { | ||
15420 | struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); | ||
15421 | |||
15422 | /* | ||
15423 | * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram | ||
15424 | * the hardware when a high res displays plugged in. DPLL P | ||
15425 | * divider is zero, and the pipe timings are bonkers. We'll | ||
15426 | * try to disable everything in that case. | ||
15427 | * | ||
15428 | * FIXME would be nice to be able to sanitize this state | ||
15429 | * without several WARNs, but for now let's take the easy | ||
15430 | * road. | ||
15431 | */ | ||
15432 | return IS_GEN6(dev_priv) && | ||
15433 | crtc_state->base.active && | ||
15434 | crtc_state->shared_dpll && | ||
15435 | crtc_state->port_clock == 0; | ||
15436 | } | ||
15437 | |||
15418 | static void intel_sanitize_encoder(struct intel_encoder *encoder) | 15438 | static void intel_sanitize_encoder(struct intel_encoder *encoder) |
15419 | { | 15439 | { |
15420 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 15440 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
15421 | struct intel_connector *connector; | 15441 | struct intel_connector *connector; |
15442 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | ||
15443 | struct intel_crtc_state *crtc_state = crtc ? | ||
15444 | to_intel_crtc_state(crtc->base.state) : NULL; | ||
15422 | 15445 | ||
15423 | /* We need to check both for a crtc link (meaning that the | 15446 | /* We need to check both for a crtc link (meaning that the |
15424 | * encoder is active and trying to read from a pipe) and the | 15447 | * encoder is active and trying to read from a pipe) and the |
15425 | * pipe itself being active. */ | 15448 | * pipe itself being active. */ |
15426 | bool has_active_crtc = encoder->base.crtc && | 15449 | bool has_active_crtc = crtc_state && |
15427 | to_intel_crtc(encoder->base.crtc)->active; | 15450 | crtc_state->base.active; |
15451 | |||
15452 | if (crtc_state && has_bogus_dpll_config(crtc_state)) { | ||
15453 | DRM_DEBUG_KMS("BIOS has misprogrammed the hardware. Disabling pipe %c\n", | ||
15454 | pipe_name(crtc->pipe)); | ||
15455 | has_active_crtc = false; | ||
15456 | } | ||
15428 | 15457 | ||
15429 | connector = intel_encoder_find_connector(encoder); | 15458 | connector = intel_encoder_find_connector(encoder); |
15430 | if (connector && !has_active_crtc) { | 15459 | if (connector && !has_active_crtc) { |
@@ -15435,16 +15464,25 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
15435 | /* Connector is active, but has no active pipe. This is | 15464 | /* Connector is active, but has no active pipe. This is |
15436 | * fallout from our resume register restoring. Disable | 15465 | * fallout from our resume register restoring. Disable |
15437 | * the encoder manually again. */ | 15466 | * the encoder manually again. */ |
15438 | if (encoder->base.crtc) { | 15467 | if (crtc_state) { |
15439 | struct drm_crtc_state *crtc_state = encoder->base.crtc->state; | 15468 | struct drm_encoder *best_encoder; |
15440 | 15469 | ||
15441 | DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", | 15470 | DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", |
15442 | encoder->base.base.id, | 15471 | encoder->base.base.id, |
15443 | encoder->base.name); | 15472 | encoder->base.name); |
15473 | |||
15474 | /* avoid oopsing in case the hooks consult best_encoder */ | ||
15475 | best_encoder = connector->base.state->best_encoder; | ||
15476 | connector->base.state->best_encoder = &encoder->base; | ||
15477 | |||
15444 | if (encoder->disable) | 15478 | if (encoder->disable) |
15445 | encoder->disable(encoder, to_intel_crtc_state(crtc_state), connector->base.state); | 15479 | encoder->disable(encoder, crtc_state, |
15480 | connector->base.state); | ||
15446 | if (encoder->post_disable) | 15481 | if (encoder->post_disable) |
15447 | encoder->post_disable(encoder, to_intel_crtc_state(crtc_state), connector->base.state); | 15482 | encoder->post_disable(encoder, crtc_state, |
15483 | connector->base.state); | ||
15484 | |||
15485 | connector->base.state->best_encoder = best_encoder; | ||
15448 | } | 15486 | } |
15449 | encoder->base.crtc = NULL; | 15487 | encoder->base.crtc = NULL; |
15450 | 15488 | ||