Re: [Intel-gfx] [PATCH 17/40] drm/i915: Add chv cmnlane power wells

2014-07-28 Thread Ville Syrjälä
On Fri, Jul 25, 2014 at 02:55:00PM +0300, Imre Deak wrote:
 On Sat, 2014-06-28 at 02:04 +0300, ville.syrj...@linux.intel.com wrote:
  From: Ville Syrjälä ville.syrj...@linux.intel.com
  
  CHV has two display PHYs so there are also two cmnlane power wells. Add
  the approriate code to power the wells up/down.
  
  Like on VLV we do the cmnreset assert/deassert and the DPLL refclock
  enabling at approriate times.
  
  This code actually works on my bsw.
  
  Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
  ---
   drivers/gpu/drm/i915/i915_reg.h |  1 +
   drivers/gpu/drm/i915/intel_pm.c | 89 
  +
   2 files changed, 90 insertions(+)
  
  diff --git a/drivers/gpu/drm/i915/i915_reg.h 
  b/drivers/gpu/drm/i915/i915_reg.h
  index d246609..19e68d6 100644
  --- a/drivers/gpu/drm/i915/i915_reg.h
  +++ b/drivers/gpu/drm/i915/i915_reg.h
  @@ -512,6 +512,7 @@ enum punit_power_well {
  PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9,
  PUNIT_POWER_WELL_DPIO_RX0   = 10,
  PUNIT_POWER_WELL_DPIO_RX1   = 11,
  +   PUNIT_POWER_WELL_DPIO_CMN_D = 12,
   
  PUNIT_POWER_WELL_NUM,
   };
  diff --git a/drivers/gpu/drm/i915/intel_pm.c 
  b/drivers/gpu/drm/i915/intel_pm.c
  index e2b956e..f88490b 100644
  --- a/drivers/gpu/drm/i915/intel_pm.c
  +++ b/drivers/gpu/drm/i915/intel_pm.c
  @@ -6200,6 +6200,64 @@ static void vlv_dpio_cmn_power_well_disable(struct 
  drm_i915_private *dev_priv,
  vlv_set_power_well(dev_priv, power_well, false);
   }
   
  +static void chv_dpio_cmn_power_well_enable(struct drm_i915_private 
  *dev_priv,
  +  struct i915_power_well *power_well)
  +{
  +   enum dpio_phy phy;
  +
  +   WARN_ON_ONCE(power_well-data != PUNIT_POWER_WELL_DPIO_CMN_BC 
  +power_well-data != PUNIT_POWER_WELL_DPIO_CMN_D);
  +
  +   /*
  +* Enable the CRI clock source so we can get at the
  +* display and the reference clock for VGA
  +* hotplug / manual detection.
  +*/
  +   if (power_well-data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
  +   phy = DPIO_PHY0;
  +   I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
  +  DPLL_REFA_CLK_ENABLE_VLV);
  +   I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
  +  DPLL_REFA_CLK_ENABLE_VLV | 
  DPLL_INTEGRATED_CRI_CLK_VLV);
 
 Any reason the two clocks are enabled sequentially? For PHY1 you don't
 do this..

I think I meant to enable the ref clock for both pipes A and B. So the
first rmw should have hit DPLL(PIPE_A).

 In any case:
 Reviewed-by: Imre Deak imre.d...@intel.com
 
  +   } else {
  +   phy = DPIO_PHY1;
  +   I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) |
  +  DPLL_REFA_CLK_ENABLE_VLV | 
  DPLL_INTEGRATED_CRI_CLK_VLV);
  +   }
  +   udelay(1); /* 10ns for cmnreset, 0ns for sidereset */
  +   vlv_set_power_well(dev_priv, power_well, true);
  +
  +   /* Poll for phypwrgood signal */
  +   if (wait_for(I915_READ(DISPLAY_PHY_STATUS)  PHY_POWERGOOD(phy), 1))
  +   DRM_ERROR(Display PHY %d is not power up\n, phy);
  +
  +   I915_WRITE(DISPLAY_PHY_CONTROL,
  +  PHY_COM_LANE_RESET_DEASSERT(phy, 
  I915_READ(DISPLAY_PHY_CONTROL)));
  +}
  +
  +static void chv_dpio_cmn_power_well_disable(struct drm_i915_private 
  *dev_priv,
  +   struct i915_power_well *power_well)
  +{
  +   enum dpio_phy phy;
  +
  +   WARN_ON_ONCE(power_well-data != PUNIT_POWER_WELL_DPIO_CMN_BC 
  +power_well-data != PUNIT_POWER_WELL_DPIO_CMN_D);
  +
  +   if (power_well-data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
  +   phy = DPIO_PHY0;
  +   assert_pll_disabled(dev_priv, PIPE_A);
  +   assert_pll_disabled(dev_priv, PIPE_B);
  +   } else {
  +   phy = DPIO_PHY1;
  +   assert_pll_disabled(dev_priv, PIPE_C);
  +   }
  +
  +   I915_WRITE(DISPLAY_PHY_CONTROL,
  +  PHY_COM_LANE_RESET_ASSERT(phy, 
  I915_READ(DISPLAY_PHY_CONTROL)));
  +
  +   vlv_set_power_well(dev_priv, power_well, false);
  +}
  +
   static void check_power_well_state(struct drm_i915_private *dev_priv,
 struct i915_power_well *power_well)
   {
  @@ -6369,6 +6427,18 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
  BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |  \
  BIT(POWER_DOMAIN_INIT))
   
  +#define CHV_DPIO_CMN_BC_POWER_DOMAINS (\
  +   BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |  \
  +   BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |  \
  +   BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |  \
  +   BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |  \
  +   BIT(POWER_DOMAIN_INIT))
  +
  +#define CHV_DPIO_CMN_D_POWER_DOMAINS ( \
  +   BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |  \
  +   BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |  \
  +   BIT(POWER_DOMAIN_INIT))
  +
   static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
  .sync_hw = 

Re: [Intel-gfx] [PATCH 17/40] drm/i915: Add chv cmnlane power wells

2014-07-25 Thread Imre Deak
On Sat, 2014-06-28 at 02:04 +0300, ville.syrj...@linux.intel.com wrote:
 From: Ville Syrjälä ville.syrj...@linux.intel.com
 
 CHV has two display PHYs so there are also two cmnlane power wells. Add
 the approriate code to power the wells up/down.
 
 Like on VLV we do the cmnreset assert/deassert and the DPLL refclock
 enabling at approriate times.
 
 This code actually works on my bsw.
 
 Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
 ---
  drivers/gpu/drm/i915/i915_reg.h |  1 +
  drivers/gpu/drm/i915/intel_pm.c | 89 
 +
  2 files changed, 90 insertions(+)
 
 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
 index d246609..19e68d6 100644
 --- a/drivers/gpu/drm/i915/i915_reg.h
 +++ b/drivers/gpu/drm/i915/i915_reg.h
 @@ -512,6 +512,7 @@ enum punit_power_well {
   PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9,
   PUNIT_POWER_WELL_DPIO_RX0   = 10,
   PUNIT_POWER_WELL_DPIO_RX1   = 11,
 + PUNIT_POWER_WELL_DPIO_CMN_D = 12,
  
   PUNIT_POWER_WELL_NUM,
  };
 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
 index e2b956e..f88490b 100644
 --- a/drivers/gpu/drm/i915/intel_pm.c
 +++ b/drivers/gpu/drm/i915/intel_pm.c
 @@ -6200,6 +6200,64 @@ static void vlv_dpio_cmn_power_well_disable(struct 
 drm_i915_private *dev_priv,
   vlv_set_power_well(dev_priv, power_well, false);
  }
  
 +static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
 +struct i915_power_well *power_well)
 +{
 + enum dpio_phy phy;
 +
 + WARN_ON_ONCE(power_well-data != PUNIT_POWER_WELL_DPIO_CMN_BC 
 +  power_well-data != PUNIT_POWER_WELL_DPIO_CMN_D);
 +
 + /*
 +  * Enable the CRI clock source so we can get at the
 +  * display and the reference clock for VGA
 +  * hotplug / manual detection.
 +  */
 + if (power_well-data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
 + phy = DPIO_PHY0;
 + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
 +DPLL_REFA_CLK_ENABLE_VLV);
 + I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
 +DPLL_REFA_CLK_ENABLE_VLV | 
 DPLL_INTEGRATED_CRI_CLK_VLV);

Any reason the two clocks are enabled sequentially? For PHY1 you don't
do this.. In any case:
Reviewed-by: Imre Deak imre.d...@intel.com

 + } else {
 + phy = DPIO_PHY1;
 + I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) |
 +DPLL_REFA_CLK_ENABLE_VLV | 
 DPLL_INTEGRATED_CRI_CLK_VLV);
 + }
 + udelay(1); /* 10ns for cmnreset, 0ns for sidereset */
 + vlv_set_power_well(dev_priv, power_well, true);
 +
 + /* Poll for phypwrgood signal */
 + if (wait_for(I915_READ(DISPLAY_PHY_STATUS)  PHY_POWERGOOD(phy), 1))
 + DRM_ERROR(Display PHY %d is not power up\n, phy);
 +
 + I915_WRITE(DISPLAY_PHY_CONTROL,
 +PHY_COM_LANE_RESET_DEASSERT(phy, 
 I915_READ(DISPLAY_PHY_CONTROL)));
 +}
 +
 +static void chv_dpio_cmn_power_well_disable(struct drm_i915_private 
 *dev_priv,
 + struct i915_power_well *power_well)
 +{
 + enum dpio_phy phy;
 +
 + WARN_ON_ONCE(power_well-data != PUNIT_POWER_WELL_DPIO_CMN_BC 
 +  power_well-data != PUNIT_POWER_WELL_DPIO_CMN_D);
 +
 + if (power_well-data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
 + phy = DPIO_PHY0;
 + assert_pll_disabled(dev_priv, PIPE_A);
 + assert_pll_disabled(dev_priv, PIPE_B);
 + } else {
 + phy = DPIO_PHY1;
 + assert_pll_disabled(dev_priv, PIPE_C);
 + }
 +
 + I915_WRITE(DISPLAY_PHY_CONTROL,
 +PHY_COM_LANE_RESET_ASSERT(phy, 
 I915_READ(DISPLAY_PHY_CONTROL)));
 +
 + vlv_set_power_well(dev_priv, power_well, false);
 +}
 +
  static void check_power_well_state(struct drm_i915_private *dev_priv,
  struct i915_power_well *power_well)
  {
 @@ -6369,6 +6427,18 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
   BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |  \
   BIT(POWER_DOMAIN_INIT))
  
 +#define CHV_DPIO_CMN_BC_POWER_DOMAINS (  \
 + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |  \
 + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) |  \
 + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) |  \
 + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |  \
 + BIT(POWER_DOMAIN_INIT))
 +
 +#define CHV_DPIO_CMN_D_POWER_DOMAINS (   \
 + BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |  \
 + BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |  \
 + BIT(POWER_DOMAIN_INIT))
 +
  static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
   .sync_hw = i9xx_always_on_power_well_noop,
   .enable = i9xx_always_on_power_well_noop,
 @@ -6498,6 +6568,13 @@ static struct i915_power_well vlv_power_wells[] = {
   },
  };
  
 +static