mvebu driver changes for v3.13 (round 2)
- mvebu - pcie - dynamic link up detection - add IO wrappers - declare some local functions static -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJSX+coAAoJEAi3KVZQDZAep64H+gMLjwXPSP9gebF69m0S5a+w p1n/k+0c7YiPoA3jMDZLGZIzRkHSdZm3oP4Zo9BFVO//fHXfydCwsK0tbmaFMqRg i9rKAt2xWBVqFdVVNP6B3od8DQ0x9jc2nJuiLKY+U0AoYb2ghMAVRvThfJ0G4UJg sjramPzI7We13MdixNL5WHpyRz1p4OLn+Xe/JTAZ82BLT2zS3Ti28adaU307KvEI mq+t0jA8tCbc0ESlW6YGOzxosHkQYO2UrdqB9IPN6VUhLVAd7iNKGWmvlXuU/jFr Zzp9nzlS+roZmc/jXiz2unYt2B/FkHj2gmhZyr669Fn33cTF+gi751IP0L3ePeg= =me+Y -----END PGP SIGNATURE----- Merge tag 'drivers-3.13-2' of git://git.infradead.org/linux-mvebu into next/drivers From Jason Cooper: mvebu driver changes for v3.13 (round 2) - mvebu - pcie - dynamic link up detection - add IO wrappers - declare some local functions static * tag 'drivers-3.13-2' of git://git.infradead.org/linux-mvebu: PCI: mvebu: make local functions static PCI: mvebu: add I/O access wrappers PCI: mvebu: Dynamically detect if the PEX link is up to enable hot plug Signed-off-by: Kevin Hilman <khilman@linaro.org>
This commit is contained in:
Коммит
f2c4e82e35
|
@ -120,7 +120,6 @@ struct mvebu_pcie_port {
|
|||
char *name;
|
||||
void __iomem *base;
|
||||
spinlock_t conf_lock;
|
||||
int haslink;
|
||||
u32 port;
|
||||
u32 lane;
|
||||
int devfn;
|
||||
|
@ -141,29 +140,39 @@ struct mvebu_pcie_port {
|
|||
size_t iowin_size;
|
||||
};
|
||||
|
||||
static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
|
||||
{
|
||||
writel(val, port->base + reg);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_readl(struct mvebu_pcie_port *port, u32 reg)
|
||||
{
|
||||
return readl(port->base + reg);
|
||||
}
|
||||
|
||||
static bool mvebu_pcie_link_up(struct mvebu_pcie_port *port)
|
||||
{
|
||||
return !(readl(port->base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
|
||||
return !(mvebu_readl(port, PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
|
||||
}
|
||||
|
||||
static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie_port *port, int nr)
|
||||
{
|
||||
u32 stat;
|
||||
|
||||
stat = readl(port->base + PCIE_STAT_OFF);
|
||||
stat = mvebu_readl(port, PCIE_STAT_OFF);
|
||||
stat &= ~PCIE_STAT_BUS;
|
||||
stat |= nr << 8;
|
||||
writel(stat, port->base + PCIE_STAT_OFF);
|
||||
mvebu_writel(port, stat, PCIE_STAT_OFF);
|
||||
}
|
||||
|
||||
static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
|
||||
{
|
||||
u32 stat;
|
||||
|
||||
stat = readl(port->base + PCIE_STAT_OFF);
|
||||
stat = mvebu_readl(port, PCIE_STAT_OFF);
|
||||
stat &= ~PCIE_STAT_DEV;
|
||||
stat |= nr << 16;
|
||||
writel(stat, port->base + PCIE_STAT_OFF);
|
||||
mvebu_writel(port, stat, PCIE_STAT_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,33 +190,34 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
|
|||
|
||||
/* First, disable and clear BARs and windows. */
|
||||
for (i = 1; i < 3; i++) {
|
||||
writel(0, port->base + PCIE_BAR_CTRL_OFF(i));
|
||||
writel(0, port->base + PCIE_BAR_LO_OFF(i));
|
||||
writel(0, port->base + PCIE_BAR_HI_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_BAR_CTRL_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_BAR_LO_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_BAR_HI_OFF(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
writel(0, port->base + PCIE_WIN04_CTRL_OFF(i));
|
||||
writel(0, port->base + PCIE_WIN04_BASE_OFF(i));
|
||||
writel(0, port->base + PCIE_WIN04_REMAP_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_WIN04_CTRL_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_WIN04_BASE_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i));
|
||||
}
|
||||
|
||||
writel(0, port->base + PCIE_WIN5_CTRL_OFF);
|
||||
writel(0, port->base + PCIE_WIN5_BASE_OFF);
|
||||
writel(0, port->base + PCIE_WIN5_REMAP_OFF);
|
||||
mvebu_writel(port, 0, PCIE_WIN5_CTRL_OFF);
|
||||
mvebu_writel(port, 0, PCIE_WIN5_BASE_OFF);
|
||||
mvebu_writel(port, 0, PCIE_WIN5_REMAP_OFF);
|
||||
|
||||
/* Setup windows for DDR banks. Count total DDR size on the fly. */
|
||||
size = 0;
|
||||
for (i = 0; i < dram->num_cs; i++) {
|
||||
const struct mbus_dram_window *cs = dram->cs + i;
|
||||
|
||||
writel(cs->base & 0xffff0000,
|
||||
port->base + PCIE_WIN04_BASE_OFF(i));
|
||||
writel(0, port->base + PCIE_WIN04_REMAP_OFF(i));
|
||||
writel(((cs->size - 1) & 0xffff0000) |
|
||||
(cs->mbus_attr << 8) |
|
||||
(dram->mbus_dram_target_id << 4) | 1,
|
||||
port->base + PCIE_WIN04_CTRL_OFF(i));
|
||||
mvebu_writel(port, cs->base & 0xffff0000,
|
||||
PCIE_WIN04_BASE_OFF(i));
|
||||
mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i));
|
||||
mvebu_writel(port,
|
||||
((cs->size - 1) & 0xffff0000) |
|
||||
(cs->mbus_attr << 8) |
|
||||
(dram->mbus_dram_target_id << 4) | 1,
|
||||
PCIE_WIN04_CTRL_OFF(i));
|
||||
|
||||
size += cs->size;
|
||||
}
|
||||
|
@ -217,41 +227,40 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
|
|||
size = 1 << fls(size);
|
||||
|
||||
/* Setup BAR[1] to all DRAM banks. */
|
||||
writel(dram->cs[0].base, port->base + PCIE_BAR_LO_OFF(1));
|
||||
writel(0, port->base + PCIE_BAR_HI_OFF(1));
|
||||
writel(((size - 1) & 0xffff0000) | 1,
|
||||
port->base + PCIE_BAR_CTRL_OFF(1));
|
||||
mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1));
|
||||
mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1));
|
||||
mvebu_writel(port, ((size - 1) & 0xffff0000) | 1,
|
||||
PCIE_BAR_CTRL_OFF(1));
|
||||
}
|
||||
|
||||
static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
|
||||
{
|
||||
u16 cmd;
|
||||
u32 mask;
|
||||
u32 cmd, mask;
|
||||
|
||||
/* Point PCIe unit MBUS decode windows to DRAM space. */
|
||||
mvebu_pcie_setup_wins(port);
|
||||
|
||||
/* Master + slave enable. */
|
||||
cmd = readw(port->base + PCIE_CMD_OFF);
|
||||
cmd = mvebu_readl(port, PCIE_CMD_OFF);
|
||||
cmd |= PCI_COMMAND_IO;
|
||||
cmd |= PCI_COMMAND_MEMORY;
|
||||
cmd |= PCI_COMMAND_MASTER;
|
||||
writew(cmd, port->base + PCIE_CMD_OFF);
|
||||
mvebu_writel(port, cmd, PCIE_CMD_OFF);
|
||||
|
||||
/* Enable interrupt lines A-D. */
|
||||
mask = readl(port->base + PCIE_MASK_OFF);
|
||||
mask = mvebu_readl(port, PCIE_MASK_OFF);
|
||||
mask |= PCIE_MASK_ENABLE_INTS;
|
||||
writel(mask, port->base + PCIE_MASK_OFF);
|
||||
mvebu_writel(port, mask, PCIE_MASK_OFF);
|
||||
}
|
||||
|
||||
static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
|
||||
struct pci_bus *bus,
|
||||
u32 devfn, int where, int size, u32 *val)
|
||||
{
|
||||
writel(PCIE_CONF_ADDR(bus->number, devfn, where),
|
||||
port->base + PCIE_CONF_ADDR_OFF);
|
||||
mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
|
||||
PCIE_CONF_ADDR_OFF);
|
||||
|
||||
*val = readl(port->base + PCIE_CONF_DATA_OFF);
|
||||
*val = mvebu_readl(port, PCIE_CONF_DATA_OFF);
|
||||
|
||||
if (size == 1)
|
||||
*val = (*val >> (8 * (where & 3))) & 0xff;
|
||||
|
@ -265,21 +274,24 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
|
|||
struct pci_bus *bus,
|
||||
u32 devfn, int where, int size, u32 val)
|
||||
{
|
||||
int ret = PCIBIOS_SUCCESSFUL;
|
||||
u32 _val, shift = 8 * (where & 3);
|
||||
|
||||
writel(PCIE_CONF_ADDR(bus->number, devfn, where),
|
||||
port->base + PCIE_CONF_ADDR_OFF);
|
||||
mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
|
||||
PCIE_CONF_ADDR_OFF);
|
||||
_val = mvebu_readl(port, PCIE_CONF_DATA_OFF);
|
||||
|
||||
if (size == 4)
|
||||
writel(val, port->base + PCIE_CONF_DATA_OFF);
|
||||
_val = val;
|
||||
else if (size == 2)
|
||||
writew(val, port->base + PCIE_CONF_DATA_OFF + (where & 3));
|
||||
_val = (_val & ~(0xffff << shift)) | ((val & 0xffff) << shift);
|
||||
else if (size == 1)
|
||||
writeb(val, port->base + PCIE_CONF_DATA_OFF + (where & 3));
|
||||
_val = (_val & ~(0xff << shift)) | ((val & 0xff) << shift);
|
||||
else
|
||||
ret = PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
|
||||
return ret;
|
||||
mvebu_writel(port, _val, PCIE_CONF_DATA_OFF);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
|
||||
|
@ -560,7 +572,7 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
|||
if (bus->number == 0)
|
||||
return mvebu_sw_pci_bridge_write(port, where, size, val);
|
||||
|
||||
if (!port->haslink)
|
||||
if (!mvebu_pcie_link_up(port))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
|
||||
/*
|
||||
|
@ -602,7 +614,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
|||
if (bus->number == 0)
|
||||
return mvebu_sw_pci_bridge_read(port, where, size, val);
|
||||
|
||||
if (!port->haslink) {
|
||||
if (!mvebu_pcie_link_up(port)) {
|
||||
*val = 0xffffffff;
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
@ -681,17 +693,17 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
return bus;
|
||||
}
|
||||
|
||||
void mvebu_pcie_add_bus(struct pci_bus *bus)
|
||||
static void mvebu_pcie_add_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
|
||||
bus->msi = pcie->msi;
|
||||
}
|
||||
|
||||
resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
|
||||
const struct resource *res,
|
||||
resource_size_t start,
|
||||
resource_size_t size,
|
||||
resource_size_t align)
|
||||
static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
|
||||
const struct resource *res,
|
||||
resource_size_t start,
|
||||
resource_size_t size,
|
||||
resource_size_t align)
|
||||
{
|
||||
if (dev->bus->number != 0)
|
||||
return start;
|
||||
|
@ -950,14 +962,12 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
mvebu_pcie_set_local_dev_nr(port, 1);
|
||||
|
||||
if (mvebu_pcie_link_up(port)) {
|
||||
port->haslink = 1;
|
||||
dev_info(&pdev->dev, "PCIe%d.%d: link up\n",
|
||||
port->port, port->lane);
|
||||
} else {
|
||||
port->haslink = 0;
|
||||
dev_info(&pdev->dev, "PCIe%d.%d: link down\n",
|
||||
port->port, port->lane);
|
||||
port->clk = of_clk_get_by_name(child, NULL);
|
||||
if (IS_ERR(port->clk)) {
|
||||
dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
|
||||
port->port, port->lane);
|
||||
iounmap(port->base);
|
||||
continue;
|
||||
}
|
||||
|
||||
port->dn = child;
|
||||
|
|
Загрузка…
Ссылка в новой задаче