X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fi915%2Fintel_dp.c;h=8935c5113ea71f7841a2ba0fb29ec8b1c4a50f35;hb=43072a454646d22f81808bdc8fb1b269ee1717a6;hp=a215a4641b25697208db743c040d0bc6079e156f;hpb=e39b999a6f229386ea6c58cb1c10ce9dc912869b;p=deliverable%2Flinux.git diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a215a4641b25..8935c5113ea7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -290,32 +290,201 @@ 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); + struct intel_encoder *encoder = &intel_dig_port->base; + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum intel_display_power_domain power_domain; + + /* + * See vlv_power_sequencer_reset() why we need + * a power domain reference here. + */ + power_domain = intel_display_port_power_domain(encoder); + intel_display_power_get(dev_priv, power_domain); + + mutex_lock(&dev_priv->pps_mutex); +} + +static void pps_unlock(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *encoder = &intel_dig_port->base; + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum intel_display_power_domain power_domain; + + mutex_unlock(&dev_priv->pps_mutex); + + power_domain = intel_display_port_power_domain(encoder); + intel_display_power_put(dev_priv, power_domain); +} + 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; + struct intel_encoder *encoder; + unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B); + struct edp_power_seq power_seq; lockdep_assert_held(&dev_priv->pps_mutex); - /* modeset should have pipe */ - if (crtc) - return to_intel_crtc(crtc)->pipe; + if (intel_dp->pps_pipe != INVALID_PIPE) + return intel_dp->pps_pipe; + + /* + * We don't have power sequencer currently. + * Pick one that's not used by other ports. + */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { + struct intel_dp *tmp; + + if (encoder->type != INTEL_OUTPUT_EDP) + continue; + + tmp = enc_to_intel_dp(&encoder->base); + + if (tmp->pps_pipe != INVALID_PIPE) + pipes &= ~(1 << tmp->pps_pipe); + } + + /* + * Didn't find one. This should not happen since there + * are two power sequencers and up to two eDP ports. + */ + if (WARN_ON(pipes == 0)) + return PIPE_A; + + intel_dp->pps_pipe = ffs(pipes) - 1; + + DRM_DEBUG_KMS("picked pipe %c power sequencer for port %c\n", + pipe_name(intel_dp->pps_pipe), + port_name(intel_dig_port->port)); + + /* 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); + + return intel_dp->pps_pipe; +} + +typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv, + enum pipe pipe); + +static bool vlv_pipe_has_pp_on(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + return I915_READ(VLV_PIPE_PP_STATUS(pipe)) & PP_ON; +} + +static bool vlv_pipe_has_vdd_on(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + return I915_READ(VLV_PIPE_PP_CONTROL(pipe)) & EDP_FORCE_VDD; +} + +static bool vlv_pipe_any(struct drm_i915_private *dev_priv, + enum pipe pipe) +{ + return true; +} + +static enum pipe +vlv_initial_pps_pipe(struct drm_i915_private *dev_priv, + enum port port, + vlv_pipe_check pipe_check) +{ + enum pipe 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_VLV(port)) - return pipe; + + if (port_sel != PANEL_PORT_SELECT_VLV(port)) + continue; + + if (!pipe_check(dev_priv, pipe)) + continue; + + return pipe; + } + + return INVALID_PIPE; +} + +static void +vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct edp_power_seq power_seq; + enum port port = intel_dig_port->port; + + lockdep_assert_held(&dev_priv->pps_mutex); + + /* try to find a pipe with this port selected */ + /* first pick one where the panel is on */ + intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port, + vlv_pipe_has_pp_on); + /* didn't find one? pick one where vdd is on */ + if (intel_dp->pps_pipe == INVALID_PIPE) + intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port, + vlv_pipe_has_vdd_on); + /* didn't find one? pick one with just the correct port */ + if (intel_dp->pps_pipe == INVALID_PIPE) + intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port, + vlv_pipe_any); + + /* didn't find one? just let vlv_power_sequencer_pipe() pick one when needed */ + if (intel_dp->pps_pipe == INVALID_PIPE) { + DRM_DEBUG_KMS("no initial power sequencer for port %c\n", + port_name(port)); + return; } - /* shrug */ - return PIPE_A; + DRM_DEBUG_KMS("initial power sequencer for port %c: pipe %c\n", + port_name(port), pipe_name(intel_dp->pps_pipe)); + + intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, + &power_seq); +} + +void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct intel_encoder *encoder; + + if (WARN_ON(!IS_VALLEYVIEW(dev))) + return; + + /* + * We can't grab pps_mutex here due to deadlock with power_domain + * mutex when power_domain functions are called while holding pps_mutex. + * That also means that in order to use pps_pipe the code needs to + * hold both a power domain reference and pps_mutex, and the power domain + * reference get/put must be done while _not_ holding pps_mutex. + * pps_{lock,unlock}() do these steps in the correct order, so one + * should use them always. + */ + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { + struct intel_dp *intel_dp; + + if (encoder->type != INTEL_OUTPUT_EDP) + continue; + + intel_dp = enc_to_intel_dp(&encoder->base); + intel_dp->pps_pipe = INVALID_PIPE; + } } static u32 _pp_ctrl_reg(struct intel_dp *intel_dp) @@ -353,7 +522,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, if (!is_edp(intel_dp) || code != SYS_RESTART) return 0; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); if (IS_VALLEYVIEW(dev)) { enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); @@ -369,7 +538,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, msleep(intel_dp->panel_power_cycle_delay); } - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); return 0; } @@ -388,15 +557,10 @@ static bool 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; - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct intel_encoder *intel_encoder = &intel_dig_port->base; - enum intel_display_power_domain power_domain; lockdep_assert_held(&dev_priv->pps_mutex); - power_domain = intel_display_port_power_domain(intel_encoder); - return intel_display_power_enabled(dev_priv, power_domain) && - (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0; + return I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD; } static void @@ -544,7 +708,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, bool has_aux_irq = HAS_AUX_IRQ(dev); bool vdd; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); /* * We will be called with VDD already enabled for dpcd/edid/oui reads. @@ -661,7 +825,7 @@ out: if (vdd) edp_panel_vdd_off(intel_dp, false); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); return ret; } @@ -1242,16 +1406,14 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) void intel_edp_panel_vdd_on(struct intel_dp *intel_dp) { - struct drm_i915_private *dev_priv = - intel_dp_to_dev(intel_dp)->dev_private; bool vdd; if (!is_edp(intel_dp)) return; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); vdd = edp_panel_vdd_on(intel_dp); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); WARN(!vdd, "eDP VDD already requested on\n"); } @@ -1300,13 +1462,11 @@ static void edp_panel_vdd_work(struct work_struct *__work) { struct intel_dp *intel_dp = container_of(to_delayed_work(__work), struct intel_dp, panel_vdd_work); - struct drm_i915_private *dev_priv = - intel_dp_to_dev(intel_dp)->dev_private; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); if (!intel_dp->want_panel_vdd) edp_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp) @@ -1344,15 +1504,12 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) static void intel_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) { - struct drm_i915_private *dev_priv = - intel_dp_to_dev(intel_dp)->dev_private; - if (!is_edp(intel_dp)) return; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); edp_panel_vdd_off(intel_dp, sync); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } void intel_edp_panel_on(struct intel_dp *intel_dp) @@ -1367,7 +1524,7 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) DRM_DEBUG_KMS("Turn eDP power on\n"); - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); if (edp_have_panel_power(intel_dp)) { DRM_DEBUG_KMS("eDP power already on\n"); @@ -1402,7 +1559,7 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) } out: - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } void intel_edp_panel_off(struct intel_dp *intel_dp) @@ -1420,7 +1577,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) DRM_DEBUG_KMS("Turn eDP power off\n"); - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); @@ -1444,7 +1601,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_put(dev_priv, power_domain); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } /* Enable backlight in the panel power control. */ @@ -1464,7 +1621,7 @@ static void _intel_edp_backlight_on(struct intel_dp *intel_dp) */ wait_backlight_on(intel_dp); - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); pp = ironlake_get_pp_control(intel_dp); pp |= EDP_BLC_ENABLE; @@ -1474,7 +1631,7 @@ static void _intel_edp_backlight_on(struct intel_dp *intel_dp) I915_WRITE(pp_ctrl_reg, pp); POSTING_READ(pp_ctrl_reg); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } /* Enable backlight PWM and backlight PP control. */ @@ -1500,7 +1657,7 @@ static void _intel_edp_backlight_off(struct intel_dp *intel_dp) if (!is_edp(intel_dp)) return; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); pp = ironlake_get_pp_control(intel_dp); pp &= ~EDP_BLC_ENABLE; @@ -1510,7 +1667,7 @@ static void _intel_edp_backlight_off(struct intel_dp *intel_dp) I915_WRITE(pp_ctrl_reg, pp); POSTING_READ(pp_ctrl_reg); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); intel_dp->last_backlight_off = jiffies; edp_wait_backlight_off(intel_dp); @@ -1535,13 +1692,12 @@ void intel_edp_backlight_off(struct intel_dp *intel_dp) static void intel_edp_backlight_power(struct intel_connector *connector, bool enable) { - struct drm_i915_private *dev_priv = connector->base.dev->dev_private; struct intel_dp *intel_dp = intel_attached_dp(&connector->base); bool is_enabled; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); is_enabled = ironlake_get_pp_control(intel_dp) & EDP_BLC_ENABLE; - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); if (is_enabled == enable) return; @@ -2218,10 +2374,10 @@ static void intel_enable_dp(struct intel_encoder *encoder) return; intel_edp_panel_vdd_on(intel_dp); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); - intel_dp_start_link_train(intel_dp); intel_edp_panel_on(intel_dp); intel_edp_panel_vdd_off(intel_dp, true); + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); + intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); } @@ -2255,6 +2411,78 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder) } } +static void vlv_steal_power_sequencer(struct drm_device *dev, + enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_encoder *encoder; + + lockdep_assert_held(&dev_priv->pps_mutex); + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { + struct intel_dp *intel_dp; + enum port port; + + if (encoder->type != INTEL_OUTPUT_EDP) + continue; + + intel_dp = enc_to_intel_dp(&encoder->base); + port = dp_to_dig_port(intel_dp)->port; + + if (intel_dp->pps_pipe != pipe) + continue; + + DRM_DEBUG_KMS("stealing pipe %c power sequencer from port %c\n", + pipe_name(pipe), port_name(port)); + + /* make sure vdd is off before we steal it */ + edp_panel_vdd_off_sync(intel_dp); + + intel_dp->pps_pipe = INVALID_PIPE; + } +} + +static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct intel_encoder *encoder = &intel_dig_port->base; + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + struct edp_power_seq power_seq; + + lockdep_assert_held(&dev_priv->pps_mutex); + + if (intel_dp->pps_pipe == crtc->pipe) + return; + + /* + * If another power sequencer was being used on this + * port previously make sure to turn off vdd there while + * we still have control of it. + */ + if (intel_dp->pps_pipe != INVALID_PIPE) + edp_panel_vdd_off_sync(intel_dp); + + /* + * We may be stealing the power + * sequencer from another port. + */ + vlv_steal_power_sequencer(dev, crtc->pipe); + + /* now it's all ours */ + intel_dp->pps_pipe = crtc->pipe; + + DRM_DEBUG_KMS("initializing pipe %c power sequencer for port %c\n", + pipe_name(intel_dp->pps_pipe), port_name(intel_dig_port->port)); + + /* 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); +} + static void vlv_pre_enable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); @@ -2264,7 +2492,6 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel 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); @@ -2283,12 +2510,9 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpio_lock); if (is_edp(intel_dp)) { - /* init power sequencer on this pipe and port */ - mutex_lock(&dev_priv->pps_mutex); - intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, - &power_seq); - mutex_unlock(&dev_priv->pps_mutex); + pps_lock(intel_dp); + vlv_init_panel_power_sequencer(intel_dp); + pps_unlock(intel_dp); } intel_enable_dp(encoder); @@ -2332,7 +2556,6 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) struct intel_digital_port *dport = dp_to_dig_port(intel_dp); struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct edp_power_seq power_seq; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel ch = vlv_dport_to_channel(dport); @@ -2378,12 +2601,9 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpio_lock); if (is_edp(intel_dp)) { - /* init power sequencer on this pipe and port */ - mutex_lock(&dev_priv->pps_mutex); - intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, - &power_seq); - mutex_unlock(&dev_priv->pps_mutex); + pps_lock(intel_dp); + vlv_init_panel_power_sequencer(intel_dp); + pps_unlock(intel_dp); } intel_enable_dp(encoder); @@ -4122,17 +4342,16 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &intel_dig_port->dp; - struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; drm_dp_aux_unregister(&intel_dp->aux); intel_dp_mst_encoder_cleanup(intel_dig_port); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { cancel_delayed_work_sync(&intel_dp->panel_vdd_work); - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); edp_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); + if (intel_dp->edp_notifier.notifier_call) { unregister_reboot_notifier(&intel_dp->edp_notifier); intel_dp->edp_notifier.notifier_call = NULL; @@ -4144,15 +4363,13 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); - struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; if (!is_edp(intel_dp)) return; - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); edp_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } static void intel_dp_encoder_reset(struct drm_encoder *encoder) @@ -4631,9 +4848,10 @@ void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder) if (intel_encoder->type != INTEL_OUTPUT_EDP) return; - mutex_lock(&dev_priv->pps_mutex); - intel_dp = enc_to_intel_dp(&intel_encoder->base); + + pps_lock(intel_dp); + if (!edp_have_panel_vdd(intel_dp)) goto out; /* @@ -4648,7 +4866,7 @@ void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder) edp_panel_vdd_schedule_off(intel_dp); out: - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } static bool intel_edp_init_connector(struct intel_dp *intel_dp, @@ -4690,9 +4908,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } /* We now know it's not a ghost, init power sequence regs. */ - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, power_seq); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); mutex_lock(&dev->mode_config.mutex); edid = drm_get_edid(connector, &intel_dp->aux.ddc); @@ -4755,6 +4973,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct edp_power_seq power_seq = { 0 }; int type; + intel_dp->pps_pipe = INVALID_PIPE; + /* intel_dp vfuncs */ if (IS_VALLEYVIEW(dev)) intel_dp->get_aux_clock_divider = vlv_get_aux_clock_divider; @@ -4825,10 +5045,15 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, } if (is_edp(intel_dp)) { - mutex_lock(&dev_priv->pps_mutex); - intel_dp_init_panel_power_timestamps(intel_dp); - intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); - mutex_unlock(&dev_priv->pps_mutex); + pps_lock(intel_dp); + if (IS_VALLEYVIEW(dev)) { + vlv_initial_power_sequencer_setup(intel_dp); + } else { + intel_dp_init_panel_power_timestamps(intel_dp); + intel_dp_init_panel_power_sequencer(dev, intel_dp, + &power_seq); + } + pps_unlock(intel_dp); } intel_dp_aux_init(intel_dp, intel_connector); @@ -4836,7 +5061,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, /* init MST on ports that can support it */ if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { if (port == PORT_B || port == PORT_C || port == PORT_D) { - intel_dp_mst_encoder_init(intel_dig_port, intel_connector->base.base.id); + intel_dp_mst_encoder_init(intel_dig_port, + intel_connector->base.base.id); } } @@ -4844,9 +5070,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, drm_dp_aux_unregister(&intel_dp->aux); if (is_edp(intel_dp)) { cancel_delayed_work_sync(&intel_dp->panel_vdd_work); - mutex_lock(&dev_priv->pps_mutex); + pps_lock(intel_dp); edp_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev_priv->pps_mutex); + pps_unlock(intel_dp); } drm_connector_unregister(connector); drm_connector_cleanup(connector);