Actually set values into PPS related registers. This implementation is equivalent to intel_dp_panel_power_sequencer_registers where the values saved intially are written into registers. Signed-off-by: Vandana Kannan <vandana.kannan@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_dp.c | 80 ++------------------------------------ drivers/gpu/drm/i915/intel_drv.h | 3 ++ drivers/gpu/drm/i915/intel_panel.c | 70 +++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a433c5f..ca11eb1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -248,7 +248,7 @@ unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) } /* hrawclock is 1/4 the FSB frequency */ -static int +int intel_hrawclk(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -281,11 +281,6 @@ intel_hrawclk(struct drm_device *dev) } } -static void -intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, - struct intel_dp *intel_dp, - struct edp_power_seq *out); - static void pps_lock(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); @@ -4716,76 +4711,6 @@ static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp) intel_dp->last_backlight_off = jiffies; } -static void -intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, - struct intel_dp *intel_dp, - struct edp_power_seq *seq) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_connector *intel_connector = intel_dp->attached_connector; - struct intel_panel *panel = &intel_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 port port = dp_to_dig_port(intel_dp)->port; - - 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_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. The - * backlight delays are set to 1 because we do manual waits on them. For - * T8, even BSpec recommends doing it. For T9, if we don't do this, - * we'll end up waiting for the backlight off delay twice: once when we - * do the manual sleep, and once when we disable the panel and wait for - * the PP_STATUS bit to become zero. - */ - pp_on = (panel->pps.panel_power_up_delay << - PANEL_POWER_UP_DELAY_SHIFT) | - (1 << PANEL_LIGHT_ON_DELAY_SHIFT); - pp_off = (1 << PANEL_LIGHT_OFF_DELAY_SHIFT) | - (panel->pps.panel_power_down_delay << - PANEL_POWER_DOWN_DELAY_SHIFT); - /* Compute the divisor for the pp clock, simply match the Bspec - * formula. */ - pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT; - 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); - I915_WRITE(pp_off_reg, pp_off); - I915_WRITE(pp_div_reg, pp_div); - - DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n", - I915_READ(pp_on_reg), - I915_READ(pp_off_reg), - I915_READ(pp_div_reg)); -} - void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -4960,6 +4885,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, bool has_dpcd; struct drm_display_mode *scan; struct edid *edid; + enum port port = intel_dig_port->port; intel_dp->drrs_state.type = DRRS_NOT_SUPPORTED; @@ -4988,7 +4914,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, pps_lock(intel_dp); intel_dp_init_panel_power_timestamps(intel_dp); intel_panel_setup_panel_power_sequencer(intel_connector); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, power_seq); + intel_panel_set_pps_registers(intel_connector, port); pps_unlock(intel_dp); mutex_lock(&dev->mode_config.mutex); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 597e09f..4ae913c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1001,6 +1001,7 @@ enum pipe vlv_power_sequencer_pipe(struct intel_dp *intel_dp); void vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp); void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv); u32 ironlake_get_pp_control(struct intel_dp *intel_dp); +int intel_hrawclk(struct drm_device *dev); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port); @@ -1102,6 +1103,8 @@ extern struct drm_display_mode *intel_find_panel_downclock( struct drm_connector *connector); void intel_panel_setup_panel_power_sequencer( struct intel_connector *connector); +void intel_panel_set_pps_registers(struct intel_connector *connector, + enum port port); void intel_panel_init_pps_funcs(struct drm_device *dev); /* intel_runtime_pm.c */ diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 9b124ef..75172ab 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1346,6 +1346,76 @@ void intel_panel_init_backlight_funcs(struct drm_device *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 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; + + 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_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. The + * backlight delays are set to 1 because we do manual waits on them. For + * T8, even BSpec recommends doing it. For T9, if we don't do this, + * we'll end up waiting for the backlight off delay twice: once when we + * do the manual sleep, and once when we disable the panel and wait for + * the PP_STATUS bit to become zero. + */ + pp_on = (panel->pps.panel_power_up_delay << + PANEL_POWER_UP_DELAY_SHIFT) | + (1 << PANEL_LIGHT_ON_DELAY_SHIFT); + pp_off = (1 << PANEL_LIGHT_OFF_DELAY_SHIFT) | + (panel->pps.panel_power_down_delay << + PANEL_POWER_DOWN_DELAY_SHIFT); + /* Compute the divisor for the pp clock, simply match the Bspec + * formula. */ + pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT; + 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); + I915_WRITE(pp_off_reg, pp_off); + I915_WRITE(pp_div_reg, pp_div); + + DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n", + I915_READ(pp_on_reg), + I915_READ(pp_off_reg), + I915_READ(pp_div_reg)); +} + static struct edp_power_seq pch_get_pps_registers( struct intel_connector *connector, u32 pp_ctrl_reg, u32 pp_on_reg, -- 2.0.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx