16ca37b86SRodrigo Vivi // SPDX-License-Identifier: MIT 26ca37b86SRodrigo Vivi /* 36ca37b86SRodrigo Vivi * Copyright 2025 Intel Corporation. 46ca37b86SRodrigo Vivi */ 56ca37b86SRodrigo Vivi 66a5cfab0SJani Nikula #include <drm/drm_print.h> 76a5cfab0SJani Nikula 86ca37b86SRodrigo Vivi #include "i915_utils.h" 96a5cfab0SJani Nikula #include "intel_display_core.h" 106ca37b86SRodrigo Vivi #include "intel_pch.h" 116ca37b86SRodrigo Vivi 126ca37b86SRodrigo Vivi #define INTEL_PCH_DEVICE_ID_MASK 0xff80 136ca37b86SRodrigo Vivi #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 146ca37b86SRodrigo Vivi #define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 156ca37b86SRodrigo Vivi #define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 166ca37b86SRodrigo Vivi #define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 176ca37b86SRodrigo Vivi #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 186ca37b86SRodrigo Vivi #define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80 196ca37b86SRodrigo Vivi #define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80 206ca37b86SRodrigo Vivi #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 216ca37b86SRodrigo Vivi #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 226ca37b86SRodrigo Vivi #define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280 236ca37b86SRodrigo Vivi #define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 246ca37b86SRodrigo Vivi #define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 256ca37b86SRodrigo Vivi #define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280 266ca37b86SRodrigo Vivi #define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 276ca37b86SRodrigo Vivi #define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 286ca37b86SRodrigo Vivi #define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 296ca37b86SRodrigo Vivi #define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880 306ca37b86SRodrigo Vivi #define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 316ca37b86SRodrigo Vivi #define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080 326ca37b86SRodrigo Vivi #define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380 336ca37b86SRodrigo Vivi #define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 346ca37b86SRodrigo Vivi #define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 356ca37b86SRodrigo Vivi #define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 366ca37b86SRodrigo Vivi #define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00 376ca37b86SRodrigo Vivi #define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480 386ca37b86SRodrigo Vivi #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 396ca37b86SRodrigo Vivi #define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 406ca37b86SRodrigo Vivi #define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ 416ca37b86SRodrigo Vivi 42246b259fSJani Nikula /* 43246b259fSJani Nikula * Check for platforms where the south display is on the same PCI device or SoC 44246b259fSJani Nikula * die as the north display. The PCH (if it even exists) is not involved in 45246b259fSJani Nikula * display. Return a fake PCH type for south display handling on these 46246b259fSJani Nikula * platforms, without actually detecting the PCH, and PCH_NONE otherwise. 47246b259fSJani Nikula */ 48246b259fSJani Nikula static enum intel_pch intel_pch_fake_for_south_display(struct intel_display *display) 49246b259fSJani Nikula { 50246b259fSJani Nikula enum intel_pch pch_type = PCH_NONE; 51246b259fSJani Nikula 52246b259fSJani Nikula if (DISPLAY_VER(display) >= 20) 53246b259fSJani Nikula pch_type = PCH_LNL; 54246b259fSJani Nikula else if (display->platform.battlemage || display->platform.meteorlake) 55246b259fSJani Nikula pch_type = PCH_MTL; 56246b259fSJani Nikula else if (display->platform.dg2) 57246b259fSJani Nikula pch_type = PCH_DG2; 58246b259fSJani Nikula else if (display->platform.dg1) 59246b259fSJani Nikula pch_type = PCH_DG1; 60246b259fSJani Nikula 61246b259fSJani Nikula return pch_type; 62246b259fSJani Nikula } 63246b259fSJani Nikula 646ca37b86SRodrigo Vivi /* Map PCH device id to PCH type, or PCH_NONE if unknown. */ 656ca37b86SRodrigo Vivi static enum intel_pch 66ad283764SRodrigo Vivi intel_pch_type(const struct intel_display *display, unsigned short id) 676ca37b86SRodrigo Vivi { 686ca37b86SRodrigo Vivi switch (id) { 696ca37b86SRodrigo Vivi case INTEL_PCH_IBX_DEVICE_ID_TYPE: 70ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Ibex Peak PCH\n"); 71ad283764SRodrigo Vivi drm_WARN_ON(display->drm, DISPLAY_VER(display) != 5); 726ca37b86SRodrigo Vivi return PCH_IBX; 736ca37b86SRodrigo Vivi case INTEL_PCH_CPT_DEVICE_ID_TYPE: 74ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found CougarPoint PCH\n"); 75ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 76ad283764SRodrigo Vivi DISPLAY_VER(display) != 6 && 77ad283764SRodrigo Vivi !display->platform.ivybridge); 786ca37b86SRodrigo Vivi return PCH_CPT; 796ca37b86SRodrigo Vivi case INTEL_PCH_PPT_DEVICE_ID_TYPE: 80ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found PantherPoint PCH\n"); 81ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 82ad283764SRodrigo Vivi DISPLAY_VER(display) != 6 && 83ad283764SRodrigo Vivi !display->platform.ivybridge); 846ca37b86SRodrigo Vivi /* PPT is CPT compatible */ 856ca37b86SRodrigo Vivi return PCH_CPT; 866ca37b86SRodrigo Vivi case INTEL_PCH_LPT_DEVICE_ID_TYPE: 87ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found LynxPoint PCH\n"); 88ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 89ad283764SRodrigo Vivi !display->platform.haswell && 90ad283764SRodrigo Vivi !display->platform.broadwell); 91ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 92ad283764SRodrigo Vivi display->platform.haswell_ult || 93ad283764SRodrigo Vivi display->platform.broadwell_ult); 946ca37b86SRodrigo Vivi return PCH_LPT_H; 956ca37b86SRodrigo Vivi case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE: 96ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found LynxPoint LP PCH\n"); 97ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 98ad283764SRodrigo Vivi !display->platform.haswell && 99ad283764SRodrigo Vivi !display->platform.broadwell); 100ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 101ad283764SRodrigo Vivi !display->platform.haswell_ult && 102ad283764SRodrigo Vivi !display->platform.broadwell_ult); 1036ca37b86SRodrigo Vivi return PCH_LPT_LP; 1046ca37b86SRodrigo Vivi case INTEL_PCH_WPT_DEVICE_ID_TYPE: 105ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found WildcatPoint PCH\n"); 106ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 107ad283764SRodrigo Vivi !display->platform.haswell && 108ad283764SRodrigo Vivi !display->platform.broadwell); 109ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 110ad283764SRodrigo Vivi display->platform.haswell_ult || 111ad283764SRodrigo Vivi display->platform.broadwell_ult); 1126ca37b86SRodrigo Vivi /* WPT is LPT compatible */ 1136ca37b86SRodrigo Vivi return PCH_LPT_H; 1146ca37b86SRodrigo Vivi case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE: 115ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found WildcatPoint LP PCH\n"); 116ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 117ad283764SRodrigo Vivi !display->platform.haswell && 118ad283764SRodrigo Vivi !display->platform.broadwell); 119ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 120ad283764SRodrigo Vivi !display->platform.haswell_ult && 121ad283764SRodrigo Vivi !display->platform.broadwell_ult); 1226ca37b86SRodrigo Vivi /* WPT is LPT compatible */ 1236ca37b86SRodrigo Vivi return PCH_LPT_LP; 1246ca37b86SRodrigo Vivi case INTEL_PCH_SPT_DEVICE_ID_TYPE: 125ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found SunrisePoint PCH\n"); 126ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 127ad283764SRodrigo Vivi !display->platform.skylake && 128*090a47b4SJiajia Liu !display->platform.kabylake && 129*090a47b4SJiajia Liu !display->platform.coffeelake); 1306ca37b86SRodrigo Vivi return PCH_SPT; 1316ca37b86SRodrigo Vivi case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE: 132ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found SunrisePoint LP PCH\n"); 133ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 134ad283764SRodrigo Vivi !display->platform.skylake && 135ad283764SRodrigo Vivi !display->platform.kabylake && 136ad283764SRodrigo Vivi !display->platform.coffeelake && 137ad283764SRodrigo Vivi !display->platform.cometlake); 1386ca37b86SRodrigo Vivi return PCH_SPT; 1396ca37b86SRodrigo Vivi case INTEL_PCH_KBP_DEVICE_ID_TYPE: 140ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Kaby Lake PCH (KBP)\n"); 141ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 142ad283764SRodrigo Vivi !display->platform.skylake && 143ad283764SRodrigo Vivi !display->platform.kabylake && 144ad283764SRodrigo Vivi !display->platform.coffeelake && 145ad283764SRodrigo Vivi !display->platform.cometlake); 1466ca37b86SRodrigo Vivi /* KBP is SPT compatible */ 1476ca37b86SRodrigo Vivi return PCH_SPT; 1486ca37b86SRodrigo Vivi case INTEL_PCH_CNP_DEVICE_ID_TYPE: 149ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Cannon Lake PCH (CNP)\n"); 150ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 151ad283764SRodrigo Vivi !display->platform.coffeelake && 152ad283764SRodrigo Vivi !display->platform.cometlake); 1536ca37b86SRodrigo Vivi return PCH_CNP; 1546ca37b86SRodrigo Vivi case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE: 155ad283764SRodrigo Vivi drm_dbg_kms(display->drm, 1566ca37b86SRodrigo Vivi "Found Cannon Lake LP PCH (CNP-LP)\n"); 157ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 158ad283764SRodrigo Vivi !display->platform.coffeelake && 159ad283764SRodrigo Vivi !display->platform.cometlake); 1606ca37b86SRodrigo Vivi return PCH_CNP; 1616ca37b86SRodrigo Vivi case INTEL_PCH_CMP_DEVICE_ID_TYPE: 1626ca37b86SRodrigo Vivi case INTEL_PCH_CMP2_DEVICE_ID_TYPE: 163ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Comet Lake PCH (CMP)\n"); 164ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 165ad283764SRodrigo Vivi !display->platform.coffeelake && 166ad283764SRodrigo Vivi !display->platform.cometlake && 167ad283764SRodrigo Vivi !display->platform.rocketlake); 1686ca37b86SRodrigo Vivi /* CMP is CNP compatible */ 1696ca37b86SRodrigo Vivi return PCH_CNP; 1706ca37b86SRodrigo Vivi case INTEL_PCH_CMP_V_DEVICE_ID_TYPE: 171ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Comet Lake V PCH (CMP-V)\n"); 172ad283764SRodrigo Vivi drm_WARN_ON(display->drm, 173ad283764SRodrigo Vivi !display->platform.coffeelake && 174ad283764SRodrigo Vivi !display->platform.cometlake); 1756ca37b86SRodrigo Vivi /* CMP-V is based on KBP, which is SPT compatible */ 1766ca37b86SRodrigo Vivi return PCH_SPT; 1776ca37b86SRodrigo Vivi case INTEL_PCH_ICP_DEVICE_ID_TYPE: 1786ca37b86SRodrigo Vivi case INTEL_PCH_ICP2_DEVICE_ID_TYPE: 179ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Ice Lake PCH\n"); 180ad283764SRodrigo Vivi drm_WARN_ON(display->drm, !display->platform.icelake); 1816ca37b86SRodrigo Vivi return PCH_ICP; 1826ca37b86SRodrigo Vivi case INTEL_PCH_MCC_DEVICE_ID_TYPE: 183ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Mule Creek Canyon PCH\n"); 184ad283764SRodrigo Vivi drm_WARN_ON(display->drm, !(display->platform.jasperlake || 185ad283764SRodrigo Vivi display->platform.elkhartlake)); 1866ca37b86SRodrigo Vivi /* MCC is TGP compatible */ 1876ca37b86SRodrigo Vivi return PCH_TGP; 1886ca37b86SRodrigo Vivi case INTEL_PCH_TGP_DEVICE_ID_TYPE: 1896ca37b86SRodrigo Vivi case INTEL_PCH_TGP2_DEVICE_ID_TYPE: 190ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Tiger Lake LP PCH\n"); 191ad283764SRodrigo Vivi drm_WARN_ON(display->drm, !display->platform.tigerlake && 192ad283764SRodrigo Vivi !display->platform.rocketlake && 193ad283764SRodrigo Vivi !display->platform.skylake && 194ad283764SRodrigo Vivi !display->platform.kabylake && 195ad283764SRodrigo Vivi !display->platform.coffeelake && 196ad283764SRodrigo Vivi !display->platform.cometlake); 1976ca37b86SRodrigo Vivi return PCH_TGP; 1986ca37b86SRodrigo Vivi case INTEL_PCH_JSP_DEVICE_ID_TYPE: 199ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Jasper Lake PCH\n"); 200ad283764SRodrigo Vivi drm_WARN_ON(display->drm, !(display->platform.jasperlake || 201ad283764SRodrigo Vivi display->platform.elkhartlake)); 2026ca37b86SRodrigo Vivi /* JSP is ICP compatible */ 2036ca37b86SRodrigo Vivi return PCH_ICP; 2046ca37b86SRodrigo Vivi case INTEL_PCH_ADP_DEVICE_ID_TYPE: 2056ca37b86SRodrigo Vivi case INTEL_PCH_ADP2_DEVICE_ID_TYPE: 2066ca37b86SRodrigo Vivi case INTEL_PCH_ADP3_DEVICE_ID_TYPE: 2076ca37b86SRodrigo Vivi case INTEL_PCH_ADP4_DEVICE_ID_TYPE: 208ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Found Alder Lake PCH\n"); 209ad283764SRodrigo Vivi drm_WARN_ON(display->drm, !display->platform.alderlake_s && 210ad283764SRodrigo Vivi !display->platform.alderlake_p); 2116ca37b86SRodrigo Vivi return PCH_ADP; 2126ca37b86SRodrigo Vivi default: 2136ca37b86SRodrigo Vivi return PCH_NONE; 2146ca37b86SRodrigo Vivi } 2156ca37b86SRodrigo Vivi } 2166ca37b86SRodrigo Vivi 2176ca37b86SRodrigo Vivi static bool intel_is_virt_pch(unsigned short id, 2186ca37b86SRodrigo Vivi unsigned short svendor, unsigned short sdevice) 2196ca37b86SRodrigo Vivi { 2206ca37b86SRodrigo Vivi return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE || 2216ca37b86SRodrigo Vivi id == INTEL_PCH_P3X_DEVICE_ID_TYPE || 2226ca37b86SRodrigo Vivi (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE && 2236ca37b86SRodrigo Vivi svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET && 2246ca37b86SRodrigo Vivi sdevice == PCI_SUBDEVICE_ID_QEMU)); 2256ca37b86SRodrigo Vivi } 2266ca37b86SRodrigo Vivi 2276ca37b86SRodrigo Vivi static void 228ad283764SRodrigo Vivi intel_virt_detect_pch(const struct intel_display *display, 2296ca37b86SRodrigo Vivi unsigned short *pch_id, enum intel_pch *pch_type) 2306ca37b86SRodrigo Vivi { 2316ca37b86SRodrigo Vivi unsigned short id = 0; 2326ca37b86SRodrigo Vivi 2336ca37b86SRodrigo Vivi /* 2346ca37b86SRodrigo Vivi * In a virtualized passthrough environment we can be in a 2356ca37b86SRodrigo Vivi * setup where the ISA bridge is not able to be passed through. 2366ca37b86SRodrigo Vivi * In this case, a south bridge can be emulated and we have to 2376ca37b86SRodrigo Vivi * make an educated guess as to which PCH is really there. 2386ca37b86SRodrigo Vivi */ 2396ca37b86SRodrigo Vivi 240ad283764SRodrigo Vivi if (display->platform.alderlake_s || display->platform.alderlake_p) 2416ca37b86SRodrigo Vivi id = INTEL_PCH_ADP_DEVICE_ID_TYPE; 242ad283764SRodrigo Vivi else if (display->platform.tigerlake || display->platform.rocketlake) 2436ca37b86SRodrigo Vivi id = INTEL_PCH_TGP_DEVICE_ID_TYPE; 244ad283764SRodrigo Vivi else if (display->platform.jasperlake || display->platform.elkhartlake) 2456ca37b86SRodrigo Vivi id = INTEL_PCH_MCC_DEVICE_ID_TYPE; 246ad283764SRodrigo Vivi else if (display->platform.icelake) 2476ca37b86SRodrigo Vivi id = INTEL_PCH_ICP_DEVICE_ID_TYPE; 248ad283764SRodrigo Vivi else if (display->platform.coffeelake || 249ad283764SRodrigo Vivi display->platform.cometlake) 2506ca37b86SRodrigo Vivi id = INTEL_PCH_CNP_DEVICE_ID_TYPE; 251ad283764SRodrigo Vivi else if (display->platform.kabylake || display->platform.skylake) 2526ca37b86SRodrigo Vivi id = INTEL_PCH_SPT_DEVICE_ID_TYPE; 253ad283764SRodrigo Vivi else if (display->platform.haswell_ult || 254ad283764SRodrigo Vivi display->platform.broadwell_ult) 2556ca37b86SRodrigo Vivi id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; 256ad283764SRodrigo Vivi else if (display->platform.haswell || display->platform.broadwell) 2576ca37b86SRodrigo Vivi id = INTEL_PCH_LPT_DEVICE_ID_TYPE; 258ad283764SRodrigo Vivi else if (DISPLAY_VER(display) == 6 || display->platform.ivybridge) 2596ca37b86SRodrigo Vivi id = INTEL_PCH_CPT_DEVICE_ID_TYPE; 260ad283764SRodrigo Vivi else if (DISPLAY_VER(display) == 5) 2616ca37b86SRodrigo Vivi id = INTEL_PCH_IBX_DEVICE_ID_TYPE; 2626ca37b86SRodrigo Vivi 2636ca37b86SRodrigo Vivi if (id) 264ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Assuming PCH ID %04x\n", id); 2656ca37b86SRodrigo Vivi else 266ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "Assuming no PCH\n"); 2676ca37b86SRodrigo Vivi 268ad283764SRodrigo Vivi *pch_type = intel_pch_type(display, id); 2696ca37b86SRodrigo Vivi 2706ca37b86SRodrigo Vivi /* Sanity check virtual PCH id */ 271ad283764SRodrigo Vivi if (drm_WARN_ON(display->drm, 2726ca37b86SRodrigo Vivi id && *pch_type == PCH_NONE)) 2736ca37b86SRodrigo Vivi id = 0; 2746ca37b86SRodrigo Vivi 2756ca37b86SRodrigo Vivi *pch_id = id; 2766ca37b86SRodrigo Vivi } 2776ca37b86SRodrigo Vivi 2783090ea03SJani Nikula void intel_pch_detect(struct intel_display *display) 2796ca37b86SRodrigo Vivi { 2806ca37b86SRodrigo Vivi struct pci_dev *pch = NULL; 2816ca37b86SRodrigo Vivi unsigned short id; 2826ca37b86SRodrigo Vivi enum intel_pch pch_type; 2836ca37b86SRodrigo Vivi 284246b259fSJani Nikula pch_type = intel_pch_fake_for_south_display(display); 285246b259fSJani Nikula if (pch_type != PCH_NONE) { 286246b259fSJani Nikula display->pch_type = pch_type; 287246b259fSJani Nikula drm_dbg_kms(display->drm, 288246b259fSJani Nikula "PCH not involved in display, using fake PCH type %d for south display\n", 289246b259fSJani Nikula pch_type); 2906ca37b86SRodrigo Vivi return; 2916ca37b86SRodrigo Vivi } 2926ca37b86SRodrigo Vivi 2936ca37b86SRodrigo Vivi /* 2946ca37b86SRodrigo Vivi * The reason to probe ISA bridge instead of Dev31:Fun0 is to 2956ca37b86SRodrigo Vivi * make graphics device passthrough work easy for VMM, that only 2966ca37b86SRodrigo Vivi * need to expose ISA bridge to let driver know the real hardware 2976ca37b86SRodrigo Vivi * underneath. This is a requirement from virtualization team. 2986ca37b86SRodrigo Vivi * 2996ca37b86SRodrigo Vivi * In some virtualized environments (e.g. XEN), there is irrelevant 3006ca37b86SRodrigo Vivi * ISA bridge in the system. To work reliably, we should scan through 3016ca37b86SRodrigo Vivi * all the ISA bridge devices and check for the first match, instead 3026ca37b86SRodrigo Vivi * of only checking the first one. 3036ca37b86SRodrigo Vivi */ 3046ca37b86SRodrigo Vivi while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { 3056ca37b86SRodrigo Vivi if (pch->vendor != PCI_VENDOR_ID_INTEL) 3066ca37b86SRodrigo Vivi continue; 3076ca37b86SRodrigo Vivi 3086ca37b86SRodrigo Vivi id = pch->device & INTEL_PCH_DEVICE_ID_MASK; 3096ca37b86SRodrigo Vivi 310ad283764SRodrigo Vivi pch_type = intel_pch_type(display, id); 3116ca37b86SRodrigo Vivi if (pch_type != PCH_NONE) { 312ad283764SRodrigo Vivi display->pch_type = pch_type; 3136ca37b86SRodrigo Vivi break; 3146ca37b86SRodrigo Vivi } else if (intel_is_virt_pch(id, pch->subsystem_vendor, 3156ca37b86SRodrigo Vivi pch->subsystem_device)) { 316ad283764SRodrigo Vivi intel_virt_detect_pch(display, &id, &pch_type); 317ad283764SRodrigo Vivi display->pch_type = pch_type; 3186ca37b86SRodrigo Vivi break; 3196ca37b86SRodrigo Vivi } 3206ca37b86SRodrigo Vivi } 3216ca37b86SRodrigo Vivi 3226ca37b86SRodrigo Vivi /* 3236ca37b86SRodrigo Vivi * Use PCH_NOP (PCH but no South Display) for PCH platforms without 3246ca37b86SRodrigo Vivi * display. 3256ca37b86SRodrigo Vivi */ 326ad283764SRodrigo Vivi if (pch && !HAS_DISPLAY(display)) { 327ad283764SRodrigo Vivi drm_dbg_kms(display->drm, 3286ca37b86SRodrigo Vivi "Display disabled, reverting to NOP PCH\n"); 329ad283764SRodrigo Vivi display->pch_type = PCH_NOP; 3306ca37b86SRodrigo Vivi } else if (!pch) { 331ad283764SRodrigo Vivi if (i915_run_as_guest() && HAS_DISPLAY(display)) { 332ad283764SRodrigo Vivi intel_virt_detect_pch(display, &id, &pch_type); 333ad283764SRodrigo Vivi display->pch_type = pch_type; 3346ca37b86SRodrigo Vivi } else { 335ad283764SRodrigo Vivi drm_dbg_kms(display->drm, "No PCH found.\n"); 3366ca37b86SRodrigo Vivi } 3376ca37b86SRodrigo Vivi } 3386ca37b86SRodrigo Vivi 3396ca37b86SRodrigo Vivi pci_dev_put(pch); 3406ca37b86SRodrigo Vivi } 341