1*f005ef32Sjsg // SPDX-License-Identifier: MIT
2*f005ef32Sjsg /*
3*f005ef32Sjsg  * Copyright © 2023 Intel Corporation
4*f005ef32Sjsg  */
5*f005ef32Sjsg 
6*f005ef32Sjsg #include "i915_drv.h"
7*f005ef32Sjsg #include "i915_reg.h"
8*f005ef32Sjsg #include "intel_de.h"
9*f005ef32Sjsg #include "intel_display_irq.h"
10*f005ef32Sjsg #include "intel_display_types.h"
11*f005ef32Sjsg #include "intel_dp_aux.h"
12*f005ef32Sjsg #include "intel_gmbus.h"
13*f005ef32Sjsg #include "intel_hotplug.h"
14*f005ef32Sjsg #include "intel_hotplug_irq.h"
15*f005ef32Sjsg 
16*f005ef32Sjsg typedef bool (*long_pulse_detect_func)(enum hpd_pin pin, u32 val);
17*f005ef32Sjsg typedef u32 (*hotplug_enables_func)(struct intel_encoder *encoder);
18*f005ef32Sjsg typedef u32 (*hotplug_mask_func)(enum hpd_pin pin);
19*f005ef32Sjsg 
20*f005ef32Sjsg static const u32 hpd_ilk[HPD_NUM_PINS] = {
21*f005ef32Sjsg 	[HPD_PORT_A] = DE_DP_A_HOTPLUG,
22*f005ef32Sjsg };
23*f005ef32Sjsg 
24*f005ef32Sjsg static const u32 hpd_ivb[HPD_NUM_PINS] = {
25*f005ef32Sjsg 	[HPD_PORT_A] = DE_DP_A_HOTPLUG_IVB,
26*f005ef32Sjsg };
27*f005ef32Sjsg 
28*f005ef32Sjsg static const u32 hpd_bdw[HPD_NUM_PINS] = {
29*f005ef32Sjsg 	[HPD_PORT_A] = GEN8_DE_PORT_HOTPLUG(HPD_PORT_A),
30*f005ef32Sjsg };
31*f005ef32Sjsg 
32*f005ef32Sjsg static const u32 hpd_ibx[HPD_NUM_PINS] = {
33*f005ef32Sjsg 	[HPD_CRT] = SDE_CRT_HOTPLUG,
34*f005ef32Sjsg 	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
35*f005ef32Sjsg 	[HPD_PORT_B] = SDE_PORTB_HOTPLUG,
36*f005ef32Sjsg 	[HPD_PORT_C] = SDE_PORTC_HOTPLUG,
37*f005ef32Sjsg 	[HPD_PORT_D] = SDE_PORTD_HOTPLUG,
38*f005ef32Sjsg };
39*f005ef32Sjsg 
40*f005ef32Sjsg static const u32 hpd_cpt[HPD_NUM_PINS] = {
41*f005ef32Sjsg 	[HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
42*f005ef32Sjsg 	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG_CPT,
43*f005ef32Sjsg 	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
44*f005ef32Sjsg 	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
45*f005ef32Sjsg 	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
46*f005ef32Sjsg };
47*f005ef32Sjsg 
48*f005ef32Sjsg static const u32 hpd_spt[HPD_NUM_PINS] = {
49*f005ef32Sjsg 	[HPD_PORT_A] = SDE_PORTA_HOTPLUG_SPT,
50*f005ef32Sjsg 	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
51*f005ef32Sjsg 	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
52*f005ef32Sjsg 	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT,
53*f005ef32Sjsg 	[HPD_PORT_E] = SDE_PORTE_HOTPLUG_SPT,
54*f005ef32Sjsg };
55*f005ef32Sjsg 
56*f005ef32Sjsg static const u32 hpd_mask_i915[HPD_NUM_PINS] = {
57*f005ef32Sjsg 	[HPD_CRT] = CRT_HOTPLUG_INT_EN,
58*f005ef32Sjsg 	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
59*f005ef32Sjsg 	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
60*f005ef32Sjsg 	[HPD_PORT_B] = PORTB_HOTPLUG_INT_EN,
61*f005ef32Sjsg 	[HPD_PORT_C] = PORTC_HOTPLUG_INT_EN,
62*f005ef32Sjsg 	[HPD_PORT_D] = PORTD_HOTPLUG_INT_EN,
63*f005ef32Sjsg };
64*f005ef32Sjsg 
65*f005ef32Sjsg static const u32 hpd_status_g4x[HPD_NUM_PINS] = {
66*f005ef32Sjsg 	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
67*f005ef32Sjsg 	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
68*f005ef32Sjsg 	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
69*f005ef32Sjsg 	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
70*f005ef32Sjsg 	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
71*f005ef32Sjsg 	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS,
72*f005ef32Sjsg };
73*f005ef32Sjsg 
74*f005ef32Sjsg static const u32 hpd_status_i915[HPD_NUM_PINS] = {
75*f005ef32Sjsg 	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
76*f005ef32Sjsg 	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
77*f005ef32Sjsg 	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
78*f005ef32Sjsg 	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
79*f005ef32Sjsg 	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
80*f005ef32Sjsg 	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS,
81*f005ef32Sjsg };
82*f005ef32Sjsg 
83*f005ef32Sjsg static const u32 hpd_bxt[HPD_NUM_PINS] = {
84*f005ef32Sjsg 	[HPD_PORT_A] = GEN8_DE_PORT_HOTPLUG(HPD_PORT_A),
85*f005ef32Sjsg 	[HPD_PORT_B] = GEN8_DE_PORT_HOTPLUG(HPD_PORT_B),
86*f005ef32Sjsg 	[HPD_PORT_C] = GEN8_DE_PORT_HOTPLUG(HPD_PORT_C),
87*f005ef32Sjsg };
88*f005ef32Sjsg 
89*f005ef32Sjsg static const u32 hpd_gen11[HPD_NUM_PINS] = {
90*f005ef32Sjsg 	[HPD_PORT_TC1] = GEN11_TC_HOTPLUG(HPD_PORT_TC1) | GEN11_TBT_HOTPLUG(HPD_PORT_TC1),
91*f005ef32Sjsg 	[HPD_PORT_TC2] = GEN11_TC_HOTPLUG(HPD_PORT_TC2) | GEN11_TBT_HOTPLUG(HPD_PORT_TC2),
92*f005ef32Sjsg 	[HPD_PORT_TC3] = GEN11_TC_HOTPLUG(HPD_PORT_TC3) | GEN11_TBT_HOTPLUG(HPD_PORT_TC3),
93*f005ef32Sjsg 	[HPD_PORT_TC4] = GEN11_TC_HOTPLUG(HPD_PORT_TC4) | GEN11_TBT_HOTPLUG(HPD_PORT_TC4),
94*f005ef32Sjsg 	[HPD_PORT_TC5] = GEN11_TC_HOTPLUG(HPD_PORT_TC5) | GEN11_TBT_HOTPLUG(HPD_PORT_TC5),
95*f005ef32Sjsg 	[HPD_PORT_TC6] = GEN11_TC_HOTPLUG(HPD_PORT_TC6) | GEN11_TBT_HOTPLUG(HPD_PORT_TC6),
96*f005ef32Sjsg };
97*f005ef32Sjsg 
98*f005ef32Sjsg static const u32 hpd_xelpdp[HPD_NUM_PINS] = {
99*f005ef32Sjsg 	[HPD_PORT_TC1] = XELPDP_TBT_HOTPLUG(HPD_PORT_TC1) | XELPDP_DP_ALT_HOTPLUG(HPD_PORT_TC1),
100*f005ef32Sjsg 	[HPD_PORT_TC2] = XELPDP_TBT_HOTPLUG(HPD_PORT_TC2) | XELPDP_DP_ALT_HOTPLUG(HPD_PORT_TC2),
101*f005ef32Sjsg 	[HPD_PORT_TC3] = XELPDP_TBT_HOTPLUG(HPD_PORT_TC3) | XELPDP_DP_ALT_HOTPLUG(HPD_PORT_TC3),
102*f005ef32Sjsg 	[HPD_PORT_TC4] = XELPDP_TBT_HOTPLUG(HPD_PORT_TC4) | XELPDP_DP_ALT_HOTPLUG(HPD_PORT_TC4),
103*f005ef32Sjsg };
104*f005ef32Sjsg 
105*f005ef32Sjsg static const u32 hpd_icp[HPD_NUM_PINS] = {
106*f005ef32Sjsg 	[HPD_PORT_A] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_A),
107*f005ef32Sjsg 	[HPD_PORT_B] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_B),
108*f005ef32Sjsg 	[HPD_PORT_C] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_C),
109*f005ef32Sjsg 	[HPD_PORT_TC1] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC1),
110*f005ef32Sjsg 	[HPD_PORT_TC2] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC2),
111*f005ef32Sjsg 	[HPD_PORT_TC3] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC3),
112*f005ef32Sjsg 	[HPD_PORT_TC4] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC4),
113*f005ef32Sjsg 	[HPD_PORT_TC5] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC5),
114*f005ef32Sjsg 	[HPD_PORT_TC6] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC6),
115*f005ef32Sjsg };
116*f005ef32Sjsg 
117*f005ef32Sjsg static const u32 hpd_sde_dg1[HPD_NUM_PINS] = {
118*f005ef32Sjsg 	[HPD_PORT_A] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_A),
119*f005ef32Sjsg 	[HPD_PORT_B] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_B),
120*f005ef32Sjsg 	[HPD_PORT_C] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_C),
121*f005ef32Sjsg 	[HPD_PORT_D] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_D),
122*f005ef32Sjsg 	[HPD_PORT_TC1] = SDE_TC_HOTPLUG_DG2(HPD_PORT_TC1),
123*f005ef32Sjsg };
124*f005ef32Sjsg 
125*f005ef32Sjsg static const u32 hpd_mtp[HPD_NUM_PINS] = {
126*f005ef32Sjsg 	[HPD_PORT_A] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_A),
127*f005ef32Sjsg 	[HPD_PORT_B] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_B),
128*f005ef32Sjsg 	[HPD_PORT_TC1] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC1),
129*f005ef32Sjsg 	[HPD_PORT_TC2] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC2),
130*f005ef32Sjsg 	[HPD_PORT_TC3] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC3),
131*f005ef32Sjsg 	[HPD_PORT_TC4] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC4),
132*f005ef32Sjsg };
133*f005ef32Sjsg 
intel_hpd_init_pins(struct drm_i915_private * dev_priv)134*f005ef32Sjsg static void intel_hpd_init_pins(struct drm_i915_private *dev_priv)
135*f005ef32Sjsg {
136*f005ef32Sjsg 	struct intel_hotplug *hpd = &dev_priv->display.hotplug;
137*f005ef32Sjsg 
138*f005ef32Sjsg 	if (HAS_GMCH(dev_priv)) {
139*f005ef32Sjsg 		if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
140*f005ef32Sjsg 		    IS_CHERRYVIEW(dev_priv))
141*f005ef32Sjsg 			hpd->hpd = hpd_status_g4x;
142*f005ef32Sjsg 		else
143*f005ef32Sjsg 			hpd->hpd = hpd_status_i915;
144*f005ef32Sjsg 		return;
145*f005ef32Sjsg 	}
146*f005ef32Sjsg 
147*f005ef32Sjsg 	if (DISPLAY_VER(dev_priv) >= 14)
148*f005ef32Sjsg 		hpd->hpd = hpd_xelpdp;
149*f005ef32Sjsg 	else if (DISPLAY_VER(dev_priv) >= 11)
150*f005ef32Sjsg 		hpd->hpd = hpd_gen11;
151*f005ef32Sjsg 	else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
152*f005ef32Sjsg 		hpd->hpd = hpd_bxt;
153*f005ef32Sjsg 	else if (DISPLAY_VER(dev_priv) == 9)
154*f005ef32Sjsg 		hpd->hpd = NULL; /* no north HPD on SKL */
155*f005ef32Sjsg 	else if (DISPLAY_VER(dev_priv) >= 8)
156*f005ef32Sjsg 		hpd->hpd = hpd_bdw;
157*f005ef32Sjsg 	else if (DISPLAY_VER(dev_priv) >= 7)
158*f005ef32Sjsg 		hpd->hpd = hpd_ivb;
159*f005ef32Sjsg 	else
160*f005ef32Sjsg 		hpd->hpd = hpd_ilk;
161*f005ef32Sjsg 
162*f005ef32Sjsg 	if ((INTEL_PCH_TYPE(dev_priv) < PCH_DG1) &&
163*f005ef32Sjsg 	    (!HAS_PCH_SPLIT(dev_priv) || HAS_PCH_NOP(dev_priv)))
164*f005ef32Sjsg 		return;
165*f005ef32Sjsg 
166*f005ef32Sjsg 	if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
167*f005ef32Sjsg 		hpd->pch_hpd = hpd_sde_dg1;
168*f005ef32Sjsg 	else if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTP)
169*f005ef32Sjsg 		hpd->pch_hpd = hpd_mtp;
170*f005ef32Sjsg 	else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
171*f005ef32Sjsg 		hpd->pch_hpd = hpd_icp;
172*f005ef32Sjsg 	else if (HAS_PCH_CNP(dev_priv) || HAS_PCH_SPT(dev_priv))
173*f005ef32Sjsg 		hpd->pch_hpd = hpd_spt;
174*f005ef32Sjsg 	else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_CPT(dev_priv))
175*f005ef32Sjsg 		hpd->pch_hpd = hpd_cpt;
176*f005ef32Sjsg 	else if (HAS_PCH_IBX(dev_priv))
177*f005ef32Sjsg 		hpd->pch_hpd = hpd_ibx;
178*f005ef32Sjsg 	else
179*f005ef32Sjsg 		MISSING_CASE(INTEL_PCH_TYPE(dev_priv));
180*f005ef32Sjsg }
181*f005ef32Sjsg 
182*f005ef32Sjsg /* For display hotplug interrupt */
i915_hotplug_interrupt_update_locked(struct drm_i915_private * dev_priv,u32 mask,u32 bits)183*f005ef32Sjsg void i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
184*f005ef32Sjsg 					  u32 mask, u32 bits)
185*f005ef32Sjsg {
186*f005ef32Sjsg 	lockdep_assert_held(&dev_priv->irq_lock);
187*f005ef32Sjsg 	drm_WARN_ON(&dev_priv->drm, bits & ~mask);
188*f005ef32Sjsg 
189*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN, mask, bits);
190*f005ef32Sjsg }
191*f005ef32Sjsg 
192*f005ef32Sjsg /**
193*f005ef32Sjsg  * i915_hotplug_interrupt_update - update hotplug interrupt enable
194*f005ef32Sjsg  * @dev_priv: driver private
195*f005ef32Sjsg  * @mask: bits to update
196*f005ef32Sjsg  * @bits: bits to enable
197*f005ef32Sjsg  * NOTE: the HPD enable bits are modified both inside and outside
198*f005ef32Sjsg  * of an interrupt context. To avoid that read-modify-write cycles
199*f005ef32Sjsg  * interfer, these bits are protected by a spinlock. Since this
200*f005ef32Sjsg  * function is usually not called from a context where the lock is
201*f005ef32Sjsg  * held already, this function acquires the lock itself. A non-locking
202*f005ef32Sjsg  * version is also available.
203*f005ef32Sjsg  */
i915_hotplug_interrupt_update(struct drm_i915_private * dev_priv,u32 mask,u32 bits)204*f005ef32Sjsg void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv,
205*f005ef32Sjsg 				   u32 mask,
206*f005ef32Sjsg 				   u32 bits)
207*f005ef32Sjsg {
208*f005ef32Sjsg 	spin_lock_irq(&dev_priv->irq_lock);
209*f005ef32Sjsg 	i915_hotplug_interrupt_update_locked(dev_priv, mask, bits);
210*f005ef32Sjsg 	spin_unlock_irq(&dev_priv->irq_lock);
211*f005ef32Sjsg }
212*f005ef32Sjsg 
gen11_port_hotplug_long_detect(enum hpd_pin pin,u32 val)213*f005ef32Sjsg static bool gen11_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
214*f005ef32Sjsg {
215*f005ef32Sjsg 	switch (pin) {
216*f005ef32Sjsg 	case HPD_PORT_TC1:
217*f005ef32Sjsg 	case HPD_PORT_TC2:
218*f005ef32Sjsg 	case HPD_PORT_TC3:
219*f005ef32Sjsg 	case HPD_PORT_TC4:
220*f005ef32Sjsg 	case HPD_PORT_TC5:
221*f005ef32Sjsg 	case HPD_PORT_TC6:
222*f005ef32Sjsg 		return val & GEN11_HOTPLUG_CTL_LONG_DETECT(pin);
223*f005ef32Sjsg 	default:
224*f005ef32Sjsg 		return false;
225*f005ef32Sjsg 	}
226*f005ef32Sjsg }
227*f005ef32Sjsg 
bxt_port_hotplug_long_detect(enum hpd_pin pin,u32 val)228*f005ef32Sjsg static bool bxt_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
229*f005ef32Sjsg {
230*f005ef32Sjsg 	switch (pin) {
231*f005ef32Sjsg 	case HPD_PORT_A:
232*f005ef32Sjsg 		return val & PORTA_HOTPLUG_LONG_DETECT;
233*f005ef32Sjsg 	case HPD_PORT_B:
234*f005ef32Sjsg 		return val & PORTB_HOTPLUG_LONG_DETECT;
235*f005ef32Sjsg 	case HPD_PORT_C:
236*f005ef32Sjsg 		return val & PORTC_HOTPLUG_LONG_DETECT;
237*f005ef32Sjsg 	default:
238*f005ef32Sjsg 		return false;
239*f005ef32Sjsg 	}
240*f005ef32Sjsg }
241*f005ef32Sjsg 
icp_ddi_port_hotplug_long_detect(enum hpd_pin pin,u32 val)242*f005ef32Sjsg static bool icp_ddi_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
243*f005ef32Sjsg {
244*f005ef32Sjsg 	switch (pin) {
245*f005ef32Sjsg 	case HPD_PORT_A:
246*f005ef32Sjsg 	case HPD_PORT_B:
247*f005ef32Sjsg 	case HPD_PORT_C:
248*f005ef32Sjsg 	case HPD_PORT_D:
249*f005ef32Sjsg 		return val & SHOTPLUG_CTL_DDI_HPD_LONG_DETECT(pin);
250*f005ef32Sjsg 	default:
251*f005ef32Sjsg 		return false;
252*f005ef32Sjsg 	}
253*f005ef32Sjsg }
254*f005ef32Sjsg 
icp_tc_port_hotplug_long_detect(enum hpd_pin pin,u32 val)255*f005ef32Sjsg static bool icp_tc_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
256*f005ef32Sjsg {
257*f005ef32Sjsg 	switch (pin) {
258*f005ef32Sjsg 	case HPD_PORT_TC1:
259*f005ef32Sjsg 	case HPD_PORT_TC2:
260*f005ef32Sjsg 	case HPD_PORT_TC3:
261*f005ef32Sjsg 	case HPD_PORT_TC4:
262*f005ef32Sjsg 	case HPD_PORT_TC5:
263*f005ef32Sjsg 	case HPD_PORT_TC6:
264*f005ef32Sjsg 		return val & ICP_TC_HPD_LONG_DETECT(pin);
265*f005ef32Sjsg 	default:
266*f005ef32Sjsg 		return false;
267*f005ef32Sjsg 	}
268*f005ef32Sjsg }
269*f005ef32Sjsg 
spt_port_hotplug2_long_detect(enum hpd_pin pin,u32 val)270*f005ef32Sjsg static bool spt_port_hotplug2_long_detect(enum hpd_pin pin, u32 val)
271*f005ef32Sjsg {
272*f005ef32Sjsg 	switch (pin) {
273*f005ef32Sjsg 	case HPD_PORT_E:
274*f005ef32Sjsg 		return val & PORTE_HOTPLUG_LONG_DETECT;
275*f005ef32Sjsg 	default:
276*f005ef32Sjsg 		return false;
277*f005ef32Sjsg 	}
278*f005ef32Sjsg }
279*f005ef32Sjsg 
spt_port_hotplug_long_detect(enum hpd_pin pin,u32 val)280*f005ef32Sjsg static bool spt_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
281*f005ef32Sjsg {
282*f005ef32Sjsg 	switch (pin) {
283*f005ef32Sjsg 	case HPD_PORT_A:
284*f005ef32Sjsg 		return val & PORTA_HOTPLUG_LONG_DETECT;
285*f005ef32Sjsg 	case HPD_PORT_B:
286*f005ef32Sjsg 		return val & PORTB_HOTPLUG_LONG_DETECT;
287*f005ef32Sjsg 	case HPD_PORT_C:
288*f005ef32Sjsg 		return val & PORTC_HOTPLUG_LONG_DETECT;
289*f005ef32Sjsg 	case HPD_PORT_D:
290*f005ef32Sjsg 		return val & PORTD_HOTPLUG_LONG_DETECT;
291*f005ef32Sjsg 	default:
292*f005ef32Sjsg 		return false;
293*f005ef32Sjsg 	}
294*f005ef32Sjsg }
295*f005ef32Sjsg 
ilk_port_hotplug_long_detect(enum hpd_pin pin,u32 val)296*f005ef32Sjsg static bool ilk_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
297*f005ef32Sjsg {
298*f005ef32Sjsg 	switch (pin) {
299*f005ef32Sjsg 	case HPD_PORT_A:
300*f005ef32Sjsg 		return val & DIGITAL_PORTA_HOTPLUG_LONG_DETECT;
301*f005ef32Sjsg 	default:
302*f005ef32Sjsg 		return false;
303*f005ef32Sjsg 	}
304*f005ef32Sjsg }
305*f005ef32Sjsg 
pch_port_hotplug_long_detect(enum hpd_pin pin,u32 val)306*f005ef32Sjsg static bool pch_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
307*f005ef32Sjsg {
308*f005ef32Sjsg 	switch (pin) {
309*f005ef32Sjsg 	case HPD_PORT_B:
310*f005ef32Sjsg 		return val & PORTB_HOTPLUG_LONG_DETECT;
311*f005ef32Sjsg 	case HPD_PORT_C:
312*f005ef32Sjsg 		return val & PORTC_HOTPLUG_LONG_DETECT;
313*f005ef32Sjsg 	case HPD_PORT_D:
314*f005ef32Sjsg 		return val & PORTD_HOTPLUG_LONG_DETECT;
315*f005ef32Sjsg 	default:
316*f005ef32Sjsg 		return false;
317*f005ef32Sjsg 	}
318*f005ef32Sjsg }
319*f005ef32Sjsg 
i9xx_port_hotplug_long_detect(enum hpd_pin pin,u32 val)320*f005ef32Sjsg static bool i9xx_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
321*f005ef32Sjsg {
322*f005ef32Sjsg 	switch (pin) {
323*f005ef32Sjsg 	case HPD_PORT_B:
324*f005ef32Sjsg 		return val & PORTB_HOTPLUG_INT_LONG_PULSE;
325*f005ef32Sjsg 	case HPD_PORT_C:
326*f005ef32Sjsg 		return val & PORTC_HOTPLUG_INT_LONG_PULSE;
327*f005ef32Sjsg 	case HPD_PORT_D:
328*f005ef32Sjsg 		return val & PORTD_HOTPLUG_INT_LONG_PULSE;
329*f005ef32Sjsg 	default:
330*f005ef32Sjsg 		return false;
331*f005ef32Sjsg 	}
332*f005ef32Sjsg }
333*f005ef32Sjsg 
334*f005ef32Sjsg /*
335*f005ef32Sjsg  * Get a bit mask of pins that have triggered, and which ones may be long.
336*f005ef32Sjsg  * This can be called multiple times with the same masks to accumulate
337*f005ef32Sjsg  * hotplug detection results from several registers.
338*f005ef32Sjsg  *
339*f005ef32Sjsg  * Note that the caller is expected to zero out the masks initially.
340*f005ef32Sjsg  */
intel_get_hpd_pins(struct drm_i915_private * dev_priv,u32 * pin_mask,u32 * long_mask,u32 hotplug_trigger,u32 dig_hotplug_reg,const u32 hpd[HPD_NUM_PINS],bool long_pulse_detect (enum hpd_pin pin,u32 val))341*f005ef32Sjsg static void intel_get_hpd_pins(struct drm_i915_private *dev_priv,
342*f005ef32Sjsg 			       u32 *pin_mask, u32 *long_mask,
343*f005ef32Sjsg 			       u32 hotplug_trigger, u32 dig_hotplug_reg,
344*f005ef32Sjsg 			       const u32 hpd[HPD_NUM_PINS],
345*f005ef32Sjsg 			       bool long_pulse_detect(enum hpd_pin pin, u32 val))
346*f005ef32Sjsg {
347*f005ef32Sjsg 	enum hpd_pin pin;
348*f005ef32Sjsg 
349*f005ef32Sjsg 	BUILD_BUG_ON(BITS_PER_TYPE(*pin_mask) < HPD_NUM_PINS);
350*f005ef32Sjsg 
351*f005ef32Sjsg 	for_each_hpd_pin(pin) {
352*f005ef32Sjsg 		if ((hpd[pin] & hotplug_trigger) == 0)
353*f005ef32Sjsg 			continue;
354*f005ef32Sjsg 
355*f005ef32Sjsg 		*pin_mask |= BIT(pin);
356*f005ef32Sjsg 
357*f005ef32Sjsg 		if (long_pulse_detect(pin, dig_hotplug_reg))
358*f005ef32Sjsg 			*long_mask |= BIT(pin);
359*f005ef32Sjsg 	}
360*f005ef32Sjsg 
361*f005ef32Sjsg 	drm_dbg(&dev_priv->drm,
362*f005ef32Sjsg 		"hotplug event received, stat 0x%08x, dig 0x%08x, pins 0x%08x, long 0x%08x\n",
363*f005ef32Sjsg 		hotplug_trigger, dig_hotplug_reg, *pin_mask, *long_mask);
364*f005ef32Sjsg }
365*f005ef32Sjsg 
intel_hpd_enabled_irqs(struct drm_i915_private * dev_priv,const u32 hpd[HPD_NUM_PINS])366*f005ef32Sjsg static u32 intel_hpd_enabled_irqs(struct drm_i915_private *dev_priv,
367*f005ef32Sjsg 				  const u32 hpd[HPD_NUM_PINS])
368*f005ef32Sjsg {
369*f005ef32Sjsg 	struct intel_encoder *encoder;
370*f005ef32Sjsg 	u32 enabled_irqs = 0;
371*f005ef32Sjsg 
372*f005ef32Sjsg 	for_each_intel_encoder(&dev_priv->drm, encoder)
373*f005ef32Sjsg 		if (dev_priv->display.hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED)
374*f005ef32Sjsg 			enabled_irqs |= hpd[encoder->hpd_pin];
375*f005ef32Sjsg 
376*f005ef32Sjsg 	return enabled_irqs;
377*f005ef32Sjsg }
378*f005ef32Sjsg 
intel_hpd_hotplug_irqs(struct drm_i915_private * dev_priv,const u32 hpd[HPD_NUM_PINS])379*f005ef32Sjsg static u32 intel_hpd_hotplug_irqs(struct drm_i915_private *dev_priv,
380*f005ef32Sjsg 				  const u32 hpd[HPD_NUM_PINS])
381*f005ef32Sjsg {
382*f005ef32Sjsg 	struct intel_encoder *encoder;
383*f005ef32Sjsg 	u32 hotplug_irqs = 0;
384*f005ef32Sjsg 
385*f005ef32Sjsg 	for_each_intel_encoder(&dev_priv->drm, encoder)
386*f005ef32Sjsg 		hotplug_irqs |= hpd[encoder->hpd_pin];
387*f005ef32Sjsg 
388*f005ef32Sjsg 	return hotplug_irqs;
389*f005ef32Sjsg }
390*f005ef32Sjsg 
intel_hpd_hotplug_mask(struct drm_i915_private * i915,hotplug_mask_func hotplug_mask)391*f005ef32Sjsg static u32 intel_hpd_hotplug_mask(struct drm_i915_private *i915,
392*f005ef32Sjsg 				  hotplug_mask_func hotplug_mask)
393*f005ef32Sjsg {
394*f005ef32Sjsg 	enum hpd_pin pin;
395*f005ef32Sjsg 	u32 hotplug = 0;
396*f005ef32Sjsg 
397*f005ef32Sjsg 	for_each_hpd_pin(pin)
398*f005ef32Sjsg 		hotplug |= hotplug_mask(pin);
399*f005ef32Sjsg 
400*f005ef32Sjsg 	return hotplug;
401*f005ef32Sjsg }
402*f005ef32Sjsg 
intel_hpd_hotplug_enables(struct drm_i915_private * i915,hotplug_enables_func hotplug_enables)403*f005ef32Sjsg static u32 intel_hpd_hotplug_enables(struct drm_i915_private *i915,
404*f005ef32Sjsg 				     hotplug_enables_func hotplug_enables)
405*f005ef32Sjsg {
406*f005ef32Sjsg 	struct intel_encoder *encoder;
407*f005ef32Sjsg 	u32 hotplug = 0;
408*f005ef32Sjsg 
409*f005ef32Sjsg 	for_each_intel_encoder(&i915->drm, encoder)
410*f005ef32Sjsg 		hotplug |= hotplug_enables(encoder);
411*f005ef32Sjsg 
412*f005ef32Sjsg 	return hotplug;
413*f005ef32Sjsg }
414*f005ef32Sjsg 
i9xx_hpd_irq_ack(struct drm_i915_private * dev_priv)415*f005ef32Sjsg u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
416*f005ef32Sjsg {
417*f005ef32Sjsg 	u32 hotplug_status = 0, hotplug_status_mask;
418*f005ef32Sjsg 	int i;
419*f005ef32Sjsg 
420*f005ef32Sjsg 	if (IS_G4X(dev_priv) ||
421*f005ef32Sjsg 	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
422*f005ef32Sjsg 		hotplug_status_mask = HOTPLUG_INT_STATUS_G4X |
423*f005ef32Sjsg 			DP_AUX_CHANNEL_MASK_INT_STATUS_G4X;
424*f005ef32Sjsg 	else
425*f005ef32Sjsg 		hotplug_status_mask = HOTPLUG_INT_STATUS_I915;
426*f005ef32Sjsg 
427*f005ef32Sjsg 	/*
428*f005ef32Sjsg 	 * We absolutely have to clear all the pending interrupt
429*f005ef32Sjsg 	 * bits in PORT_HOTPLUG_STAT. Otherwise the ISR port
430*f005ef32Sjsg 	 * interrupt bit won't have an edge, and the i965/g4x
431*f005ef32Sjsg 	 * edge triggered IIR will not notice that an interrupt
432*f005ef32Sjsg 	 * is still pending. We can't use PORT_HOTPLUG_EN to
433*f005ef32Sjsg 	 * guarantee the edge as the act of toggling the enable
434*f005ef32Sjsg 	 * bits can itself generate a new hotplug interrupt :(
435*f005ef32Sjsg 	 */
436*f005ef32Sjsg 	for (i = 0; i < 10; i++) {
437*f005ef32Sjsg 		u32 tmp = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT) & hotplug_status_mask;
438*f005ef32Sjsg 
439*f005ef32Sjsg 		if (tmp == 0)
440*f005ef32Sjsg 			return hotplug_status;
441*f005ef32Sjsg 
442*f005ef32Sjsg 		hotplug_status |= tmp;
443*f005ef32Sjsg 		intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, hotplug_status);
444*f005ef32Sjsg 	}
445*f005ef32Sjsg 
446*f005ef32Sjsg 	drm_WARN_ONCE(&dev_priv->drm, 1,
447*f005ef32Sjsg 		      "PORT_HOTPLUG_STAT did not clear (0x%08x)\n",
448*f005ef32Sjsg 		      intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
449*f005ef32Sjsg 
450*f005ef32Sjsg 	return hotplug_status;
451*f005ef32Sjsg }
452*f005ef32Sjsg 
i9xx_hpd_irq_handler(struct drm_i915_private * dev_priv,u32 hotplug_status)453*f005ef32Sjsg void i9xx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_status)
454*f005ef32Sjsg {
455*f005ef32Sjsg 	u32 pin_mask = 0, long_mask = 0;
456*f005ef32Sjsg 	u32 hotplug_trigger;
457*f005ef32Sjsg 
458*f005ef32Sjsg 	if (IS_G4X(dev_priv) ||
459*f005ef32Sjsg 	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
460*f005ef32Sjsg 		hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X;
461*f005ef32Sjsg 	else
462*f005ef32Sjsg 		hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915;
463*f005ef32Sjsg 
464*f005ef32Sjsg 	if (hotplug_trigger) {
465*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
466*f005ef32Sjsg 				   hotplug_trigger, hotplug_trigger,
467*f005ef32Sjsg 				   dev_priv->display.hotplug.hpd,
468*f005ef32Sjsg 				   i9xx_port_hotplug_long_detect);
469*f005ef32Sjsg 
470*f005ef32Sjsg 		intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
471*f005ef32Sjsg 	}
472*f005ef32Sjsg 
473*f005ef32Sjsg 	if ((IS_G4X(dev_priv) ||
474*f005ef32Sjsg 	     IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
475*f005ef32Sjsg 	    hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)
476*f005ef32Sjsg 		intel_dp_aux_irq_handler(dev_priv);
477*f005ef32Sjsg }
478*f005ef32Sjsg 
ibx_hpd_irq_handler(struct drm_i915_private * dev_priv,u32 hotplug_trigger)479*f005ef32Sjsg void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger)
480*f005ef32Sjsg {
481*f005ef32Sjsg 	u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
482*f005ef32Sjsg 
483*f005ef32Sjsg 	/*
484*f005ef32Sjsg 	 * Somehow the PCH doesn't seem to really ack the interrupt to the CPU
485*f005ef32Sjsg 	 * unless we touch the hotplug register, even if hotplug_trigger is
486*f005ef32Sjsg 	 * zero. Not acking leads to "The master control interrupt lied (SDE)!"
487*f005ef32Sjsg 	 * errors.
488*f005ef32Sjsg 	 */
489*f005ef32Sjsg 	dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
490*f005ef32Sjsg 	if (!hotplug_trigger) {
491*f005ef32Sjsg 		u32 mask = PORTA_HOTPLUG_STATUS_MASK |
492*f005ef32Sjsg 			PORTD_HOTPLUG_STATUS_MASK |
493*f005ef32Sjsg 			PORTC_HOTPLUG_STATUS_MASK |
494*f005ef32Sjsg 			PORTB_HOTPLUG_STATUS_MASK;
495*f005ef32Sjsg 		dig_hotplug_reg &= ~mask;
496*f005ef32Sjsg 	}
497*f005ef32Sjsg 
498*f005ef32Sjsg 	intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg);
499*f005ef32Sjsg 	if (!hotplug_trigger)
500*f005ef32Sjsg 		return;
501*f005ef32Sjsg 
502*f005ef32Sjsg 	intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
503*f005ef32Sjsg 			   hotplug_trigger, dig_hotplug_reg,
504*f005ef32Sjsg 			   dev_priv->display.hotplug.pch_hpd,
505*f005ef32Sjsg 			   pch_port_hotplug_long_detect);
506*f005ef32Sjsg 
507*f005ef32Sjsg 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
508*f005ef32Sjsg }
509*f005ef32Sjsg 
xelpdp_pica_irq_handler(struct drm_i915_private * i915,u32 iir)510*f005ef32Sjsg void xelpdp_pica_irq_handler(struct drm_i915_private *i915, u32 iir)
511*f005ef32Sjsg {
512*f005ef32Sjsg 	enum hpd_pin pin;
513*f005ef32Sjsg 	u32 hotplug_trigger = iir & (XELPDP_DP_ALT_HOTPLUG_MASK | XELPDP_TBT_HOTPLUG_MASK);
514*f005ef32Sjsg 	u32 trigger_aux = iir & XELPDP_AUX_TC_MASK;
515*f005ef32Sjsg 	u32 pin_mask = 0, long_mask = 0;
516*f005ef32Sjsg 
517*f005ef32Sjsg 	for (pin = HPD_PORT_TC1; pin <= HPD_PORT_TC4; pin++) {
518*f005ef32Sjsg 		u32 val;
519*f005ef32Sjsg 
520*f005ef32Sjsg 		if (!(i915->display.hotplug.hpd[pin] & hotplug_trigger))
521*f005ef32Sjsg 			continue;
522*f005ef32Sjsg 
523*f005ef32Sjsg 		pin_mask |= BIT(pin);
524*f005ef32Sjsg 
525*f005ef32Sjsg 		val = intel_de_read(i915, XELPDP_PORT_HOTPLUG_CTL(pin));
526*f005ef32Sjsg 		intel_de_write(i915, XELPDP_PORT_HOTPLUG_CTL(pin), val);
527*f005ef32Sjsg 
528*f005ef32Sjsg 		if (val & (XELPDP_DP_ALT_HPD_LONG_DETECT | XELPDP_TBT_HPD_LONG_DETECT))
529*f005ef32Sjsg 			long_mask |= BIT(pin);
530*f005ef32Sjsg 	}
531*f005ef32Sjsg 
532*f005ef32Sjsg 	if (pin_mask) {
533*f005ef32Sjsg 		drm_dbg(&i915->drm,
534*f005ef32Sjsg 			"pica hotplug event received, stat 0x%08x, pins 0x%08x, long 0x%08x\n",
535*f005ef32Sjsg 			hotplug_trigger, pin_mask, long_mask);
536*f005ef32Sjsg 
537*f005ef32Sjsg 		intel_hpd_irq_handler(i915, pin_mask, long_mask);
538*f005ef32Sjsg 	}
539*f005ef32Sjsg 
540*f005ef32Sjsg 	if (trigger_aux)
541*f005ef32Sjsg 		intel_dp_aux_irq_handler(i915);
542*f005ef32Sjsg 
543*f005ef32Sjsg 	if (!pin_mask && !trigger_aux)
544*f005ef32Sjsg 		drm_err(&i915->drm,
545*f005ef32Sjsg 			"Unexpected DE HPD/AUX interrupt 0x%08x\n", iir);
546*f005ef32Sjsg }
547*f005ef32Sjsg 
icp_irq_handler(struct drm_i915_private * dev_priv,u32 pch_iir)548*f005ef32Sjsg void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
549*f005ef32Sjsg {
550*f005ef32Sjsg 	u32 ddi_hotplug_trigger = pch_iir & SDE_DDI_HOTPLUG_MASK_ICP;
551*f005ef32Sjsg 	u32 tc_hotplug_trigger = pch_iir & SDE_TC_HOTPLUG_MASK_ICP;
552*f005ef32Sjsg 	u32 pin_mask = 0, long_mask = 0;
553*f005ef32Sjsg 
554*f005ef32Sjsg 	if (ddi_hotplug_trigger) {
555*f005ef32Sjsg 		u32 dig_hotplug_reg;
556*f005ef32Sjsg 
557*f005ef32Sjsg 		/* Locking due to DSI native GPIO sequences */
558*f005ef32Sjsg 		spin_lock(&dev_priv->irq_lock);
559*f005ef32Sjsg 		dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0);
560*f005ef32Sjsg 		spin_unlock(&dev_priv->irq_lock);
561*f005ef32Sjsg 
562*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
563*f005ef32Sjsg 				   ddi_hotplug_trigger, dig_hotplug_reg,
564*f005ef32Sjsg 				   dev_priv->display.hotplug.pch_hpd,
565*f005ef32Sjsg 				   icp_ddi_port_hotplug_long_detect);
566*f005ef32Sjsg 	}
567*f005ef32Sjsg 
568*f005ef32Sjsg 	if (tc_hotplug_trigger) {
569*f005ef32Sjsg 		u32 dig_hotplug_reg;
570*f005ef32Sjsg 
571*f005ef32Sjsg 		dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC, 0, 0);
572*f005ef32Sjsg 
573*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
574*f005ef32Sjsg 				   tc_hotplug_trigger, dig_hotplug_reg,
575*f005ef32Sjsg 				   dev_priv->display.hotplug.pch_hpd,
576*f005ef32Sjsg 				   icp_tc_port_hotplug_long_detect);
577*f005ef32Sjsg 	}
578*f005ef32Sjsg 
579*f005ef32Sjsg 	if (pin_mask)
580*f005ef32Sjsg 		intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
581*f005ef32Sjsg 
582*f005ef32Sjsg 	if (pch_iir & SDE_GMBUS_ICP)
583*f005ef32Sjsg 		intel_gmbus_irq_handler(dev_priv);
584*f005ef32Sjsg }
585*f005ef32Sjsg 
spt_irq_handler(struct drm_i915_private * dev_priv,u32 pch_iir)586*f005ef32Sjsg void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
587*f005ef32Sjsg {
588*f005ef32Sjsg 	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT &
589*f005ef32Sjsg 		~SDE_PORTE_HOTPLUG_SPT;
590*f005ef32Sjsg 	u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT;
591*f005ef32Sjsg 	u32 pin_mask = 0, long_mask = 0;
592*f005ef32Sjsg 
593*f005ef32Sjsg 	if (hotplug_trigger) {
594*f005ef32Sjsg 		u32 dig_hotplug_reg;
595*f005ef32Sjsg 
596*f005ef32Sjsg 		dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0);
597*f005ef32Sjsg 
598*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
599*f005ef32Sjsg 				   hotplug_trigger, dig_hotplug_reg,
600*f005ef32Sjsg 				   dev_priv->display.hotplug.pch_hpd,
601*f005ef32Sjsg 				   spt_port_hotplug_long_detect);
602*f005ef32Sjsg 	}
603*f005ef32Sjsg 
604*f005ef32Sjsg 	if (hotplug2_trigger) {
605*f005ef32Sjsg 		u32 dig_hotplug_reg;
606*f005ef32Sjsg 
607*f005ef32Sjsg 		dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, 0, 0);
608*f005ef32Sjsg 
609*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
610*f005ef32Sjsg 				   hotplug2_trigger, dig_hotplug_reg,
611*f005ef32Sjsg 				   dev_priv->display.hotplug.pch_hpd,
612*f005ef32Sjsg 				   spt_port_hotplug2_long_detect);
613*f005ef32Sjsg 	}
614*f005ef32Sjsg 
615*f005ef32Sjsg 	if (pin_mask)
616*f005ef32Sjsg 		intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
617*f005ef32Sjsg 
618*f005ef32Sjsg 	if (pch_iir & SDE_GMBUS_CPT)
619*f005ef32Sjsg 		intel_gmbus_irq_handler(dev_priv);
620*f005ef32Sjsg }
621*f005ef32Sjsg 
ilk_hpd_irq_handler(struct drm_i915_private * dev_priv,u32 hotplug_trigger)622*f005ef32Sjsg void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger)
623*f005ef32Sjsg {
624*f005ef32Sjsg 	u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
625*f005ef32Sjsg 
626*f005ef32Sjsg 	dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, 0, 0);
627*f005ef32Sjsg 
628*f005ef32Sjsg 	intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
629*f005ef32Sjsg 			   hotplug_trigger, dig_hotplug_reg,
630*f005ef32Sjsg 			   dev_priv->display.hotplug.hpd,
631*f005ef32Sjsg 			   ilk_port_hotplug_long_detect);
632*f005ef32Sjsg 
633*f005ef32Sjsg 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
634*f005ef32Sjsg }
635*f005ef32Sjsg 
bxt_hpd_irq_handler(struct drm_i915_private * dev_priv,u32 hotplug_trigger)636*f005ef32Sjsg void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger)
637*f005ef32Sjsg {
638*f005ef32Sjsg 	u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
639*f005ef32Sjsg 
640*f005ef32Sjsg 	dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0);
641*f005ef32Sjsg 
642*f005ef32Sjsg 	intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
643*f005ef32Sjsg 			   hotplug_trigger, dig_hotplug_reg,
644*f005ef32Sjsg 			   dev_priv->display.hotplug.hpd,
645*f005ef32Sjsg 			   bxt_port_hotplug_long_detect);
646*f005ef32Sjsg 
647*f005ef32Sjsg 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
648*f005ef32Sjsg }
649*f005ef32Sjsg 
gen11_hpd_irq_handler(struct drm_i915_private * dev_priv,u32 iir)650*f005ef32Sjsg void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
651*f005ef32Sjsg {
652*f005ef32Sjsg 	u32 pin_mask = 0, long_mask = 0;
653*f005ef32Sjsg 	u32 trigger_tc = iir & GEN11_DE_TC_HOTPLUG_MASK;
654*f005ef32Sjsg 	u32 trigger_tbt = iir & GEN11_DE_TBT_HOTPLUG_MASK;
655*f005ef32Sjsg 
656*f005ef32Sjsg 	if (trigger_tc) {
657*f005ef32Sjsg 		u32 dig_hotplug_reg;
658*f005ef32Sjsg 
659*f005ef32Sjsg 		dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, 0, 0);
660*f005ef32Sjsg 
661*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
662*f005ef32Sjsg 				   trigger_tc, dig_hotplug_reg,
663*f005ef32Sjsg 				   dev_priv->display.hotplug.hpd,
664*f005ef32Sjsg 				   gen11_port_hotplug_long_detect);
665*f005ef32Sjsg 	}
666*f005ef32Sjsg 
667*f005ef32Sjsg 	if (trigger_tbt) {
668*f005ef32Sjsg 		u32 dig_hotplug_reg;
669*f005ef32Sjsg 
670*f005ef32Sjsg 		dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, 0, 0);
671*f005ef32Sjsg 
672*f005ef32Sjsg 		intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
673*f005ef32Sjsg 				   trigger_tbt, dig_hotplug_reg,
674*f005ef32Sjsg 				   dev_priv->display.hotplug.hpd,
675*f005ef32Sjsg 				   gen11_port_hotplug_long_detect);
676*f005ef32Sjsg 	}
677*f005ef32Sjsg 
678*f005ef32Sjsg 	if (pin_mask)
679*f005ef32Sjsg 		intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
680*f005ef32Sjsg 	else
681*f005ef32Sjsg 		drm_err(&dev_priv->drm,
682*f005ef32Sjsg 			"Unexpected DE HPD interrupt 0x%08x\n", iir);
683*f005ef32Sjsg }
684*f005ef32Sjsg 
ibx_hotplug_mask(enum hpd_pin hpd_pin)685*f005ef32Sjsg static u32 ibx_hotplug_mask(enum hpd_pin hpd_pin)
686*f005ef32Sjsg {
687*f005ef32Sjsg 	switch (hpd_pin) {
688*f005ef32Sjsg 	case HPD_PORT_A:
689*f005ef32Sjsg 		return PORTA_HOTPLUG_ENABLE;
690*f005ef32Sjsg 	case HPD_PORT_B:
691*f005ef32Sjsg 		return PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_MASK;
692*f005ef32Sjsg 	case HPD_PORT_C:
693*f005ef32Sjsg 		return PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_MASK;
694*f005ef32Sjsg 	case HPD_PORT_D:
695*f005ef32Sjsg 		return PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_MASK;
696*f005ef32Sjsg 	default:
697*f005ef32Sjsg 		return 0;
698*f005ef32Sjsg 	}
699*f005ef32Sjsg }
700*f005ef32Sjsg 
ibx_hotplug_enables(struct intel_encoder * encoder)701*f005ef32Sjsg static u32 ibx_hotplug_enables(struct intel_encoder *encoder)
702*f005ef32Sjsg {
703*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
704*f005ef32Sjsg 
705*f005ef32Sjsg 	switch (encoder->hpd_pin) {
706*f005ef32Sjsg 	case HPD_PORT_A:
707*f005ef32Sjsg 		/*
708*f005ef32Sjsg 		 * When CPU and PCH are on the same package, port A
709*f005ef32Sjsg 		 * HPD must be enabled in both north and south.
710*f005ef32Sjsg 		 */
711*f005ef32Sjsg 		return HAS_PCH_LPT_LP(i915) ?
712*f005ef32Sjsg 			PORTA_HOTPLUG_ENABLE : 0;
713*f005ef32Sjsg 	case HPD_PORT_B:
714*f005ef32Sjsg 		return PORTB_HOTPLUG_ENABLE |
715*f005ef32Sjsg 			PORTB_PULSE_DURATION_2ms;
716*f005ef32Sjsg 	case HPD_PORT_C:
717*f005ef32Sjsg 		return PORTC_HOTPLUG_ENABLE |
718*f005ef32Sjsg 			PORTC_PULSE_DURATION_2ms;
719*f005ef32Sjsg 	case HPD_PORT_D:
720*f005ef32Sjsg 		return PORTD_HOTPLUG_ENABLE |
721*f005ef32Sjsg 			PORTD_PULSE_DURATION_2ms;
722*f005ef32Sjsg 	default:
723*f005ef32Sjsg 		return 0;
724*f005ef32Sjsg 	}
725*f005ef32Sjsg }
726*f005ef32Sjsg 
ibx_hpd_detection_setup(struct drm_i915_private * dev_priv)727*f005ef32Sjsg static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv)
728*f005ef32Sjsg {
729*f005ef32Sjsg 	/*
730*f005ef32Sjsg 	 * Enable digital hotplug on the PCH, and configure the DP short pulse
731*f005ef32Sjsg 	 * duration to 2ms (which is the minimum in the Display Port spec).
732*f005ef32Sjsg 	 * The pulse duration bits are reserved on LPT+.
733*f005ef32Sjsg 	 */
734*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
735*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, ibx_hotplug_mask),
736*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables));
737*f005ef32Sjsg }
738*f005ef32Sjsg 
ibx_hpd_enable_detection(struct intel_encoder * encoder)739*f005ef32Sjsg static void ibx_hpd_enable_detection(struct intel_encoder *encoder)
740*f005ef32Sjsg {
741*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
742*f005ef32Sjsg 
743*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG,
744*f005ef32Sjsg 			 ibx_hotplug_mask(encoder->hpd_pin),
745*f005ef32Sjsg 			 ibx_hotplug_enables(encoder));
746*f005ef32Sjsg }
747*f005ef32Sjsg 
ibx_hpd_irq_setup(struct drm_i915_private * dev_priv)748*f005ef32Sjsg static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv)
749*f005ef32Sjsg {
750*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
751*f005ef32Sjsg 
752*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
753*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
754*f005ef32Sjsg 
755*f005ef32Sjsg 	ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
756*f005ef32Sjsg 
757*f005ef32Sjsg 	ibx_hpd_detection_setup(dev_priv);
758*f005ef32Sjsg }
759*f005ef32Sjsg 
icp_ddi_hotplug_mask(enum hpd_pin hpd_pin)760*f005ef32Sjsg static u32 icp_ddi_hotplug_mask(enum hpd_pin hpd_pin)
761*f005ef32Sjsg {
762*f005ef32Sjsg 	switch (hpd_pin) {
763*f005ef32Sjsg 	case HPD_PORT_A:
764*f005ef32Sjsg 	case HPD_PORT_B:
765*f005ef32Sjsg 	case HPD_PORT_C:
766*f005ef32Sjsg 	case HPD_PORT_D:
767*f005ef32Sjsg 		return SHOTPLUG_CTL_DDI_HPD_ENABLE(hpd_pin);
768*f005ef32Sjsg 	default:
769*f005ef32Sjsg 		return 0;
770*f005ef32Sjsg 	}
771*f005ef32Sjsg }
772*f005ef32Sjsg 
icp_ddi_hotplug_enables(struct intel_encoder * encoder)773*f005ef32Sjsg static u32 icp_ddi_hotplug_enables(struct intel_encoder *encoder)
774*f005ef32Sjsg {
775*f005ef32Sjsg 	return icp_ddi_hotplug_mask(encoder->hpd_pin);
776*f005ef32Sjsg }
777*f005ef32Sjsg 
icp_tc_hotplug_mask(enum hpd_pin hpd_pin)778*f005ef32Sjsg static u32 icp_tc_hotplug_mask(enum hpd_pin hpd_pin)
779*f005ef32Sjsg {
780*f005ef32Sjsg 	switch (hpd_pin) {
781*f005ef32Sjsg 	case HPD_PORT_TC1:
782*f005ef32Sjsg 	case HPD_PORT_TC2:
783*f005ef32Sjsg 	case HPD_PORT_TC3:
784*f005ef32Sjsg 	case HPD_PORT_TC4:
785*f005ef32Sjsg 	case HPD_PORT_TC5:
786*f005ef32Sjsg 	case HPD_PORT_TC6:
787*f005ef32Sjsg 		return ICP_TC_HPD_ENABLE(hpd_pin);
788*f005ef32Sjsg 	default:
789*f005ef32Sjsg 		return 0;
790*f005ef32Sjsg 	}
791*f005ef32Sjsg }
792*f005ef32Sjsg 
icp_tc_hotplug_enables(struct intel_encoder * encoder)793*f005ef32Sjsg static u32 icp_tc_hotplug_enables(struct intel_encoder *encoder)
794*f005ef32Sjsg {
795*f005ef32Sjsg 	return icp_tc_hotplug_mask(encoder->hpd_pin);
796*f005ef32Sjsg }
797*f005ef32Sjsg 
icp_ddi_hpd_detection_setup(struct drm_i915_private * dev_priv)798*f005ef32Sjsg static void icp_ddi_hpd_detection_setup(struct drm_i915_private *dev_priv)
799*f005ef32Sjsg {
800*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI,
801*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, icp_ddi_hotplug_mask),
802*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables));
803*f005ef32Sjsg }
804*f005ef32Sjsg 
icp_ddi_hpd_enable_detection(struct intel_encoder * encoder)805*f005ef32Sjsg static void icp_ddi_hpd_enable_detection(struct intel_encoder *encoder)
806*f005ef32Sjsg {
807*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
808*f005ef32Sjsg 
809*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, SHOTPLUG_CTL_DDI,
810*f005ef32Sjsg 			 icp_ddi_hotplug_mask(encoder->hpd_pin),
811*f005ef32Sjsg 			 icp_ddi_hotplug_enables(encoder));
812*f005ef32Sjsg }
813*f005ef32Sjsg 
icp_tc_hpd_detection_setup(struct drm_i915_private * dev_priv)814*f005ef32Sjsg static void icp_tc_hpd_detection_setup(struct drm_i915_private *dev_priv)
815*f005ef32Sjsg {
816*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC,
817*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, icp_tc_hotplug_mask),
818*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables));
819*f005ef32Sjsg }
820*f005ef32Sjsg 
icp_tc_hpd_enable_detection(struct intel_encoder * encoder)821*f005ef32Sjsg static void icp_tc_hpd_enable_detection(struct intel_encoder *encoder)
822*f005ef32Sjsg {
823*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
824*f005ef32Sjsg 
825*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, SHOTPLUG_CTL_TC,
826*f005ef32Sjsg 			 icp_tc_hotplug_mask(encoder->hpd_pin),
827*f005ef32Sjsg 			 icp_tc_hotplug_enables(encoder));
828*f005ef32Sjsg }
829*f005ef32Sjsg 
icp_hpd_enable_detection(struct intel_encoder * encoder)830*f005ef32Sjsg static void icp_hpd_enable_detection(struct intel_encoder *encoder)
831*f005ef32Sjsg {
832*f005ef32Sjsg 	icp_ddi_hpd_enable_detection(encoder);
833*f005ef32Sjsg 	icp_tc_hpd_enable_detection(encoder);
834*f005ef32Sjsg }
835*f005ef32Sjsg 
icp_hpd_irq_setup(struct drm_i915_private * dev_priv)836*f005ef32Sjsg static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv)
837*f005ef32Sjsg {
838*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
839*f005ef32Sjsg 
840*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
841*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
842*f005ef32Sjsg 
843*f005ef32Sjsg 	if (INTEL_PCH_TYPE(dev_priv) <= PCH_TGP)
844*f005ef32Sjsg 		intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ);
845*f005ef32Sjsg 	else
846*f005ef32Sjsg 		intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
847*f005ef32Sjsg 
848*f005ef32Sjsg 	ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
849*f005ef32Sjsg 
850*f005ef32Sjsg 	icp_ddi_hpd_detection_setup(dev_priv);
851*f005ef32Sjsg 	icp_tc_hpd_detection_setup(dev_priv);
852*f005ef32Sjsg }
853*f005ef32Sjsg 
gen11_hotplug_mask(enum hpd_pin hpd_pin)854*f005ef32Sjsg static u32 gen11_hotplug_mask(enum hpd_pin hpd_pin)
855*f005ef32Sjsg {
856*f005ef32Sjsg 	switch (hpd_pin) {
857*f005ef32Sjsg 	case HPD_PORT_TC1:
858*f005ef32Sjsg 	case HPD_PORT_TC2:
859*f005ef32Sjsg 	case HPD_PORT_TC3:
860*f005ef32Sjsg 	case HPD_PORT_TC4:
861*f005ef32Sjsg 	case HPD_PORT_TC5:
862*f005ef32Sjsg 	case HPD_PORT_TC6:
863*f005ef32Sjsg 		return GEN11_HOTPLUG_CTL_ENABLE(hpd_pin);
864*f005ef32Sjsg 	default:
865*f005ef32Sjsg 		return 0;
866*f005ef32Sjsg 	}
867*f005ef32Sjsg }
868*f005ef32Sjsg 
gen11_hotplug_enables(struct intel_encoder * encoder)869*f005ef32Sjsg static u32 gen11_hotplug_enables(struct intel_encoder *encoder)
870*f005ef32Sjsg {
871*f005ef32Sjsg 	return gen11_hotplug_mask(encoder->hpd_pin);
872*f005ef32Sjsg }
873*f005ef32Sjsg 
dg1_hpd_invert(struct drm_i915_private * i915)874*f005ef32Sjsg static void dg1_hpd_invert(struct drm_i915_private *i915)
875*f005ef32Sjsg {
876*f005ef32Sjsg 	u32 val = (INVERT_DDIA_HPD |
877*f005ef32Sjsg 		   INVERT_DDIB_HPD |
878*f005ef32Sjsg 		   INVERT_DDIC_HPD |
879*f005ef32Sjsg 		   INVERT_DDID_HPD);
880*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN1, 0, val);
881*f005ef32Sjsg }
882*f005ef32Sjsg 
dg1_hpd_enable_detection(struct intel_encoder * encoder)883*f005ef32Sjsg static void dg1_hpd_enable_detection(struct intel_encoder *encoder)
884*f005ef32Sjsg {
885*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
886*f005ef32Sjsg 
887*f005ef32Sjsg 	dg1_hpd_invert(i915);
888*f005ef32Sjsg 	icp_hpd_enable_detection(encoder);
889*f005ef32Sjsg }
890*f005ef32Sjsg 
dg1_hpd_irq_setup(struct drm_i915_private * dev_priv)891*f005ef32Sjsg static void dg1_hpd_irq_setup(struct drm_i915_private *dev_priv)
892*f005ef32Sjsg {
893*f005ef32Sjsg 	dg1_hpd_invert(dev_priv);
894*f005ef32Sjsg 	icp_hpd_irq_setup(dev_priv);
895*f005ef32Sjsg }
896*f005ef32Sjsg 
gen11_tc_hpd_detection_setup(struct drm_i915_private * dev_priv)897*f005ef32Sjsg static void gen11_tc_hpd_detection_setup(struct drm_i915_private *dev_priv)
898*f005ef32Sjsg {
899*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL,
900*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, gen11_hotplug_mask),
901*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables));
902*f005ef32Sjsg }
903*f005ef32Sjsg 
gen11_tc_hpd_enable_detection(struct intel_encoder * encoder)904*f005ef32Sjsg static void gen11_tc_hpd_enable_detection(struct intel_encoder *encoder)
905*f005ef32Sjsg {
906*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
907*f005ef32Sjsg 
908*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, GEN11_TC_HOTPLUG_CTL,
909*f005ef32Sjsg 			 gen11_hotplug_mask(encoder->hpd_pin),
910*f005ef32Sjsg 			 gen11_hotplug_enables(encoder));
911*f005ef32Sjsg }
912*f005ef32Sjsg 
gen11_tbt_hpd_detection_setup(struct drm_i915_private * dev_priv)913*f005ef32Sjsg static void gen11_tbt_hpd_detection_setup(struct drm_i915_private *dev_priv)
914*f005ef32Sjsg {
915*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL,
916*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, gen11_hotplug_mask),
917*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables));
918*f005ef32Sjsg }
919*f005ef32Sjsg 
gen11_tbt_hpd_enable_detection(struct intel_encoder * encoder)920*f005ef32Sjsg static void gen11_tbt_hpd_enable_detection(struct intel_encoder *encoder)
921*f005ef32Sjsg {
922*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
923*f005ef32Sjsg 
924*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, GEN11_TBT_HOTPLUG_CTL,
925*f005ef32Sjsg 			 gen11_hotplug_mask(encoder->hpd_pin),
926*f005ef32Sjsg 			 gen11_hotplug_enables(encoder));
927*f005ef32Sjsg }
928*f005ef32Sjsg 
gen11_hpd_enable_detection(struct intel_encoder * encoder)929*f005ef32Sjsg static void gen11_hpd_enable_detection(struct intel_encoder *encoder)
930*f005ef32Sjsg {
931*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
932*f005ef32Sjsg 
933*f005ef32Sjsg 	gen11_tc_hpd_enable_detection(encoder);
934*f005ef32Sjsg 	gen11_tbt_hpd_enable_detection(encoder);
935*f005ef32Sjsg 
936*f005ef32Sjsg 	if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
937*f005ef32Sjsg 		icp_hpd_enable_detection(encoder);
938*f005ef32Sjsg }
939*f005ef32Sjsg 
gen11_hpd_irq_setup(struct drm_i915_private * dev_priv)940*f005ef32Sjsg static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv)
941*f005ef32Sjsg {
942*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
943*f005ef32Sjsg 
944*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd);
945*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd);
946*f005ef32Sjsg 
947*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, GEN11_DE_HPD_IMR, hotplug_irqs,
948*f005ef32Sjsg 			 ~enabled_irqs & hotplug_irqs);
949*f005ef32Sjsg 	intel_uncore_posting_read(&dev_priv->uncore, GEN11_DE_HPD_IMR);
950*f005ef32Sjsg 
951*f005ef32Sjsg 	gen11_tc_hpd_detection_setup(dev_priv);
952*f005ef32Sjsg 	gen11_tbt_hpd_detection_setup(dev_priv);
953*f005ef32Sjsg 
954*f005ef32Sjsg 	if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
955*f005ef32Sjsg 		icp_hpd_irq_setup(dev_priv);
956*f005ef32Sjsg }
957*f005ef32Sjsg 
mtp_ddi_hotplug_mask(enum hpd_pin hpd_pin)958*f005ef32Sjsg static u32 mtp_ddi_hotplug_mask(enum hpd_pin hpd_pin)
959*f005ef32Sjsg {
960*f005ef32Sjsg 	switch (hpd_pin) {
961*f005ef32Sjsg 	case HPD_PORT_A:
962*f005ef32Sjsg 	case HPD_PORT_B:
963*f005ef32Sjsg 		return SHOTPLUG_CTL_DDI_HPD_ENABLE(hpd_pin);
964*f005ef32Sjsg 	default:
965*f005ef32Sjsg 		return 0;
966*f005ef32Sjsg 	}
967*f005ef32Sjsg }
968*f005ef32Sjsg 
mtp_ddi_hotplug_enables(struct intel_encoder * encoder)969*f005ef32Sjsg static u32 mtp_ddi_hotplug_enables(struct intel_encoder *encoder)
970*f005ef32Sjsg {
971*f005ef32Sjsg 	return mtp_ddi_hotplug_mask(encoder->hpd_pin);
972*f005ef32Sjsg }
973*f005ef32Sjsg 
mtp_tc_hotplug_mask(enum hpd_pin hpd_pin)974*f005ef32Sjsg static u32 mtp_tc_hotplug_mask(enum hpd_pin hpd_pin)
975*f005ef32Sjsg {
976*f005ef32Sjsg 	switch (hpd_pin) {
977*f005ef32Sjsg 	case HPD_PORT_TC1:
978*f005ef32Sjsg 	case HPD_PORT_TC2:
979*f005ef32Sjsg 	case HPD_PORT_TC3:
980*f005ef32Sjsg 	case HPD_PORT_TC4:
981*f005ef32Sjsg 		return ICP_TC_HPD_ENABLE(hpd_pin);
982*f005ef32Sjsg 	default:
983*f005ef32Sjsg 		return 0;
984*f005ef32Sjsg 	}
985*f005ef32Sjsg }
986*f005ef32Sjsg 
mtp_tc_hotplug_enables(struct intel_encoder * encoder)987*f005ef32Sjsg static u32 mtp_tc_hotplug_enables(struct intel_encoder *encoder)
988*f005ef32Sjsg {
989*f005ef32Sjsg 	return mtp_tc_hotplug_mask(encoder->hpd_pin);
990*f005ef32Sjsg }
991*f005ef32Sjsg 
mtp_ddi_hpd_detection_setup(struct drm_i915_private * i915)992*f005ef32Sjsg static void mtp_ddi_hpd_detection_setup(struct drm_i915_private *i915)
993*f005ef32Sjsg {
994*f005ef32Sjsg 	intel_de_rmw(i915, SHOTPLUG_CTL_DDI,
995*f005ef32Sjsg 		     intel_hpd_hotplug_mask(i915, mtp_ddi_hotplug_mask),
996*f005ef32Sjsg 		     intel_hpd_hotplug_enables(i915, mtp_ddi_hotplug_enables));
997*f005ef32Sjsg }
998*f005ef32Sjsg 
mtp_ddi_hpd_enable_detection(struct intel_encoder * encoder)999*f005ef32Sjsg static void mtp_ddi_hpd_enable_detection(struct intel_encoder *encoder)
1000*f005ef32Sjsg {
1001*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1002*f005ef32Sjsg 
1003*f005ef32Sjsg 	intel_de_rmw(i915, SHOTPLUG_CTL_DDI,
1004*f005ef32Sjsg 		     mtp_ddi_hotplug_mask(encoder->hpd_pin),
1005*f005ef32Sjsg 		     mtp_ddi_hotplug_enables(encoder));
1006*f005ef32Sjsg }
1007*f005ef32Sjsg 
mtp_tc_hpd_detection_setup(struct drm_i915_private * i915)1008*f005ef32Sjsg static void mtp_tc_hpd_detection_setup(struct drm_i915_private *i915)
1009*f005ef32Sjsg {
1010*f005ef32Sjsg 	intel_de_rmw(i915, SHOTPLUG_CTL_TC,
1011*f005ef32Sjsg 		     intel_hpd_hotplug_mask(i915, mtp_tc_hotplug_mask),
1012*f005ef32Sjsg 		     intel_hpd_hotplug_enables(i915, mtp_tc_hotplug_enables));
1013*f005ef32Sjsg }
1014*f005ef32Sjsg 
mtp_tc_hpd_enable_detection(struct intel_encoder * encoder)1015*f005ef32Sjsg static void mtp_tc_hpd_enable_detection(struct intel_encoder *encoder)
1016*f005ef32Sjsg {
1017*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1018*f005ef32Sjsg 
1019*f005ef32Sjsg 	intel_de_rmw(i915, SHOTPLUG_CTL_DDI,
1020*f005ef32Sjsg 		     mtp_tc_hotplug_mask(encoder->hpd_pin),
1021*f005ef32Sjsg 		     mtp_tc_hotplug_enables(encoder));
1022*f005ef32Sjsg }
1023*f005ef32Sjsg 
mtp_hpd_invert(struct drm_i915_private * i915)1024*f005ef32Sjsg static void mtp_hpd_invert(struct drm_i915_private *i915)
1025*f005ef32Sjsg {
1026*f005ef32Sjsg 	u32 val = (INVERT_DDIA_HPD |
1027*f005ef32Sjsg 		   INVERT_DDIB_HPD |
1028*f005ef32Sjsg 		   INVERT_DDIC_HPD |
1029*f005ef32Sjsg 		   INVERT_TC1_HPD |
1030*f005ef32Sjsg 		   INVERT_TC2_HPD |
1031*f005ef32Sjsg 		   INVERT_TC3_HPD |
1032*f005ef32Sjsg 		   INVERT_TC4_HPD |
1033*f005ef32Sjsg 		   INVERT_DDID_HPD_MTP |
1034*f005ef32Sjsg 		   INVERT_DDIE_HPD);
1035*f005ef32Sjsg 	intel_de_rmw(i915, SOUTH_CHICKEN1, 0, val);
1036*f005ef32Sjsg }
1037*f005ef32Sjsg 
mtp_hpd_enable_detection(struct intel_encoder * encoder)1038*f005ef32Sjsg static void mtp_hpd_enable_detection(struct intel_encoder *encoder)
1039*f005ef32Sjsg {
1040*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1041*f005ef32Sjsg 
1042*f005ef32Sjsg 	mtp_hpd_invert(i915);
1043*f005ef32Sjsg 	mtp_ddi_hpd_enable_detection(encoder);
1044*f005ef32Sjsg 	mtp_tc_hpd_enable_detection(encoder);
1045*f005ef32Sjsg }
1046*f005ef32Sjsg 
mtp_hpd_irq_setup(struct drm_i915_private * i915)1047*f005ef32Sjsg static void mtp_hpd_irq_setup(struct drm_i915_private *i915)
1048*f005ef32Sjsg {
1049*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
1050*f005ef32Sjsg 
1051*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd);
1052*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd);
1053*f005ef32Sjsg 
1054*f005ef32Sjsg 	intel_de_write(i915, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250);
1055*f005ef32Sjsg 
1056*f005ef32Sjsg 	mtp_hpd_invert(i915);
1057*f005ef32Sjsg 	ibx_display_interrupt_update(i915, hotplug_irqs, enabled_irqs);
1058*f005ef32Sjsg 
1059*f005ef32Sjsg 	mtp_ddi_hpd_detection_setup(i915);
1060*f005ef32Sjsg 	mtp_tc_hpd_detection_setup(i915);
1061*f005ef32Sjsg }
1062*f005ef32Sjsg 
is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin)1063*f005ef32Sjsg static bool is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin)
1064*f005ef32Sjsg {
1065*f005ef32Sjsg 	return hpd_pin >= HPD_PORT_TC1 && hpd_pin <= HPD_PORT_TC4;
1066*f005ef32Sjsg }
1067*f005ef32Sjsg 
_xelpdp_pica_hpd_detection_setup(struct drm_i915_private * i915,enum hpd_pin hpd_pin,bool enable)1068*f005ef32Sjsg static void _xelpdp_pica_hpd_detection_setup(struct drm_i915_private *i915,
1069*f005ef32Sjsg 					     enum hpd_pin hpd_pin, bool enable)
1070*f005ef32Sjsg {
1071*f005ef32Sjsg 	u32 mask = XELPDP_TBT_HOTPLUG_ENABLE |
1072*f005ef32Sjsg 		XELPDP_DP_ALT_HOTPLUG_ENABLE;
1073*f005ef32Sjsg 
1074*f005ef32Sjsg 	if (!is_xelpdp_pica_hpd_pin(hpd_pin))
1075*f005ef32Sjsg 		return;
1076*f005ef32Sjsg 
1077*f005ef32Sjsg 	intel_de_rmw(i915, XELPDP_PORT_HOTPLUG_CTL(hpd_pin),
1078*f005ef32Sjsg 		     mask, enable ? mask : 0);
1079*f005ef32Sjsg }
1080*f005ef32Sjsg 
xelpdp_pica_hpd_enable_detection(struct intel_encoder * encoder)1081*f005ef32Sjsg static void xelpdp_pica_hpd_enable_detection(struct intel_encoder *encoder)
1082*f005ef32Sjsg {
1083*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1084*f005ef32Sjsg 
1085*f005ef32Sjsg 	_xelpdp_pica_hpd_detection_setup(i915, encoder->hpd_pin, true);
1086*f005ef32Sjsg }
1087*f005ef32Sjsg 
xelpdp_pica_hpd_detection_setup(struct drm_i915_private * i915)1088*f005ef32Sjsg static void xelpdp_pica_hpd_detection_setup(struct drm_i915_private *i915)
1089*f005ef32Sjsg {
1090*f005ef32Sjsg 	struct intel_encoder *encoder;
1091*f005ef32Sjsg 	u32 available_pins = 0;
1092*f005ef32Sjsg 	enum hpd_pin pin;
1093*f005ef32Sjsg 
1094*f005ef32Sjsg 	BUILD_BUG_ON(BITS_PER_TYPE(available_pins) < HPD_NUM_PINS);
1095*f005ef32Sjsg 
1096*f005ef32Sjsg 	for_each_intel_encoder(&i915->drm, encoder)
1097*f005ef32Sjsg 		available_pins |= BIT(encoder->hpd_pin);
1098*f005ef32Sjsg 
1099*f005ef32Sjsg 	for_each_hpd_pin(pin)
1100*f005ef32Sjsg 		_xelpdp_pica_hpd_detection_setup(i915, pin, available_pins & BIT(pin));
1101*f005ef32Sjsg }
1102*f005ef32Sjsg 
xelpdp_hpd_enable_detection(struct intel_encoder * encoder)1103*f005ef32Sjsg static void xelpdp_hpd_enable_detection(struct intel_encoder *encoder)
1104*f005ef32Sjsg {
1105*f005ef32Sjsg 	xelpdp_pica_hpd_enable_detection(encoder);
1106*f005ef32Sjsg 	mtp_hpd_enable_detection(encoder);
1107*f005ef32Sjsg }
1108*f005ef32Sjsg 
xelpdp_hpd_irq_setup(struct drm_i915_private * i915)1109*f005ef32Sjsg static void xelpdp_hpd_irq_setup(struct drm_i915_private *i915)
1110*f005ef32Sjsg {
1111*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
1112*f005ef32Sjsg 
1113*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.hpd);
1114*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.hpd);
1115*f005ef32Sjsg 
1116*f005ef32Sjsg 	intel_de_rmw(i915, PICAINTERRUPT_IMR, hotplug_irqs,
1117*f005ef32Sjsg 		     ~enabled_irqs & hotplug_irqs);
1118*f005ef32Sjsg 	intel_uncore_posting_read(&i915->uncore, PICAINTERRUPT_IMR);
1119*f005ef32Sjsg 
1120*f005ef32Sjsg 	xelpdp_pica_hpd_detection_setup(i915);
1121*f005ef32Sjsg 
1122*f005ef32Sjsg 	if (INTEL_PCH_TYPE(i915) >= PCH_MTP)
1123*f005ef32Sjsg 		mtp_hpd_irq_setup(i915);
1124*f005ef32Sjsg }
1125*f005ef32Sjsg 
spt_hotplug_mask(enum hpd_pin hpd_pin)1126*f005ef32Sjsg static u32 spt_hotplug_mask(enum hpd_pin hpd_pin)
1127*f005ef32Sjsg {
1128*f005ef32Sjsg 	switch (hpd_pin) {
1129*f005ef32Sjsg 	case HPD_PORT_A:
1130*f005ef32Sjsg 		return PORTA_HOTPLUG_ENABLE;
1131*f005ef32Sjsg 	case HPD_PORT_B:
1132*f005ef32Sjsg 		return PORTB_HOTPLUG_ENABLE;
1133*f005ef32Sjsg 	case HPD_PORT_C:
1134*f005ef32Sjsg 		return PORTC_HOTPLUG_ENABLE;
1135*f005ef32Sjsg 	case HPD_PORT_D:
1136*f005ef32Sjsg 		return PORTD_HOTPLUG_ENABLE;
1137*f005ef32Sjsg 	default:
1138*f005ef32Sjsg 		return 0;
1139*f005ef32Sjsg 	}
1140*f005ef32Sjsg }
1141*f005ef32Sjsg 
spt_hotplug_enables(struct intel_encoder * encoder)1142*f005ef32Sjsg static u32 spt_hotplug_enables(struct intel_encoder *encoder)
1143*f005ef32Sjsg {
1144*f005ef32Sjsg 	return spt_hotplug_mask(encoder->hpd_pin);
1145*f005ef32Sjsg }
1146*f005ef32Sjsg 
spt_hotplug2_mask(enum hpd_pin hpd_pin)1147*f005ef32Sjsg static u32 spt_hotplug2_mask(enum hpd_pin hpd_pin)
1148*f005ef32Sjsg {
1149*f005ef32Sjsg 	switch (hpd_pin) {
1150*f005ef32Sjsg 	case HPD_PORT_E:
1151*f005ef32Sjsg 		return PORTE_HOTPLUG_ENABLE;
1152*f005ef32Sjsg 	default:
1153*f005ef32Sjsg 		return 0;
1154*f005ef32Sjsg 	}
1155*f005ef32Sjsg }
1156*f005ef32Sjsg 
spt_hotplug2_enables(struct intel_encoder * encoder)1157*f005ef32Sjsg static u32 spt_hotplug2_enables(struct intel_encoder *encoder)
1158*f005ef32Sjsg {
1159*f005ef32Sjsg 	return spt_hotplug2_mask(encoder->hpd_pin);
1160*f005ef32Sjsg }
1161*f005ef32Sjsg 
spt_hpd_detection_setup(struct drm_i915_private * dev_priv)1162*f005ef32Sjsg static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv)
1163*f005ef32Sjsg {
1164*f005ef32Sjsg 	/* Display WA #1179 WaHardHangonHotPlug: cnp */
1165*f005ef32Sjsg 	if (HAS_PCH_CNP(dev_priv)) {
1166*f005ef32Sjsg 		intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK,
1167*f005ef32Sjsg 				 CHASSIS_CLK_REQ_DURATION(0xf));
1168*f005ef32Sjsg 	}
1169*f005ef32Sjsg 
1170*f005ef32Sjsg 	/* Enable digital hotplug on the PCH */
1171*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
1172*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, spt_hotplug_mask),
1173*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables));
1174*f005ef32Sjsg 
1175*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2,
1176*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, spt_hotplug2_mask),
1177*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables));
1178*f005ef32Sjsg }
1179*f005ef32Sjsg 
spt_hpd_enable_detection(struct intel_encoder * encoder)1180*f005ef32Sjsg static void spt_hpd_enable_detection(struct intel_encoder *encoder)
1181*f005ef32Sjsg {
1182*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1183*f005ef32Sjsg 
1184*f005ef32Sjsg 	/* Display WA #1179 WaHardHangonHotPlug: cnp */
1185*f005ef32Sjsg 	if (HAS_PCH_CNP(i915)) {
1186*f005ef32Sjsg 		intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN1,
1187*f005ef32Sjsg 				 CHASSIS_CLK_REQ_DURATION_MASK,
1188*f005ef32Sjsg 				 CHASSIS_CLK_REQ_DURATION(0xf));
1189*f005ef32Sjsg 	}
1190*f005ef32Sjsg 
1191*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG,
1192*f005ef32Sjsg 			 spt_hotplug_mask(encoder->hpd_pin),
1193*f005ef32Sjsg 			 spt_hotplug_enables(encoder));
1194*f005ef32Sjsg 
1195*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG2,
1196*f005ef32Sjsg 			 spt_hotplug2_mask(encoder->hpd_pin),
1197*f005ef32Sjsg 			 spt_hotplug2_enables(encoder));
1198*f005ef32Sjsg }
1199*f005ef32Sjsg 
spt_hpd_irq_setup(struct drm_i915_private * dev_priv)1200*f005ef32Sjsg static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv)
1201*f005ef32Sjsg {
1202*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
1203*f005ef32Sjsg 
1204*f005ef32Sjsg 	if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
1205*f005ef32Sjsg 		intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ);
1206*f005ef32Sjsg 
1207*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
1208*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd);
1209*f005ef32Sjsg 
1210*f005ef32Sjsg 	ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs);
1211*f005ef32Sjsg 
1212*f005ef32Sjsg 	spt_hpd_detection_setup(dev_priv);
1213*f005ef32Sjsg }
1214*f005ef32Sjsg 
ilk_hotplug_mask(enum hpd_pin hpd_pin)1215*f005ef32Sjsg static u32 ilk_hotplug_mask(enum hpd_pin hpd_pin)
1216*f005ef32Sjsg {
1217*f005ef32Sjsg 	switch (hpd_pin) {
1218*f005ef32Sjsg 	case HPD_PORT_A:
1219*f005ef32Sjsg 		return DIGITAL_PORTA_HOTPLUG_ENABLE |
1220*f005ef32Sjsg 			DIGITAL_PORTA_PULSE_DURATION_MASK;
1221*f005ef32Sjsg 	default:
1222*f005ef32Sjsg 		return 0;
1223*f005ef32Sjsg 	}
1224*f005ef32Sjsg }
1225*f005ef32Sjsg 
ilk_hotplug_enables(struct intel_encoder * encoder)1226*f005ef32Sjsg static u32 ilk_hotplug_enables(struct intel_encoder *encoder)
1227*f005ef32Sjsg {
1228*f005ef32Sjsg 	switch (encoder->hpd_pin) {
1229*f005ef32Sjsg 	case HPD_PORT_A:
1230*f005ef32Sjsg 		return DIGITAL_PORTA_HOTPLUG_ENABLE |
1231*f005ef32Sjsg 			DIGITAL_PORTA_PULSE_DURATION_2ms;
1232*f005ef32Sjsg 	default:
1233*f005ef32Sjsg 		return 0;
1234*f005ef32Sjsg 	}
1235*f005ef32Sjsg }
1236*f005ef32Sjsg 
ilk_hpd_detection_setup(struct drm_i915_private * dev_priv)1237*f005ef32Sjsg static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv)
1238*f005ef32Sjsg {
1239*f005ef32Sjsg 	/*
1240*f005ef32Sjsg 	 * Enable digital hotplug on the CPU, and configure the DP short pulse
1241*f005ef32Sjsg 	 * duration to 2ms (which is the minimum in the Display Port spec)
1242*f005ef32Sjsg 	 * The pulse duration bits are reserved on HSW+.
1243*f005ef32Sjsg 	 */
1244*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL,
1245*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, ilk_hotplug_mask),
1246*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables));
1247*f005ef32Sjsg }
1248*f005ef32Sjsg 
ilk_hpd_enable_detection(struct intel_encoder * encoder)1249*f005ef32Sjsg static void ilk_hpd_enable_detection(struct intel_encoder *encoder)
1250*f005ef32Sjsg {
1251*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1252*f005ef32Sjsg 
1253*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, DIGITAL_PORT_HOTPLUG_CNTRL,
1254*f005ef32Sjsg 			 ilk_hotplug_mask(encoder->hpd_pin),
1255*f005ef32Sjsg 			 ilk_hotplug_enables(encoder));
1256*f005ef32Sjsg 
1257*f005ef32Sjsg 	ibx_hpd_enable_detection(encoder);
1258*f005ef32Sjsg }
1259*f005ef32Sjsg 
ilk_hpd_irq_setup(struct drm_i915_private * dev_priv)1260*f005ef32Sjsg static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv)
1261*f005ef32Sjsg {
1262*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
1263*f005ef32Sjsg 
1264*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd);
1265*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd);
1266*f005ef32Sjsg 
1267*f005ef32Sjsg 	if (DISPLAY_VER(dev_priv) >= 8)
1268*f005ef32Sjsg 		bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs);
1269*f005ef32Sjsg 	else
1270*f005ef32Sjsg 		ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs);
1271*f005ef32Sjsg 
1272*f005ef32Sjsg 	ilk_hpd_detection_setup(dev_priv);
1273*f005ef32Sjsg 
1274*f005ef32Sjsg 	ibx_hpd_irq_setup(dev_priv);
1275*f005ef32Sjsg }
1276*f005ef32Sjsg 
bxt_hotplug_mask(enum hpd_pin hpd_pin)1277*f005ef32Sjsg static u32 bxt_hotplug_mask(enum hpd_pin hpd_pin)
1278*f005ef32Sjsg {
1279*f005ef32Sjsg 	switch (hpd_pin) {
1280*f005ef32Sjsg 	case HPD_PORT_A:
1281*f005ef32Sjsg 		return PORTA_HOTPLUG_ENABLE | BXT_DDIA_HPD_INVERT;
1282*f005ef32Sjsg 	case HPD_PORT_B:
1283*f005ef32Sjsg 		return PORTB_HOTPLUG_ENABLE | BXT_DDIB_HPD_INVERT;
1284*f005ef32Sjsg 	case HPD_PORT_C:
1285*f005ef32Sjsg 		return PORTC_HOTPLUG_ENABLE | BXT_DDIC_HPD_INVERT;
1286*f005ef32Sjsg 	default:
1287*f005ef32Sjsg 		return 0;
1288*f005ef32Sjsg 	}
1289*f005ef32Sjsg }
1290*f005ef32Sjsg 
bxt_hotplug_enables(struct intel_encoder * encoder)1291*f005ef32Sjsg static u32 bxt_hotplug_enables(struct intel_encoder *encoder)
1292*f005ef32Sjsg {
1293*f005ef32Sjsg 	u32 hotplug;
1294*f005ef32Sjsg 
1295*f005ef32Sjsg 	switch (encoder->hpd_pin) {
1296*f005ef32Sjsg 	case HPD_PORT_A:
1297*f005ef32Sjsg 		hotplug = PORTA_HOTPLUG_ENABLE;
1298*f005ef32Sjsg 		if (intel_bios_encoder_hpd_invert(encoder->devdata))
1299*f005ef32Sjsg 			hotplug |= BXT_DDIA_HPD_INVERT;
1300*f005ef32Sjsg 		return hotplug;
1301*f005ef32Sjsg 	case HPD_PORT_B:
1302*f005ef32Sjsg 		hotplug = PORTB_HOTPLUG_ENABLE;
1303*f005ef32Sjsg 		if (intel_bios_encoder_hpd_invert(encoder->devdata))
1304*f005ef32Sjsg 			hotplug |= BXT_DDIB_HPD_INVERT;
1305*f005ef32Sjsg 		return hotplug;
1306*f005ef32Sjsg 	case HPD_PORT_C:
1307*f005ef32Sjsg 		hotplug = PORTC_HOTPLUG_ENABLE;
1308*f005ef32Sjsg 		if (intel_bios_encoder_hpd_invert(encoder->devdata))
1309*f005ef32Sjsg 			hotplug |= BXT_DDIC_HPD_INVERT;
1310*f005ef32Sjsg 		return hotplug;
1311*f005ef32Sjsg 	default:
1312*f005ef32Sjsg 		return 0;
1313*f005ef32Sjsg 	}
1314*f005ef32Sjsg }
1315*f005ef32Sjsg 
bxt_hpd_detection_setup(struct drm_i915_private * dev_priv)1316*f005ef32Sjsg static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv)
1317*f005ef32Sjsg {
1318*f005ef32Sjsg 	intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
1319*f005ef32Sjsg 			 intel_hpd_hotplug_mask(dev_priv, bxt_hotplug_mask),
1320*f005ef32Sjsg 			 intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables));
1321*f005ef32Sjsg }
1322*f005ef32Sjsg 
bxt_hpd_enable_detection(struct intel_encoder * encoder)1323*f005ef32Sjsg static void bxt_hpd_enable_detection(struct intel_encoder *encoder)
1324*f005ef32Sjsg {
1325*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1326*f005ef32Sjsg 
1327*f005ef32Sjsg 	intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG,
1328*f005ef32Sjsg 			 bxt_hotplug_mask(encoder->hpd_pin),
1329*f005ef32Sjsg 			 bxt_hotplug_enables(encoder));
1330*f005ef32Sjsg }
1331*f005ef32Sjsg 
bxt_hpd_irq_setup(struct drm_i915_private * dev_priv)1332*f005ef32Sjsg static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv)
1333*f005ef32Sjsg {
1334*f005ef32Sjsg 	u32 hotplug_irqs, enabled_irqs;
1335*f005ef32Sjsg 
1336*f005ef32Sjsg 	enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd);
1337*f005ef32Sjsg 	hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd);
1338*f005ef32Sjsg 
1339*f005ef32Sjsg 	bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs);
1340*f005ef32Sjsg 
1341*f005ef32Sjsg 	bxt_hpd_detection_setup(dev_priv);
1342*f005ef32Sjsg }
1343*f005ef32Sjsg 
i915_hpd_enable_detection(struct intel_encoder * encoder)1344*f005ef32Sjsg static void i915_hpd_enable_detection(struct intel_encoder *encoder)
1345*f005ef32Sjsg {
1346*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1347*f005ef32Sjsg 	u32 hotplug_en = hpd_mask_i915[encoder->hpd_pin];
1348*f005ef32Sjsg 
1349*f005ef32Sjsg 	/* HPD sense and interrupt enable are one and the same */
1350*f005ef32Sjsg 	i915_hotplug_interrupt_update(i915, hotplug_en, hotplug_en);
1351*f005ef32Sjsg }
1352*f005ef32Sjsg 
i915_hpd_irq_setup(struct drm_i915_private * dev_priv)1353*f005ef32Sjsg static void i915_hpd_irq_setup(struct drm_i915_private *dev_priv)
1354*f005ef32Sjsg {
1355*f005ef32Sjsg 	u32 hotplug_en;
1356*f005ef32Sjsg 
1357*f005ef32Sjsg 	lockdep_assert_held(&dev_priv->irq_lock);
1358*f005ef32Sjsg 
1359*f005ef32Sjsg 	/*
1360*f005ef32Sjsg 	 * Note HDMI and DP share hotplug bits. Enable bits are the same for all
1361*f005ef32Sjsg 	 * generations.
1362*f005ef32Sjsg 	 */
1363*f005ef32Sjsg 	hotplug_en = intel_hpd_enabled_irqs(dev_priv, hpd_mask_i915);
1364*f005ef32Sjsg 	/*
1365*f005ef32Sjsg 	 * Programming the CRT detection parameters tends to generate a spurious
1366*f005ef32Sjsg 	 * hotplug event about three seconds later. So just do it once.
1367*f005ef32Sjsg 	 */
1368*f005ef32Sjsg 	if (IS_G4X(dev_priv))
1369*f005ef32Sjsg 		hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
1370*f005ef32Sjsg 	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
1371*f005ef32Sjsg 
1372*f005ef32Sjsg 	/* Ignore TV since it's buggy */
1373*f005ef32Sjsg 	i915_hotplug_interrupt_update_locked(dev_priv,
1374*f005ef32Sjsg 					     HOTPLUG_INT_EN_MASK |
1375*f005ef32Sjsg 					     CRT_HOTPLUG_VOLTAGE_COMPARE_MASK |
1376*f005ef32Sjsg 					     CRT_HOTPLUG_ACTIVATION_PERIOD_64,
1377*f005ef32Sjsg 					     hotplug_en);
1378*f005ef32Sjsg }
1379*f005ef32Sjsg 
1380*f005ef32Sjsg struct intel_hotplug_funcs {
1381*f005ef32Sjsg 	/* Enable HPD sense and interrupts for all present encoders */
1382*f005ef32Sjsg 	void (*hpd_irq_setup)(struct drm_i915_private *i915);
1383*f005ef32Sjsg 	/* Enable HPD sense for a single encoder */
1384*f005ef32Sjsg 	void (*hpd_enable_detection)(struct intel_encoder *encoder);
1385*f005ef32Sjsg };
1386*f005ef32Sjsg 
1387*f005ef32Sjsg #define HPD_FUNCS(platform)					 \
1388*f005ef32Sjsg static const struct intel_hotplug_funcs platform##_hpd_funcs = { \
1389*f005ef32Sjsg 	.hpd_irq_setup = platform##_hpd_irq_setup,		 \
1390*f005ef32Sjsg 	.hpd_enable_detection = platform##_hpd_enable_detection, \
1391*f005ef32Sjsg }
1392*f005ef32Sjsg 
1393*f005ef32Sjsg HPD_FUNCS(i915);
1394*f005ef32Sjsg HPD_FUNCS(xelpdp);
1395*f005ef32Sjsg HPD_FUNCS(dg1);
1396*f005ef32Sjsg HPD_FUNCS(gen11);
1397*f005ef32Sjsg HPD_FUNCS(bxt);
1398*f005ef32Sjsg HPD_FUNCS(icp);
1399*f005ef32Sjsg HPD_FUNCS(spt);
1400*f005ef32Sjsg HPD_FUNCS(ilk);
1401*f005ef32Sjsg #undef HPD_FUNCS
1402*f005ef32Sjsg 
intel_hpd_enable_detection(struct intel_encoder * encoder)1403*f005ef32Sjsg void intel_hpd_enable_detection(struct intel_encoder *encoder)
1404*f005ef32Sjsg {
1405*f005ef32Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1406*f005ef32Sjsg 
1407*f005ef32Sjsg 	if (i915->display.funcs.hotplug)
1408*f005ef32Sjsg 		i915->display.funcs.hotplug->hpd_enable_detection(encoder);
1409*f005ef32Sjsg }
1410*f005ef32Sjsg 
intel_hpd_irq_setup(struct drm_i915_private * i915)1411*f005ef32Sjsg void intel_hpd_irq_setup(struct drm_i915_private *i915)
1412*f005ef32Sjsg {
1413*f005ef32Sjsg 	if (i915->display_irqs_enabled && i915->display.funcs.hotplug)
1414*f005ef32Sjsg 		i915->display.funcs.hotplug->hpd_irq_setup(i915);
1415*f005ef32Sjsg }
1416*f005ef32Sjsg 
intel_hotplug_irq_init(struct drm_i915_private * i915)1417*f005ef32Sjsg void intel_hotplug_irq_init(struct drm_i915_private *i915)
1418*f005ef32Sjsg {
1419*f005ef32Sjsg 	intel_hpd_init_pins(i915);
1420*f005ef32Sjsg 
1421*f005ef32Sjsg 	intel_hpd_init_early(i915);
1422*f005ef32Sjsg 
1423*f005ef32Sjsg 	if (HAS_GMCH(i915)) {
1424*f005ef32Sjsg 		if (I915_HAS_HOTPLUG(i915))
1425*f005ef32Sjsg 			i915->display.funcs.hotplug = &i915_hpd_funcs;
1426*f005ef32Sjsg 	} else {
1427*f005ef32Sjsg 		if (HAS_PCH_DG2(i915))
1428*f005ef32Sjsg 			i915->display.funcs.hotplug = &icp_hpd_funcs;
1429*f005ef32Sjsg 		else if (HAS_PCH_DG1(i915))
1430*f005ef32Sjsg 			i915->display.funcs.hotplug = &dg1_hpd_funcs;
1431*f005ef32Sjsg 		else if (DISPLAY_VER(i915) >= 14)
1432*f005ef32Sjsg 			i915->display.funcs.hotplug = &xelpdp_hpd_funcs;
1433*f005ef32Sjsg 		else if (DISPLAY_VER(i915) >= 11)
1434*f005ef32Sjsg 			i915->display.funcs.hotplug = &gen11_hpd_funcs;
1435*f005ef32Sjsg 		else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
1436*f005ef32Sjsg 			i915->display.funcs.hotplug = &bxt_hpd_funcs;
1437*f005ef32Sjsg 		else if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
1438*f005ef32Sjsg 			i915->display.funcs.hotplug = &icp_hpd_funcs;
1439*f005ef32Sjsg 		else if (INTEL_PCH_TYPE(i915) >= PCH_SPT)
1440*f005ef32Sjsg 			i915->display.funcs.hotplug = &spt_hpd_funcs;
1441*f005ef32Sjsg 		else
1442*f005ef32Sjsg 			i915->display.funcs.hotplug = &ilk_hpd_funcs;
1443*f005ef32Sjsg 	}
1444*f005ef32Sjsg }
1445