diff mbox

[7/9] drm/i915: panel power sequencing for VLV eDP

Message ID 1348666658-31345-8-git-send-email-vijay.a.purushothaman@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vijay Purushothaman Sept. 26, 2012, 1:37 p.m. UTC
PPS register offsets have changed in Valleyview.

Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com>
Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com>
Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h |    9 +++
 drivers/gpu/drm/i915/intel_dp.c |  122 +++++++++++++++++++++++++++------------
 2 files changed, 93 insertions(+), 38 deletions(-)

Comments

Daniel Vetter Sept. 26, 2012, 2:34 p.m. UTC | #1
On Wed, Sep 26, 2012 at 07:07:36PM +0530, Vijay Purushothaman wrote:
> PPS register offsets have changed in Valleyview.
> 
> Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com>
> Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com>
> Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>

I have a feeling that we need to add some panel power sequencer
abstraction, especially if we want to support the 2nd panel power sequence
on vlv, too. I'm trying to volunteer some of the Helsinki guys here to
brush up Chris' panel refactoring (which combines lvds and edp panel
handling a bit), that would fit in. But for now this quick&dirty way looks
good enough.
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_reg.h |    9 +++
>  drivers/gpu/drm/i915/intel_dp.c |  122 +++++++++++++++++++++++++++------------
>  2 files changed, 93 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 3f75ee6..e421847 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3981,6 +3981,15 @@
>  #define PIPEB_PP_ON_DELAYS      0x61308
>  #define PIPEB_PP_OFF_DELAYS     0x6130c
>  #define PIPEB_PP_DIVISOR        0x61310
> +#define VLV_PIPE_PP_STATUS(pipe) _PIPE(pipe, PIPEA_PP_STATUS, PIPEB_PP_STATUS)
> +#define VLV_PIPE_PP_CONTROL(pipe) _PIPE(pipe, PIPEA_PP_CONTROL, PIPEB_PP_CONTROL)
> +#define VLV_PIPE_PP_ON_DELAYS(pipe) \
> +		_PIPE(pipe, PIPEA_PP_ON_DELAYS, PIPEB_PP_ON_DELAYS)
> +#define VLV_PIPE_PP_OFF_DELAYS(pipe) \
> +		_PIPE(pipe, PIPEA_PP_OFF_DELAYS, PIPEB_PP_OFF_DELAYS)
> +#define VLV_PIPE_PP_DIVISOR(pipe) \
> +		_PIPE(pipe, PIPEA_PP_DIVISOR, PIPEB_PP_DIVISOR)
> +
>  
>  #define PCH_PP_STATUS		0xc7200
>  #define PCH_PP_CONTROL		0xc7204
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index af57027..b944529 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -316,16 +316,20 @@ static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 pp_stat_reg;
>  
> -	return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0;
> +	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> +	return (I915_READ(pp_stat_reg) & PP_ON) != 0;
>  }
>  
>  static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 pp_ctrl_reg;
>  
> -	return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0;
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0;
>  }
>  
>  static void
> @@ -333,14 +337,19 @@ intel_dp_check_edp(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 pp_stat_reg, pp_ctrl_reg;
>  
>  	if (!is_edp(intel_dp))
>  		return;
> +
> +	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +
>  	if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) {
>  		WARN(1, "eDP powered off while attempting aux channel communication.\n");
>  		DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
> -			      I915_READ(PCH_PP_STATUS),
> -			      I915_READ(PCH_PP_CONTROL));
> +				I915_READ(pp_stat_reg),
> +				I915_READ(pp_ctrl_reg));
>  	}
>  }
>  
> @@ -944,16 +953,20 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
>  {
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 pp_stat_reg, pp_ctrl_reg;
> +
> +	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
>  
>  	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
> -		      mask, value,
> -		      I915_READ(PCH_PP_STATUS),
> -		      I915_READ(PCH_PP_CONTROL));
> +			mask, value,
> +			I915_READ(pp_stat_reg),
> +			I915_READ(pp_ctrl_reg));
>  
> -	if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) {
> +	if (_wait_for((I915_READ(pp_stat_reg) & mask) == value, 5000, 10)) {
>  		DRM_ERROR("Panel status timeout: status %08x control %08x\n",
> -			  I915_READ(PCH_PP_STATUS),
> -			  I915_READ(PCH_PP_CONTROL));
> +				I915_READ(pp_stat_reg),
> +				I915_READ(pp_ctrl_reg));
>  	}
>  }
>  
> @@ -980,9 +993,15 @@ static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp)
>   * is locked
>   */
>  
> -static  u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
> +static  u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
>  {
> -	u32	control = I915_READ(PCH_PP_CONTROL);
> +	struct drm_device *dev = intel_dp->base.base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 control;
> +	u32 pp_ctrl_reg;
> +
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	control = I915_READ(pp_ctrl_reg);
>  
>  	control &= ~PANEL_UNLOCK_MASK;
>  	control |= PANEL_UNLOCK_REGS;
> @@ -994,6 +1013,7 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 pp;
> +	u32 pp_stat_reg, pp_ctrl_reg;
>  
>  	if (!is_edp(intel_dp))
>  		return;
> @@ -1012,13 +1032,16 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
>  	if (!ironlake_edp_have_panel_power(intel_dp))
>  		ironlake_wait_panel_power_cycle(intel_dp);
>  
> -	pp = ironlake_get_pp_control(dev_priv);
> +	pp = ironlake_get_pp_control(intel_dp);
>  	pp |= EDP_FORCE_VDD;
> -	I915_WRITE(PCH_PP_CONTROL, pp);
> -	POSTING_READ(PCH_PP_CONTROL);
> -	DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
> -		      I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
>  
> +	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +
> +	I915_WRITE(pp_ctrl_reg, pp);
> +	POSTING_READ(pp_ctrl_reg);
> +	DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
> +			I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
>  	/*
>  	 * If the panel wasn't on, delay before accessing aux channel
>  	 */
> @@ -1033,17 +1056,21 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 pp;
> +	u32 pp_stat_reg, pp_ctrl_reg;
>  
>  	if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
> -		pp = ironlake_get_pp_control(dev_priv);
> +		pp = ironlake_get_pp_control(intel_dp);
>  		pp &= ~EDP_FORCE_VDD;
> -		I915_WRITE(PCH_PP_CONTROL, pp);
> -		POSTING_READ(PCH_PP_CONTROL);
>  
> -		/* Make sure sequencer is idle before allowing subsequent activity */
> -		DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
> -			      I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
> +		pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> +		pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
>  
> +		I915_WRITE(pp_ctrl_reg, pp);
> +		POSTING_READ(pp_ctrl_reg);
> +
> +		/* Make sure sequencer is idle before allowing subsequent activity */
> +		DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
> +		I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
>  		msleep(intel_dp->panel_power_down_delay);
>  	}
>  }
> @@ -1087,6 +1114,7 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 pp;
> +	u32 pp_ctrl_reg;
>  
>  	if (!is_edp(intel_dp))
>  		return;
> @@ -1100,7 +1128,7 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
>  
>  	ironlake_wait_panel_power_cycle(intel_dp);
>  
> -	pp = ironlake_get_pp_control(dev_priv);
> +	pp = ironlake_get_pp_control(intel_dp);
>  	if (IS_GEN5(dev)) {
>  		/* ILK workaround: disable reset around power sequence */
>  		pp &= ~PANEL_POWER_RESET;
> @@ -1112,8 +1140,10 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
>  	if (!IS_GEN5(dev))
>  		pp |= PANEL_POWER_RESET;
>  
> -	I915_WRITE(PCH_PP_CONTROL, pp);
> -	POSTING_READ(PCH_PP_CONTROL);
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +
> +	I915_WRITE(pp_ctrl_reg, pp);
> +	POSTING_READ(pp_ctrl_reg);
>  
>  	ironlake_wait_panel_on(intel_dp);
>  
> @@ -1129,6 +1159,7 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 pp;
> +	u32 pp_ctrl_reg;
>  
>  	if (!is_edp(intel_dp))
>  		return;
> @@ -1137,12 +1168,15 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
>  
>  	WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
>  
> -	pp = ironlake_get_pp_control(dev_priv);
> +	pp = ironlake_get_pp_control(intel_dp);
>  	/* We need to switch off panel power _and_ force vdd, for otherwise some
>  	 * panels get very unhappy and cease to work. */
>  	pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
> -	I915_WRITE(PCH_PP_CONTROL, pp);
> -	POSTING_READ(PCH_PP_CONTROL);
> +
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +
> +	I915_WRITE(pp_ctrl_reg, pp);
> +	POSTING_READ(pp_ctrl_reg);
>  
>  	intel_dp->want_panel_vdd = false;
>  
> @@ -1154,6 +1188,7 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 pp;
> +	u32 pp_ctrl_reg;
>  
>  	if (!is_edp(intel_dp))
>  		return;
> @@ -1166,10 +1201,13 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
>  	 * allowing it to appear.
>  	 */
>  	msleep(intel_dp->backlight_on_delay);
> -	pp = ironlake_get_pp_control(dev_priv);
> +	pp = ironlake_get_pp_control(intel_dp);
>  	pp |= EDP_BLC_ENABLE;
> -	I915_WRITE(PCH_PP_CONTROL, pp);
> -	POSTING_READ(PCH_PP_CONTROL);
> +
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +
> +	I915_WRITE(pp_ctrl_reg, pp);
> +	POSTING_READ(pp_ctrl_reg);
>  }
>  
>  static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
> @@ -1177,15 +1215,17 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 pp;
> +	u32 pp_ctrl_reg;
>  
>  	if (!is_edp(intel_dp))
>  		return;
>  
>  	DRM_DEBUG_KMS("\n");
> -	pp = ironlake_get_pp_control(dev_priv);
> +	pp = ironlake_get_pp_control(intel_dp);
>  	pp &= ~EDP_BLC_ENABLE;
> -	I915_WRITE(PCH_PP_CONTROL, pp);
> -	POSTING_READ(PCH_PP_CONTROL);
> +	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	I915_WRITE(pp_ctrl_reg, pp);
> +	POSTING_READ(pp_ctrl_reg);
>  	msleep(intel_dp->backlight_off_delay);
>  }
>  
> @@ -2543,9 +2583,15 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
>  		u32 pp_on, pp_off, pp_div;
>  		struct edid *edid;
>  
> -		pp_on = I915_READ(PCH_PP_ON_DELAYS);
> -		pp_off = I915_READ(PCH_PP_OFF_DELAYS);
> -		pp_div = I915_READ(PCH_PP_DIVISOR);
> +		if (IS_VALLEYVIEW(dev)) {
> +			pp_on = I915_READ(PIPEA_PP_ON_DELAYS);
> +			pp_off = I915_READ(PIPEA_PP_OFF_DELAYS);
> +			pp_div = I915_READ(PIPEA_PP_DIVISOR);
> +		} else {
> +			pp_on = I915_READ(PCH_PP_ON_DELAYS);
> +			pp_off = I915_READ(PCH_PP_OFF_DELAYS);
> +			pp_div = I915_READ(PCH_PP_DIVISOR);
> +		}
>  
>  		if (!pp_on || !pp_off || !pp_div) {
>  			DRM_INFO("bad panel power sequencing delays, disabling panel\n");
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3f75ee6..e421847 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3981,6 +3981,15 @@ 
 #define PIPEB_PP_ON_DELAYS      0x61308
 #define PIPEB_PP_OFF_DELAYS     0x6130c
 #define PIPEB_PP_DIVISOR        0x61310
+#define VLV_PIPE_PP_STATUS(pipe) _PIPE(pipe, PIPEA_PP_STATUS, PIPEB_PP_STATUS)
+#define VLV_PIPE_PP_CONTROL(pipe) _PIPE(pipe, PIPEA_PP_CONTROL, PIPEB_PP_CONTROL)
+#define VLV_PIPE_PP_ON_DELAYS(pipe) \
+		_PIPE(pipe, PIPEA_PP_ON_DELAYS, PIPEB_PP_ON_DELAYS)
+#define VLV_PIPE_PP_OFF_DELAYS(pipe) \
+		_PIPE(pipe, PIPEA_PP_OFF_DELAYS, PIPEB_PP_OFF_DELAYS)
+#define VLV_PIPE_PP_DIVISOR(pipe) \
+		_PIPE(pipe, PIPEA_PP_DIVISOR, PIPEB_PP_DIVISOR)
+
 
 #define PCH_PP_STATUS		0xc7200
 #define PCH_PP_CONTROL		0xc7204
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index af57027..b944529 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -316,16 +316,20 @@  static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp_stat_reg;
 
-	return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0;
+	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+	return (I915_READ(pp_stat_reg) & PP_ON) != 0;
 }
 
 static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp_ctrl_reg;
 
-	return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0;
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0;
 }
 
 static void
@@ -333,14 +337,19 @@  intel_dp_check_edp(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp_stat_reg, pp_ctrl_reg;
 
 	if (!is_edp(intel_dp))
 		return;
+
+	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
 	if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) {
 		WARN(1, "eDP powered off while attempting aux channel communication.\n");
 		DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
-			      I915_READ(PCH_PP_STATUS),
-			      I915_READ(PCH_PP_CONTROL));
+				I915_READ(pp_stat_reg),
+				I915_READ(pp_ctrl_reg));
 	}
 }
 
@@ -944,16 +953,20 @@  static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
 {
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 pp_stat_reg, pp_ctrl_reg;
+
+	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
 
 	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
-		      mask, value,
-		      I915_READ(PCH_PP_STATUS),
-		      I915_READ(PCH_PP_CONTROL));
+			mask, value,
+			I915_READ(pp_stat_reg),
+			I915_READ(pp_ctrl_reg));
 
-	if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) {
+	if (_wait_for((I915_READ(pp_stat_reg) & mask) == value, 5000, 10)) {
 		DRM_ERROR("Panel status timeout: status %08x control %08x\n",
-			  I915_READ(PCH_PP_STATUS),
-			  I915_READ(PCH_PP_CONTROL));
+				I915_READ(pp_stat_reg),
+				I915_READ(pp_ctrl_reg));
 	}
 }
 
@@ -980,9 +993,15 @@  static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp)
  * is locked
  */
 
-static  u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
+static  u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
 {
-	u32	control = I915_READ(PCH_PP_CONTROL);
+	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 control;
+	u32 pp_ctrl_reg;
+
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	control = I915_READ(pp_ctrl_reg);
 
 	control &= ~PANEL_UNLOCK_MASK;
 	control |= PANEL_UNLOCK_REGS;
@@ -994,6 +1013,7 @@  static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
+	u32 pp_stat_reg, pp_ctrl_reg;
 
 	if (!is_edp(intel_dp))
 		return;
@@ -1012,13 +1032,16 @@  static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
 	if (!ironlake_edp_have_panel_power(intel_dp))
 		ironlake_wait_panel_power_cycle(intel_dp);
 
-	pp = ironlake_get_pp_control(dev_priv);
+	pp = ironlake_get_pp_control(intel_dp);
 	pp |= EDP_FORCE_VDD;
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
-	DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
-		      I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
 
+	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
+	DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
+			I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
 	/*
 	 * If the panel wasn't on, delay before accessing aux channel
 	 */
@@ -1033,17 +1056,21 @@  static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
+	u32 pp_stat_reg, pp_ctrl_reg;
 
 	if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) {
-		pp = ironlake_get_pp_control(dev_priv);
+		pp = ironlake_get_pp_control(intel_dp);
 		pp &= ~EDP_FORCE_VDD;
-		I915_WRITE(PCH_PP_CONTROL, pp);
-		POSTING_READ(PCH_PP_CONTROL);
 
-		/* Make sure sequencer is idle before allowing subsequent activity */
-		DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n",
-			      I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL));
+		pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
+		pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
 
+		I915_WRITE(pp_ctrl_reg, pp);
+		POSTING_READ(pp_ctrl_reg);
+
+		/* Make sure sequencer is idle before allowing subsequent activity */
+		DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
+		I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
 		msleep(intel_dp->panel_power_down_delay);
 	}
 }
@@ -1087,6 +1114,7 @@  static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
+	u32 pp_ctrl_reg;
 
 	if (!is_edp(intel_dp))
 		return;
@@ -1100,7 +1128,7 @@  static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 
 	ironlake_wait_panel_power_cycle(intel_dp);
 
-	pp = ironlake_get_pp_control(dev_priv);
+	pp = ironlake_get_pp_control(intel_dp);
 	if (IS_GEN5(dev)) {
 		/* ILK workaround: disable reset around power sequence */
 		pp &= ~PANEL_POWER_RESET;
@@ -1112,8 +1140,10 @@  static void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 	if (!IS_GEN5(dev))
 		pp |= PANEL_POWER_RESET;
 
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
 
 	ironlake_wait_panel_on(intel_dp);
 
@@ -1129,6 +1159,7 @@  static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
+	u32 pp_ctrl_reg;
 
 	if (!is_edp(intel_dp))
 		return;
@@ -1137,12 +1168,15 @@  static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
 	WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
 
-	pp = ironlake_get_pp_control(dev_priv);
+	pp = ironlake_get_pp_control(intel_dp);
 	/* We need to switch off panel power _and_ force vdd, for otherwise some
 	 * panels get very unhappy and cease to work. */
 	pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
+
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
 
 	intel_dp->want_panel_vdd = false;
 
@@ -1154,6 +1188,7 @@  static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
+	u32 pp_ctrl_reg;
 
 	if (!is_edp(intel_dp))
 		return;
@@ -1166,10 +1201,13 @@  static void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
 	 * allowing it to appear.
 	 */
 	msleep(intel_dp->backlight_on_delay);
-	pp = ironlake_get_pp_control(dev_priv);
+	pp = ironlake_get_pp_control(intel_dp);
 	pp |= EDP_BLC_ENABLE;
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
+
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
 }
 
 static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
@@ -1177,15 +1215,17 @@  static void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
+	u32 pp_ctrl_reg;
 
 	if (!is_edp(intel_dp))
 		return;
 
 	DRM_DEBUG_KMS("\n");
-	pp = ironlake_get_pp_control(dev_priv);
+	pp = ironlake_get_pp_control(intel_dp);
 	pp &= ~EDP_BLC_ENABLE;
-	I915_WRITE(PCH_PP_CONTROL, pp);
-	POSTING_READ(PCH_PP_CONTROL);
+	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	I915_WRITE(pp_ctrl_reg, pp);
+	POSTING_READ(pp_ctrl_reg);
 	msleep(intel_dp->backlight_off_delay);
 }
 
@@ -2543,9 +2583,15 @@  intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 		u32 pp_on, pp_off, pp_div;
 		struct edid *edid;
 
-		pp_on = I915_READ(PCH_PP_ON_DELAYS);
-		pp_off = I915_READ(PCH_PP_OFF_DELAYS);
-		pp_div = I915_READ(PCH_PP_DIVISOR);
+		if (IS_VALLEYVIEW(dev)) {
+			pp_on = I915_READ(PIPEA_PP_ON_DELAYS);
+			pp_off = I915_READ(PIPEA_PP_OFF_DELAYS);
+			pp_div = I915_READ(PIPEA_PP_DIVISOR);
+		} else {
+			pp_on = I915_READ(PCH_PP_ON_DELAYS);
+			pp_off = I915_READ(PCH_PP_OFF_DELAYS);
+			pp_div = I915_READ(PCH_PP_DIVISOR);
+		}
 
 		if (!pp_on || !pp_off || !pp_div) {
 			DRM_INFO("bad panel power sequencing delays, disabling panel\n");