/** * Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, unsigned int devfn, int where) { struct iproc_pcie *pcie = iproc_data(bus); unsigned slot = PCI_SLOT(devfn); unsigned fn = PCI_FUNC(devfn); unsigned busno = bus->number; u32 val; u16 offset; /* root complex access */ if (busno == 0) { if (slot > 0 || fn > 0) return NULL; iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR, where & CFG_IND_ADDR_MASK); offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA); if (iproc_pcie_reg_is_invalid(offset)) return NULL; else return (pcie->base + offset); } /* * PAXC is connected to an internally emulated EP within the SoC. It * allows only one device. */ if (pcie->type == IPROC_PCIE_PAXC) if (slot > 0) return NULL; /* EP device access */ val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | (slot << CFG_ADDR_DEV_NUM_SHIFT) | (fn << CFG_ADDR_FUNC_NUM_SHIFT) | (where & CFG_ADDR_REG_NUM_MASK) | (1 & CFG_ADDR_CFG_TYPE_MASK); iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); if (iproc_pcie_reg_is_invalid(offset)) return NULL; else return (pcie->base + offset); }
static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie, enum iproc_pcie_reg reg) { u16 offset = iproc_pcie_reg_offset(pcie, reg); if (iproc_pcie_reg_is_invalid(offset)) return 0; return readl(pcie->base + offset); }
static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie, enum iproc_pcie_reg reg, u32 val) { u16 offset = iproc_pcie_reg_offset(pcie, reg); if (iproc_pcie_reg_is_invalid(offset)) return; writel(val, pcie->base + offset); }
static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie, enum iproc_pcie_reg reg, unsigned window, u32 val) { u16 offset = iproc_pcie_reg_offset(pcie, reg); if (iproc_pcie_reg_is_invalid(offset)) return; writel(val, pcie->base + offset + (window * 8)); }
/** * Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, unsigned int devfn, int where) { struct iproc_pcie *pcie = iproc_data(bus); unsigned slot = PCI_SLOT(devfn); unsigned fn = PCI_FUNC(devfn); unsigned busno = bus->number; u32 val; u16 offset; if (!iproc_pcie_device_is_valid(pcie, slot, fn)) return NULL; /* root complex access */ if (busno == 0) { iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR, where & CFG_IND_ADDR_MASK); offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA); if (iproc_pcie_reg_is_invalid(offset)) return NULL; else return (pcie->base + offset); } /* EP device access */ val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | (slot << CFG_ADDR_DEV_NUM_SHIFT) | (fn << CFG_ADDR_FUNC_NUM_SHIFT) | (where & CFG_ADDR_REG_NUM_MASK) | (1 & CFG_ADDR_CFG_TYPE_MASK); iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); if (iproc_pcie_reg_is_invalid(offset)) return NULL; else return (pcie->base + offset); }