From 462a088c474832b19ff2730de1e6bea66d399c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sat, 15 Oct 2022 23:01:29 +0200 Subject: Add Turris kernel (includes patches from OpenWrt) --- ...dge-emul-Set-position-of-PCI-capabilities.patch | 164 +++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 pkgs/patches-linux-5.15/0051-PCI-pci-bridge-emul-Set-position-of-PCI-capabilities.patch (limited to 'pkgs/patches-linux-5.15/0051-PCI-pci-bridge-emul-Set-position-of-PCI-capabilities.patch') diff --git a/pkgs/patches-linux-5.15/0051-PCI-pci-bridge-emul-Set-position-of-PCI-capabilities.patch b/pkgs/patches-linux-5.15/0051-PCI-pci-bridge-emul-Set-position-of-PCI-capabilities.patch new file mode 100644 index 0000000..0d3b160 --- /dev/null +++ b/pkgs/patches-linux-5.15/0051-PCI-pci-bridge-emul-Set-position-of-PCI-capabilities.patch @@ -0,0 +1,164 @@ +From f0a61d9c1f4396e7f3a241b9be1378ed4e5bb947 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Sun, 3 Jul 2022 12:40:13 +0200 +Subject: [PATCH 51/90] PCI: pci-bridge-emul: Set position of PCI capabilities + to real HW value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +mvebu and aardvark HW have PCIe capabilities on different offset in PCI +config space. Extend pci-bridge-emul.c code to allow setting custom driver +custom value where PCIe capabilities starts. + +With this change PCIe capabilities of both drivers are reported at the same +location as where they are reported by U-Boot - in their real HW offset. + +Signed-off-by: Pali Rohár +--- + drivers/pci/controller/pci-aardvark.c | 1 + + drivers/pci/controller/pci-mvebu.c | 1 + + drivers/pci/pci-bridge-emul.c | 48 +++++++++++++++++---------- + drivers/pci/pci-bridge-emul.h | 2 ++ + 4 files changed, 35 insertions(+), 17 deletions(-) + +diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c +index 3fe4d3329267..4ed1b3ed3d35 100644 +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -984,6 +984,7 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) + bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); + + bridge->has_pcie = true; ++ bridge->pcie_start = PCIE_CORE_PCIEXP_CAP; + bridge->data = pcie; + bridge->ops = &advk_pci_bridge_emul_ops; + +diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c +index 3c48b15e3948..8205b4d1f04c 100644 +--- a/drivers/pci/controller/pci-mvebu.c ++++ b/drivers/pci/controller/pci-mvebu.c +@@ -951,6 +951,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) + bridge->subsystem_vendor_id = ssdev_id & 0xffff; + bridge->subsystem_id = ssdev_id >> 16; + bridge->has_pcie = true; ++ bridge->pcie_start = PCIE_CAP_PCIEXP; + bridge->data = port; + bridge->ops = &mvebu_pci_bridge_emul_ops; + +diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c +index a5b662cc89d0..7a8a7c804050 100644 +--- a/drivers/pci/pci-bridge-emul.c ++++ b/drivers/pci/pci-bridge-emul.c +@@ -22,11 +22,7 @@ + + #define PCI_BRIDGE_CONF_END PCI_STD_HEADER_SIZEOF + #define PCI_CAP_SSID_SIZEOF (PCI_SSVID_DEVICE_ID + 2) +-#define PCI_CAP_SSID_START PCI_BRIDGE_CONF_END +-#define PCI_CAP_SSID_END (PCI_CAP_SSID_START + PCI_CAP_SSID_SIZEOF) + #define PCI_CAP_PCIE_SIZEOF (PCI_EXP_SLTSTA2 + 2) +-#define PCI_CAP_PCIE_START PCI_CAP_SSID_END +-#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF) + + /** + * struct pci_bridge_reg_behavior - register bits behaviors +@@ -324,7 +320,7 @@ pci_bridge_emul_read_ssid(struct pci_bridge_emul *bridge, int reg, u32 *value) + switch (reg) { + case PCI_CAP_LIST_ID: + *value = PCI_CAP_ID_SSVID | +- (bridge->has_pcie ? (PCI_CAP_PCIE_START << 8) : 0); ++ ((bridge->pcie_start > bridge->ssid_start) ? (bridge->pcie_start << 8) : 0); + return PCI_BRIDGE_EMUL_HANDLED; + + case PCI_SSVID_VENDOR_ID: +@@ -363,18 +359,33 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge, + if (!bridge->pci_regs_behavior) + return -ENOMEM; + +- if (bridge->subsystem_vendor_id) +- bridge->conf.capabilities_pointer = PCI_CAP_SSID_START; +- else if (bridge->has_pcie) +- bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START; +- else +- bridge->conf.capabilities_pointer = 0; ++ /* If ssid_start and pcie_start were not specified then choose the lowest possible value. */ ++ if (!bridge->ssid_start && !bridge->pcie_start) { ++ if (bridge->subsystem_vendor_id) ++ bridge->ssid_start = PCI_BRIDGE_CONF_END; ++ if (bridge->has_pcie) ++ bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF; ++ } else if (!bridge->ssid_start && bridge->subsystem_vendor_id) { ++ if (bridge->pcie_start - PCI_BRIDGE_CONF_END >= PCI_CAP_SSID_SIZEOF) ++ bridge->ssid_start = PCI_BRIDGE_CONF_END; ++ else ++ bridge->ssid_start = bridge->pcie_start + PCI_CAP_PCIE_SIZEOF; ++ } else if (!bridge->pcie_start && bridge->has_pcie) { ++ if (bridge->ssid_start - PCI_BRIDGE_CONF_END >= PCI_CAP_PCIE_SIZEOF) ++ bridge->pcie_start = PCI_BRIDGE_CONF_END; ++ else ++ bridge->pcie_start = bridge->ssid_start + PCI_CAP_SSID_SIZEOF; ++ } ++ ++ bridge->conf.capabilities_pointer = min(bridge->ssid_start, bridge->pcie_start); + + if (bridge->conf.capabilities_pointer) + bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST); + + if (bridge->has_pcie) { + bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; ++ bridge->pcie_conf.next = (bridge->ssid_start > bridge->pcie_start) ? ++ bridge->ssid_start : 0; + bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4); + bridge->pcie_cap_regs_behavior = + kmemdup(pcie_cap_regs_behavior, +@@ -457,15 +468,17 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, + read_op = bridge->ops->read_base; + cfgspace = (__le32 *) &bridge->conf; + behavior = bridge->pci_regs_behavior; +- } else if (reg >= PCI_CAP_SSID_START && reg < PCI_CAP_SSID_END && bridge->subsystem_vendor_id) { ++ } else if (reg >= bridge->ssid_start && reg < bridge->ssid_start + PCI_CAP_SSID_SIZEOF && ++ bridge->subsystem_vendor_id) { + /* Emulated PCI Bridge Subsystem Vendor ID capability */ +- reg -= PCI_CAP_SSID_START; ++ reg -= bridge->ssid_start; + read_op = pci_bridge_emul_read_ssid; + cfgspace = NULL; + behavior = NULL; +- } else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) { ++ } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF && ++ bridge->has_pcie) { + /* Our emulated PCIe capability */ +- reg -= PCI_CAP_PCIE_START; ++ reg -= bridge->pcie_start; + read_op = bridge->ops->read_pcie; + cfgspace = (__le32 *) &bridge->pcie_conf; + behavior = bridge->pcie_cap_regs_behavior; +@@ -536,9 +549,10 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, + write_op = bridge->ops->write_base; + cfgspace = (__le32 *) &bridge->conf; + behavior = bridge->pci_regs_behavior; +- } else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) { ++ } else if (reg >= bridge->pcie_start && reg < bridge->pcie_start + PCI_CAP_PCIE_SIZEOF && ++ bridge->has_pcie) { + /* Our emulated PCIe capability */ +- reg -= PCI_CAP_PCIE_START; ++ reg -= bridge->pcie_start; + write_op = bridge->ops->write_pcie; + cfgspace = (__le32 *) &bridge->pcie_conf; + behavior = bridge->pcie_cap_regs_behavior; +diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h +index 71392b67471d..2a0e59c7f0d9 100644 +--- a/drivers/pci/pci-bridge-emul.h ++++ b/drivers/pci/pci-bridge-emul.h +@@ -131,6 +131,8 @@ struct pci_bridge_emul { + struct pci_bridge_reg_behavior *pci_regs_behavior; + struct pci_bridge_reg_behavior *pcie_cap_regs_behavior; + void *data; ++ u8 pcie_start; ++ u8 ssid_start; + bool has_pcie; + u16 subsystem_vendor_id; + u16 subsystem_id; +-- +2.34.1 + -- cgit v1.2.3