@@ -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 {
@@ -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;
+ }
}
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(-)