Commit 26951caf authored by Xiong Zhang's avatar Xiong Zhang Committed by Jani Nikula

drm/i915/skl: enable DDI-E hotplug

v2: fix one error found by checkpath.pl
v3: Add one ignored break for switch-case. DDI-E hotplug
    function doesn't work after updating drm-intel tree,
    I checked the code and found this missing which isn't
    the root cause for broke DDI-E hp.  The broken
    DDI-E hp function is fixed by "Adding DDI_E power
    well domain".
Signed-off-by: default avatarXiong Zhang <xiong.y.zhang@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Tested-by: default avatarTimo Aaltonen <timo.aaltonen@canonical.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 8e9d597a
...@@ -214,6 +214,7 @@ enum hpd_pin { ...@@ -214,6 +214,7 @@ enum hpd_pin {
HPD_PORT_B, HPD_PORT_B,
HPD_PORT_C, HPD_PORT_C,
HPD_PORT_D, HPD_PORT_D,
HPD_PORT_E,
HPD_NUM_PINS HPD_NUM_PINS
}; };
......
...@@ -61,6 +61,13 @@ static const u32 hpd_cpt[HPD_NUM_PINS] = { ...@@ -61,6 +61,13 @@ static const u32 hpd_cpt[HPD_NUM_PINS] = {
[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT [HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
}; };
static const u32 hpd_spt[HPD_NUM_PINS] = {
[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
[HPD_PORT_E] = SDE_PORTE_HOTPLUG_SPT
};
static const u32 hpd_mask_i915[HPD_NUM_PINS] = { static const u32 hpd_mask_i915[HPD_NUM_PINS] = {
[HPD_CRT] = CRT_HOTPLUG_INT_EN, [HPD_CRT] = CRT_HOTPLUG_INT_EN,
[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN, [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
...@@ -1252,6 +1259,8 @@ static bool pch_port_hotplug_long_detect(enum port port, u32 val) ...@@ -1252,6 +1259,8 @@ static bool pch_port_hotplug_long_detect(enum port port, u32 val)
return val & PORTC_HOTPLUG_LONG_DETECT; return val & PORTC_HOTPLUG_LONG_DETECT;
case PORT_D: case PORT_D:
return val & PORTD_HOTPLUG_LONG_DETECT; return val & PORTD_HOTPLUG_LONG_DETECT;
case PORT_E:
return val & PORTE_HOTPLUG_LONG_DETECT;
default: default:
return false; return false;
} }
...@@ -1752,7 +1761,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) ...@@ -1752,7 +1761,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int pipe; int pipe;
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; u32 hotplug_trigger;
if (HAS_PCH_SPT(dev))
hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT;
else
hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
if (hotplug_trigger) { if (hotplug_trigger) {
u32 dig_hotplug_reg, pin_mask, long_mask; u32 dig_hotplug_reg, pin_mask, long_mask;
...@@ -1760,9 +1774,23 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) ...@@ -1760,9 +1774,23 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
intel_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, if (HAS_PCH_SPT(dev)) {
intel_get_hpd_pins(&pin_mask, &long_mask,
hotplug_trigger,
dig_hotplug_reg, hpd_spt,
pch_port_hotplug_long_detect);
/* detect PORTE HP event */
dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
if (pch_port_hotplug_long_detect(PORT_E,
dig_hotplug_reg))
long_mask |= 1 << HPD_PORT_E;
} else
intel_get_hpd_pins(&pin_mask, &long_mask,
hotplug_trigger,
dig_hotplug_reg, hpd_cpt, dig_hotplug_reg, hpd_cpt,
pch_port_hotplug_long_detect); pch_port_hotplug_long_detect);
intel_hpd_irq_handler(dev, pin_mask, long_mask); intel_hpd_irq_handler(dev, pin_mask, long_mask);
} }
...@@ -2984,6 +3012,11 @@ static void ibx_hpd_irq_setup(struct drm_device *dev) ...@@ -2984,6 +3012,11 @@ static void ibx_hpd_irq_setup(struct drm_device *dev)
for_each_intel_encoder(dev, intel_encoder) for_each_intel_encoder(dev, intel_encoder)
if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED) if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin]; enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin];
} else if (HAS_PCH_SPT(dev)) {
hotplug_irqs = SDE_HOTPLUG_MASK_SPT;
for_each_intel_encoder(dev, intel_encoder)
if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED)
enabled_irqs |= hpd_spt[intel_encoder->hpd_pin];
} else { } else {
hotplug_irqs = SDE_HOTPLUG_MASK_CPT; hotplug_irqs = SDE_HOTPLUG_MASK_CPT;
for_each_intel_encoder(dev, intel_encoder) for_each_intel_encoder(dev, intel_encoder)
...@@ -3005,6 +3038,13 @@ static void ibx_hpd_irq_setup(struct drm_device *dev) ...@@ -3005,6 +3038,13 @@ static void ibx_hpd_irq_setup(struct drm_device *dev)
hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms; hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms;
hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms; hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms;
I915_WRITE(PCH_PORT_HOTPLUG, hotplug); I915_WRITE(PCH_PORT_HOTPLUG, hotplug);
/* enable SPT PORTE hot plug */
if (HAS_PCH_SPT(dev)) {
hotplug = I915_READ(PCH_PORT_HOTPLUG2);
hotplug |= PORTE_HOTPLUG_ENABLE;
I915_WRITE(PCH_PORT_HOTPLUG2, hotplug);
}
} }
static void bxt_hpd_irq_setup(struct drm_device *dev) static void bxt_hpd_irq_setup(struct drm_device *dev)
......
...@@ -5949,6 +5949,7 @@ enum skl_disp_power_wells { ...@@ -5949,6 +5949,7 @@ enum skl_disp_power_wells {
#define SDE_AUXC_CPT (1 << 26) #define SDE_AUXC_CPT (1 << 26)
#define SDE_AUXB_CPT (1 << 25) #define SDE_AUXB_CPT (1 << 25)
#define SDE_AUX_MASK_CPT (7 << 25) #define SDE_AUX_MASK_CPT (7 << 25)
#define SDE_PORTE_HOTPLUG_SPT (1 << 25)
#define SDE_PORTD_HOTPLUG_CPT (1 << 23) #define SDE_PORTD_HOTPLUG_CPT (1 << 23)
#define SDE_PORTC_HOTPLUG_CPT (1 << 22) #define SDE_PORTC_HOTPLUG_CPT (1 << 22)
#define SDE_PORTB_HOTPLUG_CPT (1 << 21) #define SDE_PORTB_HOTPLUG_CPT (1 << 21)
...@@ -5959,6 +5960,10 @@ enum skl_disp_power_wells { ...@@ -5959,6 +5960,10 @@ enum skl_disp_power_wells {
SDE_PORTD_HOTPLUG_CPT | \ SDE_PORTD_HOTPLUG_CPT | \
SDE_PORTC_HOTPLUG_CPT | \ SDE_PORTC_HOTPLUG_CPT | \
SDE_PORTB_HOTPLUG_CPT) SDE_PORTB_HOTPLUG_CPT)
#define SDE_HOTPLUG_MASK_SPT (SDE_PORTE_HOTPLUG_SPT | \
SDE_PORTD_HOTPLUG_CPT | \
SDE_PORTC_HOTPLUG_CPT | \
SDE_PORTB_HOTPLUG_CPT)
#define SDE_GMBUS_CPT (1 << 17) #define SDE_GMBUS_CPT (1 << 17)
#define SDE_ERROR_CPT (1 << 16) #define SDE_ERROR_CPT (1 << 16)
#define SDE_AUDIO_CP_REQ_C_CPT (1 << 10) #define SDE_AUDIO_CP_REQ_C_CPT (1 << 10)
...@@ -6030,6 +6035,13 @@ enum skl_disp_power_wells { ...@@ -6030,6 +6035,13 @@ enum skl_disp_power_wells {
#define PORTB_HOTPLUG_SHORT_DETECT (1 << 0) #define PORTB_HOTPLUG_SHORT_DETECT (1 << 0)
#define PORTB_HOTPLUG_LONG_DETECT (2 << 0) #define PORTB_HOTPLUG_LONG_DETECT (2 << 0)
#define PCH_PORT_HOTPLUG2 0xc403C /* SHOTPLUG_CTL2 */
#define PORTE_HOTPLUG_ENABLE (1 << 4)
#define PORTE_HOTPLUG_STATUS_MASK (0x3 << 0)
#define PORTE_HOTPLUG_NO_DETECT (0 << 0)
#define PORTE_HOTPLUG_SHORT_DETECT (1 << 0)
#define PORTE_HOTPLUG_LONG_DETECT (2 << 0)
#define PCH_GPIOA 0xc5010 #define PCH_GPIOA 0xc5010
#define PCH_GPIOB 0xc5014 #define PCH_GPIOB 0xc5014
#define PCH_GPIOC 0xc5018 #define PCH_GPIOC 0xc5018
......
...@@ -1098,6 +1098,9 @@ bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, ...@@ -1098,6 +1098,9 @@ bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
case PORT_D: case PORT_D:
bit = SDE_PORTD_HOTPLUG_CPT; bit = SDE_PORTD_HOTPLUG_CPT;
break; break;
case PORT_E:
bit = SDE_PORTE_HOTPLUG_SPT;
break;
default: default:
return true; return true;
} }
......
...@@ -5860,6 +5860,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, ...@@ -5860,6 +5860,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
case PORT_D: case PORT_D:
intel_encoder->hpd_pin = HPD_PORT_D; intel_encoder->hpd_pin = HPD_PORT_D;
break; break;
case PORT_E:
intel_encoder->hpd_pin = HPD_PORT_E;
break;
default: default:
BUG(); BUG();
} }
......
...@@ -91,6 +91,9 @@ bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port) ...@@ -91,6 +91,9 @@ bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port)
case HPD_PORT_D: case HPD_PORT_D:
*port = PORT_D; *port = PORT_D;
return true; return true;
case HPD_PORT_E:
*port = PORT_E;
return true;
default: default:
return false; /* no hpd */ return false; /* no hpd */
} }
......
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