@@ -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
15438
static void intel_sanitize_encoder (struct intel_encoder * encoder )
15419
15439
{
15420
15440
struct drm_i915_private * dev_priv = to_i915 (encoder -> base .dev );
15421
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
15446
/* We need to check both for a crtc link (meaning that the
15424
15447
* encoder is active and trying to read from a pipe) and the
15425
15448
* pipe itself being active. */
15426
- bool has_active_crtc = encoder -> base .crtc &&
15427
- to_intel_crtc (encoder -> base .crtc )-> active ;
15449
+ bool has_active_crtc = crtc_state &&
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
15458
connector = intel_encoder_find_connector (encoder );
15430
15459
if (connector && !has_active_crtc ) {
@@ -15435,16 +15464,25 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
15435
15464
/* Connector is active, but has no active pipe. This is
15436
15465
* fallout from our resume register restoring. Disable
15437
15466
* the encoder manually again. */
15438
- if (encoder -> base . crtc ) {
15439
- struct drm_crtc_state * crtc_state = encoder -> base . crtc -> state ;
15467
+ if (crtc_state ) {
15468
+ struct drm_encoder * best_encoder ;
15440
15469
15441
15470
DRM_DEBUG_KMS ("[ENCODER:%d:%s] manually disabled\n" ,
15442
15471
encoder -> base .base .id ,
15443
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
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
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
15487
encoder -> base .crtc = NULL ;
15450
15488
0 commit comments