diff options
author | Dave Airlie <airlied@redhat.com> | 2017-07-20 11:31:43 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-07-20 11:31:43 +1000 |
commit | 2d62c799f8ffac4f7ffba6a4e7f148827dfc24c7 (patch) | |
tree | dbd05cdff844362a80d31e21a825b38b16967fb2 /drivers/gpu/drm/i915/intel_dp.c | |
parent | 5771a8c08880cdca3bfb4a3fc6d309d6bba20877 (diff) | |
parent | 58947144af34a08eee3388c1f039f199e80c0c6f (diff) | |
download | op-kernel-dev-2d62c799f8ffac4f7ffba6a4e7f148827dfc24c7.zip op-kernel-dev-2d62c799f8ffac4f7ffba6a4e7f148827dfc24c7.tar.gz |
Merge tag 'drm-intel-next-2017-07-17' of git://anongit.freedesktop.org/git/drm-intel into drm-next
2nd round of 4.14 features:
- prep for deferred fbdev setup
- refactor fixed 16.16 computations and skl+ wm code (Mahesh Kumar)
- more cnl paches (Rodrigo, Imre et al)
- tighten context cleanup and handling (Chris Wilson)
- fix interlaced handling on skl+ (Mahesh Kumar)
- small bits as usual
* tag 'drm-intel-next-2017-07-17' of git://anongit.freedesktop.org/git/drm-intel: (84 commits)
drm/i915: Update DRIVER_DATE to 20170717
drm/i915: Protect against deferred fbdev setup
drm/i915/fbdev: Always forward hotplug events
drm/i915/skl+: unify cpp value in WM calculation
drm/i915/skl+: WM calculation don't require height
drm/i915: Addition wrapper for fixed16.16 operation
drm/i915: cleanup fixed-point wrappers naming
drm/i915: Always perform internal fixed16 division in 64 bits
drm/i915: take-out common clamping code of fixed16 wrappers
drm/i915/cnl: Add missing type case.
drm/i915/cnl: Add max allowed Cannonlake DC.
drm/i915: Make DP-MST connector info work
drm/i915/cnl: Get DDI clock based on PLLs.
drm/i915/cnl: Inherit RPS stuff from previous platforms.
drm/i915/cnl: Gen10 render context size.
drm/i915/cnl: Don't trust VBT's alternate pin for port D for now.
drm/i915: Fix the kernel panic when using aliasing ppgtt
drm/i915/cnl: Cannonlake color init.
drm/i915/cnl: Add force wake for gen10+.
x86/gpu: CNL uses the same GMS values as SKL
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 108 |
1 files changed, 88 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 64fa774..2d42d09 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4418,8 +4418,6 @@ static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, u32 bit; switch (port->port) { - case PORT_A: - return true; case PORT_B: bit = SDE_PORTB_HOTPLUG; break; @@ -4443,8 +4441,6 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv, u32 bit; switch (port->port) { - case PORT_A: - return true; case PORT_B: bit = SDE_PORTB_HOTPLUG_CPT; break; @@ -4454,12 +4450,28 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv, case PORT_D: bit = SDE_PORTD_HOTPLUG_CPT; break; + default: + MISSING_CASE(port->port); + return false; + } + + return I915_READ(SDEISR) & bit; +} + +static bool spt_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 bit; + + switch (port->port) { + case PORT_A: + bit = SDE_PORTA_HOTPLUG_SPT; + break; case PORT_E: bit = SDE_PORTE_HOTPLUG_SPT; break; default: - MISSING_CASE(port->port); - return false; + return cpt_digital_port_connected(dev_priv, port); } return I915_READ(SDEISR) & bit; @@ -4511,6 +4523,42 @@ static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv, return I915_READ(PORT_HOTPLUG_STAT) & bit; } +static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + if (port->port == PORT_A) + return I915_READ(DEISR) & DE_DP_A_HOTPLUG; + else + return ibx_digital_port_connected(dev_priv, port); +} + +static bool snb_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + if (port->port == PORT_A) + return I915_READ(DEISR) & DE_DP_A_HOTPLUG; + else + return cpt_digital_port_connected(dev_priv, port); +} + +static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + if (port->port == PORT_A) + return I915_READ(DEISR) & DE_DP_A_HOTPLUG_IVB; + else + return cpt_digital_port_connected(dev_priv, port); +} + +static bool bdw_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + if (port->port == PORT_A) + return I915_READ(GEN8_DE_PORT_ISR) & GEN8_PORT_DP_A_HOTPLUG; + else + return cpt_digital_port_connected(dev_priv, port); +} + static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *intel_dig_port) { @@ -4547,16 +4595,25 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port) { - if (HAS_PCH_IBX(dev_priv)) - return ibx_digital_port_connected(dev_priv, port); - else if (HAS_PCH_SPLIT(dev_priv)) - return cpt_digital_port_connected(dev_priv, port); + if (HAS_GMCH_DISPLAY(dev_priv)) { + if (IS_GM45(dev_priv)) + return gm45_digital_port_connected(dev_priv, port); + else + return g4x_digital_port_connected(dev_priv, port); + } + + if (IS_GEN5(dev_priv)) + return ilk_digital_port_connected(dev_priv, port); + else if (IS_GEN6(dev_priv)) + return snb_digital_port_connected(dev_priv, port); + else if (IS_GEN7(dev_priv)) + return ivb_digital_port_connected(dev_priv, port); + else if (IS_GEN8(dev_priv)) + return bdw_digital_port_connected(dev_priv, port); else if (IS_GEN9_LP(dev_priv)) return bxt_digital_port_connected(dev_priv, port); - else if (IS_GM45(dev_priv)) - return gm45_digital_port_connected(dev_priv, port); else - return g4x_digital_port_connected(dev_priv, port); + return spt_digital_port_connected(dev_priv, port); } static struct edid * @@ -5121,12 +5178,8 @@ intel_pps_readout_hw_state(struct drm_i915_private *dev_priv, PANEL_POWER_DOWN_DELAY_SHIFT; if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) { - u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >> - BXT_POWER_CYCLE_DELAY_SHIFT; - if (tmp > 0) - seq->t11_t12 = (tmp - 1) * 1000; - else - seq->t11_t12 = 0; + seq->t11_t12 = ((pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >> + BXT_POWER_CYCLE_DELAY_SHIFT) * 1000; } else { seq->t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >> PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000; @@ -5177,6 +5230,21 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, intel_pps_dump_state("cur", &cur); vbt = dev_priv->vbt.edp.pps; + /* On Toshiba Satellite P50-C-18C system the VBT T12 delay + * of 500ms appears to be too short. Ocassionally the panel + * just fails to power back on. Increasing the delay to 800ms + * seems sufficient to avoid this problem. + */ + if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) { + vbt.t11_t12 = max_t(u16, vbt.t11_t12, 800 * 10); + DRM_DEBUG_KMS("Increasing T12 panel delay as per the quirk to %d\n", + vbt.t11_t12); + } + /* T11_T12 delay is special and actually in units of 100ms, but zero + * based in the hw (so we need to add 100 ms). But the sw vbt + * table multiplies it with 1000 to make it in units of 100usec, + * too. */ + vbt.t11_t12 += 100 * 10; /* Upper limits from eDP 1.3 spec. Note that we use the clunky units of * our hw here, which are all in 100usec. */ @@ -5280,7 +5348,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) { pp_div = I915_READ(regs.pp_ctrl); pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK; - pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000) + pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000) << BXT_POWER_CYCLE_DELAY_SHIFT); } else { pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT; |