pci: Add standard PCIe ECAM macros
Lot of PCIe controllers are using ECAM addressing. So add common ECAM
macros into U-Boot's pci.h header file which can be suitable for most
PCI controller drivers.
Replace custom ECAM address macros in every PCI controller driver by new
ECAM macros from U-Boot's pci.h header file.
Similar macros are defined also in Linux kernel. There is a small
difference between Linux and these new U-Boot macros.
U-Boot's PCIE_ECAM_OFFSET() takes device and function numbers in separate
arguments. Linux's PCIE_ECAM_OFFSET() takes device and function numbers
encoded in one argument. The reason is that U-Boot's PCI_DEVFN() macro is
different than Linux's PCI_SLOT() macro. So having device and function
numbers in separate arguments makes code more straightforward.
Signed-off-by: Pali Rohár <pali@kernel.org>
Reviewed-by: Stefan Roese <sr@denx.de>
diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c
index 4e94b77..6d73aab 100644
--- a/drivers/pci/pci-aardvark.c
+++ b/drivers/pci/pci-aardvark.c
@@ -165,16 +165,6 @@
#define PCIE_CONFIG_WR_TYPE0 0xa
#define PCIE_CONFIG_WR_TYPE1 0xb
-/* PCI_BDF shifts 8bit, so we need extra 4bit shift */
-#define PCIE_BDF(b, d, f) (PCI_BDF(b, d, f) << 4)
-#define PCIE_CONF_BUS(bus) (((bus) & 0xff) << 20)
-#define PCIE_CONF_DEV(dev) (((dev) & 0x1f) << 15)
-#define PCIE_CONF_FUNC(fun) (((fun) & 0x7) << 12)
-#define PCIE_CONF_REG(reg) ((reg) & 0xffc)
-#define PCIE_CONF_ADDR(bus, devfn, where) \
- (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn)) | \
- PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where))
-
/* PCIe Retries & Timeout definitions */
#define PIO_MAX_RETRIES 1500
#define PIO_WAIT_TIMEOUT 1000
@@ -468,7 +458,7 @@
advk_writel(pcie, reg, PIO_CTRL);
/* Program the address registers */
- reg = PCIE_BDF(busno, PCI_DEV(bdf), PCI_FUNC(bdf)) | PCIE_CONF_REG(offset);
+ reg = PCIE_ECAM_OFFSET(busno, PCI_DEV(bdf), PCI_FUNC(bdf), (offset & ~0x3));
advk_writel(pcie, reg, PIO_ADDR_LS);
advk_writel(pcie, 0, PIO_ADDR_MS);
@@ -628,7 +618,7 @@
advk_writel(pcie, reg, PIO_CTRL);
/* Program the address registers */
- reg = PCIE_BDF(busno, PCI_DEV(bdf), PCI_FUNC(bdf)) | PCIE_CONF_REG(offset);
+ reg = PCIE_ECAM_OFFSET(busno, PCI_DEV(bdf), PCI_FUNC(bdf), (offset & ~0x3));
advk_writel(pcie, reg, PIO_ADDR_LS);
advk_writel(pcie, 0, PIO_ADDR_MS);
dev_dbg(pcie->dev, "\tPIO req. - addr = 0x%08x\n", reg);
diff --git a/drivers/pci/pcie_ecam_generic.c b/drivers/pci/pcie_ecam_generic.c
index e83e5af..09b6fc1 100644
--- a/drivers/pci/pcie_ecam_generic.c
+++ b/drivers/pci/pcie_ecam_generic.c
@@ -46,10 +46,8 @@
void *addr;
addr = pcie->cfg_base;
- addr += (PCI_BUS(bdf) - pcie->first_busno) << 20;
- addr += PCI_DEV(bdf) << 15;
- addr += PCI_FUNC(bdf) << 12;
- addr += offset;
+ addr += PCIE_ECAM_OFFSET(PCI_BUS(bdf) - pcie->first_busno,
+ PCI_DEV(bdf), PCI_FUNC(bdf), offset);
*paddress = addr;
return 0;
diff --git a/drivers/pci/pcie_ecam_synquacer.c b/drivers/pci/pcie_ecam_synquacer.c
index c6e7c59..e3e2289 100644
--- a/drivers/pci/pcie_ecam_synquacer.c
+++ b/drivers/pci/pcie_ecam_synquacer.c
@@ -235,10 +235,8 @@
void *addr;
addr = pcie->cfg_base;
- addr += (PCI_BUS(bdf) - pcie->first_busno) << 20;
- addr += PCI_DEV(bdf) << 15;
- addr += PCI_FUNC(bdf) << 12;
- addr += offset;
+ addr += PCIE_ECAM_OFFSET(PCI_BUS(bdf) - pcie->first_busno,
+ PCI_DEV(bdf), PCI_FUNC(bdf), offset);
*paddress = addr;
return 0;
diff --git a/drivers/pci/pcie_phytium.c b/drivers/pci/pcie_phytium.c
index 752e170..a807276 100644
--- a/drivers/pci/pcie_phytium.c
+++ b/drivers/pci/pcie_phytium.c
@@ -36,9 +36,7 @@
unsigned short capreg;
unsigned char port_type;
- addr += PCI_BUS(parent) << 20;
- addr += PCI_DEV(parent) << 15;
- addr += PCI_FUNC(parent) << 12;
+ addr += PCIE_ECAM_OFFSET(PCI_BUS(parent), PCI_DEV(parent), PCI_FUNC(parent), 0);
pos = 0x34;
while (1) {
@@ -89,9 +87,7 @@
bdf_parent = PCI_BDF((bus_no - 1), 0, 0);
addr = pcie->cfg_base;
- addr += PCI_BUS(bdf) << 20;
- addr += PCI_DEV(bdf) << 15;
- addr += PCI_FUNC(bdf) << 12;
+ addr += PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), 0);
if (bus_no > 0 && dev_no > 0) {
if ((readb(addr + PCI_HEADER_TYPE) & 0x7f) !=
diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c
index b0c91c0..67039d2 100644
--- a/drivers/pci/pcie_rockchip.c
+++ b/drivers/pci/pcie_rockchip.c
@@ -101,15 +101,6 @@
struct phy pcie_phy;
};
-static int rockchip_pcie_off_conf(pci_dev_t bdf, uint offset)
-{
- unsigned int bus = PCI_BUS(bdf);
- unsigned int dev = PCI_DEV(bdf);
- unsigned int func = PCI_FUNC(bdf);
-
- return (bus << 20) | (dev << 15) | (func << 12) | (offset & ~0x3);
-}
-
static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
@@ -117,7 +108,7 @@
struct rockchip_pcie *priv = dev_get_priv(udev);
unsigned int bus = PCI_BUS(bdf);
unsigned int dev = PCI_DEV(bdf);
- int where = rockchip_pcie_off_conf(bdf, offset);
+ int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset & ~0x3);
ulong value;
if (bus == priv->first_busno && dev == 0) {
@@ -144,7 +135,7 @@
struct rockchip_pcie *priv = dev_get_priv(udev);
unsigned int bus = PCI_BUS(bdf);
unsigned int dev = PCI_DEV(bdf);
- int where = rockchip_pcie_off_conf(bdf, offset);
+ int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset & ~0x3);
ulong old;
if (bus == priv->first_busno && dev == 0) {
diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
index ae9a65b..eb9ec97 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -76,10 +76,7 @@
return -ENODEV;
addr = pcie->cfg_base;
- addr += bus << 20;
- addr += dev << 15;
- addr += func << 12;
- addr += offset;
+ addr += PCIE_ECAM_OFFSET(bus, dev, func, offset);
*paddress = addr;
return 0;