X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Flayerscape%2Fpatches-4.9%2F702-pci-support-layerscape.patch;h=3d7febcebb6e4d170c4a6da204b57dd5e1869e9e;hp=c3dcd73b6029dd4a369974bab797e55a17571c98;hb=aed03d5d0f304cc85a8ccb4ef98684703fc027af;hpb=8fdda1cc1033e2bd0d048188af5167faffbf9b38 diff --git a/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch b/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch index c3dcd73b60..3d7febcebb 100644 --- a/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.9/702-pci-support-layerscape.patch @@ -1,9 +1,9 @@ -From c4813da334b0c31e9c55eea015f1e898e84ff45b Mon Sep 17 00:00:00 2001 +From 5fcb42fbd224e1103bacbae4785745842cfd6304 Mon Sep 17 00:00:00 2001 From: Yangbo Lu -Date: Mon, 25 Sep 2017 11:04:10 +0800 -Subject: [PATCH] pci: support layerscape +Date: Wed, 17 Jan 2018 15:00:43 +0800 +Subject: [PATCH 08/30] pci: support layerscape -This is a integrated patch for layerscape pcie support. +This is an integrated patch for layerscape pcie support. Signed-off-by: Po Liu Signed-off-by: Liu Gang @@ -15,23 +15,23 @@ Signed-off-by: Mingkai Hu Signed-off-by: Christoph Hellwig Signed-off-by: Yangbo Lu --- - drivers/irqchip/irq-ls-scfg-msi.c | 256 +++++++-- + drivers/irqchip/irq-ls-scfg-msi.c | 257 +++++++-- drivers/pci/host/Makefile | 2 +- drivers/pci/host/pci-layerscape-ep-debugfs.c | 758 +++++++++++++++++++++++++++ drivers/pci/host/pci-layerscape-ep.c | 309 +++++++++++ drivers/pci/host/pci-layerscape-ep.h | 115 ++++ - drivers/pci/host/pci-layerscape.c | 37 +- + drivers/pci/host/pci-layerscape.c | 48 +- drivers/pci/host/pcie-designware.c | 6 + drivers/pci/host/pcie-designware.h | 1 + + drivers/pci/pci.c | 2 +- drivers/pci/pcie/portdrv_core.c | 181 +++---- + drivers/pci/quirks.c | 8 + include/linux/pci.h | 1 + - 10 files changed, 1518 insertions(+), 148 deletions(-) + 12 files changed, 1539 insertions(+), 149 deletions(-) create mode 100644 drivers/pci/host/pci-layerscape-ep-debugfs.c create mode 100644 drivers/pci/host/pci-layerscape-ep.c create mode 100644 drivers/pci/host/pci-layerscape-ep.h -diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c -index 02cca74c..119f4ef0 100644 --- a/drivers/irqchip/irq-ls-scfg-msi.c +++ b/drivers/irqchip/irq-ls-scfg-msi.c @@ -17,13 +17,32 @@ @@ -84,7 +84,7 @@ index 02cca74c..119f4ef0 100644 }; static struct irq_chip ls_scfg_msi_irq_chip = { -@@ -49,19 +71,56 @@ static struct msi_domain_info ls_scfg_msi_domain_info = { +@@ -49,19 +71,56 @@ static struct msi_domain_info ls_scfg_ms .chip = &ls_scfg_msi_irq_chip, }; @@ -143,7 +143,7 @@ index 02cca74c..119f4ef0 100644 } static struct irq_chip ls_scfg_msi_parent_chip = { -@@ -81,8 +140,8 @@ static int ls_scfg_msi_domain_irq_alloc(struct irq_domain *domain, +@@ -81,8 +140,8 @@ static int ls_scfg_msi_domain_irq_alloc( WARN_ON(nr_irqs != 1); spin_lock(&msi_data->lock); @@ -154,7 +154,7 @@ index 02cca74c..119f4ef0 100644 __set_bit(pos, msi_data->used); else err = -ENOSPC; -@@ -106,7 +165,7 @@ static void ls_scfg_msi_domain_irq_free(struct irq_domain *domain, +@@ -106,7 +165,7 @@ static void ls_scfg_msi_domain_irq_free( int pos; pos = d->hwirq; @@ -163,7 +163,7 @@ index 02cca74c..119f4ef0 100644 pr_err("failed to teardown msi. Invalid hwirq %d\n", pos); return; } -@@ -123,15 +182,22 @@ static const struct irq_domain_ops ls_scfg_msi_domain_ops = { +@@ -123,15 +182,22 @@ static const struct irq_domain_ops ls_sc static void ls_scfg_msi_irq_handler(struct irq_desc *desc) { @@ -191,7 +191,7 @@ index 02cca74c..119f4ef0 100644 if (virq) generic_handle_irq(virq); } -@@ -143,7 +209,7 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data) +@@ -143,7 +209,7 @@ static int ls_scfg_msi_domains_init(stru { /* Initialize MSI domain parent */ msi_data->parent = irq_domain_add_linear(NULL, @@ -200,7 +200,7 @@ index 02cca74c..119f4ef0 100644 &ls_scfg_msi_domain_ops, msi_data); if (!msi_data->parent) { -@@ -164,16 +230,117 @@ static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data) +@@ -164,16 +230,118 @@ static int ls_scfg_msi_domains_init(stru return 0; } @@ -290,6 +290,7 @@ index 02cca74c..119f4ef0 100644 + { .compatible = "fsl,1s1021a-msi", .data = &ls1021_msi_cfg}, + { .compatible = "fsl,1s1043a-msi", .data = &ls1021_msi_cfg}, + ++ { .compatible = "fsl,ls1012a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1021a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1043a-msi", .data = &ls1021_msi_cfg }, + { .compatible = "fsl,ls1043a-v1.1-msi", .data = &ls1043_v1_1_msi_cfg }, @@ -319,7 +320,7 @@ index 02cca74c..119f4ef0 100644 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); msi_data->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(msi_data->regs)) { -@@ -182,23 +349,48 @@ static int ls_scfg_msi_probe(struct platform_device *pdev) +@@ -182,23 +350,48 @@ static int ls_scfg_msi_probe(struct plat } msi_data->msiir_addr = res->start; @@ -378,7 +379,7 @@ index 02cca74c..119f4ef0 100644 platform_set_drvdata(pdev, msi_data); return 0; -@@ -207,8 +399,10 @@ static int ls_scfg_msi_probe(struct platform_device *pdev) +@@ -207,8 +400,10 @@ static int ls_scfg_msi_probe(struct plat static int ls_scfg_msi_remove(struct platform_device *pdev) { struct ls_scfg_msi *msi_data = platform_get_drvdata(pdev); @@ -390,7 +391,7 @@ index 02cca74c..119f4ef0 100644 irq_domain_remove(msi_data->msi_domain); irq_domain_remove(msi_data->parent); -@@ -218,12 +412,6 @@ static int ls_scfg_msi_remove(struct platform_device *pdev) +@@ -218,12 +413,6 @@ static int ls_scfg_msi_remove(struct pla return 0; } @@ -403,11 +404,9 @@ index 02cca74c..119f4ef0 100644 static struct platform_driver ls_scfg_msi_driver = { .driver = { .name = "ls-scfg-msi", -diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile -index 084cb498..88e87704 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile -@@ -17,7 +17,7 @@ obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o +@@ -17,7 +17,7 @@ obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o obj-$(CONFIG_PCI_XGENE) += pci-xgene.o obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o @@ -416,9 +415,6 @@ index 084cb498..88e87704 100644 obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o -diff --git a/drivers/pci/host/pci-layerscape-ep-debugfs.c b/drivers/pci/host/pci-layerscape-ep-debugfs.c -new file mode 100644 -index 00000000..5f4870ba --- /dev/null +++ b/drivers/pci/host/pci-layerscape-ep-debugfs.c @@ -0,0 +1,758 @@ @@ -1180,9 +1176,6 @@ index 00000000..5f4870ba +MODULE_AUTHOR("Minghuan Lian "); +MODULE_DESCRIPTION("Freescale Layerscape PCIe EP controller driver"); +MODULE_LICENSE("GPL v2"); -diff --git a/drivers/pci/host/pci-layerscape-ep.c b/drivers/pci/host/pci-layerscape-ep.c -new file mode 100644 -index 00000000..8f1cca6e --- /dev/null +++ b/drivers/pci/host/pci-layerscape-ep.c @@ -0,0 +1,309 @@ @@ -1495,9 +1488,6 @@ index 00000000..8f1cca6e +MODULE_AUTHOR("Minghuan Lian "); +MODULE_DESCRIPTION("Freescale Layerscape PCIe EP driver"); +MODULE_LICENSE("GPL v2"); -diff --git a/drivers/pci/host/pci-layerscape-ep.h b/drivers/pci/host/pci-layerscape-ep.h -new file mode 100644 -index 00000000..990c0ff5 --- /dev/null +++ b/drivers/pci/host/pci-layerscape-ep.h @@ -0,0 +1,115 @@ @@ -1616,12 +1606,14 @@ index 00000000..990c0ff5 +int ls_pcie_ep_dbgfs_remove(struct ls_pcie *pcie); + +#endif /* _PCIE_LAYERSCAPE_EP_H */ -diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c -index 65370799..4713b872 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c -@@ -35,12 +35,14 @@ +@@ -33,14 +33,18 @@ + + /* PEX Internal Configuration Registers */ #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */ ++#define PCIE_ABSERR 0x8d0 /* Bridge Slave Error Response Register */ ++#define PCIE_ABSERR_SETTING 0x9401 /* Forward error of non-posted request */ #define PCIE_DBI_RO_WR_EN 0x8bc /* DBI Read-Only Write Enable Register */ -/* PEX LUT registers */ @@ -1637,7 +1629,7 @@ index 65370799..4713b872 100644 struct pcie_host_ops *ops; }; -@@ -86,6 +88,14 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie) +@@ -86,6 +90,14 @@ static void ls_pcie_drop_msg_tlp(struct iowrite32(val, pcie->pp.dbi_base + PCIE_STRFMR1); } @@ -1652,7 +1644,7 @@ index 65370799..4713b872 100644 static int ls1021_pcie_link_up(struct pcie_port *pp) { u32 state; -@@ -134,7 +144,7 @@ static int ls_pcie_link_up(struct pcie_port *pp) +@@ -134,7 +146,7 @@ static int ls_pcie_link_up(struct pcie_p struct ls_pcie *pcie = to_ls_pcie(pp); u32 state; @@ -1661,17 +1653,31 @@ index 65370799..4713b872 100644 pcie->drvdata->ltssm_shift) & LTSSM_STATE_MASK; -@@ -153,6 +163,9 @@ static void ls_pcie_host_init(struct pcie_port *pp) +@@ -144,6 +156,12 @@ static int ls_pcie_link_up(struct pcie_p + return 1; + } + ++/* Forward error response of outbound non-posted requests */ ++static void ls_pcie_fix_error_response(struct ls_pcie *pcie) ++{ ++ iowrite32(PCIE_ABSERR_SETTING, pcie->pp.dbi_base + PCIE_ABSERR); ++} ++ + static void ls_pcie_host_init(struct pcie_port *pp) + { + struct ls_pcie *pcie = to_ls_pcie(pp); +@@ -153,6 +171,10 @@ static void ls_pcie_host_init(struct pci ls_pcie_clear_multifunction(pcie); ls_pcie_drop_msg_tlp(pcie); iowrite32(0, pcie->pp.dbi_base + PCIE_DBI_RO_WR_EN); + + ls_pcie_disable_outbound_atus(pcie); ++ ls_pcie_fix_error_response(pcie); + dw_pcie_setup_rc(pp); } static int ls_pcie_msi_host_init(struct pcie_port *pp, -@@ -196,20 +209,38 @@ static struct ls_pcie_drvdata ls1021_drvdata = { +@@ -196,20 +218,40 @@ static struct ls_pcie_drvdata ls1021_drv static struct ls_pcie_drvdata ls1043_drvdata = { .lut_offset = 0x10000, .ltssm_shift = 24, @@ -1701,20 +1707,20 @@ index 65370799..4713b872 100644 }; static const struct of_device_id ls_pcie_of_match[] = { ++ { .compatible = "fsl,ls1012a-pcie", .data = &ls1046_drvdata }, { .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata }, { .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata }, + { .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata }, { .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata }, { .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata }, + { .compatible = "fsl,ls2088a-pcie", .data = &ls2088_drvdata }, ++ { .compatible = "fsl,ls1088a-pcie", .data = &ls2088_drvdata }, { }, }; -diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c -index af8f6e92..2358e049 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c -@@ -478,6 +478,12 @@ int dw_pcie_wait_for_link(struct pcie_port *pp) +@@ -478,6 +478,12 @@ int dw_pcie_wait_for_link(struct pcie_po return -ETIMEDOUT; } @@ -1727,22 +1733,29 @@ index af8f6e92..2358e049 100644 int dw_pcie_link_up(struct pcie_port *pp) { u32 val; -diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h -index a567ea28..4e6672b2 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h -@@ -82,5 +82,6 @@ int dw_pcie_wait_for_link(struct pcie_port *pp); +@@ -82,5 +82,6 @@ int dw_pcie_wait_for_link(struct pcie_po int dw_pcie_link_up(struct pcie_port *pp); void dw_pcie_setup_rc(struct pcie_port *pp); int dw_pcie_host_init(struct pcie_port *pp); +void dw_pcie_disable_outbound_atu(struct pcie_port *pp, int index); #endif /* _PCIE_DESIGNWARE_H */ -diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c -index e9270b40..1bad877a 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -454,7 +454,7 @@ struct resource *pci_find_parent_resourc + pci_bus_for_each_resource(bus, r, i) { + if (!r) + continue; +- if (res->start && resource_contains(r, res)) { ++ if (resource_contains(r, res)) { + + /* + * If the window is prefetchable but the BAR is --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c -@@ -44,52 +44,30 @@ static void release_pcie_device(struct device *dev) +@@ -44,52 +44,30 @@ static void release_pcie_device(struct d } /** @@ -1806,7 +1819,7 @@ index e9270b40..1bad877a 100644 /* * Allocate as many entries as the port wants, so that we can check -@@ -97,20 +75,13 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) +@@ -97,20 +75,13 @@ static int pcie_port_enable_msix(struct * equal to the number of entries this port actually uses, we'll happily * go through without any tricks. */ @@ -1832,7 +1845,7 @@ index e9270b40..1bad877a 100644 /* * The code below follows the PCI Express Base Specification 2.0 -@@ -125,18 +96,16 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) +@@ -125,18 +96,16 @@ static int pcie_port_enable_msix(struct pcie_capability_read_word(dev, PCI_EXP_FLAGS, ®16); entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9; if (entry >= nr_entries) @@ -1856,7 +1869,7 @@ index e9270b40..1bad877a 100644 /* * The code below follows Section 7.10.10 of the PCI Express -@@ -151,13 +120,11 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) +@@ -151,13 +120,11 @@ static int pcie_port_enable_msix(struct pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, ®32); entry = reg32 >> 27; if (entry >= nr_entries) @@ -1873,7 +1886,7 @@ index e9270b40..1bad877a 100644 } /* -@@ -165,41 +132,54 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) +@@ -165,41 +132,54 @@ static int pcie_port_enable_msix(struct * what we have. Otherwise, the port has some extra entries not for the * services we know and we need to work around that. */ @@ -1947,7 +1960,7 @@ index e9270b40..1bad877a 100644 /* * If MSI cannot be used for PCIe PME or hotplug, we have to use -@@ -207,41 +187,25 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) +@@ -207,41 +187,25 @@ static int init_service_irqs(struct pci_ */ if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) || ((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) { @@ -2001,7 +2014,7 @@ index e9270b40..1bad877a 100644 /** * get_port_device_capability - discover capabilities of a PCI Express port * @dev: PCI Express port to examine -@@ -378,7 +342,7 @@ int pcie_port_device_register(struct pci_dev *dev) +@@ -378,7 +342,7 @@ int pcie_port_device_register(struct pci * that can be used in the absence of irqs. Allow them to determine * if that is to be used. */ @@ -2010,7 +2023,7 @@ index e9270b40..1bad877a 100644 if (status) { capabilities &= PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_HP; if (!capabilities) -@@ -401,7 +365,7 @@ int pcie_port_device_register(struct pci_dev *dev) +@@ -401,7 +365,7 @@ int pcie_port_device_register(struct pci return 0; error_cleanup_irqs: @@ -2019,7 +2032,7 @@ index e9270b40..1bad877a 100644 error_disable: pci_disable_device(dev); return status; -@@ -469,7 +433,7 @@ static int remove_iter(struct device *dev, void *data) +@@ -469,7 +433,7 @@ static int remove_iter(struct device *de void pcie_port_device_remove(struct pci_dev *dev) { device_for_each_child(&dev->dev, NULL, remove_iter); @@ -2028,7 +2041,7 @@ index e9270b40..1bad877a 100644 pci_disable_device(dev); } -@@ -499,7 +463,6 @@ static int pcie_port_probe_service(struct device *dev) +@@ -499,7 +463,6 @@ static int pcie_port_probe_service(struc if (status) return status; @@ -2036,7 +2049,7 @@ index e9270b40..1bad877a 100644 get_device(dev); return 0; } -@@ -524,8 +487,6 @@ static int pcie_port_remove_service(struct device *dev) +@@ -524,8 +487,6 @@ static int pcie_port_remove_service(stru pciedev = to_pcie_device(dev); driver = to_service_driver(dev->driver); if (driver && driver->remove) { @@ -2045,11 +2058,23 @@ index e9270b40..1bad877a 100644 driver->remove(pciedev); put_device(dev); } -diff --git a/include/linux/pci.h b/include/linux/pci.h -index 1b711796..6738d816 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4654,3 +4654,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IN + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid); ++ ++/* Freescale PCIe doesn't support MSI in RC mode */ ++static void quirk_fsl_no_msi(struct pci_dev *pdev) ++{ ++ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) ++ pdev->no_msi = 1; ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi); --- a/include/linux/pci.h +++ b/include/linux/pci.h -@@ -1823,6 +1823,7 @@ void pcibios_release_device(struct pci_dev *dev); +@@ -1823,6 +1823,7 @@ void pcibios_release_device(struct pci_d void pcibios_penalize_isa_irq(int irq, int active); int pcibios_alloc_irq(struct pci_dev *dev); void pcibios_free_irq(struct pci_dev *dev); @@ -2057,6 +2082,3 @@ index 1b711796..6738d816 100644 #ifdef CONFIG_HIBERNATE_CALLBACKS extern struct dev_pm_ops pcibios_pm_ops; --- -2.14.1 -