@@ -848,34 +848,71 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
848
848
}
849
849
850
850
static enum intel_display_power_domain
851
- intel_ddi_main_link_aux_domain (struct intel_digital_port * dig_port )
851
+ intel_ddi_main_link_aux_domain (struct intel_digital_port * dig_port ,
852
+ const struct intel_crtc_state * crtc_state )
852
853
{
853
854
struct drm_i915_private * i915 = to_i915 (dig_port -> base .base .dev );
855
+ enum phy phy = intel_port_to_phy (i915 , dig_port -> base .port );
854
856
855
- /* ICL+ HW requires corresponding AUX IOs to be powered up for PSR with
857
+ /*
858
+ * ICL+ HW requires corresponding AUX IOs to be powered up for PSR with
856
859
* DC states enabled at the same time, while for driver initiated AUX
857
860
* transfers we need the same AUX IOs to be powered but with DC states
858
- * disabled. Accordingly use the AUX power domain here which leaves DC
859
- * states enabled.
860
- * However, for non-A AUX ports the corresponding non-EDP transcoders
861
- * would have already enabled power well 2 and DC_OFF. This means we can
862
- * acquire a wider POWER_DOMAIN_AUX_{B,C,D,F} reference instead of a
863
- * specific AUX_IO reference without powering up any extra wells.
864
- * Note that PSR is enabled only on Port A even though this function
865
- * returns the correct domain for other ports too .
861
+ * disabled. Accordingly use the AUX_IO_<port> power domain here which
862
+ * leaves DC states enabled.
863
+ *
864
+ * Before MTL TypeC PHYs (in all TypeC modes and both DP/HDMI) also require
865
+ * AUX IO to be enabled, but all these require DC_OFF to be enabled as
866
+ * well, so we can acquire a wider AUX_<port> power domain reference
867
+ * instead of a specific AUX_IO_<port> reference without powering up any
868
+ * extra wells .
866
869
*/
867
870
if (intel_encoder_can_psr (& dig_port -> base ))
868
871
return intel_display_power_aux_io_domain (i915 , dig_port -> aux_ch );
869
- else
872
+ else if (intel_crtc_has_dp_encoder (crtc_state ) ||
873
+ intel_phy_is_tc (i915 , phy ))
870
874
return intel_aux_power_domain (dig_port );
875
+ else
876
+ return POWER_DOMAIN_INVALID ;
877
+ }
878
+
879
+ static void
880
+ main_link_aux_power_domain_get (struct intel_digital_port * dig_port ,
881
+ const struct intel_crtc_state * crtc_state )
882
+ {
883
+ struct drm_i915_private * i915 = to_i915 (dig_port -> base .base .dev );
884
+ enum intel_display_power_domain domain =
885
+ intel_ddi_main_link_aux_domain (dig_port , crtc_state );
886
+
887
+ drm_WARN_ON (& i915 -> drm , dig_port -> aux_wakeref );
888
+
889
+ if (domain == POWER_DOMAIN_INVALID )
890
+ return ;
891
+
892
+ dig_port -> aux_wakeref = intel_display_power_get (i915 , domain );
893
+ }
894
+
895
+ static void
896
+ main_link_aux_power_domain_put (struct intel_digital_port * dig_port ,
897
+ const struct intel_crtc_state * crtc_state )
898
+ {
899
+ struct drm_i915_private * i915 = to_i915 (dig_port -> base .base .dev );
900
+ enum intel_display_power_domain domain =
901
+ intel_ddi_main_link_aux_domain (dig_port , crtc_state );
902
+ intel_wakeref_t wf ;
903
+
904
+ wf = fetch_and_zero (& dig_port -> aux_wakeref );
905
+ if (!wf )
906
+ return ;
907
+
908
+ intel_display_power_put (i915 , domain , wf );
871
909
}
872
910
873
911
static void intel_ddi_get_power_domains (struct intel_encoder * encoder ,
874
912
struct intel_crtc_state * crtc_state )
875
913
{
876
914
struct drm_i915_private * dev_priv = to_i915 (encoder -> base .dev );
877
915
struct intel_digital_port * dig_port ;
878
- enum phy phy = intel_port_to_phy (dev_priv , encoder -> port );
879
916
880
917
/*
881
918
* TODO: Add support for MST encoders. Atm, the following should never
@@ -894,17 +931,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
894
931
dig_port -> ddi_io_power_domain );
895
932
}
896
933
897
- /*
898
- * AUX power is only needed for (e)DP mode, and for HDMI mode on TC
899
- * ports.
900
- */
901
- if (intel_crtc_has_dp_encoder (crtc_state ) ||
902
- intel_phy_is_tc (dev_priv , phy )) {
903
- drm_WARN_ON (& dev_priv -> drm , dig_port -> aux_wakeref );
904
- dig_port -> aux_wakeref =
905
- intel_display_power_get (dev_priv ,
906
- intel_ddi_main_link_aux_domain (dig_port ));
907
- }
934
+ main_link_aux_power_domain_get (dig_port , crtc_state );
908
935
}
909
936
910
937
void intel_ddi_enable_pipe_clock (struct intel_encoder * encoder ,
@@ -2743,10 +2770,7 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
2743
2770
intel_ddi_post_disable_dp (state , encoder , old_crtc_state ,
2744
2771
old_conn_state );
2745
2772
2746
- if (intel_crtc_has_dp_encoder (old_crtc_state ) || is_tc_port )
2747
- intel_display_power_put (dev_priv ,
2748
- intel_ddi_main_link_aux_domain (dig_port ),
2749
- fetch_and_zero (& dig_port -> aux_wakeref ));
2773
+ main_link_aux_power_domain_put (dig_port , old_crtc_state );
2750
2774
2751
2775
if (is_tc_port )
2752
2776
intel_tc_port_put_link (dig_port );
@@ -3067,12 +3091,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
3067
3091
if (is_tc_port )
3068
3092
intel_tc_port_get_link (dig_port , crtc_state -> lane_count );
3069
3093
3070
- if (intel_crtc_has_dp_encoder (crtc_state ) || is_tc_port ) {
3071
- drm_WARN_ON (& dev_priv -> drm , dig_port -> aux_wakeref );
3072
- dig_port -> aux_wakeref =
3073
- intel_display_power_get (dev_priv ,
3074
- intel_ddi_main_link_aux_domain (dig_port ));
3075
- }
3094
+ main_link_aux_power_domain_get (dig_port , crtc_state );
3076
3095
3077
3096
if (is_tc_port && !intel_tc_port_in_tbt_alt_mode (dig_port ))
3078
3097
/*
0 commit comments