Skip to content

Commit 637c7aa

Browse files
committed
drm/i915: Factor out function to get/put AUX_IO power for main link
Factor out functions to get/put the AUX_IO power domain for the main link on DDI ports. While at it clarify the corresponding code comment. No functional change. v2: - s/(get/put)_aux_power_for_main_link/main_link_aux_power_domain_(get/put) (Jani) - Clarify in the code comment that AUX_IO is needed only by TypeC besides eDP/PSR. v3: - Rebased on checking intel_encoder_can_psr() instead of crtc->has_psr. v4: - Don't call fetch_and_zero() with side-effect during variable declaration. (Ville) Cc: Jani Nikula <[email protected]> Cc: Ville Syrjälä <[email protected]> Signed-off-by: Imre Deak <[email protected]> Reviewed-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 406a95d commit 637c7aa

File tree

1 file changed

+52
-33
lines changed

1 file changed

+52
-33
lines changed

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -848,34 +848,71 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
848848
}
849849

850850
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)
852853
{
853854
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);
854856

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
856859
* DC states enabled at the same time, while for driver initiated AUX
857860
* 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.
866869
*/
867870
if (intel_encoder_can_psr(&dig_port->base))
868871
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))
870874
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);
871909
}
872910

873911
static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
874912
struct intel_crtc_state *crtc_state)
875913
{
876914
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
877915
struct intel_digital_port *dig_port;
878-
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
879916

880917
/*
881918
* 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,
894931
dig_port->ddi_io_power_domain);
895932
}
896933

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);
908935
}
909936

910937
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,
27432770
intel_ddi_post_disable_dp(state, encoder, old_crtc_state,
27442771
old_conn_state);
27452772

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);
27502774

27512775
if (is_tc_port)
27522776
intel_tc_port_put_link(dig_port);
@@ -3067,12 +3091,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
30673091
if (is_tc_port)
30683092
intel_tc_port_get_link(dig_port, crtc_state->lane_count);
30693093

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);
30763095

30773096
if (is_tc_port && !intel_tc_port_in_tbt_alt_mode(dig_port))
30783097
/*

0 commit comments

Comments
 (0)