Skip to content

Commit e42b855

Browse files
paliLorenzo Pieralisi
authored andcommitted
PCI: mvebu: Fix support for bus mastering and PCI_COMMAND on emulated bridge
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 beginning of driver initialization. Also remove code which unconditionally enables all 3 bits and let kernel code (via pci_set_master() function) to handle bus mastering of PCI Bridge via emulated PCI_COMMAND on emulated bridge. Adjust existing functions mvebu_pcie_handle_iobase_change() and mvebu_pcie_handle_membase_change() to handle PCI_IO_BASE and PCI_MEM_BASE registers correctly even when bus mastering on emulated bridge is disabled. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]>
1 parent 319e604 commit e42b855

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

drivers/pci/controller/pci-mvebu.c

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,14 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
215215
{
216216
u32 cmd, mask;
217217

218-
/* Point PCIe unit MBUS decode windows to DRAM space. */
219-
mvebu_pcie_setup_wins(port);
220-
221-
/* Master + slave enable. */
218+
/* Disable Root Bridge I/O space, memory space and bus mastering. */
222219
cmd = mvebu_readl(port, PCIE_CMD_OFF);
223-
cmd |= PCI_COMMAND_IO;
224-
cmd |= PCI_COMMAND_MEMORY;
225-
cmd |= PCI_COMMAND_MASTER;
220+
cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
226221
mvebu_writel(port, cmd, PCIE_CMD_OFF);
227222

223+
/* Point PCIe unit MBUS decode windows to DRAM space. */
224+
mvebu_pcie_setup_wins(port);
225+
228226
/* Enable interrupt lines A-D. */
229227
mask = mvebu_readl(port, PCIE_MASK_OFF);
230228
mask |= PCIE_MASK_ENABLE_INTS;
@@ -374,8 +372,7 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
374372

375373
/* Are the new iobase/iolimit values invalid? */
376374
if (conf->iolimit < conf->iobase ||
377-
conf->iolimitupper < conf->iobaseupper ||
378-
!(conf->command & PCI_COMMAND_IO)) {
375+
conf->iolimitupper < conf->iobaseupper) {
379376
mvebu_pcie_set_window(port, port->io_target, port->io_attr,
380377
&desired, &port->iowin);
381378
return;
@@ -412,8 +409,7 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
412409
struct pci_bridge_emul_conf *conf = &port->bridge.conf;
413410

414411
/* Are the new membase/memlimit values invalid? */
415-
if (conf->memlimit < conf->membase ||
416-
!(conf->command & PCI_COMMAND_MEMORY)) {
412+
if (conf->memlimit < conf->membase) {
417413
mvebu_pcie_set_window(port, port->mem_target, port->mem_attr,
418414
&desired, &port->memwin);
419415
return;
@@ -433,6 +429,24 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
433429
&port->memwin);
434430
}
435431

432+
static pci_bridge_emul_read_status_t
433+
mvebu_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge,
434+
int reg, u32 *value)
435+
{
436+
struct mvebu_pcie_port *port = bridge->data;
437+
438+
switch (reg) {
439+
case PCI_COMMAND:
440+
*value = mvebu_readl(port, PCIE_CMD_OFF);
441+
break;
442+
443+
default:
444+
return PCI_BRIDGE_EMUL_NOT_HANDLED;
445+
}
446+
447+
return PCI_BRIDGE_EMUL_HANDLED;
448+
}
449+
436450
static pci_bridge_emul_read_status_t
437451
mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
438452
int reg, u32 *value)
@@ -487,17 +501,14 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
487501

488502
switch (reg) {
489503
case PCI_COMMAND:
490-
{
491-
if (!mvebu_has_ioport(port))
492-
conf->command &= ~PCI_COMMAND_IO;
493-
494-
if ((old ^ new) & PCI_COMMAND_IO)
495-
mvebu_pcie_handle_iobase_change(port);
496-
if ((old ^ new) & PCI_COMMAND_MEMORY)
497-
mvebu_pcie_handle_membase_change(port);
504+
if (!mvebu_has_ioport(port)) {
505+
conf->command = cpu_to_le16(
506+
le16_to_cpu(conf->command) & ~PCI_COMMAND_IO);
507+
new &= ~PCI_COMMAND_IO;
508+
}
498509

510+
mvebu_writel(port, new, PCIE_CMD_OFF);
499511
break;
500-
}
501512

502513
case PCI_IO_BASE:
503514
/*
@@ -564,6 +575,7 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
564575
}
565576

566577
static struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
578+
.read_base = mvebu_pci_bridge_emul_base_conf_read,
567579
.write_base = mvebu_pci_bridge_emul_base_conf_write,
568580
.read_pcie = mvebu_pci_bridge_emul_pcie_conf_read,
569581
.write_pcie = mvebu_pci_bridge_emul_pcie_conf_write,

0 commit comments

Comments
 (0)