[Intel-gfx] [RFC 5/7] drm/i915: Split PPS reg write func based on platform

Vandana Kannan vandana.kannan at intel.com
Mon Oct 20 14:50:07 CEST 2014


The difference between vlv and other platforms is w.r.t registers and port
selection. Splitting the function to get value to be programmed based on 
platform and making the part which writes into registers common.

Signed-off-by: Vandana Kannan <vandana.kannan at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h    |  4 ++
 drivers/gpu/drm/i915/intel_panel.c | 85 +++++++++++++++++++++++++-------------
 2 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1446d02..da0eede 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -511,6 +511,10 @@ struct drm_i915_display_funcs {
 
 	struct edp_power_seq (*setup_panel_power_seq)
 				(struct intel_connector *connector);
+	void (*set_pps_registers)(struct intel_connector *connector,
+			enum port port, int *pp_ctrl_reg,
+			int *pp_on_reg, int *pp_off_reg,
+			int *pp_div_reg, int *port_sel, int *div);
 };
 
 struct intel_uncore_funcs {
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 75172ab..c5e6c10 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1346,32 +1346,67 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
 	}
 }
 
-void
-intel_panel_set_pps_registers(struct intel_connector *connector,
-				enum port port)
+static void vlv_set_pps_registers(struct intel_connector *connector,
+		enum port port, int *pp_ctrl_reg,
+		int *pp_on_reg, int *pp_off_reg,
+		int *pp_div_reg, int *port_sel, int *div)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_encoder *encoder = connector->base.encoder;
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
-	struct intel_panel *panel = &connector->panel;
-	u32 pp_on, pp_off, pp_div, port_sel = 0;
-	int div = HAS_PCH_SPLIT(dev) ? intel_pch_rawclk(dev) : intel_hrawclk(dev);
-	int pp_on_reg, pp_off_reg, pp_div_reg;
+	enum pipe pipe = PIPE_A;
+
+	pipe = vlv_power_sequencer_pipe(&intel_dig_port->dp);
 
 	lockdep_assert_held(&dev_priv->pps_mutex);
 
-	if (HAS_PCH_SPLIT(dev)) {
-		pp_on_reg = PCH_PP_ON_DELAYS;
-		pp_off_reg = PCH_PP_OFF_DELAYS;
-		pp_div_reg = PCH_PP_DIVISOR;
-	} else {
-		enum pipe pipe = vlv_power_sequencer_pipe(&intel_dig_port->dp);
+	*pp_ctrl_reg = 0;
+	*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);
+
+	*port_sel = PANEL_PORT_SELECT_VLV(port);
+	*div = intel_hrawclk(dev);
+}
 
-		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);
+static void pch_set_pps_registers(struct intel_connector *connector,
+		enum port port, int *pp_ctrl_reg,
+		int *pp_on_reg, int *pp_off_reg,
+		int *pp_div_reg, int *port_sel, int *div)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	lockdep_assert_held(&dev_priv->pps_mutex);
+
+	*pp_ctrl_reg = 0;
+	*pp_on_reg = PCH_PP_ON_DELAYS;
+	*pp_off_reg = PCH_PP_OFF_DELAYS;
+	*pp_div_reg = PCH_PP_DIVISOR;
+
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+		if (port == PORT_A)
+			*port_sel = PANEL_PORT_SELECT_DPA;
+		else
+			*port_sel = PANEL_PORT_SELECT_DPD;
 	}
+	*div = intel_pch_rawclk(dev);
+}
+
+void
+intel_panel_set_pps_registers(struct intel_connector *connector,
+				enum port port)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
+	u32 pp_on, pp_off, pp_div, port_sel = 0, div;
+	int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+
+	dev_priv->display.set_pps_registers(connector, port, &pp_ctrl_reg,
+			&pp_on_reg, &pp_off_reg, &pp_div_reg,
+			&port_sel, &div);
 
 	/*
 	 * And finally store the new values in the power sequencer. The
@@ -1393,17 +1428,6 @@ intel_panel_set_pps_registers(struct intel_connector *connector,
 	pp_div |= (DIV_ROUND_UP(panel->pps.panel_power_cycle_delay, 1000)
 			<< PANEL_POWER_CYCLE_DELAY_SHIFT);
 
-	/* Haswell doesn't have any port selection bits for the panel
-	 * power sequencer any more. */
-	if (IS_VALLEYVIEW(dev)) {
-		port_sel = PANEL_PORT_SELECT_VLV(port);
-	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
-		if (port == PORT_A)
-			port_sel = PANEL_PORT_SELECT_DPA;
-		else
-			port_sel = PANEL_PORT_SELECT_DPD;
-	}
-
 	pp_on |= port_sel;
 
 	I915_WRITE(pp_on_reg, pp_on);
@@ -1561,10 +1585,13 @@ void intel_panel_init_pps_funcs(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_VALLEYVIEW(dev))
+	if (IS_VALLEYVIEW(dev)) {
 		dev_priv->display.setup_panel_power_seq = vlv_setup_pps;
-	else
+		dev_priv->display.set_pps_registers = vlv_set_pps_registers;
+	} else {
 		dev_priv->display.setup_panel_power_seq = pch_setup_pps;
+		dev_priv->display.set_pps_registers = pch_set_pps_registers;
+	}
 }
 
 	
-- 
2.0.1




More information about the Intel-gfx mailing list