All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 10/11] drm/i915: Move VLV cmnlane workaround to intel_power_domains_init_hw()
Date: Wed, 25 Jun 2014 22:43:03 +0300	[thread overview]
Message-ID: <20140625194303.GC27580@intel.com> (raw)
In-Reply-To: <20140625120301.3aa2acd1@jbarnes-desktop>

On Wed, Jun 25, 2014 at 12:03:01PM -0700, Jesse Barnes wrote:
> On Fri, 13 Jun 2014 13:37:56 +0300
> ville.syrjala@linux.intel.com wrote:
> 
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > Now that the CMNRESET deassert is part of the cmnlane power well,
> > intel_reset_dpio() is called too late to make any difference. We've
> > deasserted CMNRESET by that time, and so the off+on toggle w/a will
> > never kick in.
> > 
> > Move the workaround to intel_power_domains_init_hw() where it gets
> > called before we enable the init power domain.
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 23 -------------
> >  drivers/gpu/drm/i915/intel_drv.h     |  3 +-
> >  drivers/gpu/drm/i915/intel_pm.c      | 67 ++++++++++++++++++++++++++++++------
> >  3 files changed, 58 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 33cc213..bcd32322 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -1508,9 +1508,6 @@ static void intel_reset_dpio(struct drm_device *dev)
> >  {
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  
> > -	if (!IS_VALLEYVIEW(dev))
> > -		return;
> > -
> >  	if (IS_CHERRYVIEW(dev)) {
> >  		enum dpio_phy phy;
> >  		u32 val;
> > @@ -1532,26 +1529,6 @@ static void intel_reset_dpio(struct drm_device *dev)
> >  			I915_WRITE(DISPLAY_PHY_CONTROL,
> >  				PHY_COM_LANE_RESET_DEASSERT(phy, val));
> >  		}
> > -
> > -	} else {
> > -		/*
> > -		 * If DPIO has already been reset, e.g. by BIOS, just skip all
> > -		 * this.
> > -		 */
> > -		if (I915_READ(DPIO_CTL) & DPIO_CMNRST)
> > -			return;
> > -
> > -		/*
> > -		 * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
> > -		 * Need to assert and de-assert PHY SB reset by gating the
> > -		 * common lane power, then un-gating it.
> > -		 * Simply ungating isn't enough to reset the PHY enough to get
> > -		 * ports and lanes running.
> > -		 */
> > -		__vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
> > -				     false);
> > -		__vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
> > -				     true);
> >  	}
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 5740be0..e565906 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -970,8 +970,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
> >  void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
> >  void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
> >  void ilk_wm_get_hw_state(struct drm_device *dev);
> > -void __vlv_set_power_well(struct drm_i915_private *dev_priv,
> > -			  enum punit_power_well power_well_id, bool enable);
> > +
> >  
> >  /* intel_sdvo.c */
> >  bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index e9a8565..d8e20d3 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -5962,9 +5962,10 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
> >  	return true;
> >  }
> >  
> > -void __vlv_set_power_well(struct drm_i915_private *dev_priv,
> > -			  enum punit_power_well power_well_id, bool enable)
> > +static void vlv_set_power_well(struct drm_i915_private *dev_priv,
> > +			       struct i915_power_well *power_well, bool enable)
> >  {
> > +	enum punit_power_well power_well_id = power_well->data;
> >  	u32 mask;
> >  	u32 state;
> >  	u32 ctrl;
> > @@ -5997,14 +5998,6 @@ out:
> >  	mutex_unlock(&dev_priv->rps.hw_lock);
> >  }
> >  
> > -static void vlv_set_power_well(struct drm_i915_private *dev_priv,
> > -			       struct i915_power_well *power_well, bool enable)
> > -{
> > -	enum punit_power_well power_well_id = power_well->data;
> > -
> > -	__vlv_set_power_well(dev_priv, power_well_id, enable);
> > -}
> > -
> >  static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
> >  				   struct i915_power_well *power_well)
> >  {
> > @@ -6435,6 +6428,21 @@ static struct i915_power_well vlv_power_wells[] = {
> >  	},
> >  };
> >  
> > +static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
> > +						 enum punit_power_well power_well_id)
> > +{
> > +	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> > +	struct i915_power_well *power_well;
> > +	int i;
> > +
> > +	for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
> > +		if (power_well->data == power_well_id)
> > +			return power_well;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> >  #define set_power_wells(power_domains, __power_wells) ({		\
> >  	(power_domains)->power_wells = (__power_wells);			\
> >  	(power_domains)->power_well_count = ARRAY_SIZE(__power_wells);	\
> > @@ -6482,11 +6490,50 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
> >  	mutex_unlock(&power_domains->lock);
> >  }
> >  
> > +static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
> > +{
> > +	struct i915_power_well *cmn =
> > +		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC);
> > +	struct i915_power_well *disp2d =
> > +		lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D);
> > +
> > +	/* nothing to do if common lane is already off */
> > +	if (!cmn->ops->is_enabled(dev_priv, cmn))
> > +		return;
> > +
> > +	/* If the display might be already active skip this */
> > +	if (disp2d->ops->is_enabled(dev_priv, disp2d) &&
> > +	    I915_READ(DPIO_CTL) & DPIO_CMNRST)
> > +		return;
> > +
> > +	DRM_DEBUG_KMS("toggling display PHY side reset\n");
> > +
> > +	/* cmnlane needs DPLL registers */
> > +	disp2d->ops->enable(dev_priv, disp2d);
> > +
> > +	/*
> > +	 * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
> > +	 * Need to assert and de-assert PHY SB reset by gating the
> > +	 * common lane power, then un-gating it.
> > +	 * Simply ungating isn't enough to reset the PHY enough to get
> > +	 * ports and lanes running.
> > +	 */
> > +	cmn->ops->disable(dev_priv, cmn);
> > +}
> > +
> >  void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
> >  {
> > +	struct drm_device *dev = dev_priv->dev;
> >  	struct i915_power_domains *power_domains = &dev_priv->power_domains;
> >  
> >  	power_domains->initializing = true;
> > +
> > +	if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
> > +		mutex_lock(&power_domains->lock);
> > +		vlv_cmnlane_wa(dev_priv);
> > +		mutex_unlock(&power_domains->lock);
> > +	}
> > +
> >  	/* For now, we need the power well to be always enabled. */
> >  	intel_display_set_init_power(dev_priv, true);
> >  	intel_power_domains_resume(dev_priv);
> 
> I kind of preferred the low level function that just took a well ID
> directly since the idea of looking something we already know seems
> silly (and it should probably be a separate patch anyway).

Yeah the lookup part is a bit silly. But it avoids leaking the
implementation details of the relevant power well ops into vlv_cmnlane_wa().
The disp2d and cmnlane enable/disable hooks do other things besides just
frobbing the punit register, and we should always follow the proper
sequence.

> Also I'm not
> sure I would describe this as a W/A; the phy needs to get reset
> somehow...

I'd call it a hardware or firmware bug if it manages to power things up
in the wrong order and we have to step in to fix it. So calling it a w/a
seems reasonable to me. I can rename though if desired.

> 
> But with or without those changes, we need this.
> 
> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> 
> -- 
> Jesse Barnes, Intel Open Source Technology Center

-- 
Ville Syrjälä
Intel OTC

  reply	other threads:[~2014-06-25 19:43 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-13 10:37 [PATCH 00/11] drm/i915: VLV display clock/phy stuff ville.syrjala
2014-06-13 10:37 ` [PATCH 01/11] drm/i915: Change vlv cdclk to use kHz units ville.syrjala
2014-06-25 18:36   ` Jesse Barnes
2014-06-13 10:37 ` [PATCH 02/11] drm/i915: Give names to the CCK_DISPLAY_CLOCK_CONTROL bits ville.syrjala
2014-06-25 18:45   ` Jesse Barnes
2014-06-13 10:37 ` [PATCH 03/11] drm/i915: Move vlv cdclk code to .get_display_clock_speed() ville.syrjala
2014-06-25 18:47   ` Jesse Barnes
2014-07-07  9:17     ` Daniel Vetter
2014-06-13 10:37 ` [PATCH 04/11] drm/i915: Handle 320 vs. 333 MHz cdclk on vlv ville.syrjala
2014-06-25 18:53   ` Jesse Barnes
2014-06-13 10:37 ` [PATCH 05/11] drm/i915: Use 200MHz cdclk on vlv when all pipes are off ville.syrjala
2014-06-25 18:54   ` Jesse Barnes
2014-06-25 19:32     ` Ville Syrjälä
2014-06-13 10:37 ` [PATCH 06/11] drm/i915: Wait for cdclk change to occure when going for 400MHz ville.syrjala
2014-06-25 18:54   ` Jesse Barnes
2014-06-13 10:37 ` [PATCH 07/11] drm/i915: Warn if there's a cdclk change in progess ville.syrjala
2014-06-25 18:55   ` Jesse Barnes
2014-06-25 19:34     ` Ville Syrjälä
2014-07-07  9:26       ` Daniel Vetter
2014-06-13 10:37 ` [PATCH 08/11] drm/i915: Kill duplicated cdclk readout code from i2c ville.syrjala
2014-06-25 18:58   ` Jesse Barnes
2014-06-13 10:37 ` [PATCH 09/11] drm/i915: Pull the cmnlane tricks into its own power well ops ville.syrjala
2014-06-25 18:59   ` Jesse Barnes
2014-06-13 10:37 ` [PATCH 10/11] drm/i915: Move VLV cmnlane workaround to intel_power_domains_init_hw() ville.syrjala
2014-06-25 19:03   ` Jesse Barnes
2014-06-25 19:43     ` Ville Syrjälä [this message]
2014-06-13 10:37 ` [WIP][PATCH 11/11] drm/i915: Turn off clocks when disp2d is powered down ville.syrjala
2014-06-25 19:03   ` Jesse Barnes
2014-07-07  9:30     ` Daniel Vetter

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=20140625194303.GC27580@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jbarnes@virtuousgeek.org \
    /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.