Merge tag 'drm-intel-next-2014-11-07-fixups' of git://anongit.freedesktop.org/drm-intel into drm-next

- skl watermarks code (Damien, Vandana, Pradeep)
- reworked audio codec /eld handling code (Jani)
- rework the mmio_flip code to use the vblank evade logic and wait for rendering
  using the standard wait_seqno interface (Ander)
- skl forcewake support (Zhe Wang)
- refactor the chv interrupt code to use functions shared with vlv (Ville)
- prep work for different global gtt views (Tvrtko Ursulin)
- precompute the display PLL config before touching hw state (Ander)
- completely reworked panel power sequencer code for chv/vlv (Ville)
- pre work to split the plane update code into a prepare and commit phase
  (Gustavo Padovan)
- golden context for skl (Armin Reese)
- as usual tons of fixes and improvements all over

* tag 'drm-intel-next-2014-11-07-fixups' of git://anongit.freedesktop.org/drm-intel: (135 commits)
  drm/i915: Use correct pipe config to update pll dividers. V2
  drm/i915: Plug memory leak in intel_shared_dpll_start_config()
  drm/i915: Update DRIVER_DATE to 20141107
  drm/i915: Add gen to the gpu hang ecode
  drm/i915: Cache HPLL frequency on VLV/CHV
  Revert "drm/i915/vlv: Remove check for Old Ack during forcewake"
  drm/i915: Make mmio flip wait for seqno in the work function
  drm/i915: Make __wait_seqno non-static and rename to __i915_wait_seqno
  drm/i915: Move the .global_resources() hook call into modeset_update_crtc_power_domains()
  drm/i915/audio: add DOC comment describing HDA over HDMI/DP
  drm/i915: make pipe/port based audio valid accessors easier to use
  drm/i915/audio: add audio codec enable debug log for g4x
  drm/i915/audio: add audio codec disable on g4x
  drm/i915: enable audio codec after port
  drm/i915/audio: add vlv/chv/gen5-7 audio codec disable sequence
  drm/i915/audio: rewrite vlv/chv and gen 5-7 audio codec enable sequence
  drm/i915/skl: Enable Gen9 RC6
  drm/i915/skl: Gen9 Forcewake
  drm/i915/skl: Log the order in which we flush the pipes in the WM code
  drm/i915/skl: Flush the WM configuration
  ...
This commit is contained in:
Dave Airlie
2014-11-15 09:33:40 +10:00
35 changed files with 5167 additions and 1661 deletions

View File

@@ -113,6 +113,9 @@ static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
static void intel_dp_link_down(struct intel_dp *intel_dp);
static bool edp_panel_vdd_on(struct intel_dp *intel_dp);
static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp);
static void vlv_steal_power_sequencer(struct drm_device *dev,
enum pipe pipe);
int
intel_dp_max_link_bw(struct intel_dp *intel_dp)
@@ -283,12 +286,10 @@ intel_hrawclk(struct drm_device *dev)
static void
intel_dp_init_panel_power_sequencer(struct drm_device *dev,
struct intel_dp *intel_dp,
struct edp_power_seq *out);
struct intel_dp *intel_dp);
static void
intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
struct intel_dp *intel_dp,
struct edp_power_seq *out);
struct intel_dp *intel_dp);
static void pps_lock(struct intel_dp *intel_dp)
{
@@ -322,6 +323,66 @@ static void pps_unlock(struct intel_dp *intel_dp)
intel_display_power_put(dev_priv, power_domain);
}
static void
vlv_power_sequencer_kick(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;
enum pipe pipe = intel_dp->pps_pipe;
bool pll_enabled;
uint32_t DP;
if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN,
"skipping pipe %c power seqeuncer kick due to port %c being active\n",
pipe_name(pipe), port_name(intel_dig_port->port)))
return;
DRM_DEBUG_KMS("kicking pipe %c power sequencer for port %c\n",
pipe_name(pipe), port_name(intel_dig_port->port));
/* Preserve the BIOS-computed detected bit. This is
* supposed to be read-only.
*/
DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
DP |= DP_PORT_WIDTH(1);
DP |= DP_LINK_TRAIN_PAT_1;
if (IS_CHERRYVIEW(dev))
DP |= DP_PIPE_SELECT_CHV(pipe);
else if (pipe == PIPE_B)
DP |= DP_PIPEB_SELECT;
pll_enabled = I915_READ(DPLL(pipe)) & DPLL_VCO_ENABLE;
/*
* The DPLL for the pipe must be enabled for this to work.
* So enable temporarily it if it's not already enabled.
*/
if (!pll_enabled)
vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ?
&chv_dpll[0].dpll : &vlv_dpll[0].dpll);
/*
* Similar magic as in intel_dp_enable_port().
* We _must_ do this port enable + disable trick
* to make this power seqeuencer lock onto the port.
* Otherwise even VDD force bit won't work.
*/
I915_WRITE(intel_dp->output_reg, DP);
POSTING_READ(intel_dp->output_reg);
I915_WRITE(intel_dp->output_reg, DP | DP_PORT_EN);
POSTING_READ(intel_dp->output_reg);
I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN);
POSTING_READ(intel_dp->output_reg);
if (!pll_enabled)
vlv_force_pll_off(dev, pipe);
}
static enum pipe
vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
{
@@ -330,10 +391,13 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B);
struct edp_power_seq power_seq;
enum pipe pipe;
lockdep_assert_held(&dev_priv->pps_mutex);
/* We should never land here with regular DP ports */
WARN_ON(!is_edp(intel_dp));
if (intel_dp->pps_pipe != INVALID_PIPE)
return intel_dp->pps_pipe;
@@ -359,18 +423,26 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
* are two power sequencers and up to two eDP ports.
*/
if (WARN_ON(pipes == 0))
return PIPE_A;
pipe = PIPE_A;
else
pipe = ffs(pipes) - 1;
intel_dp->pps_pipe = ffs(pipes) - 1;
vlv_steal_power_sequencer(dev, pipe);
intel_dp->pps_pipe = pipe;
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);
intel_dp_init_panel_power_sequencer(dev, intel_dp);
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
/*
* Even vdd force doesn't work until we've made
* the power sequencer lock in on the port.
*/
vlv_power_sequencer_kick(intel_dp);
return intel_dp->pps_pipe;
}
@@ -425,7 +497,6 @@ 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);
@@ -453,9 +524,8 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
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);
intel_dp_init_panel_power_sequencer(dev, intel_dp);
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
}
void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv)
@@ -550,6 +620,10 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp)
lockdep_assert_held(&dev_priv->pps_mutex);
if (IS_VALLEYVIEW(dev) &&
intel_dp->pps_pipe == INVALID_PIPE)
return false;
return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
}
@@ -560,6 +634,10 @@ static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
lockdep_assert_held(&dev_priv->pps_mutex);
if (IS_VALLEYVIEW(dev) &&
intel_dp->pps_pipe == INVALID_PIPE)
return false;
return I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD;
}
@@ -1246,12 +1324,8 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
if (crtc->config.has_audio) {
DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
pipe_name(crtc->pipe));
if (crtc->config.has_audio)
intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
intel_write_eld(&encoder->base, adjusted_mode);
}
/* Split out the IBX/CPU vs CPT settings */
@@ -1409,7 +1483,8 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
DRM_DEBUG_KMS("Turning eDP VDD on\n");
DRM_DEBUG_KMS("Turning eDP port %c VDD on\n",
port_name(intel_dig_port->port));
if (!edp_have_panel_power(intel_dp))
wait_panel_power_cycle(intel_dp);
@@ -1428,7 +1503,8 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
* If the panel wasn't on, delay before accessing aux channel
*/
if (!edp_have_panel_power(intel_dp)) {
DRM_DEBUG_KMS("eDP was not running\n");
DRM_DEBUG_KMS("eDP port %c panel power wasn't enabled\n",
port_name(intel_dig_port->port));
msleep(intel_dp->panel_power_up_delay);
}
@@ -1453,7 +1529,8 @@ void intel_edp_panel_vdd_on(struct intel_dp *intel_dp)
vdd = edp_panel_vdd_on(intel_dp);
pps_unlock(intel_dp);
WARN(!vdd, "eDP VDD already requested on\n");
WARN(!vdd, "eDP port %c VDD already requested on\n",
port_name(dp_to_dig_port(intel_dp)->port));
}
static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
@@ -1474,7 +1551,8 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
if (!edp_have_panel_vdd(intel_dp))
return;
DRM_DEBUG_KMS("Turning eDP VDD off\n");
DRM_DEBUG_KMS("Turning eDP port %c VDD off\n",
port_name(intel_dig_port->port));
pp = ironlake_get_pp_control(intel_dp);
pp &= ~EDP_FORCE_VDD;
@@ -1535,7 +1613,8 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
if (!is_edp(intel_dp))
return;
WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on");
WARN(!intel_dp->want_panel_vdd, "eDP port %c VDD not forced on",
port_name(dp_to_dig_port(intel_dp)->port));
intel_dp->want_panel_vdd = false;
@@ -1545,40 +1624,25 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
edp_panel_vdd_schedule_off(intel_dp);
}
/*
* Must be paired with intel_edp_panel_vdd_on().
* Nested calls to these functions are not allowed since
* we drop the lock. Caller must use some higher level
* locking to prevent nested calls from other threads.
*/
static void intel_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
{
if (!is_edp(intel_dp))
return;
pps_lock(intel_dp);
edp_panel_vdd_off(intel_dp, sync);
pps_unlock(intel_dp);
}
void intel_edp_panel_on(struct intel_dp *intel_dp)
static void edp_panel_on(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
u32 pp;
u32 pp_ctrl_reg;
lockdep_assert_held(&dev_priv->pps_mutex);
if (!is_edp(intel_dp))
return;
DRM_DEBUG_KMS("Turn eDP power on\n");
DRM_DEBUG_KMS("Turn eDP port %c panel power on\n",
port_name(dp_to_dig_port(intel_dp)->port));
pps_lock(intel_dp);
if (edp_have_panel_power(intel_dp)) {
DRM_DEBUG_KMS("eDP power already on\n");
goto out;
}
if (WARN(edp_have_panel_power(intel_dp),
"eDP port %c panel power already on\n",
port_name(dp_to_dig_port(intel_dp)->port)))
return;
wait_panel_power_cycle(intel_dp);
@@ -1606,12 +1670,20 @@ void intel_edp_panel_on(struct intel_dp *intel_dp)
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
}
}
out:
void intel_edp_panel_on(struct intel_dp *intel_dp)
{
if (!is_edp(intel_dp))
return;
pps_lock(intel_dp);
edp_panel_on(intel_dp);
pps_unlock(intel_dp);
}
void intel_edp_panel_off(struct intel_dp *intel_dp)
static void edp_panel_off(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *intel_encoder = &intel_dig_port->base;
@@ -1621,14 +1693,16 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
u32 pp;
u32 pp_ctrl_reg;
lockdep_assert_held(&dev_priv->pps_mutex);
if (!is_edp(intel_dp))
return;
DRM_DEBUG_KMS("Turn eDP power off\n");
DRM_DEBUG_KMS("Turn eDP port %c panel power off\n",
port_name(dp_to_dig_port(intel_dp)->port));
pps_lock(intel_dp);
WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
WARN(!intel_dp->want_panel_vdd, "Need eDP port %c VDD to turn off panel\n",
port_name(dp_to_dig_port(intel_dp)->port));
pp = ironlake_get_pp_control(intel_dp);
/* We need to switch off panel power _and_ force vdd, for otherwise some
@@ -1649,7 +1723,15 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
/* We got a reference when we enabled the VDD. */
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_put(dev_priv, power_domain);
}
void intel_edp_panel_off(struct intel_dp *intel_dp)
{
if (!is_edp(intel_dp))
return;
pps_lock(intel_dp);
edp_panel_off(intel_dp);
pps_unlock(intel_dp);
}
@@ -2368,6 +2450,10 @@ static void intel_disable_dp(struct intel_encoder *encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
struct drm_device *dev = encoder->base.dev;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
if (crtc->config.has_audio)
intel_audio_codec_disable(encoder);
/* Make sure the panel is off before trying to change the mode. But also
* ensure that we have vdd while we switch off the panel. */
@@ -2522,14 +2608,23 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
intel_dp->DP |= DP_PORT_EN;
/* enable with pattern 1 (as per spec) */
_intel_dp_set_link_train(intel_dp, &intel_dp->DP,
DP_TRAINING_PATTERN_1);
I915_WRITE(intel_dp->output_reg, intel_dp->DP);
POSTING_READ(intel_dp->output_reg);
/*
* Magic for VLV/CHV. We _must_ first set up the register
* without actually enabling the port, and then do another
* write to enable the port. Otherwise link training will
* fail when the power sequencer is freshly used for this port.
*/
intel_dp->DP |= DP_PORT_EN;
I915_WRITE(intel_dp->output_reg, intel_dp->DP);
POSTING_READ(intel_dp->output_reg);
}
static void intel_enable_dp(struct intel_encoder *encoder)
@@ -2537,19 +2632,38 @@ static void intel_enable_dp(struct intel_encoder *encoder)
struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->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);
uint32_t dp_reg = I915_READ(intel_dp->output_reg);
if (WARN_ON(dp_reg & DP_PORT_EN))
return;
pps_lock(intel_dp);
if (IS_VALLEYVIEW(dev))
vlv_init_panel_power_sequencer(intel_dp);
intel_dp_enable_port(intel_dp);
intel_edp_panel_vdd_on(intel_dp);
intel_edp_panel_on(intel_dp);
intel_edp_panel_vdd_off(intel_dp, true);
edp_panel_vdd_on(intel_dp);
edp_panel_on(intel_dp);
edp_panel_vdd_off(intel_dp, true);
pps_unlock(intel_dp);
if (IS_VALLEYVIEW(dev))
vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp));
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);
if (crtc->config.has_audio) {
DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
pipe_name(crtc->pipe));
intel_audio_codec_enable(encoder);
}
}
static void g4x_enable_dp(struct intel_encoder *encoder)
@@ -2581,6 +2695,32 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder)
}
}
static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = intel_dig_port->base.base.dev->dev_private;
enum pipe pipe = intel_dp->pps_pipe;
int pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
edp_panel_vdd_off_sync(intel_dp);
/*
* VLV seems to get confused when multiple power seqeuencers
* have the same port selected (even if only one has power/vdd
* enabled). The failure manifests as vlv_wait_port_ready() failing
* CHV on the other hand doesn't seem to mind having the same port
* selected in multiple power seqeuencers, but let's clear the
* port select always when logically disconnecting a power sequencer
* from a port.
*/
DRM_DEBUG_KMS("detaching pipe %c power sequencer from port %c\n",
pipe_name(pipe), port_name(intel_dig_port->port));
I915_WRITE(pp_on_reg, 0);
POSTING_READ(pp_on_reg);
intel_dp->pps_pipe = INVALID_PIPE;
}
static void vlv_steal_power_sequencer(struct drm_device *dev,
enum pipe pipe)
{
@@ -2589,6 +2729,9 @@ static void vlv_steal_power_sequencer(struct drm_device *dev,
lockdep_assert_held(&dev_priv->pps_mutex);
if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
return;
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
base.head) {
struct intel_dp *intel_dp;
@@ -2606,10 +2749,12 @@ static void vlv_steal_power_sequencer(struct drm_device *dev,
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);
WARN(encoder->connectors_active,
"stealing pipe %c power sequencer from active eDP port %c\n",
pipe_name(pipe), port_name(port));
intel_dp->pps_pipe = INVALID_PIPE;
/* make sure vdd is off before we steal it */
vlv_detach_power_sequencer(intel_dp);
}
}
@@ -2620,10 +2765,12 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
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 (!is_edp(intel_dp))
return;
if (intel_dp->pps_pipe == crtc->pipe)
return;
@@ -2633,7 +2780,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
* we still have control of it.
*/
if (intel_dp->pps_pipe != INVALID_PIPE)
edp_panel_vdd_off_sync(intel_dp);
vlv_detach_power_sequencer(intel_dp);
/*
* We may be stealing the power
@@ -2648,9 +2795,8 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
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);
intel_dp_init_panel_power_sequencer(dev, intel_dp);
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
}
static void vlv_pre_enable_dp(struct intel_encoder *encoder)
@@ -2679,15 +2825,7 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock);
if (is_edp(intel_dp)) {
pps_lock(intel_dp);
vlv_init_panel_power_sequencer(intel_dp);
pps_unlock(intel_dp);
}
intel_enable_dp(encoder);
vlv_wait_port_ready(dev_priv, dport);
}
static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
@@ -2779,15 +2917,7 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock);
if (is_edp(intel_dp)) {
pps_lock(intel_dp);
vlv_init_panel_power_sequencer(intel_dp);
pps_unlock(intel_dp);
}
intel_enable_dp(encoder);
vlv_wait_port_ready(dev_priv, dport);
}
static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
@@ -3696,7 +3826,6 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
/* Try 5 times, then try clock recovery if that fails */
if (tries > 5) {
intel_dp_link_down(intel_dp);
intel_dp_start_link_train(intel_dp);
intel_dp_set_link_train(intel_dp, &DP,
training_pattern |
@@ -3854,8 +3983,6 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;
intel_edp_panel_vdd_on(intel_dp);
if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_SINK_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
@@ -3863,8 +3990,6 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_BRANCH_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
intel_edp_panel_vdd_off(intel_dp, false);
}
static bool
@@ -3878,7 +4003,6 @@ intel_dp_probe_mst(struct intel_dp *intel_dp)
if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
return false;
intel_edp_panel_vdd_on(intel_dp);
if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) {
if (buf[0] & DP_MST_CAP) {
DRM_DEBUG_KMS("Sink is MST capable\n");
@@ -3888,7 +4012,6 @@ intel_dp_probe_mst(struct intel_dp *intel_dp)
intel_dp->is_mst = false;
}
}
intel_edp_panel_vdd_off(intel_dp, false);
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
return intel_dp->is_mst;
@@ -4568,9 +4691,52 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
pps_unlock(intel_dp);
}
static void intel_edp_panel_vdd_sanitize(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;
enum intel_display_power_domain power_domain;
lockdep_assert_held(&dev_priv->pps_mutex);
if (!edp_have_panel_vdd(intel_dp))
return;
/*
* The VDD bit needs a power domain reference, so if the bit is
* already enabled when we boot or resume, grab this reference and
* schedule a vdd off, so we don't hold on to the reference
* indefinitely.
*/
DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
power_domain = intel_display_port_power_domain(&intel_dig_port->base);
intel_display_power_get(dev_priv, power_domain);
edp_panel_vdd_schedule_off(intel_dp);
}
static void intel_dp_encoder_reset(struct drm_encoder *encoder)
{
intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
struct intel_dp *intel_dp;
if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
return;
intel_dp = enc_to_intel_dp(encoder);
pps_lock(intel_dp);
/*
* Read out the current power sequencer assignment,
* in case the BIOS did something with it.
*/
if (IS_VALLEYVIEW(encoder->dev))
vlv_initial_power_sequencer_setup(intel_dp);
intel_edp_panel_vdd_sanitize(intel_dp);
pps_unlock(intel_dp);
}
static const struct drm_connector_funcs intel_dp_connector_funcs = {
@@ -4757,16 +4923,20 @@ static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp)
static void
intel_dp_init_panel_power_sequencer(struct drm_device *dev,
struct intel_dp *intel_dp,
struct edp_power_seq *out)
struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct edp_power_seq cur, vbt, spec, final;
struct edp_power_seq cur, vbt, spec,
*final = &intel_dp->pps_delays;
u32 pp_on, pp_off, pp_div, pp;
int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
lockdep_assert_held(&dev_priv->pps_mutex);
/* already initialized? */
if (final->t11_t12 != 0)
return;
if (HAS_PCH_SPLIT(dev)) {
pp_ctrl_reg = PCH_PP_CONTROL;
pp_on_reg = PCH_PP_ON_DELAYS;
@@ -4828,7 +4998,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
/* Use the max of the register settings and vbt. If both are
* unset, fall back to the spec limits. */
#define assign_final(field) final.field = (max(cur.field, vbt.field) == 0 ? \
#define assign_final(field) final->field = (max(cur.field, vbt.field) == 0 ? \
spec.field : \
max(cur.field, vbt.field))
assign_final(t1_t3);
@@ -4838,7 +5008,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
assign_final(t11_t12);
#undef assign_final
#define get_delay(field) (DIV_ROUND_UP(final.field, 10))
#define get_delay(field) (DIV_ROUND_UP(final->field, 10))
intel_dp->panel_power_up_delay = get_delay(t1_t3);
intel_dp->backlight_on_delay = get_delay(t8);
intel_dp->backlight_off_delay = get_delay(t9);
@@ -4852,21 +5022,18 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
if (out)
*out = final;
}
static void
intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
struct intel_dp *intel_dp,
struct edp_power_seq *seq)
struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
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;
const struct edp_power_seq *seq = &intel_dp->pps_delays;
lockdep_assert_held(&dev_priv->pps_mutex);
@@ -5052,40 +5219,8 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
return downclock_mode;
}
void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
{
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp *intel_dp;
enum intel_display_power_domain power_domain;
if (intel_encoder->type != INTEL_OUTPUT_EDP)
return;
intel_dp = enc_to_intel_dp(&intel_encoder->base);
pps_lock(intel_dp);
if (!edp_have_panel_vdd(intel_dp))
goto out;
/*
* The VDD bit needs a power domain reference, so if the bit is
* already enabled when we boot or resume, grab this reference and
* schedule a vdd off, so we don't hold on to the reference
* indefinitely.
*/
DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
edp_panel_vdd_schedule_off(intel_dp);
out:
pps_unlock(intel_dp);
}
static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct intel_connector *intel_connector,
struct edp_power_seq *power_seq)
struct intel_connector *intel_connector)
{
struct drm_connector *connector = &intel_connector->base;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -5103,12 +5238,12 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
if (!is_edp(intel_dp))
return true;
intel_edp_panel_vdd_sanitize(intel_encoder);
pps_lock(intel_dp);
intel_edp_panel_vdd_sanitize(intel_dp);
pps_unlock(intel_dp);
/* Cache DPCD and EDID for edp. */
intel_edp_panel_vdd_on(intel_dp);
has_dpcd = intel_dp_get_dpcd(intel_dp);
intel_edp_panel_vdd_off(intel_dp, false);
if (has_dpcd) {
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
@@ -5123,7 +5258,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
/* We now know it's not a ghost, init power sequence regs. */
pps_lock(intel_dp);
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, power_seq);
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
pps_unlock(intel_dp);
mutex_lock(&dev->mode_config.mutex);
@@ -5184,7 +5319,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum port port = intel_dig_port->port;
struct edp_power_seq power_seq = { 0 };
int type;
intel_dp->pps_pipe = INVALID_PIPE;
@@ -5223,6 +5357,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
if (type == DRM_MODE_CONNECTOR_eDP)
intel_encoder->type = INTEL_OUTPUT_EDP;
/* eDP only on port B and/or C on vlv/chv */
if (WARN_ON(IS_VALLEYVIEW(dev) && is_edp(intel_dp) &&
port != PORT_B && port != PORT_C))
return false;
DRM_DEBUG_KMS("Adding %s connector on port %c\n",
type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
port_name(port));
@@ -5265,13 +5404,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
if (is_edp(intel_dp)) {
pps_lock(intel_dp);
if (IS_VALLEYVIEW(dev)) {
intel_dp_init_panel_power_timestamps(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);
}
else
intel_dp_init_panel_power_sequencer(dev, intel_dp);
pps_unlock(intel_dp);
}
@@ -5285,7 +5422,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
}
}
if (!intel_edp_init_connector(intel_dp, intel_connector, &power_seq)) {
if (!intel_edp_init_connector(intel_dp, intel_connector)) {
drm_dp_aux_unregister(&intel_dp->aux);
if (is_edp(intel_dp)) {
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);