PCI: Layerscape: Add Layerscape PCIe driver
PATCH v6 1/1 PCI: Layerscape: Add Layerscape PCIe driver
Add support for Freescale Layerscape PCIe controller. This driver re-uses the designware core code.
---
Based on pci-next branch
Change log:
v6:
1. remove MSI support. MSI driver will be implemented in a separate file
2. remove bitrev() because SCFG is set bit reverse mode as default.
v5:
1. Add MAINTAINERS information
2. Remove unnecessary NULL pointer check
3. Use dev_dbg instead of dev_err in ls_pcie_msi_irq_handler()
v4:
1. Add 'depends on OF' to Kconfig
v3:
1. Add prefechable mem region and adjust mem region
2. Rename 'pcie-scfg' to 'fsl,pcie-scfg'
3. Change MSI interrupt handler
4. Use module_platform_driver_probe instead of subsys_initcall
v2:
1. Add pcie-scfg to link scfg device node and remove "fsl, ls-pcie" compatible
2. Use regmap API to access scfg.
3. remove ls1021 PCI device ID.
4. remove unused irq pme_irq and ls_pcie_list.
5. Do not set scfg bit reverse mode
.../devicetree/bindings/pci/layerscape-pci.txt | 42 +++++ MAINTAINERS | 10 ++ drivers/pci/host/Kconfig | 8 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-layerscape.c | 179 +++++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci.txt create mode 100644 drivers/pci/host/pci-layerscape.c
Documentation/devicetree/bindings/pci/layerscape-pci.txt new file +42 -0
@@ -0,0 +1,42 @@ +Freescale Layerscape PCIe controller + +This PCIe host controller is based on the Synopsis Designware PCIe IP +and thus inherits all the common properties defined in designware-pcie.txt. + +Required properties: +- compatible: should contain the platform identifier such as "fsl,ls1021a-pcie" +- reg: base addresses and lengths of the PCIe controller +- interrupts: A list of interrupt outputs of the controller. Must contain an + entry for each entry in the interrupt-names property. +- interrupt-names: Must include the following entries: + "intr": The interrupt that is asserted for controller interrupts +- fsl,pcie-scfg: Must include two entries. + The first entry must be a link to the SCFG device node + The second entry must be '0' or '1' based on physical PCIe controller index. + used to get SCFG PEXN registers + +Example: + + pcie@3400000 { + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; + reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ + 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + fsl,pcie-scfg = <&scfg 0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + num-lanes = <4>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0xc2000000 0x0 0x20000000 0x40 0x20000000 0x0 0x20000000 /* prefetchable memory */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + };
MAINTAINERS +10 -0
@@ -6983,6 +6983,16 @@ S: Maintained F: Documentation/devicetree/bindings/pci/xgene-pci.txt F: drivers/pci/host/pci-xgene.c +PCIe DRIVER FOR FREESCALE LAYERSCAPE +M: Minghuan Lian <[email protected]> +M: Mingkai Hu <[email protected]> +M: Roy Zang <[email protected]> +L: [email protected] +L: [email protected] +L: [email protected] +S: Maintained +F: drivers/pci/host/pci-layerscape.c + PCI DRIVER FOR IMX6 M: Richard Zhu <[email protected]> M: Lucas Stach <[email protected]>
drivers/pci/host/Kconfig +8 -0
@@ -91,4 +91,12 @@ config PCI_XGENE There are 5 internal PCIe ports available. Each port is GEN3 capable and have varied lanes from x1 to x8. +config PCI_LAYERSCAPE + bool "Freescale Layerscape PCIe controller" + depends on OF + select PCIE_DW + select MFD_SYSCON + help + Say Y here if you want PCIe controller support on Layerscape SoCs. + endmenu
drivers/pci/host/Makefile +1 -0
@@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o obj-$(CONFIG_PCI_XGENE) += pci-xgene.o +obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
drivers/pci/host/pci-layerscape.c new file +179 -0
179 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v6 1/1 PCI: Layerscape: Add Layerscape PCIe driver
Quoted 5 lines · On Wednesday 05 November 2014 16:45:11 Minghuan Lian wrote:
Add support for Freescale Layerscape PCIe controller. This driver re-uses the designware core code.
Signed-off-by Minghuan Lian <[email protected]>
Bjorn Helgaas
maintainerPATCH v6 1/1 PCI: Layerscape: Add Layerscape PCIe driver
In reply to Minghuan LianQuoted 4 lines · Minghuan Lian
Add support for Freescale Layerscape PCIe controller. This driver re-uses the designware core code.
Signed-off-by Minghuan Lian <[email protected]>
Applied with Arnd's ack to pci/host-layerscape for v3.19, thanks!
Quoted 321 lines
---
Based on pci-next branchChange log:
v6:
1. remove MSI support. MSI driver will be implemented in a separate file
2. removebitrev()because SCFG is set bit reverse mode as default.v5:
1. AddMAINTAINERSinformation
2. Remove unnecessary NULL pointer check
3. Usedev_dbginstead ofdev_errinls_pcie_msi_irq_handler()v4:
1. Add 'depends on OF' toKconfigv3:
1. Add prefechable mem region and adjust mem region
2. Rename 'pcie-scfg' to 'fsl,pcie-scfg'
3. Change MSI interrupt handler
4. Usemodule_platform_driver_probeinstead ofsubsys_initcallv2:
1. Add pcie-scfg to link scfg device node and remove "fsl, ls-pcie" compatible
2. Use regmap API to access scfg.
3. remove ls1021 PCI device ID.
4. remove unused irqpme_irqandls_pcie_list.
5. Do not set scfg bit reverse mode.../devicetree/bindings/pci/layerscape-pci.txt | 42 +++++ MAINTAINERS | 10 ++ drivers/pci/host/Kconfig | 8 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-layerscape.c | 179 +++++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci.txt create mode 100644 drivers/pci/host/pci-layerscape.cDocumentation/devicetree/bindings/pci/layerscape-pci.txt new file +42
-0@@ -0,0 +1,42 @@ +Freescale Layerscape PCIe controller + +This PCIe host controller is based on the Synopsis Designware PCIe IP +and thus inherits all the common properties defined in designware-pcie.txt. + +Required properties: +- compatible: should contain the platform identifier such as "fsl,ls1021a-pcie" +- reg: base addresses and lengths of the PCIe controller +- interrupts: A list of interrupt outputs of the controller. Must contain an + entry for each entry in the interrupt-names property. +- interrupt-names: Must include the following entries: + "intr": The interrupt that is asserted for controller interrupts +- fsl,pcie-scfg: Must include two entries. + The first entry must be a link to the SCFG device node + The second entry must be '0' or '1' based on physical PCIe controller index. + used to get SCFG PEXN registers + +Example: + + pcie at 3400000 { + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; + reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ + 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + fsl,pcie-scfg = <&scfg 0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + num-lanes = <4>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0xc2000000 0x0 0x20000000 0x40 0x20000000 0x0 0x20000000 /* prefetchable memory */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + };MAINTAINERS +10
-0@@ -6983,6 +6983,16 @@ S: Maintained F: Documentation/devicetree/bindings/pci/xgene-pci.txt F: drivers/pci/host/pci-xgene.c +PCIe DRIVER FOR FREESCALE LAYERSCAPE +M: Minghuan Lian <[email protected]> +M: Mingkai Hu <[email protected]> +M: Roy Zang <[email protected]> +L: linuxppc-dev at lists.ozlabs.org +L: linux-pci at vger.kernel.org +L: linux-arm-kernel at lists.infradead.org +S: Maintained +F: drivers/pci/host/pci-layerscape.c + PCI DRIVER FOR IMX6 M: Richard Zhu <[email protected]> M: Lucas Stach <[email protected]>drivers/pci/host/Kconfig +8
-0@@ -91,4 +91,12 @@ config PCI_XGENE There are 5 internal PCIe ports available. Each port is GEN3 capable and have varied lanes from x1 to x8. +config PCI_LAYERSCAPE + bool "Freescale Layerscape PCIe controller" + depends on OF + select PCIE_DW + select MFD_SYSCON + help + Say Y here if you want PCIe controller support on Layerscape SoCs. + endmenudrivers/pci/host/Makefile +1
-0@@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o obj-$(CONFIG_PCI_XGENE) += pci-xgene.o +obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.odrivers/pci/host/pci-layerscape.c new file +179
-0@@ -0,0 +1,179 @@ +/* +* PCIe host controller driver for Freescale Layerscape SoCs +* +* Copyright (C) 2014 Freescale Semiconductor. +* +* Author: Minghuan Lian <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of_pci.h> +#include <linux/of_platform.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/resource.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> + +#include "pcie-designware.h" + +/* PEX1/2 Misc Ports Status Register */ +#define SCFG_PEXMSCPORTSR (pex_idx) (0x94 + (pex_idx) * 4) +#define LTSSM_STATE_SHIFT 20 +#define LTSSM_STATE_MASK 0x3f +#define LTSSM_PCIE_L0 0x11/* L0 state */ + +/* Symbol Timer Register and Filter Mask Register 1 */ +#define PCIE_STRFMR1 0x71c + +struct ls_pcie { +struct list_head node; +struct device *dev; +struct pci_bus *bus; +void __iomem *dbi; +struct regmap *scfg; +struct pcie_port pp; +int index; +int msi_irq; +}; + +#define to_ls_pcie (x) container_of(x, struct ls_pcie, pp) + +static int ls_pcie_link_up (struct pcie_port *pp) +{ +u32 state; +struct ls_pcie *pcie =to_ls_pcie (pp); + +regmap_read (pcie->scfg,SCFG_PEXMSCPORTSR (pcie->index), &state); + state = (state >>LTSSM_STATE_SHIFT ) <SSM_STATE_MASK ; + +if (state <LTSSM_PCIE_L0 ) +return 0 ; + +return 1 ; +} + +static void ls_pcie_host_init (struct pcie_port *pp) +{ +struct ls_pcie *pcie =to_ls_pcie (pp); +int count =0 ; +u32 val; + +dw_pcie_setup_rc (pp); + +while (!ls_pcie_link_up (pp)) { +usleep_range (100 ,1000 ); + count++; +if (count >=200 ) { +dev_err (pp->dev,"phy link never came up\n" ); +return ; + } + } + +/* +* LS1021A Workaround for internal TKT228622 +* to fix the INTx hang issue +*/ + val =ioread32 (pcie->dbi +PCIE_STRFMR1 ); + val &=0xffff ; +iowrite32 (val, pcie->dbi +PCIE_STRFMR1 ); +} + +static struct pcie_host_ops ls_pcie_host_ops = { + .link_up = ls_pcie_link_up, + .host_init = ls_pcie_host_init, +}; + +static int ls_add_pcie_port (struct ls_pcie *pcie) +{ +struct pcie_port *pp; +int ret; + + pp = &pcie->pp; + pp->dev = pcie->dev; + pp->dbi_base = pcie->dbi; + pp->root_bus_nr =-1 ; + pp->ops = &ls_pcie_host_ops; + + ret =dw_pcie_host_init (pp); +if (ret) { +dev_err (pp->dev,"failed to initialize host\n" ); +return ret; + } + +return 0 ; +} + +static int __init ls_pcie_probe (struct platform_device *pdev) +{ +struct ls_pcie *pcie; +struct resource *dbi_base; +u32 index[2 ]; +int ret; + + pcie =devm_kzalloc (&pdev->dev,sizeof (*pcie),GFP_KERNEL ); +if (!pcie) +return -ENOMEM ; + + pcie->dev = &pdev->dev; + + dbi_base =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"regs" ); +if (!dbi_base) { +dev_err (&pdev->dev,"missing *regs* space\n" ); +return -ENODEV ; + } + + pcie->dbi =devm_ioremap_resource (&pdev->dev, dbi_base); +if (IS_ERR (pcie->dbi)) +return PTR_ERR (pcie->dbi); + + pcie->scfg =syscon_regmap_lookup_by_phandle (pdev->dev.of_node, +"fsl,pcie-scfg" ); +if (IS_ERR (pcie->scfg)) { +dev_err (&pdev->dev,"No syscfg phandle specified\n" ); +return PTR_ERR (pcie->scfg); + } + + ret =of_property_read_u32_array (pdev->dev.of_node, +"fsl,pcie-scfg" , index,2 ); +if (ret) +return ret; + pcie->index = index[1 ]; + + ret =ls_add_pcie_port (pcie); +if (ret <0 ) +return ret; + +platform_set_drvdata (pdev, pcie); + +return 0 ; +} + +static const struct of_device_id ls_pcie_of_match[] = { + { .compatible ="fsl,ls1021a-pcie" }, + { }, +}; +MODULE_DEVICE_TABLE (of, ls_pcie_of_match); + +static struct platform_driver ls_pcie_driver = { + .driver = { + .name ="layerscape-pcie" , + .owner =THIS_MODULE , + .of_match_table = ls_pcie_of_match, + }, +}; + +module_platform_driver_probe (ls_pcie_driver, ls_pcie_probe); + +MODULE_AUTHOR ("Minghuan Lian <[email protected]>" ); +MODULE_DESCRIPTION ("Freescale Layerscape PCIe host controller driver" ); +MODULE_LICENSE ("GPL v2" );Signature · 1 line
1.9.1
PATCH v6 1/1 PCI: Layerscape: Add Layerscape PCIe driver
Quoted 8 lines · On Thursday 13 November 2014 09:38:33 Bjorn Helgaas wrote:
Quoted 4 lines · Minghuan Lian
Add support for Freescale Layerscape PCIe controller. This driver re-uses the designware core code.
Signed-off-by Minghuan Lian <[email protected]>Applied with Arnd's ack to pci/host-layerscape for v3.19, thanks!
the build bot just came back with an error:
make.cross ARCH=xtensa
All error/warnings:
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c:168:52: warning: 'structpci_sys_data' declared inside parameter list
static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
^
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c:168:52: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/pci/host/pcie-designware.c: In function 'sys_to_pcie':
drivers/pci/host/pcie-designware.c:170:12: error: dereferencing pointer to incomplete type
return sys->private_data;
^ drivers/pci/host/pcie-designware.c: At top level:
Quoted 1 line
Quoted 1 line
drivers/pci/host/pcie-designware.c:397:45: warning: 'structpci_sys_data' declared inside parameter list
The new Kconfig symbol evidently needs a 'depends on ARM'.
Arnd