Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2016 Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *	Author: Jayachandran C <jchandra@broadcom.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2016 Semihalf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * 	Author: Tomasz Nowicki <tn@semihalf.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #define pr_fmt(fmt) "ACPI: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/pci-acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/pci-ecam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) /* Structure to hold entries from the MCFG table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) struct mcfg_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	struct list_head	list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	phys_addr_t		addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	u16			segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	u8			bus_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	u8			bus_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #ifdef CONFIG_PCI_QUIRKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct mcfg_fixup {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	char oem_id[ACPI_OEM_ID_SIZE + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	u32 oem_revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	u16 segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct resource bus_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	const struct pci_ecam_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct resource cfgres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define MCFG_BUS_RANGE(start, end)	DEFINE_RES_NAMED((start),	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 						((end) - (start) + 1),	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 						NULL, IORESOURCE_BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define MCFG_BUS_ANY			MCFG_BUS_RANGE(0x0, 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static struct mcfg_fixup mcfg_quirks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /*	{ OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define AL_ECAM(table_id, rev, seg, ops) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	{ "AMAZON", table_id, rev, seg, MCFG_BUS_ANY, ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	AL_ECAM("GRAVITON", 0, 0, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	AL_ECAM("GRAVITON", 0, 1, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	AL_ECAM("GRAVITON", 0, 2, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	AL_ECAM("GRAVITON", 0, 3, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	AL_ECAM("GRAVITON", 0, 4, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	AL_ECAM("GRAVITON", 0, 5, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	AL_ECAM("GRAVITON", 0, 6, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	AL_ECAM("GRAVITON", 0, 7, &al_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define QCOM_ECAM32(seg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{ "QCOM  ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	QCOM_ECAM32(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	QCOM_ECAM32(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	QCOM_ECAM32(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	QCOM_ECAM32(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	QCOM_ECAM32(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	QCOM_ECAM32(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	QCOM_ECAM32(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	QCOM_ECAM32(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define RKCP_ECAM(seg, table_id, ops) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	{ "RKCP  ", table_id, 0x0000, seg, MCFG_BUS_ANY, ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	RKCP_ECAM(0, "RK3588  ", &rk_pcie_ecam_ops), /* pcie3x4: Name (_SEG, Zero) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define HISI_QUAD_DOM(table_id, seg, ops) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	{ "HISI  ", table_id, 0, (seg) + 0, MCFG_BUS_ANY, ops }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{ "HISI  ", table_id, 0, (seg) + 1, MCFG_BUS_ANY, ops }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{ "HISI  ", table_id, 0, (seg) + 2, MCFG_BUS_ANY, ops }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{ "HISI  ", table_id, 0, (seg) + 3, MCFG_BUS_ANY, ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	HISI_QUAD_DOM("HIP05   ",  0, &hisi_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	HISI_QUAD_DOM("HIP06   ",  0, &hisi_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	HISI_QUAD_DOM("HIP07   ",  0, &hisi_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	HISI_QUAD_DOM("HIP07   ",  4, &hisi_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	HISI_QUAD_DOM("HIP07   ",  8, &hisi_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	HISI_QUAD_DOM("HIP07   ", 12, &hisi_pcie_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define THUNDER_PEM_RES(addr, node) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	DEFINE_RES_MEM((addr) + ((u64) (node) << 44), 0x39 * SZ_16M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define THUNDER_PEM_QUIRK(rev, node) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{ "CAVIUM", "THUNDERX", rev, 4 + (10 * (node)), MCFG_BUS_ANY,	    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	  &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88001f000000UL, node) },  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	{ "CAVIUM", "THUNDERX", rev, 5 + (10 * (node)), MCFG_BUS_ANY,	    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	  &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x884057000000UL, node) },  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{ "CAVIUM", "THUNDERX", rev, 6 + (10 * (node)), MCFG_BUS_ANY,	    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	  &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88808f000000UL, node) },  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{ "CAVIUM", "THUNDERX", rev, 7 + (10 * (node)), MCFG_BUS_ANY,	    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	  &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89001f000000UL, node) },  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	{ "CAVIUM", "THUNDERX", rev, 8 + (10 * (node)), MCFG_BUS_ANY,	    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	  &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x894057000000UL, node) },  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	{ "CAVIUM", "THUNDERX", rev, 9 + (10 * (node)), MCFG_BUS_ANY,	    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	  &thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89808f000000UL, node) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define THUNDER_ECAM_QUIRK(rev, seg)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	{ "CAVIUM", "THUNDERX", rev, seg, MCFG_BUS_ANY,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	&pci_thunder_ecam_ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	/* SoC pass2.x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	THUNDER_PEM_QUIRK(1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	THUNDER_PEM_QUIRK(1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	THUNDER_ECAM_QUIRK(1, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* SoC pass1.x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	THUNDER_PEM_QUIRK(2, 0),	/* off-chip devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	THUNDER_PEM_QUIRK(2, 1),	/* off-chip devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	THUNDER_ECAM_QUIRK(2,  0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	THUNDER_ECAM_QUIRK(2,  1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	THUNDER_ECAM_QUIRK(2,  2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	THUNDER_ECAM_QUIRK(2,  3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	THUNDER_ECAM_QUIRK(2, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	THUNDER_ECAM_QUIRK(2, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	THUNDER_ECAM_QUIRK(2, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	THUNDER_ECAM_QUIRK(2, 13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define XGENE_V1_ECAM_MCFG(rev, seg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	{"APM   ", "XGENE   ", rev, seg, MCFG_BUS_ANY, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		&xgene_v1_pcie_ecam_ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define XGENE_V2_ECAM_MCFG(rev, seg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	{"APM   ", "XGENE   ", rev, seg, MCFG_BUS_ANY, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		&xgene_v2_pcie_ecam_ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	/* X-Gene SoC with v1 PCIe controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	XGENE_V1_ECAM_MCFG(1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	XGENE_V1_ECAM_MCFG(1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	XGENE_V1_ECAM_MCFG(1, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	XGENE_V1_ECAM_MCFG(1, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	XGENE_V1_ECAM_MCFG(1, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	XGENE_V1_ECAM_MCFG(2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	XGENE_V1_ECAM_MCFG(2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	XGENE_V1_ECAM_MCFG(2, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	XGENE_V1_ECAM_MCFG(2, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	XGENE_V1_ECAM_MCFG(2, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	/* X-Gene SoC with v2.1 PCIe controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	XGENE_V2_ECAM_MCFG(3, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	XGENE_V2_ECAM_MCFG(3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	/* X-Gene SoC with v2.2 PCIe controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	XGENE_V2_ECAM_MCFG(4, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	XGENE_V2_ECAM_MCFG(4, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	XGENE_V2_ECAM_MCFG(4, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define ALTRA_ECAM_QUIRK(rev, seg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	{ "Ampere", "Altra   ", rev, seg, MCFG_BUS_ANY, &pci_32b_read_ops }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	ALTRA_ECAM_QUIRK(1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	ALTRA_ECAM_QUIRK(1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	ALTRA_ECAM_QUIRK(1, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	ALTRA_ECAM_QUIRK(1, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	ALTRA_ECAM_QUIRK(1, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	ALTRA_ECAM_QUIRK(1, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	ALTRA_ECAM_QUIRK(1, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	ALTRA_ECAM_QUIRK(1, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	ALTRA_ECAM_QUIRK(1, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	ALTRA_ECAM_QUIRK(1, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	ALTRA_ECAM_QUIRK(1, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ALTRA_ECAM_QUIRK(1, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	ALTRA_ECAM_QUIRK(1, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	ALTRA_ECAM_QUIRK(1, 13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	ALTRA_ECAM_QUIRK(1, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	ALTRA_ECAM_QUIRK(1, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static u32 mcfg_oem_revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int pci_mcfg_quirk_matches(struct mcfg_fixup *f, u16 segment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				  struct resource *bus_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (!memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	    !memcmp(f->oem_table_id, mcfg_oem_table_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		    ACPI_OEM_TABLE_ID_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	    f->oem_revision == mcfg_oem_revision &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	    f->segment == segment &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	    resource_contains(&f->bus_range, bus_range))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 				  struct resource *cfgres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 				  const struct pci_ecam_ops **ecam_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #ifdef CONFIG_PCI_QUIRKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	u16 segment = root->segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	struct resource *bus_range = &root->secondary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	struct mcfg_fixup *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			if (f->cfgres.start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				*cfgres = f->cfgres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			if (f->ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 				*ecam_ops =  f->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			dev_info(&root->device->dev, "MCFG quirk: ECAM at %pR for %pR with %ps\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 				 cfgres, bus_range, *ecam_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* List to save MCFG entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static LIST_HEAD(pci_mcfg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		    const struct pci_ecam_ops **ecam_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	const struct pci_ecam_ops *ops = &pci_generic_ecam_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct resource *bus_res = &root->secondary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	u16 seg = root->segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	struct mcfg_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	/* Use address from _CBA if present, otherwise lookup MCFG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (root->mcfg_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		goto skip_lookup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 * We expect the range in bus_res in the coverage of MCFG bus range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	list_for_each_entry(e, &pci_mcfg_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		if (e->segment == seg && e->bus_start <= bus_res->start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		    e->bus_end >= bus_res->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			root->mcfg_addr = e->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) skip_lookup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	memset(&res, 0, sizeof(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (root->mcfg_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		res.start = root->mcfg_addr + (bus_res->start << 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		res.end = res.start + (resource_size(bus_res) << 20) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		res.flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 * Allow quirks to override default ECAM ops and CFG resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	 * range.  This may even fabricate a CFG resource range in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	 * MCFG does not have it.  Invalid CFG start address means MCFG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 * firmware bug or we need another quirk in array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	pci_mcfg_apply_quirks(root, &res, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (!res.start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	*cfgres = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	*ecam_ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static __init int pci_mcfg_parse(struct acpi_table_header *header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	struct acpi_table_mcfg *mcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	struct acpi_mcfg_allocation *mptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	struct mcfg_entry *e, *arr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (header->length < sizeof(struct acpi_table_mcfg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	n = (header->length - sizeof(struct acpi_table_mcfg)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 					sizeof(struct acpi_mcfg_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	mcfg = (struct acpi_table_mcfg *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	mptr = (struct acpi_mcfg_allocation *) &mcfg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	arr = kcalloc(n, sizeof(*arr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	if (!arr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	for (i = 0, e = arr; i < n; i++, mptr++, e++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		e->segment = mptr->pci_segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		e->addr =  mptr->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		e->bus_start = mptr->start_bus_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		e->bus_end = mptr->end_bus_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		list_add(&e->list, &pci_mcfg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #ifdef CONFIG_PCI_QUIRKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	/* Save MCFG IDs and revision for quirks matching */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	mcfg_oem_revision = header->oem_revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	pr_info("MCFG table detected, %d entries\n", n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* Interface called by ACPI - parse and save MCFG table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void __init pci_mmcfg_late_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		pr_debug("Failed to parse MCFG (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }