<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jul 19, 2021 at 10:29 PM Tim Gardner <<a href="mailto:tim.gardner@canonical.com">tim.gardner@canonical.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Backports of more then simple complexity generally deserve some <br>
explanation. In this case it looks like you've dropped a couple of <br>
functions.<br>
<br></blockquote><div><br></div><div>In the v2 version, I did miss the code of intel_ddi_encoder_suspend and shutdown, so I added them back in v3. In the v3 version, the dropped function which causes unclean cherry-pick is skl_hpd_pin() which is handled by the following commit which does not affect the TGL  models.</div><div><br></div><div>commit c8455098c67914c59d07f01819469e2e6f76f358<br>Author: Lyude Paul <<a href="mailto:lyude@redhat.com">lyude@redhat.com</a>><br>Date:   Tue Feb 9 14:16:28 2021 -0500<br><br>    drm/i915/gen9_bc: Introduce HPD pin mappings for TGP PCH + CML combos<br></div><div><br></div><div>and intel_ddi_is_tc() from the following commit which could cause lots of conflicts but we don't really need it for TGL model.</div><div>commit 36ecb0ec105412aa7e7c89991a7cff90bf90b2f1</div>Author: Ville Syrjälä <<a href="mailto:ville.syrjala@linux.intel.com">ville.syrjala@linux.intel.com</a>><br>Date:   Fri Feb 5 23:46:26 2021 +0200<br><br>    drm/i915: Extract icl+ .{enable,disable}_clock() vfuncs<br>   </div><div class="gmail_quote">Should I explain in the cover letter? Which part would be appropriate? [Fix]? I'll propose a v4 with explanations. Thanks</div><div class="gmail_quote"><br></div><div class="gmail_quote"><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">  </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 7/16/21 2:48 AM, <a href="mailto:chris.chiu@canonical.com" target="_blank">chris.chiu@canonical.com</a> wrote:<br>
> From: Imre Deak <<a href="mailto:imre.deak@intel.com" target="_blank">imre.deak@intel.com</a>><br>
> <br>
> BugLink: <a href="https://bugs.launchpad.net/bugs/1931072" rel="noreferrer" target="_blank">https://bugs.launchpad.net/bugs/1931072</a><br>
> <br>
> Disconnect TypeC PHYs during system suspend and shutdown, even with the<br>
> corresponding TypeC sink still plugged to its connector, since leaving<br>
> the PHY connected causes havoc at least during system resume in the<br>
> presence of an Nvidia card.<br>
> <br>
> Note that this will only make a difference in the TypeC DP alternate<br>
> mode, since in Thunderbolt alternate mode the PHY is never owned by the<br>
> display engine and there is no notion of PHY ownership in legacy mode<br>
> (the display engine being the only possible owner in that mode and the<br>
> TypeC subsystem not having anything to do with the port in that case).<br>
> <br>
> Closes: <a href="https://gitlab.freedesktop.org/drm/intel/-/issues/3500" rel="noreferrer" target="_blank">https://gitlab.freedesktop.org/drm/intel/-/issues/3500</a><br>
> Reported-and-tested-by: Chris Chiu <<a href="mailto:chris.chiu@canonical.com" target="_blank">chris.chiu@canonical.com</a>><br>
> Signed-off-by: Imre Deak <<a href="mailto:imre.deak@intel.com" target="_blank">imre.deak@intel.com</a>><br>
> Reviewed-by: Uma Shankar <<a href="mailto:uma.shankar@intel.com" target="_blank">uma.shankar@intel.com</a>><br>
> Link: <a href="https://patchwork.freedesktop.org/patch/msgid/20210610174223.605904-1-imre.deak@intel.com" rel="noreferrer" target="_blank">https://patchwork.freedesktop.org/patch/msgid/20210610174223.605904-1-imre.deak@intel.com</a><br>
> (backported from commit 151ec347b06a2fb6ecd2922475dca71a7af827a5<br>
> linux-next)<br>
> Signed-off-by: Chris Chiu <<a href="mailto:chris.chiu@canonical.com" target="_blank">chris.chiu@canonical.com</a>><br>
> ---<br>
>   drivers/gpu/drm/i915/display/intel_ddi.c | 34 ++++++++++++++++++++++--<br>
>   drivers/gpu/drm/i915/display/intel_tc.c  | 34 +++++++++++++++++++-----<br>
>   drivers/gpu/drm/i915/display/intel_tc.h  |  2 ++<br>
>   3 files changed, 61 insertions(+), 9 deletions(-)<br>
> <br>
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c<br>
> index cf665636408b..b272da304795 100644<br>
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c<br>
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c<br>
> @@ -5338,6 +5338,36 @@ static enum hpd_pin cnl_hpd_pin(struct drm_i915_private *dev_priv,<br>
>       return HPD_PORT_A + port - PORT_A;<br>
>   }<br>
>   <br>
> +static void intel_ddi_encoder_suspend(struct intel_encoder *encoder)<br>
> +{<br>
> +     struct intel_dp *intel_dp = enc_to_intel_dp(encoder);<br>
> +     struct drm_i915_private *i915 = dp_to_i915(intel_dp);<br>
> +     struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);<br>
> +     enum phy phy = intel_port_to_phy(i915, encoder->port);<br>
> +<br>
> +     intel_dp_encoder_suspend(encoder);<br>
> +<br>
> +     if (!intel_phy_is_tc(i915, phy))<br>
> +             return;<br>
> +<br>
> +     intel_tc_port_disconnect_phy(dig_port);<br>
> +}<br>
> +<br>
> +static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder)<br>
> +{<br>
> +     struct intel_dp *intel_dp = enc_to_intel_dp(encoder);<br>
> +     struct drm_i915_private *i915 = dp_to_i915(intel_dp);<br>
> +     struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);<br>
> +     enum phy phy = intel_port_to_phy(i915, encoder->port);<br>
> +<br>
> +     intel_dp_encoder_shutdown(encoder);<br>
> +<br>
> +     if (!intel_phy_is_tc(i915, phy))<br>
> +             return;<br>
> +<br>
> +     intel_tc_port_disconnect_phy(dig_port);<br>
> +}<br>
> +<br>
>   #define port_tc_name(port) ((port) - PORT_TC1 + '1')<br>
>   #define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1')<br>
>   <br>
> @@ -5432,8 +5462,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)<br>
>       encoder->get_config = intel_ddi_get_config;<br>
>       encoder->sync_state = intel_ddi_sync_state;<br>
>       encoder->initial_fastset_check = intel_ddi_initial_fastset_check;<br>
> -     encoder->suspend = intel_dp_encoder_suspend;<br>
> -     encoder->shutdown = intel_dp_encoder_shutdown;<br>
> +     encoder->suspend = intel_ddi_encoder_suspend;<br>
> +     encoder->shutdown = intel_ddi_encoder_shutdown;<br>
>       encoder->get_power_domains = intel_ddi_get_power_domains;<br>
>   <br>
>       encoder->type = INTEL_OUTPUT_DDI;<br>
> diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c<br>
> index 8b6f16f9d0d1..2f4d7336d76e 100644<br>
> --- a/drivers/gpu/drm/i915/display/intel_tc.c<br>
> +++ b/drivers/gpu/drm/i915/display/intel_tc.c<br>
> @@ -449,7 +449,7 @@ intel_tc_port_get_target_mode(struct intel_digital_port *dig_port)<br>
>   }<br>
>   <br>
>   static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,<br>
> -                                  int required_lanes)<br>
> +                                  int required_lanes, bool force_disconnect)<br>
>   {<br>
>       struct drm_i915_private *i915 = to_i915(dig_port-><a href="http://base.base.dev" rel="noreferrer" target="_blank">base.base.dev</a>);<br>
>       enum tc_port_mode old_tc_mode = dig_port->tc_mode;<br>
> @@ -465,7 +465,8 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,<br>
>       }<br>
>   <br>
>       icl_tc_phy_disconnect(dig_port);<br>
> -     icl_tc_phy_connect(dig_port, required_lanes);<br>
> +     if (!force_disconnect)<br>
> +             icl_tc_phy_connect(dig_port, required_lanes);<br>
>   <br>
>       drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n",<br>
>                   dig_port->tc_port_name,<br>
> @@ -555,7 +556,7 @@ bool intel_tc_port_connected(struct intel_encoder *encoder)<br>
>   }<br>
>   <br>
>   static void __intel_tc_port_lock(struct intel_digital_port *dig_port,<br>
> -                              int required_lanes)<br>
> +                              int required_lanes, bool force_disconnect)<br>
>   {<br>
>       struct drm_i915_private *i915 = to_i915(dig_port-><a href="http://base.base.dev" rel="noreferrer" target="_blank">base.base.dev</a>);<br>
>       intel_wakeref_t wakeref;<br>
> @@ -569,8 +570,9 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,<br>
>   <br>
>               tc_cold_wref = tc_cold_block(dig_port);<br>
>   <br>
> -             if (intel_tc_port_needs_reset(dig_port))<br>
> -                     intel_tc_port_reset_mode(dig_port, required_lanes);<br>
> +             if (force_disconnect || intel_tc_port_needs_reset(dig_port))<br>
> +                     intel_tc_port_reset_mode(dig_port, required_lanes,<br>
> +                                              force_disconnect);<br>
>   <br>
>               tc_cold_unblock(dig_port, tc_cold_wref);<br>
>       }<br>
> @@ -581,7 +583,7 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,<br>
>   <br>
>   void intel_tc_port_lock(struct intel_digital_port *dig_port)<br>
>   {<br>
> -     __intel_tc_port_lock(dig_port, 1);<br>
> +     __intel_tc_port_lock(dig_port, 1, false);<br>
>   }<br>
>   <br>
>   void intel_tc_port_unlock(struct intel_digital_port *dig_port)<br>
> @@ -595,6 +597,24 @@ void intel_tc_port_unlock(struct intel_digital_port *dig_port)<br>
>                                     wakeref);<br>
>   }<br>
>   <br>
> +/**<br>
> + * intel_tc_port_disconnect_phy: disconnect TypeC PHY from display port<br>
> + * @dig_port: digital port<br>
> + *<br>
> + * Disconnect the given digital port from its TypeC PHY (handing back the<br>
> + * control of the PHY to the TypeC subsystem). The only purpose of this<br>
> + * function is to force the disconnect even with a TypeC display output still<br>
> + * plugged to the TypeC connector, which is required by the TypeC firmwares<br>
> + * during system suspend and shutdown. Otherwise - during the unplug event<br>
> + * handling - the PHY ownership is released automatically by<br>
> + * intel_tc_port_reset_mode(), when calling this function is not required.<br>
> + */<br>
> +void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port)<br>
> +{<br>
> +     __intel_tc_port_lock(dig_port, 1, true);<br>
> +     intel_tc_port_unlock(dig_port);<br>
> +}<br>
> +<br>
>   bool intel_tc_port_ref_held(struct intel_digital_port *dig_port)<br>
>   {<br>
>       return mutex_is_locked(&dig_port->tc_lock) ||<br>
> @@ -604,7 +624,7 @@ bool intel_tc_port_ref_held(struct intel_digital_port *dig_port)<br>
>   void intel_tc_port_get_link(struct intel_digital_port *dig_port,<br>
>                           int required_lanes)<br>
>   {<br>
> -     __intel_tc_port_lock(dig_port, required_lanes);<br>
> +     __intel_tc_port_lock(dig_port, required_lanes, false);<br>
>       dig_port->tc_link_refcount++;<br>
>       intel_tc_port_unlock(dig_port);<br>
>   }<br>
> diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h<br>
> index b619e4736f85..57d157fc822f 100644<br>
> --- a/drivers/gpu/drm/i915/display/intel_tc.h<br>
> +++ b/drivers/gpu/drm/i915/display/intel_tc.h<br>
> @@ -13,6 +13,8 @@ struct intel_digital_port;<br>
>   struct intel_encoder;<br>
>   <br>
>   bool intel_tc_port_connected(struct intel_encoder *encoder);<br>
> +void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port);<br>
> +<br>
>   u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port);<br>
>   u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port);<br>
>   int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port);<br>
> <br>
<br>
-- <br>
-----------<br>
Tim Gardner<br>
Canonical, Inc<br>
</blockquote></div></div>