Commit 1a56b1a2 authored by Imre Deak's avatar Imre Deak

drm/i915/gen5+, pch: Enable hotplug detection early

To be consistent with the recent change to enable hotplug detection
early on GEN9 platforms do the same on all non-GMCH platforms starting
from GEN5. On GMCH platforms enabling detection without interrupts isn't
trivial, since AUX and HPD have a shared interrupt line. It could be
done there too by using a SW interrupt mask, but I punt on that for now.

Cc: Shashank Sharma <shashank.sharma@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarShashank Sharma <shashank.sharma@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1485509961-9010-5-git-send-email-imre.deak@intel.com
parent f1239595
...@@ -3096,19 +3096,9 @@ static u32 intel_hpd_enabled_irqs(struct drm_i915_private *dev_priv, ...@@ -3096,19 +3096,9 @@ static u32 intel_hpd_enabled_irqs(struct drm_i915_private *dev_priv,
return enabled_irqs; return enabled_irqs;
} }
static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv)
{ {
u32 hotplug_irqs, hotplug, enabled_irqs; u32 hotplug;
if (HAS_PCH_IBX(dev_priv)) {
hotplug_irqs = SDE_HOTPLUG_MASK;
enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_ibx);
} else {
hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_cpt);
}
ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
/* /*
* Enable digital hotplug on the PCH, and configure the DP short pulse * Enable digital hotplug on the PCH, and configure the DP short pulse
...@@ -3116,10 +3106,12 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) ...@@ -3116,10 +3106,12 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv)
* The pulse duration bits are reserved on LPT+. * The pulse duration bits are reserved on LPT+.
*/ */
hotplug = I915_READ(PCH_PORT_HOTPLUG); hotplug = I915_READ(PCH_PORT_HOTPLUG);
hotplug &= ~(PORTD_PULSE_DURATION_MASK|PORTC_PULSE_DURATION_MASK|PORTB_PULSE_DURATION_MASK); hotplug &= ~(PORTB_PULSE_DURATION_MASK |
hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms; PORTC_PULSE_DURATION_MASK |
hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms; PORTD_PULSE_DURATION_MASK);
hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms; hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms;
hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms;
hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms;
/* /*
* When CPU and PCH are on the same package, port A * When CPU and PCH are on the same package, port A
* HPD must be enabled in both north and south. * HPD must be enabled in both north and south.
...@@ -3129,6 +3121,23 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) ...@@ -3129,6 +3121,23 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv)
I915_WRITE(PCH_PORT_HOTPLUG, hotplug); I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
} }
static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv)
{
u32 hotplug_irqs, enabled_irqs;
if (HAS_PCH_IBX(dev_priv)) {
hotplug_irqs = SDE_HOTPLUG_MASK;
enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_ibx);
} else {
hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_cpt);
}
ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
ibx_hpd_detection_setup(dev_priv);
}
static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv)
{ {
u32 hotplug; u32 hotplug;
...@@ -3158,9 +3167,25 @@ static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) ...@@ -3158,9 +3167,25 @@ static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv)
spt_hpd_detection_setup(dev_priv); spt_hpd_detection_setup(dev_priv);
} }
static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv)
{
u32 hotplug;
/*
* Enable digital hotplug on the CPU, and configure the DP short pulse
* duration to 2ms (which is the minimum in the Display Port spec)
* The pulse duration bits are reserved on HSW+.
*/
hotplug = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
hotplug &= ~DIGITAL_PORTA_PULSE_DURATION_MASK;
hotplug |= DIGITAL_PORTA_HOTPLUG_ENABLE |
DIGITAL_PORTA_PULSE_DURATION_2ms;
I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hotplug);
}
static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv)
{ {
u32 hotplug_irqs, hotplug, enabled_irqs; u32 hotplug_irqs, enabled_irqs;
if (INTEL_GEN(dev_priv) >= 8) { if (INTEL_GEN(dev_priv) >= 8) {
hotplug_irqs = GEN8_PORT_DP_A_HOTPLUG; hotplug_irqs = GEN8_PORT_DP_A_HOTPLUG;
...@@ -3179,15 +3204,7 @@ static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) ...@@ -3179,15 +3204,7 @@ static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv)
ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs); ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs);
} }
/* ilk_hpd_detection_setup(dev_priv);
* Enable digital hotplug on the CPU, and configure the DP short pulse
* duration to 2ms (which is the minimum in the Display Port spec)
* The pulse duration bits are reserved on HSW+.
*/
hotplug = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
hotplug &= ~DIGITAL_PORTA_PULSE_DURATION_MASK;
hotplug |= DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_2ms;
I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hotplug);
ibx_hpd_irq_setup(dev_priv); ibx_hpd_irq_setup(dev_priv);
} }
...@@ -3258,7 +3275,7 @@ static void ibx_irq_postinstall(struct drm_device *dev) ...@@ -3258,7 +3275,7 @@ static void ibx_irq_postinstall(struct drm_device *dev)
if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) || if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) ||
HAS_PCH_LPT(dev_priv)) HAS_PCH_LPT(dev_priv))
; /* TODO: Enable HPD detection on older PCH platforms too */ ibx_hpd_detection_setup(dev_priv);
else else
spt_hpd_detection_setup(dev_priv); spt_hpd_detection_setup(dev_priv);
} }
...@@ -3335,6 +3352,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) ...@@ -3335,6 +3352,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
gen5_gt_irq_postinstall(dev); gen5_gt_irq_postinstall(dev);
ilk_hpd_detection_setup(dev_priv);
ibx_irq_postinstall(dev); ibx_irq_postinstall(dev);
if (IS_IRONLAKE_M(dev_priv)) { if (IS_IRONLAKE_M(dev_priv)) {
...@@ -3475,6 +3494,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) ...@@ -3475,6 +3494,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
if (IS_GEN9_LP(dev_priv)) if (IS_GEN9_LP(dev_priv))
bxt_hpd_detection_setup(dev_priv); bxt_hpd_detection_setup(dev_priv);
else if (IS_BROADWELL(dev_priv))
ilk_hpd_detection_setup(dev_priv);
} }
static int gen8_irq_postinstall(struct drm_device *dev) static int gen8_irq_postinstall(struct drm_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment