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>
This commit is contained in:
parent
b814e0007e
commit
a4bc38da27
@ -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 @@ static int pcie_advk_read_config(const struct udevice *bus, pci_dev_t bdf,
|
||||
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 @@ static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf,
|
||||
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);
|
||||
|
@ -46,10 +46,8 @@ static int pci_generic_ecam_conf_address(const struct udevice *bus,
|
||||
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;
|
||||
|
@ -235,10 +235,8 @@ static int pci_synquacer_ecam_conf_address(const struct udevice *bus,
|
||||
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;
|
||||
|
@ -36,9 +36,7 @@ static int phytium_pci_skip_dev(pci_dev_t parent)
|
||||
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 @@ static int pci_phytium_conf_address(const struct udevice *bus, pci_dev_t bdf,
|
||||
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) !=
|
||||
|
@ -101,15 +101,6 @@ struct rockchip_pcie {
|
||||
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 @@ static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
|
||||
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 @@ static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf,
|
||||
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) {
|
||||
|
@ -76,10 +76,7 @@ static int pcie_xilinx_config_address(const struct udevice *udev, pci_dev_t bdf,
|
||||
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;
|
||||
|
@ -522,6 +522,32 @@
|
||||
|
||||
#include <pci_ids.h>
|
||||
|
||||
/*
|
||||
* Enhanced Configuration Access Mechanism (ECAM)
|
||||
*
|
||||
* See PCI Express Base Specification, Revision 5.0, Version 1.0,
|
||||
* Section 7.2.2, Table 7-1, p. 677.
|
||||
*/
|
||||
#define PCIE_ECAM_BUS_SHIFT 20 /* Bus number */
|
||||
#define PCIE_ECAM_DEV_SHIFT 15 /* Device number */
|
||||
#define PCIE_ECAM_FUNC_SHIFT 12 /* Function number */
|
||||
|
||||
#define PCIE_ECAM_BUS_MASK 0xff
|
||||
#define PCIE_ECAM_DEV_MASK 0x1f
|
||||
#define PCIE_ECAM_FUNC_MASK 0x7
|
||||
#define PCIE_ECAM_REG_MASK 0xfff /* Limit offset to a maximum of 4K */
|
||||
|
||||
#define PCIE_ECAM_BUS(x) (((x) & PCIE_ECAM_BUS_MASK) << PCIE_ECAM_BUS_SHIFT)
|
||||
#define PCIE_ECAM_DEV(x) (((x) & PCIE_ECAM_DEV_MASK) << PCIE_ECAM_DEV_SHIFT)
|
||||
#define PCIE_ECAM_FUNC(x) (((x) & PCIE_ECAM_FUNC_MASK) << PCIE_ECAM_FUNC_SHIFT)
|
||||
#define PCIE_ECAM_REG(x) ((x) & PCIE_ECAM_REG_MASK)
|
||||
|
||||
#define PCIE_ECAM_OFFSET(bus, dev, func, where) \
|
||||
(PCIE_ECAM_BUS(bus) | \
|
||||
PCIE_ECAM_DEV(dev) | \
|
||||
PCIE_ECAM_FUNC(func) | \
|
||||
PCIE_ECAM_REG(where))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <dm/pci.h>
|
||||
|
Loading…
Reference in New Issue
Block a user