--- zzzz-none-000/linux-5.4.213/drivers/pci/controller/dwc/pcie-designware-host.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/drivers/pci/controller/dwc/pcie-designware-host.c 2024-05-29 11:19:59.000000000 +0000 @@ -18,7 +18,7 @@ #include "../../pci.h" #include "pcie-designware.h" -static struct pci_ops dw_pcie_ops; +struct pci_ops dw_pcie_ops; static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val) @@ -277,7 +277,7 @@ return 0; } -void dw_pcie_free_msi(struct pcie_port *pp) +static void dw_pcie_free_msi(struct pcie_port *pp) { if (pp->msi_irq) { irq_set_chained_handler(pp->msi_irq, NULL); @@ -291,12 +291,15 @@ __free_page(pp->msi_page); } -void dw_pcie_msi_init(struct pcie_port *pp) +static void dw_pcie_msi_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct device *dev = pci->dev; u64 msi_target; + if (!pci_msi_enabled() || !pp->has_msi_ctrl) + return; + pp->msi_page = alloc_page(GFP_KERNEL); pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE, DMA_FROM_DEVICE); @@ -304,7 +307,6 @@ dev_err(dev, "Failed to map MSI data\n"); __free_page(pp->msi_page); pp->msi_page = NULL; - return; } msi_target = (u64)pp->msi_data; @@ -314,7 +316,6 @@ dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, upper_32_bits(msi_target)); } -EXPORT_SYMBOL_GPL(dw_pcie_msi_init); int dw_pcie_host_init(struct pcie_port *pp) { @@ -333,10 +334,8 @@ cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (cfg_res) { - pp->cfg0_size = resource_size(cfg_res) >> 1; - pp->cfg1_size = resource_size(cfg_res) >> 1; + pp->cfg0_size = resource_size(cfg_res); pp->cfg0_base = cfg_res->start; - pp->cfg1_base = cfg_res->start + pp->cfg0_size; } else if (!pp->va_cfg0_base) { dev_err(dev, "Missing *config* reg space\n"); } @@ -378,11 +377,18 @@ pp->mem_bus_addr = pp->mem->start - win->offset; break; case 0: - pp->cfg = win->res; - pp->cfg0_size = resource_size(pp->cfg) >> 1; - pp->cfg1_size = resource_size(pp->cfg) >> 1; - pp->cfg0_base = pp->cfg->start; - pp->cfg1_base = pp->cfg->start + pp->cfg0_size; + dev_err(dev, "Missing *config* reg space\n"); + pp->cfg0_size = resource_size(win->res); + pp->cfg0_base = win->res->start; + if (!pci->dbi_base) { + pci->dbi_base = devm_pci_remap_cfgspace(dev, + pp->cfg0_base, + pp->cfg0_size); + if (!pci->dbi_base) { + dev_err(dev, "Error with ioremap\n"); + return -ENOMEM; + } + } break; case IORESOURCE_BUS: pp->busn = win->res; @@ -390,16 +396,6 @@ } } - if (!pci->dbi_base) { - pci->dbi_base = devm_pci_remap_cfgspace(dev, - pp->cfg->start, - resource_size(pp->cfg)); - if (!pci->dbi_base) { - dev_err(dev, "Error with ioremap\n"); - return -ENOMEM; - } - } - pp->mem_base = pp->mem->start; if (!pp->va_cfg0_base) { @@ -411,21 +407,14 @@ } } - if (!pp->va_cfg1_base) { - pp->va_cfg1_base = devm_pci_remap_cfgspace(dev, - pp->cfg1_base, - pp->cfg1_size); - if (!pp->va_cfg1_base) { - dev_err(dev, "Error with ioremap\n"); - return -ENOMEM; - } - } - ret = of_property_read_u32(np, "num-viewport", &pci->num_viewport); if (ret) pci->num_viewport = 2; if (pci_msi_enabled()) { + pp->has_msi_ctrl = !(pp->ops->msi_host_init || + of_property_read_bool(np, "msi-parent") || + of_property_read_bool(np, "msi-map")); /* * If a specific SoC driver needs to change the * default number of vectors, it needs to implement @@ -444,21 +433,30 @@ } } - if (!pp->ops->msi_host_init) { + if (pp->ops->msi_host_init) { + ret = pp->ops->msi_host_init(pp); + if (ret < 0) + return ret; + } else if (pp->has_msi_ctrl) { + if (!pp->msi_irq) { + pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi"); + if (pp->msi_irq < 0) { + pp->msi_irq = platform_get_irq(pdev, 0); + if (pp->msi_irq < 0) + return pp->msi_irq; + } + } + pp->msi_irq_chip = &dw_pci_msi_bottom_irq_chip; ret = dw_pcie_allocate_domains(pp); if (ret) return ret; - if (pp->msi_irq) + if (pp->msi_irq > 0) irq_set_chained_handler_and_data(pp->msi_irq, dw_chained_msi_isr, pp); - } else { - ret = pp->ops->msi_host_init(pp); - if (ret < 0) - return ret; } } @@ -468,6 +466,8 @@ goto err_free_msi; } + dw_pcie_msi_init(pp); + ret = dw_pcie_rd_own_conf(pp, PCI_HEADER_TYPE, 1, &hdr_type); if (ret != PCIBIOS_SUCCESSFUL) { dev_err(pci->dev, "Failed reading PCI_HEADER_TYPE cfg space reg (ret: 0x%x)\n", @@ -511,7 +511,7 @@ return 0; err_free_msi: - if (pci_msi_enabled() && !pp->ops->msi_host_init) + if (pp->has_msi_ctrl) dw_pcie_free_msi(pp); return ret; } @@ -521,7 +521,7 @@ { pci_stop_root_bus(pp->root_bus); pci_remove_root_bus(pp->root_bus); - if (pci_msi_enabled() && !pp->ops->msi_host_init) + if (pp->has_msi_ctrl) dw_pcie_free_msi(pp); } EXPORT_SYMBOL_GPL(dw_pcie_host_deinit); @@ -531,33 +531,24 @@ bool write) { int ret, type; - u32 busdev, cfg_size; - u64 cpu_addr; - void __iomem *va_cfg_base; + u32 busdev; struct dw_pcie *pci = to_dw_pcie_from_pp(pp); busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | PCIE_ATU_FUNC(PCI_FUNC(devfn)); - if (bus->parent->number == pp->root_bus_nr) { + if (bus->parent->number == pp->root_bus_nr) type = PCIE_ATU_TYPE_CFG0; - cpu_addr = pp->cfg0_base; - cfg_size = pp->cfg0_size; - va_cfg_base = pp->va_cfg0_base; - } else { + else type = PCIE_ATU_TYPE_CFG1; - cpu_addr = pp->cfg1_base; - cfg_size = pp->cfg1_size; - va_cfg_base = pp->va_cfg1_base; - } dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, - type, cpu_addr, - busdev, cfg_size); + type, pp->cfg0_base, + busdev, pp->cfg0_size); if (write) - ret = dw_pcie_write(va_cfg_base + where, size, *val); + ret = dw_pcie_write(pp->va_cfg0_base + where, size, *val); else - ret = dw_pcie_read(va_cfg_base + where, size, val); + ret = dw_pcie_read(pp->va_cfg0_base + where, size, val); if (pci->num_viewport <= 2) dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, @@ -637,7 +628,7 @@ return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val); } -static struct pci_ops dw_pcie_ops = { +struct pci_ops dw_pcie_ops = { .read = dw_pcie_rd_conf, .write = dw_pcie_wr_conf, }; @@ -655,7 +646,7 @@ dw_pcie_setup(pci); - if (!pp->ops->msi_host_init) { + if (pp->has_msi_ctrl) { num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; /* Initialize IRQ Status array */