0001
0002
0003
0004
0005
0006 #include "i915_drv.h"
0007 #include "i915_utils.h"
0008 #include "intel_pch.h"
0009
0010
0011 static enum intel_pch
0012 intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
0013 {
0014 switch (id) {
0015 case INTEL_PCH_IBX_DEVICE_ID_TYPE:
0016 drm_dbg_kms(&dev_priv->drm, "Found Ibex Peak PCH\n");
0017 drm_WARN_ON(&dev_priv->drm, GRAPHICS_VER(dev_priv) != 5);
0018 return PCH_IBX;
0019 case INTEL_PCH_CPT_DEVICE_ID_TYPE:
0020 drm_dbg_kms(&dev_priv->drm, "Found CougarPoint PCH\n");
0021 drm_WARN_ON(&dev_priv->drm,
0022 GRAPHICS_VER(dev_priv) != 6 && !IS_IVYBRIDGE(dev_priv));
0023 return PCH_CPT;
0024 case INTEL_PCH_PPT_DEVICE_ID_TYPE:
0025 drm_dbg_kms(&dev_priv->drm, "Found PantherPoint PCH\n");
0026 drm_WARN_ON(&dev_priv->drm,
0027 GRAPHICS_VER(dev_priv) != 6 && !IS_IVYBRIDGE(dev_priv));
0028
0029 return PCH_CPT;
0030 case INTEL_PCH_LPT_DEVICE_ID_TYPE:
0031 drm_dbg_kms(&dev_priv->drm, "Found LynxPoint PCH\n");
0032 drm_WARN_ON(&dev_priv->drm,
0033 !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
0034 drm_WARN_ON(&dev_priv->drm,
0035 IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv));
0036 return PCH_LPT;
0037 case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE:
0038 drm_dbg_kms(&dev_priv->drm, "Found LynxPoint LP PCH\n");
0039 drm_WARN_ON(&dev_priv->drm,
0040 !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
0041 drm_WARN_ON(&dev_priv->drm,
0042 !IS_HSW_ULT(dev_priv) && !IS_BDW_ULT(dev_priv));
0043 return PCH_LPT;
0044 case INTEL_PCH_WPT_DEVICE_ID_TYPE:
0045 drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint PCH\n");
0046 drm_WARN_ON(&dev_priv->drm,
0047 !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
0048 drm_WARN_ON(&dev_priv->drm,
0049 IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv));
0050
0051 return PCH_LPT;
0052 case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE:
0053 drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint LP PCH\n");
0054 drm_WARN_ON(&dev_priv->drm,
0055 !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
0056 drm_WARN_ON(&dev_priv->drm,
0057 !IS_HSW_ULT(dev_priv) && !IS_BDW_ULT(dev_priv));
0058
0059 return PCH_LPT;
0060 case INTEL_PCH_SPT_DEVICE_ID_TYPE:
0061 drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint PCH\n");
0062 drm_WARN_ON(&dev_priv->drm,
0063 !IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv));
0064 return PCH_SPT;
0065 case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE:
0066 drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint LP PCH\n");
0067 drm_WARN_ON(&dev_priv->drm,
0068 !IS_SKYLAKE(dev_priv) &&
0069 !IS_KABYLAKE(dev_priv) &&
0070 !IS_COFFEELAKE(dev_priv) &&
0071 !IS_COMETLAKE(dev_priv));
0072 return PCH_SPT;
0073 case INTEL_PCH_KBP_DEVICE_ID_TYPE:
0074 drm_dbg_kms(&dev_priv->drm, "Found Kaby Lake PCH (KBP)\n");
0075 drm_WARN_ON(&dev_priv->drm,
0076 !IS_SKYLAKE(dev_priv) &&
0077 !IS_KABYLAKE(dev_priv) &&
0078 !IS_COFFEELAKE(dev_priv) &&
0079 !IS_COMETLAKE(dev_priv));
0080
0081 return PCH_SPT;
0082 case INTEL_PCH_CNP_DEVICE_ID_TYPE:
0083 drm_dbg_kms(&dev_priv->drm, "Found Cannon Lake PCH (CNP)\n");
0084 drm_WARN_ON(&dev_priv->drm,
0085 !IS_COFFEELAKE(dev_priv) &&
0086 !IS_COMETLAKE(dev_priv));
0087 return PCH_CNP;
0088 case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE:
0089 drm_dbg_kms(&dev_priv->drm,
0090 "Found Cannon Lake LP PCH (CNP-LP)\n");
0091 drm_WARN_ON(&dev_priv->drm,
0092 !IS_COFFEELAKE(dev_priv) &&
0093 !IS_COMETLAKE(dev_priv));
0094 return PCH_CNP;
0095 case INTEL_PCH_CMP_DEVICE_ID_TYPE:
0096 case INTEL_PCH_CMP2_DEVICE_ID_TYPE:
0097 drm_dbg_kms(&dev_priv->drm, "Found Comet Lake PCH (CMP)\n");
0098 drm_WARN_ON(&dev_priv->drm,
0099 !IS_COFFEELAKE(dev_priv) &&
0100 !IS_COMETLAKE(dev_priv) &&
0101 !IS_ROCKETLAKE(dev_priv));
0102
0103 return PCH_CNP;
0104 case INTEL_PCH_CMP_V_DEVICE_ID_TYPE:
0105 drm_dbg_kms(&dev_priv->drm, "Found Comet Lake V PCH (CMP-V)\n");
0106 drm_WARN_ON(&dev_priv->drm,
0107 !IS_COFFEELAKE(dev_priv) &&
0108 !IS_COMETLAKE(dev_priv));
0109
0110 return PCH_SPT;
0111 case INTEL_PCH_ICP_DEVICE_ID_TYPE:
0112 case INTEL_PCH_ICP2_DEVICE_ID_TYPE:
0113 drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n");
0114 drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv));
0115 return PCH_ICP;
0116 case INTEL_PCH_MCC_DEVICE_ID_TYPE:
0117 drm_dbg_kms(&dev_priv->drm, "Found Mule Creek Canyon PCH\n");
0118 drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv));
0119
0120 return PCH_TGP;
0121 case INTEL_PCH_TGP_DEVICE_ID_TYPE:
0122 case INTEL_PCH_TGP2_DEVICE_ID_TYPE:
0123 drm_dbg_kms(&dev_priv->drm, "Found Tiger Lake LP PCH\n");
0124 drm_WARN_ON(&dev_priv->drm, !IS_TIGERLAKE(dev_priv) &&
0125 !IS_ROCKETLAKE(dev_priv) &&
0126 !IS_GEN9_BC(dev_priv));
0127 return PCH_TGP;
0128 case INTEL_PCH_JSP_DEVICE_ID_TYPE:
0129 drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n");
0130 drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv));
0131
0132 return PCH_ICP;
0133 case INTEL_PCH_ADP_DEVICE_ID_TYPE:
0134 case INTEL_PCH_ADP2_DEVICE_ID_TYPE:
0135 case INTEL_PCH_ADP3_DEVICE_ID_TYPE:
0136 case INTEL_PCH_ADP4_DEVICE_ID_TYPE:
0137 drm_dbg_kms(&dev_priv->drm, "Found Alder Lake PCH\n");
0138 drm_WARN_ON(&dev_priv->drm, !IS_ALDERLAKE_S(dev_priv) &&
0139 !IS_ALDERLAKE_P(dev_priv));
0140 return PCH_ADP;
0141 default:
0142 return PCH_NONE;
0143 }
0144 }
0145
0146 static bool intel_is_virt_pch(unsigned short id,
0147 unsigned short svendor, unsigned short sdevice)
0148 {
0149 return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
0150 id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
0151 (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
0152 svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
0153 sdevice == PCI_SUBDEVICE_ID_QEMU));
0154 }
0155
0156 static void
0157 intel_virt_detect_pch(const struct drm_i915_private *dev_priv,
0158 unsigned short *pch_id, enum intel_pch *pch_type)
0159 {
0160 unsigned short id = 0;
0161
0162
0163
0164
0165
0166
0167
0168
0169 if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv))
0170 id = INTEL_PCH_ADP_DEVICE_ID_TYPE;
0171 else if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv))
0172 id = INTEL_PCH_TGP_DEVICE_ID_TYPE;
0173 else if (IS_JSL_EHL(dev_priv))
0174 id = INTEL_PCH_MCC_DEVICE_ID_TYPE;
0175 else if (IS_ICELAKE(dev_priv))
0176 id = INTEL_PCH_ICP_DEVICE_ID_TYPE;
0177 else if (IS_COFFEELAKE(dev_priv) ||
0178 IS_COMETLAKE(dev_priv))
0179 id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
0180 else if (IS_KABYLAKE(dev_priv) || IS_SKYLAKE(dev_priv))
0181 id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
0182 else if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
0183 id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
0184 else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
0185 id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
0186 else if (GRAPHICS_VER(dev_priv) == 6 || IS_IVYBRIDGE(dev_priv))
0187 id = INTEL_PCH_CPT_DEVICE_ID_TYPE;
0188 else if (GRAPHICS_VER(dev_priv) == 5)
0189 id = INTEL_PCH_IBX_DEVICE_ID_TYPE;
0190
0191 if (id)
0192 drm_dbg_kms(&dev_priv->drm, "Assuming PCH ID %04x\n", id);
0193 else
0194 drm_dbg_kms(&dev_priv->drm, "Assuming no PCH\n");
0195
0196 *pch_type = intel_pch_type(dev_priv, id);
0197
0198
0199 if (drm_WARN_ON(&dev_priv->drm,
0200 id && *pch_type == PCH_NONE))
0201 id = 0;
0202
0203 *pch_id = id;
0204 }
0205
0206 void intel_detect_pch(struct drm_i915_private *dev_priv)
0207 {
0208 struct pci_dev *pch = NULL;
0209 unsigned short id;
0210 enum intel_pch pch_type;
0211
0212
0213 if (IS_DG1(dev_priv)) {
0214 dev_priv->pch_type = PCH_DG1;
0215 return;
0216 } else if (IS_DG2(dev_priv)) {
0217 dev_priv->pch_type = PCH_DG2;
0218 return;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
0233 if (pch->vendor != PCI_VENDOR_ID_INTEL)
0234 continue;
0235
0236 id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
0237
0238 pch_type = intel_pch_type(dev_priv, id);
0239 if (pch_type != PCH_NONE) {
0240 dev_priv->pch_type = pch_type;
0241 dev_priv->pch_id = id;
0242 break;
0243 } else if (intel_is_virt_pch(id, pch->subsystem_vendor,
0244 pch->subsystem_device)) {
0245 intel_virt_detect_pch(dev_priv, &id, &pch_type);
0246 dev_priv->pch_type = pch_type;
0247 dev_priv->pch_id = id;
0248 break;
0249 }
0250 }
0251
0252
0253
0254
0255
0256 if (pch && !HAS_DISPLAY(dev_priv)) {
0257 drm_dbg_kms(&dev_priv->drm,
0258 "Display disabled, reverting to NOP PCH\n");
0259 dev_priv->pch_type = PCH_NOP;
0260 dev_priv->pch_id = 0;
0261 } else if (!pch) {
0262 if (i915_run_as_guest() && HAS_DISPLAY(dev_priv)) {
0263 intel_virt_detect_pch(dev_priv, &id, &pch_type);
0264 dev_priv->pch_type = pch_type;
0265 dev_priv->pch_id = id;
0266 } else {
0267 drm_dbg_kms(&dev_priv->drm, "No PCH found.\n");
0268 }
0269 }
0270
0271 pci_dev_put(pch);
0272 }