FAILED: patch "[PATCH] PCI: aardvark: Fix support for bus mastering and PCI_COMMAND" failed to apply to 4.19-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 771153fc884f566a89af2d30033b7f3bc6e24e84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <[email protected]>
Date: Thu, 28 Oct 2021 20:56:56 +0200
Subject: [PATCH] PCI: aardvark: Fix support for bus mastering and PCI_COMMAND
on emulated bridge
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From very vague, ambiguous and incomplete information from Marvell we deduced that the 32-bit Aardvark register at address 0x4 (PCIE_CORE_CMD_STATUS_REG), which is not documented for Root Complex mode in the Functional Specification (only for Endpoint mode), controls two 16-bit PCIe registers: Command Register and Status Registers of PCIe Root Port.
This means that bit 2 controls bus mastering and forwarding of memory and I/O requests in the upstream direction. According to PCI specifications bits [0:2] of Command Register, this should be by default disabled on reset. So explicitly disable these bits at early setup of the Aardvark driver.
Remove code which unconditionally enables all 3 bits and let kernel code (via pci_set_master() function) to handle bus mastering of Root PCIe Bridge via emulated PCI_COMMAND on emulated bridge.
drivers/pci/controller/pci-aardvark.c +38 -16
@@ -31,9 +31,6 @@/* PCIe core registers */ #define PCIE_CORE_DEV_ID_REG 0x0#define PCIE_CORE_CMD_STATUS_REG 0x4 -#define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) -#define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) -#define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2)#define PCIE_CORE_DEV_REV_REG 0x8#define PCIE_CORE_PCIEXP_CAP 0xc0#define PCIE_CORE_ERR_CAPCTL_REG 0x118
@@ -514,6 +511,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) reg = (PCI_VENDOR_ID_MARVELL <<16 ) |PCI_VENDOR_ID_MARVELL ;advk_writel (pcie, reg,VENDOR_ID_REG ); +/* Disable Root Bridge I/O space, memory space and bus mastering */ + reg =advk_readl (pcie,PCIE_CORE_CMD_STATUS_REG ); + reg &= ~(PCI_COMMAND_IO |PCI_COMMAND_MEMORY |PCI_COMMAND_MASTER ); +advk_writel (pcie, reg,PCIE_CORE_CMD_STATUS_REG ); +/* Set Advanced Error Capabilities and Control PF0 register */ reg =PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
@@ -612,19 +614,6 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)advk_pcie_disable_ob_win (pcie, i);advk_pcie_train_link (pcie); - -/* -* FIXME: The following register update is suspicious. This register is -* applicable only when the PCI controller is configured for Endpoint -* mode, not as a Root Complex. But apparently when this code is -* removed, some cards stop working. This should be investigated and -* a comment explaining this should be put here. -*/ - reg =advk_readl (pcie,PCIE_CORE_CMD_STATUS_REG ); - reg |=PCIE_CORE_CMD_MEM_ACCESS_EN | -PCIE_CORE_CMD_IO_ACCESS_EN | -PCIE_CORE_CMD_MEM_IO_REQ_EN ; -advk_writel (pcie, reg,PCIE_CORE_CMD_STATUS_REG ); }static int advk_pcie_check_pio_status (struct advk_pcie *pcie,bool allow_crs,u32 *val)
@@ -753,6 +742,37 @@ static int advk_pcie_wait_pio(struct advk_pcie *pcie)return -ETIMEDOUT ; } +static pci_bridge_emul_read_status_t +advk_pci_bridge_emul_base_conf_read (struct pci_bridge_emul *bridge, +int reg,u32 *value) +{ +struct advk_pcie *pcie = bridge->data; + +switch (reg) { +case PCI_COMMAND : + *value =advk_readl (pcie,PCIE_CORE_CMD_STATUS_REG ); +return PCI_BRIDGE_EMUL_HANDLED ; + +default : +return PCI_BRIDGE_EMUL_NOT_HANDLED ; + } +} + +static void +advk_pci_bridge_emul_base_conf_write (struct pci_bridge_emul *bridge, +int reg,u32 old,u32 new,u32 mask) +{ +struct advk_pcie *pcie = bridge->data; + +switch (reg) { +case PCI_COMMAND : +advk_writel (pcie, new,PCIE_CORE_CMD_STATUS_REG ); +break ; + +default : +break ; + } +} static pci_bridge_emul_read_status_t advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
@@ -854,6 +874,8 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, }static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { + .read_base = advk_pci_bridge_emul_base_conf_read, + .write_base = advk_pci_bridge_emul_base_conf_write, .read_pcie = advk_pci_bridge_emul_pcie_conf_read, .write_pcie = advk_pci_bridge_emul_pcie_conf_write, };