#include <dm.h>
#include <log.h>
#include <malloc.h>
+#include <asm/global_data.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/of_access.h>
void __iomem *membase;
struct resource mem;
void __iomem *iobase;
+ struct resource io;
u32 port;
u32 lane;
int devfn;
char name[16];
unsigned int mem_target;
unsigned int mem_attr;
+ unsigned int io_target;
+ unsigned int io_attr;
};
/*
*/
static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
#define PCIE_MEM_SIZE (128 << 20)
+static void __iomem *mvebu_pcie_iobase = (void __iomem *)MBUS_PCI_IO_BASE;
static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
{
u32 reg;
u32 data;
- debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
- PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
-
- /* Only allow one other device besides the local one on the local bus */
- if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) != local_dev) {
- if (local_dev == 0 && PCI_DEV(bdf) != 1) {
- debug("- out of range\n");
- /*
- * If local dev is 0, the first other dev can
- * only be 1
- */
- *valuep = pci_get_ff(size);
- return 0;
- } else if (local_dev != 0 && PCI_DEV(bdf) != 0) {
- debug("- out of range\n");
- /*
- * If local dev is not 0, the first other dev can
- * only be 0
- */
- *valuep = pci_get_ff(size);
- return 0;
- }
+ debug("PCIE CFG read: loc_bus=%d loc_dev=%d (b,d,f)=(%2d,%2d,%2d) ",
+ local_bus, local_dev, PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+
+ /* Don't access the local host controller via this API */
+ if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) == local_dev) {
+ debug("- skipping host controller\n");
+ *valuep = pci_get_ff(size);
+ return 0;
+ }
+
+ /* If local dev is 0, the first other dev can only be 1 */
+ if (PCI_BUS(bdf) == local_bus && local_dev == 0 && PCI_DEV(bdf) != 1) {
+ debug("- out of range\n");
+ *valuep = pci_get_ff(size);
+ return 0;
}
/* write address */
int local_dev = PCI_DEV(pcie->dev);
u32 data;
- debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
- PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
+ debug("PCIE CFG write: loc_bus=%d loc_dev=%d (b,d,f)=(%2d,%2d,%2d) ",
+ local_bus, local_dev, PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
- /* Only allow one other device besides the local one on the local bus */
- if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) != local_dev) {
- if (local_dev == 0 && PCI_DEV(bdf) != 1) {
- /*
- * If local dev is 0, the first other dev can
- * only be 1
- */
- return 0;
- } else if (local_dev != 0 && PCI_DEV(bdf) != 0) {
- /*
- * If local dev is not 0, the first other dev can
- * only be 0
- */
- return 0;
- }
+ /* Don't access the local host controller via this API */
+ if (PCI_BUS(bdf) == local_bus && PCI_DEV(bdf) == local_dev) {
+ debug("- skipping host controller\n");
+ return 0;
+ }
+
+ /* If local dev is 0, the first other dev can only be 1 */
+ if (PCI_BUS(bdf) == local_bus && local_dev == 0 && PCI_DEV(bdf) != 1) {
+ debug("- out of range\n");
+ return 0;
}
writel(PCIE_CONF_ADDR(bdf, offset), pcie->base + PCIE_CONF_ADDR_OFF);
(u32)pcie->mem.start, PCIE_MEM_SIZE);
}
+ pcie->io.start = (u32)mvebu_pcie_iobase;
+ pcie->io.end = pcie->io.start + MBUS_PCI_IO_SIZE - 1;
+ mvebu_pcie_iobase += MBUS_PCI_IO_SIZE;
+
+ if (mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
+ (phys_addr_t)pcie->io.start,
+ MBUS_PCI_IO_SIZE)) {
+ printf("PCIe unable to add mbus window for IO at %08x+%08x\n",
+ (u32)pcie->io.start, MBUS_PCI_IO_SIZE);
+ }
+
/* Setup windows and configure host bridge */
mvebu_pcie_setup_wins(pcie);
/* Master + slave enable. */
reg = readl(pcie->base + PCIE_CMD_OFF);
reg |= PCI_COMMAND_MEMORY;
+ reg |= PCI_COMMAND_IO;
reg |= PCI_COMMAND_MASTER;
reg |= BIT(10); /* disable interrupts */
writel(reg, pcie->base + PCIE_CMD_OFF);
0, 0,
gd->ram_size,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
- hose->region_count = 2;
+ pci_set_region(hose->regions + 2, pcie->io.start,
+ pcie->io.start, MBUS_PCI_IO_SIZE, PCI_REGION_IO);
+ hose->region_count = 3;
/* Set BAR0 to internal registers */
writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
goto err;
}
+ ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
+ IORESOURCE_IO,
+ &pcie->io_target, &pcie->io_attr);
+ if (ret < 0) {
+ printf("%s: cannot get tgt/attr for IO window\n", pcie->name);
+ goto err;
+ }
+
/* Parse PCIe controller register base from DT */
ret = mvebu_pcie_port_parse_dt(dev_ofnode(dev), pcie);
if (ret < 0)