All of lore.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: "José Roberto de Souza" <jose.souza@intel.com>
Cc: Cooper Chiou <cooper.chiou@intel.com>,
	intel-gfx@lists.freedesktop.org,
	Kai-Heng Feng <kai.heng.feng@canonical.com>
Subject: Re: [Intel-gfx] [PATCH v4 4/9] drm/i915/tc/icl: Implement TC cold sequences
Date: Tue, 14 Apr 2020 20:31:26 +0300	[thread overview]
Message-ID: <20200414173126.GA5942@ideak-desk.fi.intel.com> (raw)
In-Reply-To: <20200413164515.13355-4-jose.souza@intel.com>

On Mon, Apr 13, 2020 at 09:45:10AM -0700, José Roberto de Souza wrote:
> This is required for legacy/static TC ports as IOM is not aware of
> the connection and will not trigger the TC cold exit.
> 
> Just request PCODE to exit TCCOLD is not enough as it could enter
> again before driver makes use of the port, to prevent it BSpec states
> that aux powerwell should be held.
> 
> So here embedding the TC cold exit sequence into ICL aux enable,
> it will enable aux and then request TC cold to exit.
> 
> The TC cold block(exit and aux hold) and unblock was added to some
> exported TC functions for the others and to access PHY registers,
> callers should enable and keep aux powerwell enabled during access.
> 
> Also adding TC cold check and warnig in tc_port_load_fia_params() as
> at this point of the driver initialization we can't request power
> wells, if we get this warning we will need to figure out how to handle
> it.
> 
> v2:
> - moved ICL TC cold exit function to intel_display_power
> - using dig_port->tc_legacy_port to only execute sequences for legacy
> ports, hopefully VBTs will have this right
> - fixed check to call _hsw_power_well_continue_enable()
> - calling _hsw_power_well_continue_enable() unconditionally in
> icl_tc_phy_aux_power_well_enable(), if needed we will surpress timeout
> warnings of TC legacy ports
> - only blocking TC cold around fia access
> 
> v3:
> - added timeout of 5msec to not loop forever if
> sandybridge_pcode_write_timeout() keeps returning -EAGAIN
> returning -EAGAIN in in icl_tc_cold_exit()
> - removed leftover tc_cold_wakeref
> - added one msec sleep when PCODE returns -EAGAIN
> 
> v4:
> - removed 5msec timeout, instead giving 1msec to whoever is using
> PCODE to finish it up to 3 times
> - added a comment about turn TC cold exit failure as a error in future
> 
> BSpec: 21750
> Fixes: https://gitlab.freedesktop.org/drm/intel/issues/1296
> Cc: Imre Deak <imre.deak@intel.com>
> Cc: Cooper Chiou <cooper.chiou@intel.com>
> Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Signed-off-by: José Roberto de Souza <jose.souza@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  .../drm/i915/display/intel_display_power.c    | 25 +++++++-
>  drivers/gpu/drm/i915/display/intel_tc.c       | 64 +++++++++++++++++--
>  drivers/gpu/drm/i915/i915_reg.h               |  1 +
>  3 files changed, 83 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
> index 5bef7dda4a7a..e2dddaf1051b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> @@ -575,6 +575,28 @@ static void icl_tc_port_assert_ref_held(struct drm_i915_private *dev_priv,
>  
>  #define TGL_AUX_PW_TO_TC_PORT(pw_idx)	((pw_idx) - TGL_PW_CTL_IDX_AUX_TC1)
>  
> +static void icl_tc_cold_exit(struct drm_i915_private *i915)
> +{
> +	int ret, tries = 0;
> +
> +	while (1) {
> +		ret = sandybridge_pcode_write_timeout(i915,
> +						      ICL_PCODE_EXIT_TCCOLD,
> +						      0, 250, 1);
> +		if (ret != -EAGAIN || ++tries == 3)
> +			break;
> +		msleep(1);
> +	}
> +
> +	/* Spec states that TC cold exit can take up to 1ms to complete */
> +	if (!ret)
> +		msleep(1);
> +
> +	/* TODO: turn failure into a error as soon i915 CI updates ICL IFWI */
> +	drm_dbg_kms(&i915->drm, "TC cold block %s\n", ret ? "failed" :
> +		    "succeeded");
> +}
> +
>  static void
>  icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
>  				 struct i915_power_well *power_well)
> @@ -593,7 +615,8 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
>  
>  	hsw_power_well_enable_prepare(dev_priv, power_well);
>  
> -	/* TODO ICL TC cold handling */
> +	if (INTEL_GEN(dev_priv) == 11 && dig_port->tc_legacy_port)
> +		icl_tc_cold_exit(dev_priv);
>  
>  	hsw_power_well_enable_complete(dev_priv, power_well);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
> index 275618bedf32..0cf33d4d21c3 100644
> --- a/drivers/gpu/drm/i915/display/intel_tc.c
> +++ b/drivers/gpu/drm/i915/display/intel_tc.c
> @@ -34,6 +34,7 @@ tc_port_load_fia_params(struct drm_i915_private *i915,
>  	if (INTEL_INFO(i915)->display.has_modular_fia) {
>  		modular_fia = intel_uncore_read(&i915->uncore,
>  						PORT_TX_DFLEXDPSP(FIA1));
> +		drm_WARN_ON(&i915->drm, modular_fia == 0xffffffff);
>  		modular_fia &= MODULAR_FIA_MASK;
>  	} else {
>  		modular_fia = 0;
> @@ -52,6 +53,37 @@ tc_port_load_fia_params(struct drm_i915_private *i915,
>  	}
>  }
>  
> +static intel_wakeref_t
> +tc_cold_block(struct intel_digital_port *dig_port)
> +{
> +	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
> +	enum intel_display_power_domain domain;
> +
> +	if (INTEL_GEN(i915) != 11 || !dig_port->tc_legacy_port)
> +		return 0;
> +
> +	domain = intel_legacy_aux_to_power_domain(dig_port->aux_ch);
> +	return intel_display_power_get(i915, domain);
> +}
> +
> +static void
> +tc_cold_unblock(struct intel_digital_port *dig_port, intel_wakeref_t wakeref)
> +{
> +	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
> +	enum intel_display_power_domain domain;
> +
> +	/*
> +	 * wakeref == -1, means some error happened saving save_depot_stack but
> +	 * power should still be put down and 0 is a invalid save_depot_stack
> +	 * id so can be used to skip it for non TC legacy ports.
> +	 */
> +	if (wakeref == 0)
> +		return;
> +
> +	domain = intel_legacy_aux_to_power_domain(dig_port->aux_ch);
> +	intel_display_power_put_async(i915, domain, wakeref);
> +}
> +
>  u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port)
>  {
>  	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
> @@ -420,9 +452,14 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
>  	enum tc_port_mode old_tc_mode = dig_port->tc_mode;
>  
>  	intel_display_power_flush_work(i915);
> -	drm_WARN_ON(&i915->drm,
> -		    intel_display_power_is_enabled(i915,
> -					intel_aux_power_domain(dig_port)));
> +	if (INTEL_GEN(i915) != 11 || !dig_port->tc_legacy_port) {
> +		enum intel_display_power_domain aux_domain;
> +		bool aux_powered;
> +
> +		aux_domain = intel_aux_power_domain(dig_port);
> +		aux_powered = intel_display_power_is_enabled(i915, aux_domain);
> +		drm_WARN_ON(&i915->drm, aux_powered);
> +	}
>  
>  	icl_tc_phy_disconnect(dig_port);
>  	icl_tc_phy_connect(dig_port, required_lanes);
> @@ -445,9 +482,11 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
>  {
>  	struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
>  	struct intel_encoder *encoder = &dig_port->base;
> +	intel_wakeref_t tc_cold_wref;
>  	int active_links = 0;
>  
>  	mutex_lock(&dig_port->tc_lock);
> +	tc_cold_wref = tc_cold_block(dig_port);
>  
>  	dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
>  	if (dig_port->dp.is_mst)
> @@ -473,6 +512,7 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
>  		    dig_port->tc_port_name,
>  		    tc_port_mode_name(dig_port->tc_mode));
>  
> +	tc_cold_unblock(dig_port, tc_cold_wref);
>  	mutex_unlock(&dig_port->tc_lock);
>  }
>  
> @@ -494,10 +534,15 @@ static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
>  bool intel_tc_port_connected(struct intel_digital_port *dig_port)
>  {
>  	bool is_connected;
> +	intel_wakeref_t tc_cold_wref;
>  
>  	intel_tc_port_lock(dig_port);
> +	tc_cold_wref = tc_cold_block(dig_port);
> +
>  	is_connected = tc_port_live_status_mask(dig_port) &
>  		       BIT(dig_port->tc_mode);
> +
> +	tc_cold_unblock(dig_port, tc_cold_wref);
>  	intel_tc_port_unlock(dig_port);
>  
>  	return is_connected;
> @@ -513,9 +558,16 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,
>  
>  	mutex_lock(&dig_port->tc_lock);
>  
> -	if (!dig_port->tc_link_refcount &&
> -	    intel_tc_port_needs_reset(dig_port))
> -		intel_tc_port_reset_mode(dig_port, required_lanes);
> +	if (!dig_port->tc_link_refcount) {
> +		intel_wakeref_t tc_cold_wref;
> +
> +		tc_cold_wref = tc_cold_block(dig_port);
> +
> +		if (intel_tc_port_needs_reset(dig_port))
> +			intel_tc_port_reset_mode(dig_port, required_lanes);
> +
> +		tc_cold_unblock(dig_port, tc_cold_wref);
> +	}
>  
>  	drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
>  	dig_port->tc_lock_wakeref = wakeref;
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 0b39b9abf8a4..e4667add70b0 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -9108,6 +9108,7 @@ enum {
>  #define     ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point)	(((point) << 16) | (0x1 << 8))
>  #define   GEN6_PCODE_READ_D_COMP		0x10
>  #define   GEN6_PCODE_WRITE_D_COMP		0x11
> +#define   ICL_PCODE_EXIT_TCCOLD			0x12
>  #define   HSW_PCODE_DE_WRITE_FREQ_REQ		0x17
>  #define   DISPLAY_IPS_CONTROL			0x19
>              /* See also IPS_CTL */
> -- 
> 2.26.0
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2020-04-14 17:31 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-13 16:45 [Intel-gfx] [PATCH v4 1/9] drm/i915/display: Move out code to return the digital_port of the aux ch José Roberto de Souza
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 2/9] drm/i915/display: Add intel_legacy_aux_to_power_domain() José Roberto de Souza
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 3/9] drm/i915/display: Split hsw_power_well_enable() into two José Roberto de Souza
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 4/9] drm/i915/tc/icl: Implement TC cold sequences José Roberto de Souza
2020-04-14 17:31   ` Imre Deak [this message]
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 5/9] drm/i915/tc: Skip ref held check for TC legacy aux power wells José Roberto de Souza
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 6/9] drm/i915/tc/tgl: Implement TC cold sequences José Roberto de Souza
2020-04-14 17:39   ` Imre Deak
2020-04-14 17:41     ` Souza, Jose
2020-04-14 19:02       ` Imre Deak
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 7/9] drm/i915/tc: Catch TC users accessing FIA registers without enable aux José Roberto de Souza
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 8/9] drm/i915/tc: Do not warn when aux power well of static TC ports timeout José Roberto de Souza
2020-04-14 17:47   ` Imre Deak
2020-04-14 18:05     ` Souza, Jose
2020-04-13 16:45 ` [Intel-gfx] [PATCH v4 9/9] drm/i915: Add missing deinitialization cases of load failure José Roberto de Souza
2020-04-14 18:29   ` Imre Deak
2020-04-14 20:50     ` Souza, Jose
2020-04-14 20:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v4,1/9] drm/i915/display: Move out code to return the digital_port of the aux ch Patchwork
2020-04-14 20:21 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2020-04-14 20:25 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-04-15 12:05 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200414173126.GA5942@ideak-desk.fi.intel.com \
    --to=imre.deak@intel.com \
    --cc=cooper.chiou@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jose.souza@intel.com \
    --cc=kai.heng.feng@canonical.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.