public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] drm/i915: vlv backlight, per-pipe power sequencing fixes
@ 2013-09-03 11:43 Jani Nikula
  2013-09-03 11:43 ` [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence Jani Nikula
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jani Nikula @ 2013-09-03 11:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Okay, I'm not overly confident about the correctness of this series, but
here goes anyway.

Cheers,
Jani.


Jani Nikula (3):
  drm/i915: move backlight enable later in vlv enable sequence
  drm/i915: clean up power sequencing register port select definitions
  drm/i915: add support for per-pipe power sequencing on vlv

 drivers/gpu/drm/i915/i915_reg.h |    7 +-
 drivers/gpu/drm/i915/intel_dp.c |  151 +++++++++++++++++++++++++++------------
 2 files changed, 107 insertions(+), 51 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence
  2013-09-03 11:43 [RFC PATCH 0/3] drm/i915: vlv backlight, per-pipe power sequencing fixes Jani Nikula
@ 2013-09-03 11:43 ` Jani Nikula
  2013-09-04 18:30   ` Ville Syrjälä
  2013-09-03 11:43 ` [RFC PATCH 2/3] drm/i915: clean up power sequencing register port select definitions Jani Nikula
  2013-09-03 11:43 ` [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv Jani Nikula
  2 siblings, 1 reply; 7+ messages in thread
From: Jani Nikula @ 2013-09-03 11:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Follow-up to
commit 5004945f1d6c0282c0288afa89ad85d7f2bea4d5
Author: Jani Nikula <jani.nikula@intel.com>
Date:   Tue Jul 30 12:20:32 2013 +0300

    drm/i915: move encoder->enable callback later in VLV crtc enable

Reference: http://mid.gmane.org/CAKMK7uFs9EMvMW8BnS24e5UNm1D7JrfVg3SD5SDFtVEamGfOOg@mail.gmail.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c192dbb..adbe7bc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1717,11 +1717,17 @@ static void intel_enable_dp(struct intel_encoder *encoder)
 	ironlake_edp_panel_vdd_off(intel_dp, true);
 	intel_dp_complete_link_train(intel_dp);
 	intel_dp_stop_link_train(intel_dp);
-	ironlake_edp_backlight_on(intel_dp);
+
+	/* this function is called from vlv_pre_enable_dp() */
+	if (!IS_VALLEYVIEW(dev))
+		ironlake_edp_backlight_on(intel_dp);
 }
 
 static void vlv_enable_dp(struct intel_encoder *encoder)
 {
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
+	ironlake_edp_backlight_on(intel_dp);
 }
 
 static void intel_pre_enable_dp(struct intel_encoder *encoder)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 2/3] drm/i915: clean up power sequencing register port select definitions
  2013-09-03 11:43 [RFC PATCH 0/3] drm/i915: vlv backlight, per-pipe power sequencing fixes Jani Nikula
  2013-09-03 11:43 ` [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence Jani Nikula
@ 2013-09-03 11:43 ` Jani Nikula
  2013-09-05 11:55   ` Ville Syrjälä
  2013-09-03 11:43 ` [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv Jani Nikula
  2 siblings, 1 reply; 7+ messages in thread
From: Jani Nikula @ 2013-09-03 11:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Remove dupes, add VLV port B.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h |    7 +------
 drivers/gpu/drm/i915/intel_dp.c |    4 ++--
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c7f2da3..accbd1f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4449,6 +4449,7 @@
 #define PIPEA_PP_STATUS         (VLV_DISPLAY_BASE + 0x61200)
 #define PIPEA_PP_CONTROL        (VLV_DISPLAY_BASE + 0x61204)
 #define PIPEA_PP_ON_DELAYS      (VLV_DISPLAY_BASE + 0x61208)
+#define  PANEL_PORT_SELECT_DPB_VLV	(1 << 30)
 #define PIPEA_PP_OFF_DELAYS     (VLV_DISPLAY_BASE + 0x6120c)
 #define PIPEA_PP_DIVISOR        (VLV_DISPLAY_BASE + 0x61210)
 
@@ -4480,7 +4481,6 @@
 #define  PANEL_PORT_SELECT_MASK	(3 << 30)
 #define  PANEL_PORT_SELECT_LVDS	(0 << 30)
 #define  PANEL_PORT_SELECT_DPA	(1 << 30)
-#define  EDP_PANEL		(1 << 30)
 #define  PANEL_PORT_SELECT_DPC	(2 << 30)
 #define  PANEL_PORT_SELECT_DPD	(3 << 30)
 #define  PANEL_POWER_UP_DELAY_MASK	(0x1fff0000)
@@ -4489,11 +4489,6 @@
 #define  PANEL_LIGHT_ON_DELAY_SHIFT	0
 
 #define PCH_PP_OFF_DELAYS	0xc720c
-#define  PANEL_POWER_PORT_SELECT_MASK	(0x3 << 30)
-#define  PANEL_POWER_PORT_LVDS		(0 << 30)
-#define  PANEL_POWER_PORT_DP_A		(1 << 30)
-#define  PANEL_POWER_PORT_DP_C		(2 << 30)
-#define  PANEL_POWER_PORT_DP_D		(3 << 30)
 #define  PANEL_POWER_DOWN_DELAY_MASK	(0x1fff0000)
 #define  PANEL_POWER_DOWN_DELAY_SHIFT	16
 #define  PANEL_LIGHT_OFF_DELAY_MASK	(0x1fff)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index adbe7bc..0ba72f1 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3281,9 +3281,9 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 		port_sel = I915_READ(pp_on_reg) & 0xc0000000;
 	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
 		if (dp_to_dig_port(intel_dp)->port == PORT_A)
-			port_sel = PANEL_POWER_PORT_DP_A;
+			port_sel = PANEL_PORT_SELECT_DPA;
 		else
-			port_sel = PANEL_POWER_PORT_DP_D;
+			port_sel = PANEL_PORT_SELECT_DPD;
 	}
 
 	pp_on |= port_sel;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv
  2013-09-03 11:43 [RFC PATCH 0/3] drm/i915: vlv backlight, per-pipe power sequencing fixes Jani Nikula
  2013-09-03 11:43 ` [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence Jani Nikula
  2013-09-03 11:43 ` [RFC PATCH 2/3] drm/i915: clean up power sequencing register port select definitions Jani Nikula
@ 2013-09-03 11:43 ` Jani Nikula
  2013-09-05 12:12   ` Ville Syrjälä
  2 siblings, 1 reply; 7+ messages in thread
From: Jani Nikula @ 2013-09-03 11:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

VLV has per-pipe PP registers. Set up power sequencing on mode set. The
connector init time setup is problematic, since we don't have a pipe at
that time. Cook up something.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c |  139 +++++++++++++++++++++++++++------------
 1 file changed, 97 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0ba72f1..95d67fc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -237,24 +237,47 @@ intel_hrawclk(struct drm_device *dev)
 	}
 }
 
+static void
+intel_dp_init_panel_power_sequencer(struct drm_device *dev,
+				    struct intel_dp *intel_dp,
+				    struct edp_power_seq *out);
+static void
+intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
+				    struct intel_dp *intel_dp,
+				    struct edp_power_seq *out);
+
+static u32 _pp_ctrl_reg(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
+
+	return HAS_PCH_SPLIT(dev) ? PCH_PP_CONTROL : VLV_PIPE_PP_CONTROL(pipe);
+}
+
+static u32 _pp_stat_reg(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
+
+	return HAS_PCH_SPLIT(dev) ? PCH_PP_STATUS : VLV_PIPE_PP_STATUS(pipe);
+}
+
 static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp_stat_reg;
 
-	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-	return (I915_READ(pp_stat_reg) & PP_ON) != 0;
+	return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
 }
 
 static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 pp_ctrl_reg;
 
-	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
-	return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0;
+	return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0;
 }
 
 static void
@@ -262,19 +285,15 @@ intel_dp_check_edp(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	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(pp_stat_reg),
-				I915_READ(pp_ctrl_reg));
+			      I915_READ(_pp_stat_reg(intel_dp)),
+			      I915_READ(_pp_ctrl_reg(intel_dp)));
 	}
 }
 
@@ -948,8 +967,8 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
 	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;
+	pp_stat_reg = _pp_stat_reg(intel_dp);
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
 	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
 			mask, value,
@@ -991,11 +1010,8 @@ static  u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	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 = I915_READ(_pp_ctrl_reg(intel_dp));
 	control &= ~PANEL_UNLOCK_MASK;
 	control |= PANEL_UNLOCK_REGS;
 	return control;
@@ -1028,8 +1044,8 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
 	pp = ironlake_get_pp_control(intel_dp);
 	pp |= EDP_FORCE_VDD;
 
-	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	pp_stat_reg = _pp_stat_reg(intel_dp);
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
 	I915_WRITE(pp_ctrl_reg, pp);
 	POSTING_READ(pp_ctrl_reg);
@@ -1057,8 +1073,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
 		pp = ironlake_get_pp_control(intel_dp);
 		pp &= ~EDP_FORCE_VDD;
 
-		pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-		pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+		pp_stat_reg = _pp_ctrl_reg(intel_dp);
+		pp_ctrl_reg = _pp_stat_reg(intel_dp);
 
 		I915_WRITE(pp_ctrl_reg, pp);
 		POSTING_READ(pp_ctrl_reg);
@@ -1123,20 +1139,19 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 
 	ironlake_wait_panel_power_cycle(intel_dp);
 
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 	pp = ironlake_get_pp_control(intel_dp);
 	if (IS_GEN5(dev)) {
 		/* ILK workaround: disable reset around power sequence */
 		pp &= ~PANEL_POWER_RESET;
-		I915_WRITE(PCH_PP_CONTROL, pp);
-		POSTING_READ(PCH_PP_CONTROL);
+		I915_WRITE(pp_ctrl_reg, pp);
+		POSTING_READ(pp_ctrl_reg);
 	}
 
 	pp |= POWER_TARGET_ON;
 	if (!IS_GEN5(dev))
 		pp |= PANEL_POWER_RESET;
 
-	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
-
 	I915_WRITE(pp_ctrl_reg, pp);
 	POSTING_READ(pp_ctrl_reg);
 
@@ -1144,8 +1159,8 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 
 	if (IS_GEN5(dev)) {
 		pp |= PANEL_POWER_RESET; /* restore panel reset bit */
-		I915_WRITE(PCH_PP_CONTROL, pp);
-		POSTING_READ(PCH_PP_CONTROL);
+		I915_WRITE(pp_ctrl_reg, pp);
+		POSTING_READ(pp_ctrl_reg);
 	}
 }
 
@@ -1168,7 +1183,7 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 	 * panels get very unhappy and cease to work. */
 	pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
 
-	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
 	I915_WRITE(pp_ctrl_reg, pp);
 	POSTING_READ(pp_ctrl_reg);
@@ -1201,7 +1216,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
 	pp = ironlake_get_pp_control(intel_dp);
 	pp |= EDP_BLC_ENABLE;
 
-	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
 	I915_WRITE(pp_ctrl_reg, pp);
 	POSTING_READ(pp_ctrl_reg);
@@ -1225,7 +1240,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
 	pp = ironlake_get_pp_control(intel_dp);
 	pp &= ~EDP_BLC_ENABLE;
 
-	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
 	I915_WRITE(pp_ctrl_reg, pp);
 	POSTING_READ(pp_ctrl_reg);
@@ -1748,6 +1763,7 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
 	int port = vlv_dport_to_channel(dport);
 	int pipe = intel_crtc->pipe;
+	struct edp_power_seq power_seq;
 	u32 val;
 
 	mutex_lock(&dev_priv->dpio_lock);
@@ -1765,6 +1781,10 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
 
 	mutex_unlock(&dev_priv->dpio_lock);
 
+	/* init power sequencer on this pipe and port */
+	intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
+	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, &power_seq);
+
 	intel_enable_dp(encoder);
 
 	vlv_wait_port_ready(dev_priv, port);
@@ -3146,6 +3166,34 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
 	}
 }
 
+static enum pipe
+vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
+	enum pipe pipe;
+
+	/* modeset should have pipe */
+	if (crtc)
+		return to_intel_crtc(crtc)->pipe;
+
+	/* init time, try to find a pipe with this port selected */
+	for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
+		u32 port_sel = I915_READ(VLV_PIPE_PP_ON_DELAYS(pipe)) &
+			PANEL_PORT_SELECT_MASK;
+		if (port_sel == PANEL_PORT_SELECT_DPB_VLV && port == PORT_B)
+			return pipe;
+		else if (port_sel == PANEL_PORT_SELECT_DPC && port == PORT_C)
+			return pipe;
+	}
+
+	/* shrug */
+	return PIPE_A;
+}
+
 static void
 intel_dp_init_panel_power_sequencer(struct drm_device *dev,
 				    struct intel_dp *intel_dp,
@@ -3154,24 +3202,26 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct edp_power_seq cur, vbt, spec, final;
 	u32 pp_on, pp_off, pp_div, pp;
-	int pp_control_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+	int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
 
 	if (HAS_PCH_SPLIT(dev)) {
-		pp_control_reg = PCH_PP_CONTROL;
+		pp_ctrl_reg = PCH_PP_CONTROL;
 		pp_on_reg = PCH_PP_ON_DELAYS;
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_div_reg = PCH_PP_DIVISOR;
 	} else {
-		pp_control_reg = PIPEA_PP_CONTROL;
-		pp_on_reg = PIPEA_PP_ON_DELAYS;
-		pp_off_reg = PIPEA_PP_OFF_DELAYS;
-		pp_div_reg = PIPEA_PP_DIVISOR;
+		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+
+		pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
+		pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+		pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
+		pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
 	}
 
 	/* Workaround: Need to write PP_CONTROL with the unlock key as
 	 * the very first thing. */
 	pp = ironlake_get_pp_control(intel_dp);
-	I915_WRITE(pp_control_reg, pp);
+	I915_WRITE(pp_ctrl_reg, pp);
 
 	pp_on = I915_READ(pp_on_reg);
 	pp_off = I915_READ(pp_off_reg);
@@ -3259,9 +3309,11 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 		pp_off_reg = PCH_PP_OFF_DELAYS;
 		pp_div_reg = PCH_PP_DIVISOR;
 	} else {
-		pp_on_reg = PIPEA_PP_ON_DELAYS;
-		pp_off_reg = PIPEA_PP_OFF_DELAYS;
-		pp_div_reg = PIPEA_PP_DIVISOR;
+		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+
+		pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+		pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
+		pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
 	}
 
 	/* And finally store the new values in the power sequencer. */
@@ -3278,7 +3330,10 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 	/* Haswell doesn't have any port selection bits for the panel
 	 * power sequencer any more. */
 	if (IS_VALLEYVIEW(dev)) {
-		port_sel = I915_READ(pp_on_reg) & 0xc0000000;
+		if (dp_to_dig_port(intel_dp)->port == PORT_B)
+			port_sel = PANEL_PORT_SELECT_DPB_VLV;
+		else
+			port_sel = PANEL_PORT_SELECT_DPC;
 	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
 		if (dp_to_dig_port(intel_dp)->port == PORT_A)
 			port_sel = PANEL_PORT_SELECT_DPA;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence
  2013-09-03 11:43 ` [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence Jani Nikula
@ 2013-09-04 18:30   ` Ville Syrjälä
  0 siblings, 0 replies; 7+ messages in thread
From: Ville Syrjälä @ 2013-09-04 18:30 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Tue, Sep 03, 2013 at 02:43:37PM +0300, Jani Nikula wrote:
> Follow-up to
> commit 5004945f1d6c0282c0288afa89ad85d7f2bea4d5
> Author: Jani Nikula <jani.nikula@intel.com>
> Date:   Tue Jul 30 12:20:32 2013 +0300
> 
>     drm/i915: move encoder->enable callback later in VLV crtc enable
> 
> Reference: http://mid.gmane.org/CAKMK7uFs9EMvMW8BnS24e5UNm1D7JrfVg3SD5SDFtVEamGfOOg@mail.gmail.com
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c |    8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index c192dbb..adbe7bc 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1717,11 +1717,17 @@ static void intel_enable_dp(struct intel_encoder *encoder)
>  	ironlake_edp_panel_vdd_off(intel_dp, true);
>  	intel_dp_complete_link_train(intel_dp);
>  	intel_dp_stop_link_train(intel_dp);
> -	ironlake_edp_backlight_on(intel_dp);
> +
> +	/* this function is called from vlv_pre_enable_dp() */
> +	if (!IS_VALLEYVIEW(dev))
> +		ironlake_edp_backlight_on(intel_dp);
>  }
>  
>  static void vlv_enable_dp(struct intel_encoder *encoder)
>  {
> +	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +
> +	ironlake_edp_backlight_on(intel_dp);
>  }

This feels a bit off to me since we've already started to use
separate functions for VLV vs. others. So how about something a bit
more in line with that design:

 	intel_enable_dp() {
 		...
-		ironlake_edp_backlight_on()
 	}
 
+	g4x_enable_dp() {
+		intel_enable_dp()
+		ironlake_edp_backlight_on()
+	}
 
 	vlv_enable_dp() {
+		ironlake_edp_backlight_on()
 	}
...
-		intel_encoder->enable = intel_enable_dp;
+		intel_encoder->enable = g4x_enable_dp;

And also perhaps s/intel_pre_enable_dp/g4x_pre_enable_dp/
and s/intel_dp_pre_pll_enable/vlv_dp_pre_pll_enable/
just to keep the naming somewhat predictable.

Also we could kill the !IS_VLV check from intel_dp_pre_pll_enable()
since we don't plug that guy in except on VLV.

>  
>  static void intel_pre_enable_dp(struct intel_encoder *encoder)
> -- 
> 1.7.9.5

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 2/3] drm/i915: clean up power sequencing register port select definitions
  2013-09-03 11:43 ` [RFC PATCH 2/3] drm/i915: clean up power sequencing register port select definitions Jani Nikula
@ 2013-09-05 11:55   ` Ville Syrjälä
  0 siblings, 0 replies; 7+ messages in thread
From: Ville Syrjälä @ 2013-09-05 11:55 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Tue, Sep 03, 2013 at 02:43:38PM +0300, Jani Nikula wrote:
> Remove dupes, add VLV port B.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h |    7 +------
>  drivers/gpu/drm/i915/intel_dp.c |    4 ++--
>  2 files changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index c7f2da3..accbd1f 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4449,6 +4449,7 @@
>  #define PIPEA_PP_STATUS         (VLV_DISPLAY_BASE + 0x61200)
>  #define PIPEA_PP_CONTROL        (VLV_DISPLAY_BASE + 0x61204)
>  #define PIPEA_PP_ON_DELAYS      (VLV_DISPLAY_BASE + 0x61208)
> +#define  PANEL_PORT_SELECT_DPB_VLV	(1 << 30)

The DPC value is the same as on other platforms, but since the
other values are not valid for VLV it might be a bit cleaner to
define also DPC_VLV here. I'm won't insist though if you don't
want it there.

>  #define PIPEA_PP_OFF_DELAYS     (VLV_DISPLAY_BASE + 0x6120c)
>  #define PIPEA_PP_DIVISOR        (VLV_DISPLAY_BASE + 0x61210)
>  
> @@ -4480,7 +4481,6 @@
>  #define  PANEL_PORT_SELECT_MASK	(3 << 30)
>  #define  PANEL_PORT_SELECT_LVDS	(0 << 30)
>  #define  PANEL_PORT_SELECT_DPA	(1 << 30)
> -#define  EDP_PANEL		(1 << 30)

Hmm. Yeah, the EDP bit is there only for CTG, and we don't do eDP on
CTG. I must assume such hardware never existed.

So w/ or w/o the DPC_VLV thing:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  #define  PANEL_PORT_SELECT_DPC	(2 << 30)
>  #define  PANEL_PORT_SELECT_DPD	(3 << 30)
>  #define  PANEL_POWER_UP_DELAY_MASK	(0x1fff0000)
> @@ -4489,11 +4489,6 @@
>  #define  PANEL_LIGHT_ON_DELAY_SHIFT	0
>  
>  #define PCH_PP_OFF_DELAYS	0xc720c
> -#define  PANEL_POWER_PORT_SELECT_MASK	(0x3 << 30)
> -#define  PANEL_POWER_PORT_LVDS		(0 << 30)
> -#define  PANEL_POWER_PORT_DP_A		(1 << 30)
> -#define  PANEL_POWER_PORT_DP_C		(2 << 30)
> -#define  PANEL_POWER_PORT_DP_D		(3 << 30)
>  #define  PANEL_POWER_DOWN_DELAY_MASK	(0x1fff0000)
>  #define  PANEL_POWER_DOWN_DELAY_SHIFT	16
>  #define  PANEL_LIGHT_OFF_DELAY_MASK	(0x1fff)
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index adbe7bc..0ba72f1 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3281,9 +3281,9 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
>  		port_sel = I915_READ(pp_on_reg) & 0xc0000000;
>  	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
>  		if (dp_to_dig_port(intel_dp)->port == PORT_A)
> -			port_sel = PANEL_POWER_PORT_DP_A;
> +			port_sel = PANEL_PORT_SELECT_DPA;
>  		else
> -			port_sel = PANEL_POWER_PORT_DP_D;
> +			port_sel = PANEL_PORT_SELECT_DPD;
>  	}
>  
>  	pp_on |= port_sel;
> -- 
> 1.7.9.5

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv
  2013-09-03 11:43 ` [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv Jani Nikula
@ 2013-09-05 12:12   ` Ville Syrjälä
  0 siblings, 0 replies; 7+ messages in thread
From: Ville Syrjälä @ 2013-09-05 12:12 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Tue, Sep 03, 2013 at 02:43:39PM +0300, Jani Nikula wrote:
> VLV has per-pipe PP registers. Set up power sequencing on mode set. The
> connector init time setup is problematic, since we don't have a pipe at
> that time. Cook up something.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c |  139 +++++++++++++++++++++++++++------------
>  1 file changed, 97 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 0ba72f1..95d67fc 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -237,24 +237,47 @@ intel_hrawclk(struct drm_device *dev)
>  	}
>  }
>  
> +static void
> +intel_dp_init_panel_power_sequencer(struct drm_device *dev,
> +				    struct intel_dp *intel_dp,
> +				    struct edp_power_seq *out);
> +static void
> +intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
> +				    struct intel_dp *intel_dp,
> +				    struct edp_power_seq *out);
> +
> +static u32 _pp_ctrl_reg(struct intel_dp *intel_dp)
> +{
> +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
> +
> +	return HAS_PCH_SPLIT(dev) ? PCH_PP_CONTROL : VLV_PIPE_PP_CONTROL(pipe);
> +}
> +
> +static u32 _pp_stat_reg(struct intel_dp *intel_dp)
> +{
> +	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
> +
> +	return HAS_PCH_SPLIT(dev) ? PCH_PP_STATUS : VLV_PIPE_PP_STATUS(pipe);
> +}
> +
>  static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 pp_stat_reg;
>  
> -	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> -	return (I915_READ(pp_stat_reg) & PP_ON) != 0;
> +	return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
>  }
>  
>  static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 pp_ctrl_reg;
>  
> -	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> -	return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0;
> +	return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0;
>  }
>  
>  static void
> @@ -262,19 +285,15 @@ intel_dp_check_edp(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	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(pp_stat_reg),
> -				I915_READ(pp_ctrl_reg));
> +			      I915_READ(_pp_stat_reg(intel_dp)),
> +			      I915_READ(_pp_ctrl_reg(intel_dp)));
>  	}
>  }
>  
> @@ -948,8 +967,8 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
>  	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;
> +	pp_stat_reg = _pp_stat_reg(intel_dp);
> +	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>  
>  	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
>  			mask, value,
> @@ -991,11 +1010,8 @@ static  u32 ironlake_get_pp_control(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	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 = I915_READ(_pp_ctrl_reg(intel_dp));
>  	control &= ~PANEL_UNLOCK_MASK;
>  	control |= PANEL_UNLOCK_REGS;
>  	return control;
> @@ -1028,8 +1044,8 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
>  	pp = ironlake_get_pp_control(intel_dp);
>  	pp |= EDP_FORCE_VDD;
>  
> -	pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> -	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	pp_stat_reg = _pp_stat_reg(intel_dp);
> +	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>  
>  	I915_WRITE(pp_ctrl_reg, pp);
>  	POSTING_READ(pp_ctrl_reg);
> @@ -1057,8 +1073,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
>  		pp = ironlake_get_pp_control(intel_dp);
>  		pp &= ~EDP_FORCE_VDD;
>  
> -		pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
> -		pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +		pp_stat_reg = _pp_ctrl_reg(intel_dp);
> +		pp_ctrl_reg = _pp_stat_reg(intel_dp);
>  
>  		I915_WRITE(pp_ctrl_reg, pp);
>  		POSTING_READ(pp_ctrl_reg);
> @@ -1123,20 +1139,19 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
>  
>  	ironlake_wait_panel_power_cycle(intel_dp);
>  
> +	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>  	pp = ironlake_get_pp_control(intel_dp);
>  	if (IS_GEN5(dev)) {
>  		/* ILK workaround: disable reset around power sequence */
>  		pp &= ~PANEL_POWER_RESET;
> -		I915_WRITE(PCH_PP_CONTROL, pp);
> -		POSTING_READ(PCH_PP_CONTROL);
> +		I915_WRITE(pp_ctrl_reg, pp);
> +		POSTING_READ(pp_ctrl_reg);
>  	}
>  
>  	pp |= POWER_TARGET_ON;
>  	if (!IS_GEN5(dev))
>  		pp |= PANEL_POWER_RESET;
>  
> -	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> -
>  	I915_WRITE(pp_ctrl_reg, pp);
>  	POSTING_READ(pp_ctrl_reg);
>  
> @@ -1144,8 +1159,8 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
>  
>  	if (IS_GEN5(dev)) {
>  		pp |= PANEL_POWER_RESET; /* restore panel reset bit */
> -		I915_WRITE(PCH_PP_CONTROL, pp);
> -		POSTING_READ(PCH_PP_CONTROL);
> +		I915_WRITE(pp_ctrl_reg, pp);
> +		POSTING_READ(pp_ctrl_reg);
>  	}
>  }
>  
> @@ -1168,7 +1183,7 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
>  	 * panels get very unhappy and cease to work. */
>  	pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
>  
> -	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>  
>  	I915_WRITE(pp_ctrl_reg, pp);
>  	POSTING_READ(pp_ctrl_reg);
> @@ -1201,7 +1216,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
>  	pp = ironlake_get_pp_control(intel_dp);
>  	pp |= EDP_BLC_ENABLE;
>  
> -	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>  
>  	I915_WRITE(pp_ctrl_reg, pp);
>  	POSTING_READ(pp_ctrl_reg);
> @@ -1225,7 +1240,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
>  	pp = ironlake_get_pp_control(intel_dp);
>  	pp &= ~EDP_BLC_ENABLE;
>  
> -	pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
> +	pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
>  
>  	I915_WRITE(pp_ctrl_reg, pp);
>  	POSTING_READ(pp_ctrl_reg);
> @@ -1748,6 +1763,7 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
>  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
>  	int port = vlv_dport_to_channel(dport);
>  	int pipe = intel_crtc->pipe;
> +	struct edp_power_seq power_seq;
>  	u32 val;
>  
>  	mutex_lock(&dev_priv->dpio_lock);
> @@ -1765,6 +1781,10 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
>  
>  	mutex_unlock(&dev_priv->dpio_lock);
>  
> +	/* init power sequencer on this pipe and port */
> +	intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
> +	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, &power_seq);
> +
>  	intel_enable_dp(encoder);
>  
>  	vlv_wait_port_ready(dev_priv, port);
> @@ -3146,6 +3166,34 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
>  	}
>  }
>  
> +static enum pipe
> +vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
> +{
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
> +	struct drm_device *dev = intel_dig_port->base.base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	enum port port = intel_dig_port->port;
> +	enum pipe pipe;
> +
> +	/* modeset should have pipe */
> +	if (crtc)
> +		return to_intel_crtc(crtc)->pipe;
> +
> +	/* init time, try to find a pipe with this port selected */
> +	for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
> +		u32 port_sel = I915_READ(VLV_PIPE_PP_ON_DELAYS(pipe)) &
> +			PANEL_PORT_SELECT_MASK;
> +		if (port_sel == PANEL_PORT_SELECT_DPB_VLV && port == PORT_B)
> +			return pipe;
> +		else if (port_sel == PANEL_PORT_SELECT_DPC && port == PORT_C)
> +			return pipe;
> +	}
> +
> +	/* shrug */
> +	return PIPE_A;

Yeah, looks reasonable enough to me. If the BIOS already set up
something keep using it, otherwise just pick A.

The only concern here is whether the power sequencer requires something
else to be set up? Maybe we'd need the DP port register to have the
matching pipe configured too? Would need to test that on real hardware I
suppose.

But to me this seems at least better than the current use pipe A
always situation:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +}
> +
>  static void
>  intel_dp_init_panel_power_sequencer(struct drm_device *dev,
>  				    struct intel_dp *intel_dp,
> @@ -3154,24 +3202,26 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct edp_power_seq cur, vbt, spec, final;
>  	u32 pp_on, pp_off, pp_div, pp;
> -	int pp_control_reg, pp_on_reg, pp_off_reg, pp_div_reg;
> +	int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
>  
>  	if (HAS_PCH_SPLIT(dev)) {
> -		pp_control_reg = PCH_PP_CONTROL;
> +		pp_ctrl_reg = PCH_PP_CONTROL;
>  		pp_on_reg = PCH_PP_ON_DELAYS;
>  		pp_off_reg = PCH_PP_OFF_DELAYS;
>  		pp_div_reg = PCH_PP_DIVISOR;
>  	} else {
> -		pp_control_reg = PIPEA_PP_CONTROL;
> -		pp_on_reg = PIPEA_PP_ON_DELAYS;
> -		pp_off_reg = PIPEA_PP_OFF_DELAYS;
> -		pp_div_reg = PIPEA_PP_DIVISOR;
> +		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
> +
> +		pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
> +		pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
> +		pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
> +		pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
>  	}
>  
>  	/* Workaround: Need to write PP_CONTROL with the unlock key as
>  	 * the very first thing. */
>  	pp = ironlake_get_pp_control(intel_dp);
> -	I915_WRITE(pp_control_reg, pp);
> +	I915_WRITE(pp_ctrl_reg, pp);
>  
>  	pp_on = I915_READ(pp_on_reg);
>  	pp_off = I915_READ(pp_off_reg);
> @@ -3259,9 +3309,11 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
>  		pp_off_reg = PCH_PP_OFF_DELAYS;
>  		pp_div_reg = PCH_PP_DIVISOR;
>  	} else {
> -		pp_on_reg = PIPEA_PP_ON_DELAYS;
> -		pp_off_reg = PIPEA_PP_OFF_DELAYS;
> -		pp_div_reg = PIPEA_PP_DIVISOR;
> +		enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
> +
> +		pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
> +		pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
> +		pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
>  	}
>  
>  	/* And finally store the new values in the power sequencer. */
> @@ -3278,7 +3330,10 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
>  	/* Haswell doesn't have any port selection bits for the panel
>  	 * power sequencer any more. */
>  	if (IS_VALLEYVIEW(dev)) {
> -		port_sel = I915_READ(pp_on_reg) & 0xc0000000;
> +		if (dp_to_dig_port(intel_dp)->port == PORT_B)
> +			port_sel = PANEL_PORT_SELECT_DPB_VLV;
> +		else
> +			port_sel = PANEL_PORT_SELECT_DPC;
>  	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
>  		if (dp_to_dig_port(intel_dp)->port == PORT_A)
>  			port_sel = PANEL_PORT_SELECT_DPA;
> -- 
> 1.7.9.5

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-09-05 12:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-03 11:43 [RFC PATCH 0/3] drm/i915: vlv backlight, per-pipe power sequencing fixes Jani Nikula
2013-09-03 11:43 ` [RFC PATCH 1/3] drm/i915: move backlight enable later in vlv enable sequence Jani Nikula
2013-09-04 18:30   ` Ville Syrjälä
2013-09-03 11:43 ` [RFC PATCH 2/3] drm/i915: clean up power sequencing register port select definitions Jani Nikula
2013-09-05 11:55   ` Ville Syrjälä
2013-09-03 11:43 ` [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv Jani Nikula
2013-09-05 12:12   ` Ville Syrjälä

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox