phys_addr_t ks_dw_pcie_get_msi_addr(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); return ks_pcie->app.start + MSI_IRQ; }
void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) { u32 reg_offset, bit_pos; struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); writel(BIT(bit_pos), ks_pcie->va_app_base + MSI0_IRQ_ENABLE_CLR + (reg_offset << 4)); }
void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq) { u32 reg_offset, bit_pos; struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); ks_dw_app_writel(ks_pcie, MSI0_IRQ_ENABLE_CLR + (reg_offset << 4), BIT(bit_pos)); }
int ks_dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); u8 bus_num = bus->number; void __iomem *addr; addr = ks_pcie_cfg_setup(ks_pcie, bus_num, devfn); return dw_pcie_cfg_write(addr + (where & ~0x3), where, size, val); }
int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); u8 bus_num = bus->number; void __iomem *addr; addr = ks_pcie_cfg_setup(ks_pcie, bus_num, devfn); return dw_pcie_read(addr + where, size, val); }
void ks_dw_pcie_msi_irq_ack(int irq, struct pcie_port *pp) { u32 reg_offset, bit_pos; struct keystone_pcie *ks_pcie; struct dw_pcie *pci; pci = to_dw_pcie_from_pp(pp); ks_pcie = to_keystone_pcie(pci); update_reg_offset_bit_pos(irq, ®_offset, &bit_pos); ks_dw_app_writel(ks_pcie, MSI0_IRQ_STATUS + (reg_offset << 4), BIT(bit_pos)); ks_dw_app_writel(ks_pcie, IRQ_EOI, reg_offset + MSI_IRQ_OFFSET); }
static void ks_dw_pcie_msi_irq_ack(struct irq_data *d) { u32 offset, reg_offset, bit_pos; struct keystone_pcie *ks_pcie; unsigned int irq = d->irq; struct msi_desc *msi; struct pcie_port *pp; msi = irq_get_msi_desc(irq); pp = sys_to_pcie(msi->dev->bus->sysdata); ks_pcie = to_keystone_pcie(pp); offset = irq - irq_linear_revmap(pp->irq_domain, 0); update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); writel(BIT(bit_pos), ks_pcie->va_app_base + MSI0_IRQ_STATUS + (reg_offset << 4)); writel(reg_offset + MSI_IRQ_OFFSET, ks_pcie->va_app_base + IRQ_EOI); }
/** * ks_dw_pcie_v3_65_scan_bus() - keystone scan_bus post initialization * * This sets BAR0 to enable inbound access for MSI_IRQ register */ void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp) { struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); /* Configure and set up BAR0 */ ks_dw_pcie_set_dbi_mode(ks_pcie->va_app_base); /* Enable BAR0 */ writel(1, pp->dbi_base + PCI_BASE_ADDRESS_0); writel(SZ_4K - 1, pp->dbi_base + PCI_BASE_ADDRESS_0); ks_dw_pcie_clear_dbi_mode(ks_pcie->va_app_base); /* * For BAR0, just setting bus address for inbound writes (MSI) should * be sufficient. Use physical address to avoid any conflicts. */ writel(ks_pcie->app.start, pp->dbi_base + PCI_BASE_ADDRESS_0); }
int ks_dw_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip) { struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); int i; pp->irq_domain = irq_domain_add_linear(ks_pcie->msi_intc_np, MAX_MSI_IRQS, &ks_dw_pcie_msi_domain_ops, chip); if (!pp->irq_domain) { dev_err(pp->dev, "irq domain init failed\n"); return -ENXIO; } for (i = 0; i < MAX_MSI_IRQS; i++) irq_create_mapping(pp->irq_domain, i); return 0; }
/** * ks_dw_pcie_v3_65_scan_bus() - keystone scan_bus post initialization * * This sets BAR0 to enable inbound access for MSI_IRQ register */ void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); /* Configure and set up BAR0 */ ks_dw_pcie_set_dbi_mode(ks_pcie); /* Enable BAR0 */ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 1); dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, SZ_4K - 1); ks_dw_pcie_clear_dbi_mode(ks_pcie); /* * For BAR0, just setting bus address for inbound writes (MSI) should * be sufficient. Use physical address to avoid any conflicts. */ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, ks_pcie->app.start); }
static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d) { struct keystone_pcie *ks_pcie; unsigned int irq = d->irq; struct msi_desc *msi; struct pcie_port *pp; u32 offset; msi = irq_get_msi_desc(irq); pp = sys_to_pcie(msi->dev->bus->sysdata); ks_pcie = to_keystone_pcie(pp); offset = irq - irq_linear_revmap(pp->irq_domain, 0); /* Mask the end point if PVM implemented */ if (IS_ENABLED(CONFIG_PCI_MSI)) { if (msi->msi_attrib.maskbit) pci_msi_unmask_irq(d); } ks_dw_pcie_msi_set_irq(pp, offset); }
u32 ks_dw_pcie_get_msi_addr(struct pcie_port *pp) { struct keystone_pcie *ks_pcie = to_keystone_pcie(pp); return ks_pcie->app.start + MSI_IRQ; }