162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2019 Intel Corporation.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include "i915_drv.h"
762306a36Sopenharmony_ci#include "i915_utils.h"
862306a36Sopenharmony_ci#include "intel_pch.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/* Map PCH device id to PCH type, or PCH_NONE if unknown. */
1162306a36Sopenharmony_cistatic enum intel_pch
1262306a36Sopenharmony_ciintel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
1362306a36Sopenharmony_ci{
1462306a36Sopenharmony_ci	switch (id) {
1562306a36Sopenharmony_ci	case INTEL_PCH_IBX_DEVICE_ID_TYPE:
1662306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Ibex Peak PCH\n");
1762306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, GRAPHICS_VER(dev_priv) != 5);
1862306a36Sopenharmony_ci		return PCH_IBX;
1962306a36Sopenharmony_ci	case INTEL_PCH_CPT_DEVICE_ID_TYPE:
2062306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found CougarPoint PCH\n");
2162306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
2262306a36Sopenharmony_ci			    GRAPHICS_VER(dev_priv) != 6 && !IS_IVYBRIDGE(dev_priv));
2362306a36Sopenharmony_ci		return PCH_CPT;
2462306a36Sopenharmony_ci	case INTEL_PCH_PPT_DEVICE_ID_TYPE:
2562306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found PantherPoint PCH\n");
2662306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
2762306a36Sopenharmony_ci			    GRAPHICS_VER(dev_priv) != 6 && !IS_IVYBRIDGE(dev_priv));
2862306a36Sopenharmony_ci		/* PPT is CPT compatible */
2962306a36Sopenharmony_ci		return PCH_CPT;
3062306a36Sopenharmony_ci	case INTEL_PCH_LPT_DEVICE_ID_TYPE:
3162306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found LynxPoint PCH\n");
3262306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
3362306a36Sopenharmony_ci			    !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
3462306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
3562306a36Sopenharmony_ci			    IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv));
3662306a36Sopenharmony_ci		return PCH_LPT;
3762306a36Sopenharmony_ci	case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE:
3862306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found LynxPoint LP PCH\n");
3962306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
4062306a36Sopenharmony_ci			    !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
4162306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
4262306a36Sopenharmony_ci			    !IS_HASWELL_ULT(dev_priv) && !IS_BROADWELL_ULT(dev_priv));
4362306a36Sopenharmony_ci		return PCH_LPT;
4462306a36Sopenharmony_ci	case INTEL_PCH_WPT_DEVICE_ID_TYPE:
4562306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint PCH\n");
4662306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
4762306a36Sopenharmony_ci			    !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
4862306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
4962306a36Sopenharmony_ci			    IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv));
5062306a36Sopenharmony_ci		/* WPT is LPT compatible */
5162306a36Sopenharmony_ci		return PCH_LPT;
5262306a36Sopenharmony_ci	case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE:
5362306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint LP PCH\n");
5462306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
5562306a36Sopenharmony_ci			    !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
5662306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
5762306a36Sopenharmony_ci			    !IS_HASWELL_ULT(dev_priv) && !IS_BROADWELL_ULT(dev_priv));
5862306a36Sopenharmony_ci		/* WPT is LPT compatible */
5962306a36Sopenharmony_ci		return PCH_LPT;
6062306a36Sopenharmony_ci	case INTEL_PCH_SPT_DEVICE_ID_TYPE:
6162306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint PCH\n");
6262306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
6362306a36Sopenharmony_ci			    !IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv));
6462306a36Sopenharmony_ci		return PCH_SPT;
6562306a36Sopenharmony_ci	case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE:
6662306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint LP PCH\n");
6762306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
6862306a36Sopenharmony_ci			    !IS_SKYLAKE(dev_priv) &&
6962306a36Sopenharmony_ci			    !IS_KABYLAKE(dev_priv) &&
7062306a36Sopenharmony_ci			    !IS_COFFEELAKE(dev_priv) &&
7162306a36Sopenharmony_ci			    !IS_COMETLAKE(dev_priv));
7262306a36Sopenharmony_ci		return PCH_SPT;
7362306a36Sopenharmony_ci	case INTEL_PCH_KBP_DEVICE_ID_TYPE:
7462306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Kaby Lake PCH (KBP)\n");
7562306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
7662306a36Sopenharmony_ci			    !IS_SKYLAKE(dev_priv) &&
7762306a36Sopenharmony_ci			    !IS_KABYLAKE(dev_priv) &&
7862306a36Sopenharmony_ci			    !IS_COFFEELAKE(dev_priv) &&
7962306a36Sopenharmony_ci			    !IS_COMETLAKE(dev_priv));
8062306a36Sopenharmony_ci		/* KBP is SPT compatible */
8162306a36Sopenharmony_ci		return PCH_SPT;
8262306a36Sopenharmony_ci	case INTEL_PCH_CNP_DEVICE_ID_TYPE:
8362306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Cannon Lake PCH (CNP)\n");
8462306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
8562306a36Sopenharmony_ci			    !IS_COFFEELAKE(dev_priv) &&
8662306a36Sopenharmony_ci			    !IS_COMETLAKE(dev_priv));
8762306a36Sopenharmony_ci		return PCH_CNP;
8862306a36Sopenharmony_ci	case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE:
8962306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm,
9062306a36Sopenharmony_ci			    "Found Cannon Lake LP PCH (CNP-LP)\n");
9162306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
9262306a36Sopenharmony_ci			    !IS_COFFEELAKE(dev_priv) &&
9362306a36Sopenharmony_ci			    !IS_COMETLAKE(dev_priv));
9462306a36Sopenharmony_ci		return PCH_CNP;
9562306a36Sopenharmony_ci	case INTEL_PCH_CMP_DEVICE_ID_TYPE:
9662306a36Sopenharmony_ci	case INTEL_PCH_CMP2_DEVICE_ID_TYPE:
9762306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Comet Lake PCH (CMP)\n");
9862306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
9962306a36Sopenharmony_ci			    !IS_COFFEELAKE(dev_priv) &&
10062306a36Sopenharmony_ci			    !IS_COMETLAKE(dev_priv) &&
10162306a36Sopenharmony_ci			    !IS_ROCKETLAKE(dev_priv));
10262306a36Sopenharmony_ci		/* CMP is CNP compatible */
10362306a36Sopenharmony_ci		return PCH_CNP;
10462306a36Sopenharmony_ci	case INTEL_PCH_CMP_V_DEVICE_ID_TYPE:
10562306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Comet Lake V PCH (CMP-V)\n");
10662306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm,
10762306a36Sopenharmony_ci			    !IS_COFFEELAKE(dev_priv) &&
10862306a36Sopenharmony_ci			    !IS_COMETLAKE(dev_priv));
10962306a36Sopenharmony_ci		/* CMP-V is based on KBP, which is SPT compatible */
11062306a36Sopenharmony_ci		return PCH_SPT;
11162306a36Sopenharmony_ci	case INTEL_PCH_ICP_DEVICE_ID_TYPE:
11262306a36Sopenharmony_ci	case INTEL_PCH_ICP2_DEVICE_ID_TYPE:
11362306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n");
11462306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv));
11562306a36Sopenharmony_ci		return PCH_ICP;
11662306a36Sopenharmony_ci	case INTEL_PCH_MCC_DEVICE_ID_TYPE:
11762306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Mule Creek Canyon PCH\n");
11862306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, !(IS_JASPERLAKE(dev_priv) ||
11962306a36Sopenharmony_ci					      IS_ELKHARTLAKE(dev_priv)));
12062306a36Sopenharmony_ci		/* MCC is TGP compatible */
12162306a36Sopenharmony_ci		return PCH_TGP;
12262306a36Sopenharmony_ci	case INTEL_PCH_TGP_DEVICE_ID_TYPE:
12362306a36Sopenharmony_ci	case INTEL_PCH_TGP2_DEVICE_ID_TYPE:
12462306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Tiger Lake LP PCH\n");
12562306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, !IS_TIGERLAKE(dev_priv) &&
12662306a36Sopenharmony_ci			    !IS_ROCKETLAKE(dev_priv) &&
12762306a36Sopenharmony_ci			    !IS_GEN9_BC(dev_priv));
12862306a36Sopenharmony_ci		return PCH_TGP;
12962306a36Sopenharmony_ci	case INTEL_PCH_JSP_DEVICE_ID_TYPE:
13062306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n");
13162306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, !(IS_JASPERLAKE(dev_priv) ||
13262306a36Sopenharmony_ci					      IS_ELKHARTLAKE(dev_priv)));
13362306a36Sopenharmony_ci		/* JSP is ICP compatible */
13462306a36Sopenharmony_ci		return PCH_ICP;
13562306a36Sopenharmony_ci	case INTEL_PCH_ADP_DEVICE_ID_TYPE:
13662306a36Sopenharmony_ci	case INTEL_PCH_ADP2_DEVICE_ID_TYPE:
13762306a36Sopenharmony_ci	case INTEL_PCH_ADP3_DEVICE_ID_TYPE:
13862306a36Sopenharmony_ci	case INTEL_PCH_ADP4_DEVICE_ID_TYPE:
13962306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Alder Lake PCH\n");
14062306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, !IS_ALDERLAKE_S(dev_priv) &&
14162306a36Sopenharmony_ci			    !IS_ALDERLAKE_P(dev_priv));
14262306a36Sopenharmony_ci		return PCH_ADP;
14362306a36Sopenharmony_ci	case INTEL_PCH_MTP_DEVICE_ID_TYPE:
14462306a36Sopenharmony_ci	case INTEL_PCH_MTP2_DEVICE_ID_TYPE:
14562306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Found Meteor Lake PCH\n");
14662306a36Sopenharmony_ci		drm_WARN_ON(&dev_priv->drm, !IS_METEORLAKE(dev_priv));
14762306a36Sopenharmony_ci		return PCH_MTP;
14862306a36Sopenharmony_ci	default:
14962306a36Sopenharmony_ci		return PCH_NONE;
15062306a36Sopenharmony_ci	}
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_cistatic bool intel_is_virt_pch(unsigned short id,
15462306a36Sopenharmony_ci			      unsigned short svendor, unsigned short sdevice)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
15762306a36Sopenharmony_ci		id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
15862306a36Sopenharmony_ci		(id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
15962306a36Sopenharmony_ci		 svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
16062306a36Sopenharmony_ci		 sdevice == PCI_SUBDEVICE_ID_QEMU));
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic void
16462306a36Sopenharmony_ciintel_virt_detect_pch(const struct drm_i915_private *dev_priv,
16562306a36Sopenharmony_ci		      unsigned short *pch_id, enum intel_pch *pch_type)
16662306a36Sopenharmony_ci{
16762306a36Sopenharmony_ci	unsigned short id = 0;
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	/*
17062306a36Sopenharmony_ci	 * In a virtualized passthrough environment we can be in a
17162306a36Sopenharmony_ci	 * setup where the ISA bridge is not able to be passed through.
17262306a36Sopenharmony_ci	 * In this case, a south bridge can be emulated and we have to
17362306a36Sopenharmony_ci	 * make an educated guess as to which PCH is really there.
17462306a36Sopenharmony_ci	 */
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	if (IS_METEORLAKE(dev_priv))
17762306a36Sopenharmony_ci		id = INTEL_PCH_MTP_DEVICE_ID_TYPE;
17862306a36Sopenharmony_ci	else if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv))
17962306a36Sopenharmony_ci		id = INTEL_PCH_ADP_DEVICE_ID_TYPE;
18062306a36Sopenharmony_ci	else if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv))
18162306a36Sopenharmony_ci		id = INTEL_PCH_TGP_DEVICE_ID_TYPE;
18262306a36Sopenharmony_ci	else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv))
18362306a36Sopenharmony_ci		id = INTEL_PCH_MCC_DEVICE_ID_TYPE;
18462306a36Sopenharmony_ci	else if (IS_ICELAKE(dev_priv))
18562306a36Sopenharmony_ci		id = INTEL_PCH_ICP_DEVICE_ID_TYPE;
18662306a36Sopenharmony_ci	else if (IS_COFFEELAKE(dev_priv) ||
18762306a36Sopenharmony_ci		 IS_COMETLAKE(dev_priv))
18862306a36Sopenharmony_ci		id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
18962306a36Sopenharmony_ci	else if (IS_KABYLAKE(dev_priv) || IS_SKYLAKE(dev_priv))
19062306a36Sopenharmony_ci		id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
19162306a36Sopenharmony_ci	else if (IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv))
19262306a36Sopenharmony_ci		id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
19362306a36Sopenharmony_ci	else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
19462306a36Sopenharmony_ci		id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
19562306a36Sopenharmony_ci	else if (GRAPHICS_VER(dev_priv) == 6 || IS_IVYBRIDGE(dev_priv))
19662306a36Sopenharmony_ci		id = INTEL_PCH_CPT_DEVICE_ID_TYPE;
19762306a36Sopenharmony_ci	else if (GRAPHICS_VER(dev_priv) == 5)
19862306a36Sopenharmony_ci		id = INTEL_PCH_IBX_DEVICE_ID_TYPE;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	if (id)
20162306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Assuming PCH ID %04x\n", id);
20262306a36Sopenharmony_ci	else
20362306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm, "Assuming no PCH\n");
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci	*pch_type = intel_pch_type(dev_priv, id);
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	/* Sanity check virtual PCH id */
20862306a36Sopenharmony_ci	if (drm_WARN_ON(&dev_priv->drm,
20962306a36Sopenharmony_ci			id && *pch_type == PCH_NONE))
21062306a36Sopenharmony_ci		id = 0;
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	*pch_id = id;
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_civoid intel_detect_pch(struct drm_i915_private *dev_priv)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	struct pci_dev *pch = NULL;
21862306a36Sopenharmony_ci	unsigned short id;
21962306a36Sopenharmony_ci	enum intel_pch pch_type;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	/* DG1 has south engine display on the same PCI device */
22262306a36Sopenharmony_ci	if (IS_DG1(dev_priv)) {
22362306a36Sopenharmony_ci		dev_priv->pch_type = PCH_DG1;
22462306a36Sopenharmony_ci		return;
22562306a36Sopenharmony_ci	} else if (IS_DG2(dev_priv)) {
22662306a36Sopenharmony_ci		dev_priv->pch_type = PCH_DG2;
22762306a36Sopenharmony_ci		return;
22862306a36Sopenharmony_ci	}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	/*
23162306a36Sopenharmony_ci	 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
23262306a36Sopenharmony_ci	 * make graphics device passthrough work easy for VMM, that only
23362306a36Sopenharmony_ci	 * need to expose ISA bridge to let driver know the real hardware
23462306a36Sopenharmony_ci	 * underneath. This is a requirement from virtualization team.
23562306a36Sopenharmony_ci	 *
23662306a36Sopenharmony_ci	 * In some virtualized environments (e.g. XEN), there is irrelevant
23762306a36Sopenharmony_ci	 * ISA bridge in the system. To work reliably, we should scan trhough
23862306a36Sopenharmony_ci	 * all the ISA bridge devices and check for the first match, instead
23962306a36Sopenharmony_ci	 * of only checking the first one.
24062306a36Sopenharmony_ci	 */
24162306a36Sopenharmony_ci	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
24262306a36Sopenharmony_ci		if (pch->vendor != PCI_VENDOR_ID_INTEL)
24362306a36Sopenharmony_ci			continue;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci		id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci		pch_type = intel_pch_type(dev_priv, id);
24862306a36Sopenharmony_ci		if (pch_type != PCH_NONE) {
24962306a36Sopenharmony_ci			dev_priv->pch_type = pch_type;
25062306a36Sopenharmony_ci			dev_priv->pch_id = id;
25162306a36Sopenharmony_ci			break;
25262306a36Sopenharmony_ci		} else if (intel_is_virt_pch(id, pch->subsystem_vendor,
25362306a36Sopenharmony_ci					     pch->subsystem_device)) {
25462306a36Sopenharmony_ci			intel_virt_detect_pch(dev_priv, &id, &pch_type);
25562306a36Sopenharmony_ci			dev_priv->pch_type = pch_type;
25662306a36Sopenharmony_ci			dev_priv->pch_id = id;
25762306a36Sopenharmony_ci			break;
25862306a36Sopenharmony_ci		}
25962306a36Sopenharmony_ci	}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	/*
26262306a36Sopenharmony_ci	 * Use PCH_NOP (PCH but no South Display) for PCH platforms without
26362306a36Sopenharmony_ci	 * display.
26462306a36Sopenharmony_ci	 */
26562306a36Sopenharmony_ci	if (pch && !HAS_DISPLAY(dev_priv)) {
26662306a36Sopenharmony_ci		drm_dbg_kms(&dev_priv->drm,
26762306a36Sopenharmony_ci			    "Display disabled, reverting to NOP PCH\n");
26862306a36Sopenharmony_ci		dev_priv->pch_type = PCH_NOP;
26962306a36Sopenharmony_ci		dev_priv->pch_id = 0;
27062306a36Sopenharmony_ci	} else if (!pch) {
27162306a36Sopenharmony_ci		if (i915_run_as_guest() && HAS_DISPLAY(dev_priv)) {
27262306a36Sopenharmony_ci			intel_virt_detect_pch(dev_priv, &id, &pch_type);
27362306a36Sopenharmony_ci			dev_priv->pch_type = pch_type;
27462306a36Sopenharmony_ci			dev_priv->pch_id = id;
27562306a36Sopenharmony_ci		} else {
27662306a36Sopenharmony_ci			drm_dbg_kms(&dev_priv->drm, "No PCH found.\n");
27762306a36Sopenharmony_ci		}
27862306a36Sopenharmony_ci	}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	pci_dev_put(pch);
28162306a36Sopenharmony_ci}
282