Skip to content

Commit 075f553

Browse files
palismb49
authored andcommitted
PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated bridge
BugLink: https://bugs.launchpad.net/bugs/1956380 commit 771153f upstream. >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. Link: https://lore.kernel.org/r/20211028185659.20329-5-kabel@kernel.org Fixes: 8a3ebd8 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: stable@vger.kernel.org # b2a5646 ("PCI: aardvark: Add FIXME comment for PCIE_CORE_CMD_STATUS_REG access") Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent fad6d51 commit 075f553

File tree

1 file changed

+38
-9
lines changed

1 file changed

+38
-9
lines changed

drivers/pci/controller/pci-aardvark.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
/* PCIe core registers */
2828
#define PCIE_CORE_DEV_ID_REG 0x0
2929
#define PCIE_CORE_CMD_STATUS_REG 0x4
30-
#define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0)
31-
#define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1)
32-
#define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2)
3330
#define PCIE_CORE_DEV_REV_REG 0x8
3431
#define PCIE_CORE_PCIEXP_CAP 0xc0
3532
#define PCIE_CORE_ERR_CAPCTL_REG 0x118
@@ -505,6 +502,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
505502
reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL;
506503
advk_writel(pcie, reg, VENDOR_ID_REG);
507504

505+
/* Disable Root Bridge I/O space, memory space and bus mastering */
506+
reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
507+
reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
508+
advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);
509+
508510
/* Set Advanced Error Capabilities and Control PF0 register */
509511
reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
510512
PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
@@ -603,12 +605,6 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
603605
advk_pcie_disable_ob_win(pcie, i);
604606

605607
advk_pcie_train_link(pcie);
606-
607-
reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
608-
reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
609-
PCIE_CORE_CMD_IO_ACCESS_EN |
610-
PCIE_CORE_CMD_MEM_IO_REQ_EN;
611-
advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);
612608
}
613609

614610
static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u32 *val)
@@ -737,6 +733,37 @@ static int advk_pcie_wait_pio(struct advk_pcie *pcie)
737733
return -ETIMEDOUT;
738734
}
739735

736+
static pci_bridge_emul_read_status_t
737+
advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge,
738+
int reg, u32 *value)
739+
{
740+
struct advk_pcie *pcie = bridge->data;
741+
742+
switch (reg) {
743+
case PCI_COMMAND:
744+
*value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
745+
return PCI_BRIDGE_EMUL_HANDLED;
746+
747+
default:
748+
return PCI_BRIDGE_EMUL_NOT_HANDLED;
749+
}
750+
}
751+
752+
static void
753+
advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
754+
int reg, u32 old, u32 new, u32 mask)
755+
{
756+
struct advk_pcie *pcie = bridge->data;
757+
758+
switch (reg) {
759+
case PCI_COMMAND:
760+
advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG);
761+
break;
762+
763+
default:
764+
break;
765+
}
766+
}
740767

741768
static pci_bridge_emul_read_status_t
742769
advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
@@ -838,6 +865,8 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
838865
}
839866

840867
static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = {
868+
.read_base = advk_pci_bridge_emul_base_conf_read,
869+
.write_base = advk_pci_bridge_emul_base_conf_write,
841870
.read_pcie = advk_pci_bridge_emul_pcie_conf_read,
842871
.write_pcie = advk_pci_bridge_emul_pcie_conf_write,
843872
};

0 commit comments

Comments
 (0)