diff mbox

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

Message ID 1413809409-8569-6-git-send-email-vandana.kannan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

vandana.kannan@intel.com Oct. 20, 2014, 12:50 p.m. UTC
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@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 mbox

Patch

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;
+	}
 }