@@ -3589,7 +3589,7 @@ void intel_connector_dpms(struct drm_connector *connector, int mode)
3589
3589
* of the connector. */
3590
3590
bool intel_connector_get_hw_state (struct intel_connector * connector )
3591
3591
{
3592
- enum pipe pipe ;
3592
+ enum pipe pipe = 0 ;
3593
3593
struct intel_encoder * encoder = connector -> encoder ;
3594
3594
3595
3595
return encoder -> get_hw_state (encoder , & pipe );
@@ -6533,65 +6533,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
6533
6533
return ret ;
6534
6534
}
6535
6535
6536
- static void intel_sanitize_modesetting (struct drm_device * dev ,
6537
- int pipe , int plane )
6538
- {
6539
- struct drm_i915_private * dev_priv = dev -> dev_private ;
6540
- u32 reg , val ;
6541
- int i ;
6542
-
6543
- /* Clear any frame start delays used for debugging left by the BIOS */
6544
- for_each_pipe (i ) {
6545
- reg = PIPECONF (i );
6546
- I915_WRITE (reg , I915_READ (reg ) & ~PIPECONF_FRAME_START_DELAY_MASK );
6547
- }
6548
-
6549
- if (HAS_PCH_SPLIT (dev ))
6550
- return ;
6551
-
6552
- /* Who knows what state these registers were left in by the BIOS or
6553
- * grub?
6554
- *
6555
- * If we leave the registers in a conflicting state (e.g. with the
6556
- * display plane reading from the other pipe than the one we intend
6557
- * to use) then when we attempt to teardown the active mode, we will
6558
- * not disable the pipes and planes in the correct order -- leaving
6559
- * a plane reading from a disabled pipe and possibly leading to
6560
- * undefined behaviour.
6561
- */
6562
-
6563
- reg = DSPCNTR (plane );
6564
- val = I915_READ (reg );
6565
-
6566
- if ((val & DISPLAY_PLANE_ENABLE ) == 0 )
6567
- return ;
6568
- if (!!(val & DISPPLANE_SEL_PIPE_MASK ) == pipe )
6569
- return ;
6570
-
6571
- /* This display plane is active and attached to the other CPU pipe. */
6572
- pipe = !pipe ;
6573
-
6574
- /* Disable the plane and wait for it to stop reading from the pipe. */
6575
- intel_disable_plane (dev_priv , plane , pipe );
6576
- intel_disable_pipe (dev_priv , pipe );
6577
- }
6578
-
6579
- static void intel_crtc_reset (struct drm_crtc * crtc )
6580
- {
6581
- struct drm_device * dev = crtc -> dev ;
6582
- struct intel_crtc * intel_crtc = to_intel_crtc (crtc );
6583
-
6584
- /* Reset flags back to the 'unknown' status so that they
6585
- * will be correctly set on the initial modeset.
6586
- */
6587
- intel_crtc -> dpms_mode = -1 ;
6588
-
6589
- /* We need to fix up any BIOS configuration that conflicts with
6590
- * our expectations.
6591
- */
6592
- intel_sanitize_modesetting (dev , intel_crtc -> pipe , intel_crtc -> plane );
6593
- }
6594
-
6595
6536
static struct drm_crtc_helper_funcs intel_helper_funcs = {
6596
6537
.mode_set_base_atomic = intel_pipe_set_base_atomic ,
6597
6538
.load_lut = intel_crtc_load_lut ,
@@ -7006,7 +6947,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
7006
6947
}
7007
6948
7008
6949
static const struct drm_crtc_funcs intel_crtc_funcs = {
7009
- .reset = intel_crtc_reset ,
7010
6950
.cursor_set = intel_crtc_cursor_set ,
7011
6951
.cursor_move = intel_crtc_cursor_move ,
7012
6952
.gamma_set = intel_crtc_gamma_set ,
@@ -7064,8 +7004,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
7064
7004
dev_priv -> plane_to_crtc_mapping [intel_crtc -> plane ] = & intel_crtc -> base ;
7065
7005
dev_priv -> pipe_to_crtc_mapping [intel_crtc -> pipe ] = & intel_crtc -> base ;
7066
7006
7067
- intel_crtc_reset (& intel_crtc -> base );
7068
- intel_crtc -> active = true; /* force the pipe off on setup_init_config */
7069
7007
intel_crtc -> bpp = 24 ; /* default for pre-Ironlake */
7070
7008
7071
7009
drm_crtc_helper_add (& intel_crtc -> base , & intel_helper_funcs );
@@ -7273,9 +7211,6 @@ static void intel_setup_outputs(struct drm_device *dev)
7273
7211
intel_encoder_clones (encoder );
7274
7212
}
7275
7213
7276
- /* disable all the possible outputs/crtcs before entering KMS mode */
7277
- drm_helper_disable_unused_functions (dev );
7278
-
7279
7214
if (HAS_PCH_IBX (dev ) || HAS_PCH_CPT (dev ))
7280
7215
ironlake_init_pch_refclk (dev );
7281
7216
}
@@ -7634,11 +7569,222 @@ void intel_modeset_init(struct drm_device *dev)
7634
7569
intel_setup_outputs (dev );
7635
7570
}
7636
7571
7572
+ static void
7573
+ intel_connector_break_all_links (struct intel_connector * connector )
7574
+ {
7575
+ connector -> base .dpms = DRM_MODE_DPMS_OFF ;
7576
+ connector -> base .encoder = NULL ;
7577
+ connector -> encoder -> connectors_active = false;
7578
+ connector -> encoder -> base .crtc = NULL ;
7579
+ }
7580
+
7581
+ static void intel_sanitize_crtc (struct intel_crtc * crtc )
7582
+ {
7583
+ struct drm_device * dev = crtc -> base .dev ;
7584
+ struct drm_i915_private * dev_priv = dev -> dev_private ;
7585
+ u32 reg , val ;
7586
+
7587
+ /* Clear the dpms state for compatibility with code still using that
7588
+ * deprecated state variable. */
7589
+ crtc -> dpms_mode = -1 ;
7590
+
7591
+ /* Clear any frame start delays used for debugging left by the BIOS */
7592
+ reg = PIPECONF (crtc -> pipe );
7593
+ I915_WRITE (reg , I915_READ (reg ) & ~PIPECONF_FRAME_START_DELAY_MASK );
7594
+
7595
+ /* We need to sanitize the plane -> pipe mapping first because this will
7596
+ * disable the crtc (and hence change the state) if it is wrong. */
7597
+ if (!HAS_PCH_SPLIT (dev )) {
7598
+ struct intel_connector * connector ;
7599
+ bool plane ;
7600
+
7601
+ reg = DSPCNTR (crtc -> plane );
7602
+ val = I915_READ (reg );
7603
+
7604
+ if ((val & DISPLAY_PLANE_ENABLE ) == 0 &&
7605
+ (!!(val & DISPPLANE_SEL_PIPE_MASK ) == crtc -> pipe ))
7606
+ goto ok ;
7607
+
7608
+ DRM_DEBUG_KMS ("[CRTC:%d] wrong plane connection detected!\n" ,
7609
+ crtc -> base .base .id );
7610
+
7611
+ /* Pipe has the wrong plane attached and the plane is active.
7612
+ * Temporarily change the plane mapping and disable everything
7613
+ * ... */
7614
+ plane = crtc -> plane ;
7615
+ crtc -> plane = !plane ;
7616
+ dev_priv -> display .crtc_disable (& crtc -> base );
7617
+ crtc -> plane = plane ;
7618
+
7619
+ /* ... and break all links. */
7620
+ list_for_each_entry (connector , & dev -> mode_config .connector_list ,
7621
+ base .head ) {
7622
+ if (connector -> encoder -> base .crtc != & crtc -> base )
7623
+ continue ;
7624
+
7625
+ intel_connector_break_all_links (connector );
7626
+ }
7627
+
7628
+ WARN_ON (crtc -> active );
7629
+ crtc -> base .enabled = false;
7630
+ }
7631
+ ok :
7632
+
7633
+ /* Adjust the state of the output pipe according to whether we
7634
+ * have active connectors/encoders. */
7635
+ intel_crtc_update_dpms (& crtc -> base );
7636
+
7637
+ if (crtc -> active != crtc -> base .enabled ) {
7638
+ struct intel_encoder * encoder ;
7639
+
7640
+ /* This can happen either due to bugs in the get_hw_state
7641
+ * functions or because the pipe is force-enabled due to the
7642
+ * pipe A quirk. */
7643
+ DRM_DEBUG_KMS ("[CRTC:%d] hw state adjusted, was %s, now %s\n" ,
7644
+ crtc -> base .base .id ,
7645
+ crtc -> base .enabled ? "enabled" : "disabled" ,
7646
+ crtc -> active ? "enabled" : "disabled" );
7647
+
7648
+ crtc -> base .enabled = crtc -> active ;
7649
+
7650
+ /* Because we only establish the connector -> encoder ->
7651
+ * crtc links if something is active, this means the
7652
+ * crtc is now deactivated. Break the links. connector
7653
+ * -> encoder links are only establish when things are
7654
+ * actually up, hence no need to break them. */
7655
+ WARN_ON (crtc -> active );
7656
+
7657
+ for_each_encoder_on_crtc (dev , & crtc -> base , encoder ) {
7658
+ WARN_ON (encoder -> connectors_active );
7659
+ encoder -> base .crtc = NULL ;
7660
+ }
7661
+ }
7662
+ }
7663
+
7664
+ static void intel_sanitize_encoder (struct intel_encoder * encoder )
7665
+ {
7666
+ struct intel_connector * connector ;
7667
+ struct drm_device * dev = encoder -> base .dev ;
7668
+
7669
+ /* We need to check both for a crtc link (meaning that the
7670
+ * encoder is active and trying to read from a pipe) and the
7671
+ * pipe itself being active. */
7672
+ bool has_active_crtc = encoder -> base .crtc &&
7673
+ to_intel_crtc (encoder -> base .crtc )-> active ;
7674
+
7675
+ if (encoder -> connectors_active && !has_active_crtc ) {
7676
+ DRM_DEBUG_KMS ("[ENCODER:%d:%s] has active connectors but no active pipe!\n" ,
7677
+ encoder -> base .base .id ,
7678
+ drm_get_encoder_name (& encoder -> base ));
7679
+
7680
+ /* Connector is active, but has no active pipe. This is
7681
+ * fallout from our resume register restoring. Disable
7682
+ * the encoder manually again. */
7683
+ if (encoder -> base .crtc ) {
7684
+ DRM_DEBUG_KMS ("[ENCODER:%d:%s] manually disabled\n" ,
7685
+ encoder -> base .base .id ,
7686
+ drm_get_encoder_name (& encoder -> base ));
7687
+ encoder -> disable (encoder );
7688
+ }
7689
+
7690
+ /* Inconsistent output/port/pipe state happens presumably due to
7691
+ * a bug in one of the get_hw_state functions. Or someplace else
7692
+ * in our code, like the register restore mess on resume. Clamp
7693
+ * things to off as a safer default. */
7694
+ list_for_each_entry (connector ,
7695
+ & dev -> mode_config .connector_list ,
7696
+ base .head ) {
7697
+ if (connector -> encoder != encoder )
7698
+ continue ;
7699
+
7700
+ intel_connector_break_all_links (connector );
7701
+ }
7702
+ }
7703
+ /* Enabled encoders without active connectors will be fixed in
7704
+ * the crtc fixup. */
7705
+ }
7706
+
7707
+ /* Scan out the current hw modeset state, sanitizes it and maps it into the drm
7708
+ * and i915 state tracking structures. */
7709
+ void intel_modeset_setup_hw_state (struct drm_device * dev )
7710
+ {
7711
+ struct drm_i915_private * dev_priv = dev -> dev_private ;
7712
+ enum pipe pipe ;
7713
+ u32 tmp ;
7714
+ struct intel_crtc * crtc ;
7715
+ struct intel_encoder * encoder ;
7716
+ struct intel_connector * connector ;
7717
+
7718
+ for_each_pipe (pipe ) {
7719
+ crtc = to_intel_crtc (dev_priv -> pipe_to_crtc_mapping [pipe ]);
7720
+
7721
+ tmp = I915_READ (PIPECONF (pipe ));
7722
+ if (tmp & PIPECONF_ENABLE )
7723
+ crtc -> active = true;
7724
+ else
7725
+ crtc -> active = false;
7726
+
7727
+ crtc -> base .enabled = crtc -> active ;
7728
+
7729
+ DRM_DEBUG_KMS ("[CRTC:%d] hw state readout: %s\n" ,
7730
+ crtc -> base .base .id ,
7731
+ crtc -> active ? "enabled" : "disabled" );
7732
+ }
7733
+
7734
+ list_for_each_entry (encoder , & dev -> mode_config .encoder_list ,
7735
+ base .head ) {
7736
+ pipe = 0 ;
7737
+
7738
+ if (encoder -> get_hw_state (encoder , & pipe )) {
7739
+ encoder -> base .crtc =
7740
+ dev_priv -> pipe_to_crtc_mapping [pipe ];
7741
+ } else {
7742
+ encoder -> base .crtc = NULL ;
7743
+ }
7744
+
7745
+ encoder -> connectors_active = false;
7746
+ DRM_DEBUG_KMS ("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n" ,
7747
+ encoder -> base .base .id ,
7748
+ drm_get_encoder_name (& encoder -> base ),
7749
+ encoder -> base .crtc ? "enabled" : "disabled" ,
7750
+ pipe );
7751
+ }
7752
+
7753
+ list_for_each_entry (connector , & dev -> mode_config .connector_list ,
7754
+ base .head ) {
7755
+ if (connector -> get_hw_state (connector )) {
7756
+ connector -> base .dpms = DRM_MODE_DPMS_ON ;
7757
+ connector -> encoder -> connectors_active = true;
7758
+ connector -> base .encoder = & connector -> encoder -> base ;
7759
+ } else {
7760
+ connector -> base .dpms = DRM_MODE_DPMS_OFF ;
7761
+ connector -> base .encoder = NULL ;
7762
+ }
7763
+ DRM_DEBUG_KMS ("[CONNECTOR:%d:%s] hw state readout: %s\n" ,
7764
+ connector -> base .base .id ,
7765
+ drm_get_connector_name (& connector -> base ),
7766
+ connector -> base .encoder ? "enabled" : "disabled" );
7767
+ }
7768
+
7769
+ /* HW state is read out, now we need to sanitize this mess. */
7770
+ list_for_each_entry (encoder , & dev -> mode_config .encoder_list ,
7771
+ base .head ) {
7772
+ intel_sanitize_encoder (encoder );
7773
+ }
7774
+
7775
+ for_each_pipe (pipe ) {
7776
+ crtc = to_intel_crtc (dev_priv -> pipe_to_crtc_mapping [pipe ]);
7777
+ intel_sanitize_crtc (crtc );
7778
+ }
7779
+ }
7780
+
7637
7781
void intel_modeset_gem_init (struct drm_device * dev )
7638
7782
{
7639
7783
intel_modeset_init_hw (dev );
7640
7784
7641
7785
intel_setup_overlay (dev );
7786
+
7787
+ intel_modeset_setup_hw_state (dev );
7642
7788
}
7643
7789
7644
7790
void intel_modeset_cleanup (struct drm_device * dev )
0 commit comments