+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2017 NXP
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
{
struct udevice *bus = pcie->bus;
+ if (pcie->mode == PCI_HEADER_TYPE_NORMAL)
+ return -ENODEV;
+
if (!pcie->enabled)
return -ENXIO;
return 0;
}
-void *ls_pcie_conf_address(struct ls_pcie *pcie, pci_dev_t bdf,
- int offset)
+int ls_pcie_conf_address(struct udevice *bus, pci_dev_t bdf,
+ uint offset, void **paddress)
{
- struct udevice *bus = pcie->bus;
+ struct ls_pcie *pcie = dev_get_priv(bus);
u32 busdev;
- if (PCI_BUS(bdf) == bus->seq)
- return pcie->dbi + offset;
+ if (ls_pcie_addr_valid(pcie, bdf))
+ return -EINVAL;
- busdev = PCIE_ATU_BUS(PCI_BUS(bdf)) |
+ if (PCI_BUS(bdf) == bus->seq) {
+ *paddress = pcie->dbi + offset;
+ return 0;
+ }
+
+ busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - bus->seq) |
PCIE_ATU_DEV(PCI_DEV(bdf)) |
PCIE_ATU_FUNC(PCI_FUNC(bdf));
if (PCI_BUS(bdf) == bus->seq + 1) {
ls_pcie_cfg0_set_busdev(pcie, busdev);
- return pcie->cfg0 + offset;
+ *paddress = pcie->cfg0 + offset;
} else {
ls_pcie_cfg1_set_busdev(pcie, busdev);
- return pcie->cfg1 + offset;
+ *paddress = pcie->cfg1 + offset;
}
+ return 0;
}
static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
{
- struct ls_pcie *pcie = dev_get_priv(bus);
- void *address;
-
- if (ls_pcie_addr_valid(pcie, bdf)) {
- *valuep = pci_get_ff(size);
- return 0;
- }
-
- address = ls_pcie_conf_address(pcie, bdf, offset);
-
- switch (size) {
- case PCI_SIZE_8:
- *valuep = readb(address);
- return 0;
- case PCI_SIZE_16:
- *valuep = readw(address);
- return 0;
- case PCI_SIZE_32:
- *valuep = readl(address);
- return 0;
- default:
- return -EINVAL;
- }
+ return pci_generic_mmap_read_config(bus, ls_pcie_conf_address,
+ bdf, offset, valuep, size);
}
static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
{
- struct ls_pcie *pcie = dev_get_priv(bus);
- void *address;
-
- if (ls_pcie_addr_valid(pcie, bdf))
- return 0;
-
- address = ls_pcie_conf_address(pcie, bdf, offset);
-
- switch (size) {
- case PCI_SIZE_8:
- writeb(value, address);
- return 0;
- case PCI_SIZE_16:
- writew(value, address);
- return 0;
- case PCI_SIZE_32:
- writel(value, address);
- return 0;
- default:
- return -EINVAL;
- }
+ return pci_generic_mmap_write_config(bus, ls_pcie_conf_address,
+ bdf, offset, value, size);
}
/* Clear multi-function bit */
struct ls_pcie *pcie = dev_get_priv(dev);
const void *fdt = gd->fdt_blob;
int node = dev_of_offset(dev);
- u8 header_type;
u16 link_sta;
- bool ep_mode;
uint svr;
int ret;
fdt_size_t cfg_size;
(unsigned long)pcie->ctrl, (unsigned long)pcie->cfg0,
pcie->big_endian);
- header_type = readb(pcie->dbi + PCI_HEADER_TYPE);
- ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
- printf("PCIe%u: %s %s", pcie->idx, dev->name,
- ep_mode ? "Endpoint" : "Root Complex");
+ pcie->mode = readb(pcie->dbi + PCI_HEADER_TYPE) & 0x7f;
- if (ep_mode)
- ls_pcie_setup_ep(pcie);
- else
- ls_pcie_setup_ctrl(pcie);
+ if (pcie->mode == PCI_HEADER_TYPE_NORMAL) {
+ printf("PCIe%u: %s %s", pcie->idx, dev->name, "Endpoint");
+ ls_pcie_setup_ep(pcie);
+ } else {
+ printf("PCIe%u: %s %s", pcie->idx, dev->name, "Root Complex");
+ ls_pcie_setup_ctrl(pcie);
+ }
if (!ls_pcie_link_up(pcie)) {
/* Let the user know there's no PCIe link */