1 // SPDX-License-Identifier: MIT
3 * Copyright 2019 Intel Corporation.
9 /* Map PCH device id to PCH type, or PCH_NONE if unknown. */
11 intel_pch_type(const struct drm_i915_private
*dev_priv
, unsigned short id
)
14 case INTEL_PCH_IBX_DEVICE_ID_TYPE
:
15 drm_dbg_kms(&dev_priv
->drm
, "Found Ibex Peak PCH\n");
16 drm_WARN_ON(&dev_priv
->drm
, !IS_GEN(dev_priv
, 5));
18 case INTEL_PCH_CPT_DEVICE_ID_TYPE
:
19 drm_dbg_kms(&dev_priv
->drm
, "Found CougarPoint PCH\n");
20 drm_WARN_ON(&dev_priv
->drm
,
21 !IS_GEN(dev_priv
, 6) && !IS_IVYBRIDGE(dev_priv
));
23 case INTEL_PCH_PPT_DEVICE_ID_TYPE
:
24 drm_dbg_kms(&dev_priv
->drm
, "Found PantherPoint PCH\n");
25 drm_WARN_ON(&dev_priv
->drm
,
26 !IS_GEN(dev_priv
, 6) && !IS_IVYBRIDGE(dev_priv
));
27 /* PantherPoint is CPT compatible */
29 case INTEL_PCH_LPT_DEVICE_ID_TYPE
:
30 drm_dbg_kms(&dev_priv
->drm
, "Found LynxPoint PCH\n");
31 drm_WARN_ON(&dev_priv
->drm
,
32 !IS_HASWELL(dev_priv
) && !IS_BROADWELL(dev_priv
));
33 drm_WARN_ON(&dev_priv
->drm
,
34 IS_HSW_ULT(dev_priv
) || IS_BDW_ULT(dev_priv
));
36 case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE
:
37 drm_dbg_kms(&dev_priv
->drm
, "Found LynxPoint LP PCH\n");
38 drm_WARN_ON(&dev_priv
->drm
,
39 !IS_HASWELL(dev_priv
) && !IS_BROADWELL(dev_priv
));
40 drm_WARN_ON(&dev_priv
->drm
,
41 !IS_HSW_ULT(dev_priv
) && !IS_BDW_ULT(dev_priv
));
43 case INTEL_PCH_WPT_DEVICE_ID_TYPE
:
44 drm_dbg_kms(&dev_priv
->drm
, "Found WildcatPoint PCH\n");
45 drm_WARN_ON(&dev_priv
->drm
,
46 !IS_HASWELL(dev_priv
) && !IS_BROADWELL(dev_priv
));
47 drm_WARN_ON(&dev_priv
->drm
,
48 IS_HSW_ULT(dev_priv
) || IS_BDW_ULT(dev_priv
));
49 /* WildcatPoint is LPT compatible */
51 case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE
:
52 drm_dbg_kms(&dev_priv
->drm
, "Found WildcatPoint LP PCH\n");
53 drm_WARN_ON(&dev_priv
->drm
,
54 !IS_HASWELL(dev_priv
) && !IS_BROADWELL(dev_priv
));
55 drm_WARN_ON(&dev_priv
->drm
,
56 !IS_HSW_ULT(dev_priv
) && !IS_BDW_ULT(dev_priv
));
57 /* WildcatPoint is LPT compatible */
59 case INTEL_PCH_SPT_DEVICE_ID_TYPE
:
60 drm_dbg_kms(&dev_priv
->drm
, "Found SunrisePoint PCH\n");
61 drm_WARN_ON(&dev_priv
->drm
,
62 !IS_SKYLAKE(dev_priv
) && !IS_KABYLAKE(dev_priv
));
64 case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE
:
65 drm_dbg_kms(&dev_priv
->drm
, "Found SunrisePoint LP PCH\n");
66 drm_WARN_ON(&dev_priv
->drm
,
67 !IS_SKYLAKE(dev_priv
) &&
68 !IS_KABYLAKE(dev_priv
) &&
69 !IS_COFFEELAKE(dev_priv
) &&
70 !IS_COMETLAKE(dev_priv
));
72 case INTEL_PCH_KBP_DEVICE_ID_TYPE
:
73 drm_dbg_kms(&dev_priv
->drm
, "Found Kaby Lake PCH (KBP)\n");
74 drm_WARN_ON(&dev_priv
->drm
,
75 !IS_SKYLAKE(dev_priv
) &&
76 !IS_KABYLAKE(dev_priv
) &&
77 !IS_COFFEELAKE(dev_priv
) &&
78 !IS_COMETLAKE(dev_priv
));
79 /* KBP is SPT compatible */
81 case INTEL_PCH_CNP_DEVICE_ID_TYPE
:
82 drm_dbg_kms(&dev_priv
->drm
, "Found Cannon Lake PCH (CNP)\n");
83 drm_WARN_ON(&dev_priv
->drm
,
84 !IS_CANNONLAKE(dev_priv
) &&
85 !IS_COFFEELAKE(dev_priv
) &&
86 !IS_COMETLAKE(dev_priv
));
88 case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE
:
89 drm_dbg_kms(&dev_priv
->drm
,
90 "Found Cannon Lake LP PCH (CNP-LP)\n");
91 drm_WARN_ON(&dev_priv
->drm
,
92 !IS_CANNONLAKE(dev_priv
) &&
93 !IS_COFFEELAKE(dev_priv
) &&
94 !IS_COMETLAKE(dev_priv
));
96 case INTEL_PCH_CMP_DEVICE_ID_TYPE
:
97 case INTEL_PCH_CMP2_DEVICE_ID_TYPE
:
98 drm_dbg_kms(&dev_priv
->drm
, "Found Comet Lake PCH (CMP)\n");
99 drm_WARN_ON(&dev_priv
->drm
,
100 !IS_COFFEELAKE(dev_priv
) &&
101 !IS_COMETLAKE(dev_priv
) &&
102 !IS_ROCKETLAKE(dev_priv
));
103 /* CometPoint is CNP Compatible */
105 case INTEL_PCH_CMP_V_DEVICE_ID_TYPE
:
106 drm_dbg_kms(&dev_priv
->drm
, "Found Comet Lake V PCH (CMP-V)\n");
107 drm_WARN_ON(&dev_priv
->drm
,
108 !IS_COFFEELAKE(dev_priv
) &&
109 !IS_COMETLAKE(dev_priv
));
110 /* Comet Lake V PCH is based on KBP, which is SPT compatible */
112 case INTEL_PCH_ICP_DEVICE_ID_TYPE
:
113 drm_dbg_kms(&dev_priv
->drm
, "Found Ice Lake PCH\n");
114 drm_WARN_ON(&dev_priv
->drm
, !IS_ICELAKE(dev_priv
));
116 case INTEL_PCH_MCC_DEVICE_ID_TYPE
:
117 drm_dbg_kms(&dev_priv
->drm
, "Found Mule Creek Canyon PCH\n");
118 drm_WARN_ON(&dev_priv
->drm
, !IS_JSL_EHL(dev_priv
));
120 case INTEL_PCH_TGP_DEVICE_ID_TYPE
:
121 case INTEL_PCH_TGP2_DEVICE_ID_TYPE
:
122 drm_dbg_kms(&dev_priv
->drm
, "Found Tiger Lake LP PCH\n");
123 drm_WARN_ON(&dev_priv
->drm
, !IS_TIGERLAKE(dev_priv
) &&
124 !IS_ROCKETLAKE(dev_priv
));
126 case INTEL_PCH_JSP_DEVICE_ID_TYPE
:
127 case INTEL_PCH_JSP2_DEVICE_ID_TYPE
:
128 drm_dbg_kms(&dev_priv
->drm
, "Found Jasper Lake PCH\n");
129 drm_WARN_ON(&dev_priv
->drm
, !IS_JSL_EHL(dev_priv
));
136 static bool intel_is_virt_pch(unsigned short id
,
137 unsigned short svendor
, unsigned short sdevice
)
139 return (id
== INTEL_PCH_P2X_DEVICE_ID_TYPE
||
140 id
== INTEL_PCH_P3X_DEVICE_ID_TYPE
||
141 (id
== INTEL_PCH_QEMU_DEVICE_ID_TYPE
&&
142 svendor
== PCI_SUBVENDOR_ID_REDHAT_QUMRANET
&&
143 sdevice
== PCI_SUBDEVICE_ID_QEMU
));
146 static unsigned short
147 intel_virt_detect_pch(const struct drm_i915_private
*dev_priv
)
149 unsigned short id
= 0;
152 * In a virtualized passthrough environment we can be in a
153 * setup where the ISA bridge is not able to be passed through.
154 * In this case, a south bridge can be emulated and we have to
155 * make an educated guess as to which PCH is really there.
158 if (IS_TIGERLAKE(dev_priv
) || IS_ROCKETLAKE(dev_priv
))
159 id
= INTEL_PCH_TGP_DEVICE_ID_TYPE
;
160 else if (IS_JSL_EHL(dev_priv
))
161 id
= INTEL_PCH_MCC_DEVICE_ID_TYPE
;
162 else if (IS_ICELAKE(dev_priv
))
163 id
= INTEL_PCH_ICP_DEVICE_ID_TYPE
;
164 else if (IS_CANNONLAKE(dev_priv
) ||
165 IS_COFFEELAKE(dev_priv
) ||
166 IS_COMETLAKE(dev_priv
))
167 id
= INTEL_PCH_CNP_DEVICE_ID_TYPE
;
168 else if (IS_KABYLAKE(dev_priv
) || IS_SKYLAKE(dev_priv
))
169 id
= INTEL_PCH_SPT_DEVICE_ID_TYPE
;
170 else if (IS_HSW_ULT(dev_priv
) || IS_BDW_ULT(dev_priv
))
171 id
= INTEL_PCH_LPT_LP_DEVICE_ID_TYPE
;
172 else if (IS_HASWELL(dev_priv
) || IS_BROADWELL(dev_priv
))
173 id
= INTEL_PCH_LPT_DEVICE_ID_TYPE
;
174 else if (IS_GEN(dev_priv
, 6) || IS_IVYBRIDGE(dev_priv
))
175 id
= INTEL_PCH_CPT_DEVICE_ID_TYPE
;
176 else if (IS_GEN(dev_priv
, 5))
177 id
= INTEL_PCH_IBX_DEVICE_ID_TYPE
;
180 drm_dbg_kms(&dev_priv
->drm
, "Assuming PCH ID %04x\n", id
);
182 drm_dbg_kms(&dev_priv
->drm
, "Assuming no PCH\n");
187 void intel_detect_pch(struct drm_i915_private
*dev_priv
)
189 struct pci_dev
*pch
= NULL
;
191 /* DG1 has south engine display on the same PCI device */
192 if (IS_DG1(dev_priv
)) {
193 dev_priv
->pch_type
= PCH_DG1
;
198 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
199 * make graphics device passthrough work easy for VMM, that only
200 * need to expose ISA bridge to let driver know the real hardware
201 * underneath. This is a requirement from virtualization team.
203 * In some virtualized environments (e.g. XEN), there is irrelevant
204 * ISA bridge in the system. To work reliably, we should scan trhough
205 * all the ISA bridge devices and check for the first match, instead
206 * of only checking the first one.
208 while ((pch
= pci_get_class(PCI_CLASS_BRIDGE_ISA
<< 8, pch
))) {
210 enum intel_pch pch_type
;
212 if (pch
->vendor
!= PCI_VENDOR_ID_INTEL
)
215 id
= pch
->device
& INTEL_PCH_DEVICE_ID_MASK
;
217 pch_type
= intel_pch_type(dev_priv
, id
);
218 if (pch_type
!= PCH_NONE
) {
219 dev_priv
->pch_type
= pch_type
;
220 dev_priv
->pch_id
= id
;
222 } else if (intel_is_virt_pch(id
, pch
->subsystem_vendor
,
223 pch
->subsystem_device
)) {
224 id
= intel_virt_detect_pch(dev_priv
);
225 pch_type
= intel_pch_type(dev_priv
, id
);
227 /* Sanity check virtual PCH id */
228 if (drm_WARN_ON(&dev_priv
->drm
,
229 id
&& pch_type
== PCH_NONE
))
232 dev_priv
->pch_type
= pch_type
;
233 dev_priv
->pch_id
= id
;
239 * Use PCH_NOP (PCH but no South Display) for PCH platforms without
242 if (pch
&& !HAS_DISPLAY(dev_priv
)) {
243 drm_dbg_kms(&dev_priv
->drm
,
244 "Display disabled, reverting to NOP PCH\n");
245 dev_priv
->pch_type
= PCH_NOP
;
246 dev_priv
->pch_id
= 0;
250 drm_dbg_kms(&dev_priv
->drm
, "No PCH found.\n");