* Re: [PATCH v9 2/2] pcie-designware platform driver
2016-02-17 17:46 ` [PATCH RESEND v9 2/2] pcie-designware platform driver Joao Pinto
@ 2016-02-08 21:29 ` kbuild test robot
2016-02-08 23:28 ` Bjorn Helgaas
2016-02-25 16:32 ` [PATCH RESEND " Bjorn Helgaas
2016-02-25 17:01 ` Bjorn Helgaas
2 siblings, 1 reply; 11+ messages in thread
From: kbuild test robot @ 2016-02-08 21:29 UTC (permalink / raw)
To: Joao Pinto
Cc: kbuild-all, Vineet.Gupta1, helgaas, arnd, linux-pci, linux-kernel,
linux-snps-arc, CARLOS.PALMINHA, Alexey.Brodkin, robh+dt,
pawel.moll, mark.rutland, ijc+devicetree, galak, Joao Pinto
[-- Attachment #1: Type: text/plain, Size: 2462 bytes --]
Hi Joao,
[auto build test ERROR on arc/for-next]
[cannot apply to pci/next v4.5-rc3 next-20160208]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Joao-Pinto/PCI-support-added-to-ARC/20160209-014808
base: https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next
config: x86_64-allmodconfig (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
include/linux/compiler.h:228:8: sparse: attribute 'no_sanitize_address': unknown attribute
drivers/pci/host/pcie-designware.c:581:14: sparse: undefined identifier 'pci_has_flag'
drivers/pci/host/pcie-designware.c: In function 'dw_pcie_host_init':
>> drivers/pci/host/pcie-designware.c:581:7: error: implicit declaration of function 'pci_has_flag' [-Werror=implicit-function-declaration]
if (!pci_has_flag(PCI_PROBE_ONLY)) {
^
>> drivers/pci/host/pcie-designware.c:581:20: error: 'PCI_PROBE_ONLY' undeclared (first use in this function)
if (!pci_has_flag(PCI_PROBE_ONLY)) {
^
drivers/pci/host/pcie-designware.c:581:20: note: each undeclared identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
vim +/pci_has_flag +581 drivers/pci/host/pcie-designware.c
cbce7900 Zhou Wang 2015-10-29 575
cbce7900 Zhou Wang 2015-10-29 576 #ifdef CONFIG_ARM
cbce7900 Zhou Wang 2015-10-29 577 /* support old dtbs that incorrectly describe IRQs */
cbce7900 Zhou Wang 2015-10-29 578 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
0815f957 Yijing Wang 2014-11-11 579 #endif
0815f957 Yijing Wang 2014-11-11 580
cbce7900 Zhou Wang 2015-10-29 @581 if (!pci_has_flag(PCI_PROBE_ONLY)) {
cbce7900 Zhou Wang 2015-10-29 582 pci_bus_size_bridges(bus);
cbce7900 Zhou Wang 2015-10-29 583 pci_bus_assign_resources(bus);
4b1ced84 Jingoo Han 2013-07-31 584
:::::: The code at line 581 was first introduced by commit
:::::: cbce7900598c26a12652f8ca9c41c5b29034c38d PCI: designware: Make driver arch-agnostic
:::::: TO: Zhou Wang <wangzhou1@hisilicon.com>
:::::: CC: Bjorn Helgaas <bhelgaas@google.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 51059 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 2/2] pcie-designware platform driver
2016-02-08 21:29 ` [PATCH " kbuild test robot
@ 2016-02-08 23:28 ` Bjorn Helgaas
2016-02-10 9:48 ` Joao Pinto
0 siblings, 1 reply; 11+ messages in thread
From: Bjorn Helgaas @ 2016-02-08 23:28 UTC (permalink / raw)
To: kbuild test robot
Cc: Joao Pinto, kbuild-all, Vineet.Gupta1, arnd, linux-pci,
linux-kernel, linux-snps-arc, CARLOS.PALMINHA, Alexey.Brodkin,
robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
On Tue, Feb 09, 2016 at 05:29:15AM +0800, kbuild test robot wrote:
> Hi Joao,
>
> [auto build test ERROR on arc/for-next]
> [cannot apply to pci/next v4.5-rc3 next-20160208]
> [if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
>
> url: https://github.com/0day-ci/linux/commits/Joao-Pinto/PCI-support-added-to-ARC/20160209-014808
> base: https://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc for-next
> config: x86_64-allmodconfig (attached as .config)
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
> include/linux/compiler.h:228:8: sparse: attribute 'no_sanitize_address': unknown attribute
> drivers/pci/host/pcie-designware.c:581:14: sparse: undefined identifier 'pci_has_flag'
> drivers/pci/host/pcie-designware.c: In function 'dw_pcie_host_init':
> >> drivers/pci/host/pcie-designware.c:581:7: error: implicit declaration of function 'pci_has_flag' [-Werror=implicit-function-declaration]
> if (!pci_has_flag(PCI_PROBE_ONLY)) {
> ^
> >> drivers/pci/host/pcie-designware.c:581:20: error: 'PCI_PROBE_ONLY' undeclared (first use in this function)
> if (!pci_has_flag(PCI_PROBE_ONLY)) {
> ^
> drivers/pci/host/pcie-designware.c:581:20: note: each undeclared identifier is reported only once for each function it appears in
> cc1: some warnings being treated as errors
I have fixes for this on my pci/misc branch, so you don't need to
worry about these errors. Basically I'm moving the PCI_PROBE_ONLY and
pci_has_flag() declarations from the arch-specific asm/pci-bridge.h
files to the generic linux/pci.h file.
> vim +/pci_has_flag +581 drivers/pci/host/pcie-designware.c
>
> cbce7900 Zhou Wang 2015-10-29 575
> cbce7900 Zhou Wang 2015-10-29 576 #ifdef CONFIG_ARM
> cbce7900 Zhou Wang 2015-10-29 577 /* support old dtbs that incorrectly describe IRQs */
> cbce7900 Zhou Wang 2015-10-29 578 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> 0815f957 Yijing Wang 2014-11-11 579 #endif
> 0815f957 Yijing Wang 2014-11-11 580
> cbce7900 Zhou Wang 2015-10-29 @581 if (!pci_has_flag(PCI_PROBE_ONLY)) {
> cbce7900 Zhou Wang 2015-10-29 582 pci_bus_size_bridges(bus);
> cbce7900 Zhou Wang 2015-10-29 583 pci_bus_assign_resources(bus);
> 4b1ced84 Jingoo Han 2013-07-31 584
>
> :::::: The code at line 581 was first introduced by commit
> :::::: cbce7900598c26a12652f8ca9c41c5b29034c38d PCI: designware: Make driver arch-agnostic
>
> :::::: TO: Zhou Wang <wangzhou1@hisilicon.com>
> :::::: CC: Bjorn Helgaas <bhelgaas@google.com>
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 2/2] pcie-designware platform driver
2016-02-08 23:28 ` Bjorn Helgaas
@ 2016-02-10 9:48 ` Joao Pinto
2016-02-15 18:15 ` Joao Pinto
0 siblings, 1 reply; 11+ messages in thread
From: Joao Pinto @ 2016-02-10 9:48 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Joao Pinto, kbuild-all, Vineet.Gupta1, arnd, linux-pci,
linux-kernel, linux-snps-arc, CARLOS.PALMINHA, Alexey.Brodkin,
robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
Hi Bjorn,
On 2/8/2016 11:28 PM, Bjorn Helgaas wrote:
>> if (!pci_has_flag(PCI_PROBE_ONLY)) {
>> ^
>> drivers/pci/host/pcie-designware.c:581:20: note: each undeclared identifier is reported only once for each function it appears in
>> cc1: some warnings being treated as errors
>
> I have fixes for this on my pci/misc branch, so you don't need to
> worry about these errors. Basically I'm moving the PCI_PROBE_ONLY and
> pci_has_flag() declarations from the arch-specific asm/pci-bridge.h
> files to the generic linux/pci.h file.
Ok, thanks.
>
>> vim +/pci_has_flag +581 drivers/pci/host/pcie-designware.c
>>
>> cbce7900 Zhou Wang 2015-10-29 575
>> cbce7900 Zhou Wang 2015-10-29 576 #ifdef CONFIG_ARM
>> cbce7900 Zhou Wang 2015-10-29 577 /* support old dtbs that incorrectly describe IRQs */
>> cbce7900 Zhou Wang 2015-10-29 578 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> 0815f957 Yijing Wang 2014-11-11 579 #endif
>> 0815f957 Yijing Wang 2014-11-11 580
>> cbce7900 Zhou Wang 2015-10-29 @581 if (!pci_has_flag(PCI_PROBE_ONLY)) {
>> cbce7900 Zhou Wang 2015-10-29 582 pci_bus_size_bridges(bus);
>> cbce7900 Zhou Wang 2015-10-29 583 pci_bus_assign_resources(bus);
>> 4b1ced84 Jingoo Han 2013-07-31 584
>>
>> :::::: The code at line 581 was first introduced by commit
>> :::::: cbce7900598c26a12652f8ca9c41c5b29034c38d PCI: designware: Make driver arch-agnostic
>>
>> :::::: TO: Zhou Wang <wangzhou1@hisilicon.com>
>> :::::: CC: Bjorn Helgaas <bhelgaas@google.com>
>>
>> ---
>> 0-DAY kernel test infrastructure Open Source Technology Center
>> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
>
If there's anything else that is needed for the pcie-designware platform driver,
please let me know.
Thanks,
Joao
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9 2/2] pcie-designware platform driver
2016-02-10 9:48 ` Joao Pinto
@ 2016-02-15 18:15 ` Joao Pinto
0 siblings, 0 replies; 11+ messages in thread
From: Joao Pinto @ 2016-02-15 18:15 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Joao Pinto, kbuild-all, Vineet.Gupta1, arnd, linux-pci,
linux-kernel, linux-snps-arc, CARLOS.PALMINHA, Alexey.Brodkin,
robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak
Hi Bjorn!
Did you have opportunity to check the v9 patch set?
Thanks.
Joao
On 2/10/2016 9:48 AM, Joao Pinto wrote:
> Hi Bjorn,
>
> On 2/8/2016 11:28 PM, Bjorn Helgaas wrote:
>>> if (!pci_has_flag(PCI_PROBE_ONLY)) {
>>> ^
>>> drivers/pci/host/pcie-designware.c:581:20: note: each undeclared identifier is reported only once for each function it appears in
>>> cc1: some warnings being treated as errors
>>
>> I have fixes for this on my pci/misc branch, so you don't need to
>> worry about these errors. Basically I'm moving the PCI_PROBE_ONLY and
>> pci_has_flag() declarations from the arch-specific asm/pci-bridge.h
>> files to the generic linux/pci.h file.
>
> Ok, thanks.
>
>>
>>> vim +/pci_has_flag +581 drivers/pci/host/pcie-designware.c
>>>
>>> cbce7900 Zhou Wang 2015-10-29 575
>>> cbce7900 Zhou Wang 2015-10-29 576 #ifdef CONFIG_ARM
>>> cbce7900 Zhou Wang 2015-10-29 577 /* support old dtbs that incorrectly describe IRQs */
>>> cbce7900 Zhou Wang 2015-10-29 578 pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>>> 0815f957 Yijing Wang 2014-11-11 579 #endif
>>> 0815f957 Yijing Wang 2014-11-11 580
>>> cbce7900 Zhou Wang 2015-10-29 @581 if (!pci_has_flag(PCI_PROBE_ONLY)) {
>>> cbce7900 Zhou Wang 2015-10-29 582 pci_bus_size_bridges(bus);
>>> cbce7900 Zhou Wang 2015-10-29 583 pci_bus_assign_resources(bus);
>>> 4b1ced84 Jingoo Han 2013-07-31 584
>>>
>>> :::::: The code at line 581 was first introduced by commit
>>> :::::: cbce7900598c26a12652f8ca9c41c5b29034c38d PCI: designware: Make driver arch-agnostic
>>>
>>> :::::: TO: Zhou Wang <wangzhou1@hisilicon.com>
>>> :::::: CC: Bjorn Helgaas <bhelgaas@google.com>
>>>
>>> ---
>>> 0-DAY kernel test infrastructure Open Source Technology Center
>>> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>>
>>
>
> If there's anything else that is needed for the pcie-designware platform driver,
> please let me know.
>
> Thanks,
> Joao
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RESEND v9 2/2] pcie-designware platform driver
2016-02-17 17:46 ` [PATCH RESEND v9 2/2] pcie-designware platform driver Joao Pinto
2016-02-08 21:29 ` [PATCH " kbuild test robot
@ 2016-02-25 16:32 ` Bjorn Helgaas
2016-02-25 17:01 ` Bjorn Helgaas
2 siblings, 0 replies; 11+ messages in thread
From: Bjorn Helgaas @ 2016-02-25 16:32 UTC (permalink / raw)
To: Joao Pinto
Cc: Vineet.Gupta1, linux-pci, linux-kernel, linux-snps-arc,
CARLOS.PALMINHA, Alexey.Brodkin, robh+dt, pawel.moll,
mark.rutland, ijc+devicetree, galak, arnd
Hi Joao,
On Wed, Feb 17, 2016 at 05:46:19PM +0000, Joao Pinto wrote:
> The "wait for link" routine was centralised and so all drivers using it
> (dra7xx, exynos, imx6 and spear13xx) were updated to include the new
> function. The keystone driver was not updated because it had some custom
> opreations in the link waiting loop.
>
> A simple module (pcie-designware-plat) was created to contain the
> specific platform init code for pcie-designware.
>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
This seems to have a couple things mashed together that should be
split apart:
- add and use dw_pcie_wait_for_link(), and
- add pcie-designware-plat.c)
I'll untangle them and post a v10 for your approval.
> ---
> Change v8 -> v9 (Bjorn Helgaas and Arnd Bergmann):
> - wait for link routine was moved to pcie-designware, this implicated
> an update in ra7xx, exynos, imx6 and spear13xx pcie drivers
> - the proposed synopsys pcie rc platform driver is now a simple module
> that uses pcie-designware functions only and has no custom features
> - the designware-pcie.txt was updated with a DT example
> Change v7 -> v8 (Bjorn Helgaas and Arnd Bergmann):
> - driver name was changed from pcie-synopsys to pcie-dw-pltfm
> - mdelay() replaced for msleep() in the new driver
> - Devicetree bindings for the new driver was updated (config space removed
> from ranges)
> - Unnecessary synopsys_pcie_irq_handler() was removed
> - Driver compatibility strings updated
> Change v6 -> v7 (Bjorn Helgaas):
> - driver name was changed from pcie-snpsdev to pcie-synopsys
> - driver internals (functions and certain variables) also changed name
> accordingly
> - devicetree bindings documentation also changed accordingly
> - quirk function dw_pcie_link_retrain() was removed (tests were made
> successfully without it)
> - driver was changed to meet pci standards (link up confirmation routine,
> init rc functions, etc.)
> - EPROBE_DEFER were removed
> Change v5 -> v6:
> - Nothing changed (just to keep up with patch set version).
> Change v4 -> v5:
> - Nothing changed (just to keep up with patch set version).
> Changes v3 -> v4 (Bjorn Helgaas):
> - ARCH dependencies were added to the drivers/pci/host/kconfig for the
> PCIE_SNPSDEV.
> Changes v2 -> v3 (Bjorn Helgaas):
> - link init stuff was moved to a snpsdev_pcie_establish_link() function in
> pcie-snpsdev
> - pcie-snpsdev driver declaration was changed to be more
> standard (Bjorn Helgaas)
> - pcie-designware' dw_pcie_link_retrain() now use standard registers from
> pci-regs.h (Bjorn Helgaas)
> - pcie-snpsdev.txt was complemented with more info (Mark Rutland)
> Changes v1 -> v2 (Bjorn Helgaas):
> - Fixups snpsdev_pcie_fixup_bridge() and snpsdev_pcie_fixup_res() were removed
> from the driver (these functions were for specific tests only and not usefull
> in mainline)
> - Driver' comments were reviewed (fix Typos and excessive comments removal)
> - Removed unnecessary definitions in the driver source (PCIE_PHY_CTRL and
> PCIE_PHY_STAT)
>
> .../devicetree/bindings/pci/designware-pcie.txt | 17 +++
> drivers/pci/host/Kconfig | 11 ++
> drivers/pci/host/Makefile | 1 +
> drivers/pci/host/pci-dra7xx.c | 11 +-
> drivers/pci/host/pci-exynos.c | 11 +-
> drivers/pci/host/pci-imx6.c | 11 +-
> drivers/pci/host/pcie-designware-plat.c | 143 +++++++++++++++++++++
> drivers/pci/host/pcie-designware.c | 31 ++++-
> drivers/pci/host/pcie-designware.h | 6 +
> drivers/pci/host/pcie-spear13xx.c | 12 +-
> 10 files changed, 217 insertions(+), 37 deletions(-)
> create mode 100644 drivers/pci/host/pcie-designware-plat.c
>
> diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
> index 5b0853d..64f2fff 100644
> --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
> @@ -28,3 +28,20 @@ Optional properties:
> - clock-names: Must include the following entries:
> - "pcie"
> - "pcie_bus"
> +
> +Example configuration:
> +
> + pcie: pcie@0xdffff000 {
> + compatible = "snps,dw-pcie";
> + reg = <0xdffff000 0x1000>, /* Controller registers */
> + <0xd0000000 0x2000>; /* PCI config space */
> + reg-names = "ctrlreg", "config";
> + #address-cells = <3>;
> + #size-cells = <2>;
> + device_type = "pci";
> + ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000
> + 0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
> + interrupts = <25>, <24>;
> + #interrupt-cells = <1>;
> + num-lanes = <1>;
> + };
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index f131ba9..b564f8a 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -15,6 +15,17 @@ config PCI_MVEBU
> depends on ARCH_MVEBU || ARCH_DOVE
> depends on OF
>
> +config PCIE_DW_PLAT
> + bool "Platform bus based DesignWare PCIe Controller"
> + select PCIE_DW
> + ---help---
> + This selects the DesignWare PCIe controller support. Select this if
> + you have an PCIe controller on Platform bus.
> +
> + If you have a controller with this interface, say Y or M here.
> +
> + If unsure, say N.
> +
> config PCIE_DW
> bool
>
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 9d4d3c6..d979121 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -1,4 +1,5 @@
> obj-$(CONFIG_PCIE_DW) += pcie-designware.o
> +obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 8c36880..9b394bb 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -10,7 +10,6 @@
> * published by the Free Software Foundation.
> */
>
> -#include <linux/delay.h>
> #include <linux/err.h>
> #include <linux/interrupt.h>
> #include <linux/irq.h>
> @@ -108,7 +107,6 @@ static int dra7xx_pcie_establish_link(struct pcie_port *pp)
> {
> struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
> u32 reg;
> - unsigned int retries;
>
> if (dw_pcie_link_up(pp)) {
> dev_err(pp->dev, "link is already up\n");
> @@ -119,13 +117,10 @@ static int dra7xx_pcie_establish_link(struct pcie_port *pp)
> reg |= LTSSM_EN;
> dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
>
> - for (retries = 0; retries < 1000; retries++) {
> - if (dw_pcie_link_up(pp))
> - return 0;
> - usleep_range(10, 20);
> - }
> + /* check if the link is up or not */
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> - dev_err(pp->dev, "link is not up\n");
> return -EINVAL;
> }
>
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index 01095e1..bd26e15 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -318,7 +318,6 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
> {
> struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
> u32 val;
> - unsigned int retries;
>
> if (dw_pcie_link_up(pp)) {
> dev_err(pp->dev, "Link already up\n");
> @@ -357,13 +356,8 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
> PCIE_APP_LTSSM_ENABLE);
>
> /* check if the link is up or not */
> - for (retries = 0; retries < 10; retries++) {
> - if (dw_pcie_link_up(pp)) {
> - dev_info(pp->dev, "Link up\n");
> - return 0;
> - }
> - mdelay(100);
> - }
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) {
> val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED);
> @@ -372,7 +366,6 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
> /* power off phy */
> exynos_pcie_power_off_phy(pp);
>
> - dev_err(pp->dev, "PCIe Link Fail\n");
> return -EINVAL;
> }
>
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 22e8224..42c6930 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -330,15 +330,10 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)
>
> static int imx6_pcie_wait_for_link(struct pcie_port *pp)
> {
> - unsigned int retries;
> -
> - for (retries = 0; retries < 200; retries++) {
> - if (dw_pcie_link_up(pp))
> - return 0;
> - usleep_range(100, 1000);
> - }
> + /* check if the link is up or not */
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> - dev_err(pp->dev, "phy link never came up\n");
> dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
> readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
> readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
> diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c
> new file mode 100644
> index 0000000..5f75aba
> --- /dev/null
> +++ b/drivers/pci/host/pcie-designware-plat.c
> @@ -0,0 +1,143 @@
> +/*
> + * PCIe RC driver for Synopsys Designware Core
> + *
> + * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
> + *
> + * Authors: Joao Pinto <jpinto@synopsys.com>
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_gpio.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/resource.h>
> +#include <linux/signal.h>
> +#include <linux/types.h>
> +
> +#include "pcie-designware.h"
> +
> +struct dw_plat_pcie {
> + void __iomem *mem_base;
> + struct pcie_port pp;
> +};
> +
> +static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
> +{
> + struct pcie_port *pp = arg;
> +
> + return dw_handle_msi_irq(pp);
> +}
> +
> +static void dw_plat_pcie_host_init(struct pcie_port *pp)
> +{
> + dw_pcie_setup_rc(pp);
> +
> + dw_pcie_wait_for_link(pp);
> +
> + if (IS_ENABLED(CONFIG_PCI_MSI))
> + dw_pcie_msi_init(pp);
> +}
> +
> +static struct pcie_host_ops dw_plat_pcie_host_ops = {
> + .host_init = dw_plat_pcie_host_init,
> +};
> +
> +static int dw_plat_add_pcie_port(struct pcie_port *pp,
> + struct platform_device *pdev)
> +{
> + int ret;
> +
> + pp->irq = platform_get_irq(pdev, 1);
> +
> + if (pp->irq < 0)
> + return pp->irq;
> +
> + if (IS_ENABLED(CONFIG_PCI_MSI)) {
> + pp->msi_irq = platform_get_irq(pdev, 0);
> +
> + if (pp->msi_irq < 0)
> + return pp->msi_irq;
> +
> + ret = devm_request_irq(&pdev->dev, pp->msi_irq,
> + dw_plat_pcie_msi_irq_handler,
> + IRQF_SHARED, "dw-plat-pcie-msi", pp);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to request msi irq\n");
> + return ret;
> + }
> + }
> +
> + pp->root_bus_nr = -1;
> + pp->ops = &dw_plat_pcie_host_ops;
> +
> + ret = dw_pcie_host_init(pp);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to initialize host\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int dw_plat_pcie_probe(struct platform_device *pdev)
> +{
> + struct dw_plat_pcie *dw_plat_pcie;
> + struct pcie_port *pp;
> + struct resource *res; /* Resource from DT */
> + int ret;
> +
> + dw_plat_pcie = devm_kzalloc(&pdev->dev, sizeof(*dw_plat_pcie),
> + GFP_KERNEL);
> + if (!dw_plat_pcie)
> + return -ENOMEM;
> +
> + pp = &dw_plat_pcie->pp;
> + pp->dev = &pdev->dev;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + if (!res)
> + return -ENODEV;
> +
> + dw_plat_pcie->mem_base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(dw_plat_pcie->mem_base))
> + return PTR_ERR(dw_plat_pcie->mem_base);
> +
> + pp->dbi_base = dw_plat_pcie->mem_base;
> +
> + ret = dw_plat_add_pcie_port(pp, pdev);
> + if (ret < 0)
> + return ret;
> +
> + platform_set_drvdata(pdev, dw_plat_pcie);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id dw_plat_pcie_of_match[] = {
> + { .compatible = "snps,dw-pcie", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, dw_plat_pcie_of_match);
> +
> +static struct platform_driver dw_plat_pcie_driver = {
> + .driver = {
> + .name = "dw-pcie",
> + .of_match_table = dw_plat_pcie_of_match,
> + },
> + .probe = dw_plat_pcie_probe,
> +};
> +
> +module_platform_driver(dw_plat_pcie_driver);
> +
> +MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
> +MODULE_DESCRIPTION("Synopsys PCIe host controller glue platform driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 540f077..68ca614 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -22,6 +22,7 @@
> #include <linux/pci_regs.h>
> #include <linux/platform_device.h>
> #include <linux/types.h>
> +#include <linux/delay.h>
>
> #include "pcie-designware.h"
>
> @@ -69,6 +70,11 @@
> #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
> #define PCIE_ATU_UPPER_TARGET 0x91C
>
> +/* PCIe Port Logic registers */
> +#define PCIE_PHY_DEBUG_R1_LINK_UP 0x00000010
> +#define PLR_OFFSET 0x700
> +#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
> +
> static struct pci_ops dw_pcie_ops;
>
> int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
> @@ -380,12 +386,33 @@ static struct msi_controller dw_pcie_msi_chip = {
> .teardown_irq = dw_msi_teardown_irq,
> };
>
> +int dw_pcie_wait_for_link(struct pcie_port *pp)
> +{
> + int retries;
> +
> + /* check if the link is up or not */
> + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
> + if (dw_pcie_link_up(pp)) {
> + dev_info(pp->dev, "link up\n");
> + return 0;
> + }
> + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
> + }
> +
> + dev_err(pp->dev, "phy link never came up\n");
> +
> + return 1;
> +}
> +
> int dw_pcie_link_up(struct pcie_port *pp)
> {
> + u32 val;
> +
> if (pp->ops->link_up)
> return pp->ops->link_up(pp);
> - else
> - return 0;
> +
> + val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
> + return val & PCIE_PHY_DEBUG_R1_LINK_UP;
> }
>
> static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index 2356d29..8e42624 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -22,6 +22,11 @@
> #define MAX_MSI_IRQS 32
> #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
>
> +/* Parameters for the Waiting for link up routine */
> +#define LINK_WAIT_MAX_RETRIES 10
> +#define LINK_WAIT_USLEEP_MIN 90000
> +#define LINK_WAIT_USLEEP_MAX 100000
> +
> struct pcie_port {
> struct device *dev;
> u8 root_bus_nr;
> @@ -76,6 +81,7 @@ int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val);
> int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
> irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
> void dw_pcie_msi_init(struct pcie_port *pp);
> +int dw_pcie_wait_for_link(struct pcie_port *pp);
> 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);
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index b95b756..ffdff1d 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -13,7 +13,6 @@
> */
>
> #include <linux/clk.h>
> -#include <linux/delay.h>
> #include <linux/interrupt.h>
> #include <linux/kernel.h>
> #include <linux/module.h>
> @@ -149,7 +148,6 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
> struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
> struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
> u32 exp_cap_off = EXP_CAP_ID_OFFSET;
> - unsigned int retries;
>
> if (dw_pcie_link_up(pp)) {
> dev_err(pp->dev, "link already up\n");
> @@ -201,15 +199,9 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
> &app_reg->app_ctrl_0);
>
> /* check if the link is up or not */
> - for (retries = 0; retries < 10; retries++) {
> - if (dw_pcie_link_up(pp)) {
> - dev_info(pp->dev, "link up\n");
> - return 0;
> - }
> - mdelay(100);
> - }
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> - dev_err(pp->dev, "link Fail\n");
> return -EINVAL;
> }
>
> --
> 1.8.1.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RESEND v9 2/2] pcie-designware platform driver
2016-02-17 17:46 ` [PATCH RESEND v9 2/2] pcie-designware platform driver Joao Pinto
2016-02-08 21:29 ` [PATCH " kbuild test robot
2016-02-25 16:32 ` [PATCH RESEND " Bjorn Helgaas
@ 2016-02-25 17:01 ` Bjorn Helgaas
2 siblings, 0 replies; 11+ messages in thread
From: Bjorn Helgaas @ 2016-02-25 17:01 UTC (permalink / raw)
To: Joao Pinto
Cc: Vineet.Gupta1, linux-pci, linux-kernel, linux-snps-arc,
CARLOS.PALMINHA, Alexey.Brodkin, robh+dt, pawel.moll,
mark.rutland, ijc+devicetree, galak, arnd, Murali Karicheri
[+cc Murali]
On Wed, Feb 17, 2016 at 05:46:19PM +0000, Joao Pinto wrote:
> The "wait for link" routine was centralised and so all drivers using it
> (dra7xx, exynos, imx6 and spear13xx) were updated to include the new
> function. The keystone driver was not updated because it had some custom
> opreations in the link waiting loop.
I'm dubious about the keystone code:
ks_pcie_establish_link(...)
{
if (dw_pcie_link_up(...))
return 0;
ks_dw_pcie_initiate_link_train(...);
for (retries = 0; retries < 200; retries++) {
if (dw_pcie_link_up(...))
return 0;
usleep_range(100, 1000);
ks_dw_pcie_initiate_link_train(...);
}
}
It doesn't seem reasonable to me to disable, then re-initiate link
training every time around the loop, after waiting only 100 to 1000
usec. What if we did somethin like this:
ks_pcie_establish_link(...)
{
if (dw_pcie_link_up(...))
return 0;
for (retries = 0; retries < 5; retries++) {
ks_dw_pcie_initiate_link_train(...);
if (!dw_pcie_wait_for_link(...))
return 0;
}
Murali, any thoughts on this?
Was there a reason you didn't update pcie-qcom.c?
> A simple module (pcie-designware-plat) was created to contain the
> specific platform init code for pcie-designware.
>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> ---
> Change v8 -> v9 (Bjorn Helgaas and Arnd Bergmann):
> - wait for link routine was moved to pcie-designware, this implicated
> an update in ra7xx, exynos, imx6 and spear13xx pcie drivers
> - the proposed synopsys pcie rc platform driver is now a simple module
> that uses pcie-designware functions only and has no custom features
> - the designware-pcie.txt was updated with a DT example
> Change v7 -> v8 (Bjorn Helgaas and Arnd Bergmann):
> - driver name was changed from pcie-synopsys to pcie-dw-pltfm
> - mdelay() replaced for msleep() in the new driver
> - Devicetree bindings for the new driver was updated (config space removed
> from ranges)
> - Unnecessary synopsys_pcie_irq_handler() was removed
> - Driver compatibility strings updated
> Change v6 -> v7 (Bjorn Helgaas):
> - driver name was changed from pcie-snpsdev to pcie-synopsys
> - driver internals (functions and certain variables) also changed name
> accordingly
> - devicetree bindings documentation also changed accordingly
> - quirk function dw_pcie_link_retrain() was removed (tests were made
> successfully without it)
> - driver was changed to meet pci standards (link up confirmation routine,
> init rc functions, etc.)
> - EPROBE_DEFER were removed
> Change v5 -> v6:
> - Nothing changed (just to keep up with patch set version).
> Change v4 -> v5:
> - Nothing changed (just to keep up with patch set version).
> Changes v3 -> v4 (Bjorn Helgaas):
> - ARCH dependencies were added to the drivers/pci/host/kconfig for the
> PCIE_SNPSDEV.
> Changes v2 -> v3 (Bjorn Helgaas):
> - link init stuff was moved to a snpsdev_pcie_establish_link() function in
> pcie-snpsdev
> - pcie-snpsdev driver declaration was changed to be more
> standard (Bjorn Helgaas)
> - pcie-designware' dw_pcie_link_retrain() now use standard registers from
> pci-regs.h (Bjorn Helgaas)
> - pcie-snpsdev.txt was complemented with more info (Mark Rutland)
> Changes v1 -> v2 (Bjorn Helgaas):
> - Fixups snpsdev_pcie_fixup_bridge() and snpsdev_pcie_fixup_res() were removed
> from the driver (these functions were for specific tests only and not usefull
> in mainline)
> - Driver' comments were reviewed (fix Typos and excessive comments removal)
> - Removed unnecessary definitions in the driver source (PCIE_PHY_CTRL and
> PCIE_PHY_STAT)
>
> .../devicetree/bindings/pci/designware-pcie.txt | 17 +++
> drivers/pci/host/Kconfig | 11 ++
> drivers/pci/host/Makefile | 1 +
> drivers/pci/host/pci-dra7xx.c | 11 +-
> drivers/pci/host/pci-exynos.c | 11 +-
> drivers/pci/host/pci-imx6.c | 11 +-
> drivers/pci/host/pcie-designware-plat.c | 143 +++++++++++++++++++++
> drivers/pci/host/pcie-designware.c | 31 ++++-
> drivers/pci/host/pcie-designware.h | 6 +
> drivers/pci/host/pcie-spear13xx.c | 12 +-
> 10 files changed, 217 insertions(+), 37 deletions(-)
> create mode 100644 drivers/pci/host/pcie-designware-plat.c
>
> diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
> index 5b0853d..64f2fff 100644
> --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
> @@ -28,3 +28,20 @@ Optional properties:
> - clock-names: Must include the following entries:
> - "pcie"
> - "pcie_bus"
> +
> +Example configuration:
> +
> + pcie: pcie@0xdffff000 {
> + compatible = "snps,dw-pcie";
> + reg = <0xdffff000 0x1000>, /* Controller registers */
> + <0xd0000000 0x2000>; /* PCI config space */
> + reg-names = "ctrlreg", "config";
> + #address-cells = <3>;
> + #size-cells = <2>;
> + device_type = "pci";
> + ranges = <0x81000000 0 0x00000000 0xde000000 0 0x00010000
> + 0x82000000 0 0xd0400000 0xd0400000 0 0x0d000000>;
> + interrupts = <25>, <24>;
> + #interrupt-cells = <1>;
> + num-lanes = <1>;
> + };
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index f131ba9..b564f8a 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -15,6 +15,17 @@ config PCI_MVEBU
> depends on ARCH_MVEBU || ARCH_DOVE
> depends on OF
>
> +config PCIE_DW_PLAT
> + bool "Platform bus based DesignWare PCIe Controller"
> + select PCIE_DW
> + ---help---
> + This selects the DesignWare PCIe controller support. Select this if
> + you have an PCIe controller on Platform bus.
> +
> + If you have a controller with this interface, say Y or M here.
> +
> + If unsure, say N.
> +
> config PCIE_DW
> bool
>
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 9d4d3c6..d979121 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -1,4 +1,5 @@
> obj-$(CONFIG_PCIE_DW) += pcie-designware.o
> +obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
> obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
> obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
> obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 8c36880..9b394bb 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -10,7 +10,6 @@
> * published by the Free Software Foundation.
> */
>
> -#include <linux/delay.h>
> #include <linux/err.h>
> #include <linux/interrupt.h>
> #include <linux/irq.h>
> @@ -108,7 +107,6 @@ static int dra7xx_pcie_establish_link(struct pcie_port *pp)
> {
> struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
> u32 reg;
> - unsigned int retries;
>
> if (dw_pcie_link_up(pp)) {
> dev_err(pp->dev, "link is already up\n");
> @@ -119,13 +117,10 @@ static int dra7xx_pcie_establish_link(struct pcie_port *pp)
> reg |= LTSSM_EN;
> dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
>
> - for (retries = 0; retries < 1000; retries++) {
> - if (dw_pcie_link_up(pp))
> - return 0;
> - usleep_range(10, 20);
> - }
> + /* check if the link is up or not */
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> - dev_err(pp->dev, "link is not up\n");
> return -EINVAL;
> }
>
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index 01095e1..bd26e15 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -318,7 +318,6 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
> {
> struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
> u32 val;
> - unsigned int retries;
>
> if (dw_pcie_link_up(pp)) {
> dev_err(pp->dev, "Link already up\n");
> @@ -357,13 +356,8 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
> PCIE_APP_LTSSM_ENABLE);
>
> /* check if the link is up or not */
> - for (retries = 0; retries < 10; retries++) {
> - if (dw_pcie_link_up(pp)) {
> - dev_info(pp->dev, "Link up\n");
> - return 0;
> - }
> - mdelay(100);
> - }
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) {
> val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED);
> @@ -372,7 +366,6 @@ static int exynos_pcie_establish_link(struct pcie_port *pp)
> /* power off phy */
> exynos_pcie_power_off_phy(pp);
>
> - dev_err(pp->dev, "PCIe Link Fail\n");
> return -EINVAL;
> }
>
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 22e8224..42c6930 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -330,15 +330,10 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)
>
> static int imx6_pcie_wait_for_link(struct pcie_port *pp)
> {
> - unsigned int retries;
> -
> - for (retries = 0; retries < 200; retries++) {
> - if (dw_pcie_link_up(pp))
> - return 0;
> - usleep_range(100, 1000);
> - }
> + /* check if the link is up or not */
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> - dev_err(pp->dev, "phy link never came up\n");
> dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
> readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
> readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
> diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c
> new file mode 100644
> index 0000000..5f75aba
> --- /dev/null
> +++ b/drivers/pci/host/pcie-designware-plat.c
> @@ -0,0 +1,143 @@
> +/*
> + * PCIe RC driver for Synopsys Designware Core
> + *
> + * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
> + *
> + * Authors: Joao Pinto <jpinto@synopsys.com>
> + *
> + * 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_gpio.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/resource.h>
> +#include <linux/signal.h>
> +#include <linux/types.h>
> +
> +#include "pcie-designware.h"
> +
> +struct dw_plat_pcie {
> + void __iomem *mem_base;
> + struct pcie_port pp;
> +};
> +
> +static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
> +{
> + struct pcie_port *pp = arg;
> +
> + return dw_handle_msi_irq(pp);
> +}
> +
> +static void dw_plat_pcie_host_init(struct pcie_port *pp)
> +{
> + dw_pcie_setup_rc(pp);
> +
> + dw_pcie_wait_for_link(pp);
> +
> + if (IS_ENABLED(CONFIG_PCI_MSI))
> + dw_pcie_msi_init(pp);
> +}
> +
> +static struct pcie_host_ops dw_plat_pcie_host_ops = {
> + .host_init = dw_plat_pcie_host_init,
> +};
> +
> +static int dw_plat_add_pcie_port(struct pcie_port *pp,
> + struct platform_device *pdev)
> +{
> + int ret;
> +
> + pp->irq = platform_get_irq(pdev, 1);
> +
> + if (pp->irq < 0)
> + return pp->irq;
> +
> + if (IS_ENABLED(CONFIG_PCI_MSI)) {
> + pp->msi_irq = platform_get_irq(pdev, 0);
> +
> + if (pp->msi_irq < 0)
> + return pp->msi_irq;
> +
> + ret = devm_request_irq(&pdev->dev, pp->msi_irq,
> + dw_plat_pcie_msi_irq_handler,
> + IRQF_SHARED, "dw-plat-pcie-msi", pp);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to request msi irq\n");
> + return ret;
> + }
> + }
> +
> + pp->root_bus_nr = -1;
> + pp->ops = &dw_plat_pcie_host_ops;
> +
> + ret = dw_pcie_host_init(pp);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to initialize host\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int dw_plat_pcie_probe(struct platform_device *pdev)
> +{
> + struct dw_plat_pcie *dw_plat_pcie;
> + struct pcie_port *pp;
> + struct resource *res; /* Resource from DT */
> + int ret;
> +
> + dw_plat_pcie = devm_kzalloc(&pdev->dev, sizeof(*dw_plat_pcie),
> + GFP_KERNEL);
> + if (!dw_plat_pcie)
> + return -ENOMEM;
> +
> + pp = &dw_plat_pcie->pp;
> + pp->dev = &pdev->dev;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + if (!res)
> + return -ENODEV;
> +
> + dw_plat_pcie->mem_base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(dw_plat_pcie->mem_base))
> + return PTR_ERR(dw_plat_pcie->mem_base);
> +
> + pp->dbi_base = dw_plat_pcie->mem_base;
> +
> + ret = dw_plat_add_pcie_port(pp, pdev);
> + if (ret < 0)
> + return ret;
> +
> + platform_set_drvdata(pdev, dw_plat_pcie);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id dw_plat_pcie_of_match[] = {
> + { .compatible = "snps,dw-pcie", },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, dw_plat_pcie_of_match);
> +
> +static struct platform_driver dw_plat_pcie_driver = {
> + .driver = {
> + .name = "dw-pcie",
> + .of_match_table = dw_plat_pcie_of_match,
> + },
> + .probe = dw_plat_pcie_probe,
> +};
> +
> +module_platform_driver(dw_plat_pcie_driver);
> +
> +MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
> +MODULE_DESCRIPTION("Synopsys PCIe host controller glue platform driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 540f077..68ca614 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -22,6 +22,7 @@
> #include <linux/pci_regs.h>
> #include <linux/platform_device.h>
> #include <linux/types.h>
> +#include <linux/delay.h>
>
> #include "pcie-designware.h"
>
> @@ -69,6 +70,11 @@
> #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
> #define PCIE_ATU_UPPER_TARGET 0x91C
>
> +/* PCIe Port Logic registers */
> +#define PCIE_PHY_DEBUG_R1_LINK_UP 0x00000010
> +#define PLR_OFFSET 0x700
> +#define PCIE_PHY_DEBUG_R1 (PLR_OFFSET + 0x2c)
> +
> static struct pci_ops dw_pcie_ops;
>
> int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
> @@ -380,12 +386,33 @@ static struct msi_controller dw_pcie_msi_chip = {
> .teardown_irq = dw_msi_teardown_irq,
> };
>
> +int dw_pcie_wait_for_link(struct pcie_port *pp)
> +{
> + int retries;
> +
> + /* check if the link is up or not */
> + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
> + if (dw_pcie_link_up(pp)) {
> + dev_info(pp->dev, "link up\n");
> + return 0;
> + }
> + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
> + }
> +
> + dev_err(pp->dev, "phy link never came up\n");
> +
> + return 1;
> +}
> +
> int dw_pcie_link_up(struct pcie_port *pp)
> {
> + u32 val;
> +
> if (pp->ops->link_up)
> return pp->ops->link_up(pp);
> - else
> - return 0;
> +
> + val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
> + return val & PCIE_PHY_DEBUG_R1_LINK_UP;
> }
>
> static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index 2356d29..8e42624 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -22,6 +22,11 @@
> #define MAX_MSI_IRQS 32
> #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
>
> +/* Parameters for the Waiting for link up routine */
> +#define LINK_WAIT_MAX_RETRIES 10
> +#define LINK_WAIT_USLEEP_MIN 90000
> +#define LINK_WAIT_USLEEP_MAX 100000
> +
> struct pcie_port {
> struct device *dev;
> u8 root_bus_nr;
> @@ -76,6 +81,7 @@ int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val);
> int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
> irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
> void dw_pcie_msi_init(struct pcie_port *pp);
> +int dw_pcie_wait_for_link(struct pcie_port *pp);
> 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);
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index b95b756..ffdff1d 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -13,7 +13,6 @@
> */
>
> #include <linux/clk.h>
> -#include <linux/delay.h>
> #include <linux/interrupt.h>
> #include <linux/kernel.h>
> #include <linux/module.h>
> @@ -149,7 +148,6 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
> struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
> struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
> u32 exp_cap_off = EXP_CAP_ID_OFFSET;
> - unsigned int retries;
>
> if (dw_pcie_link_up(pp)) {
> dev_err(pp->dev, "link already up\n");
> @@ -201,15 +199,9 @@ static int spear13xx_pcie_establish_link(struct pcie_port *pp)
> &app_reg->app_ctrl_0);
>
> /* check if the link is up or not */
> - for (retries = 0; retries < 10; retries++) {
> - if (dw_pcie_link_up(pp)) {
> - dev_info(pp->dev, "link up\n");
> - return 0;
> - }
> - mdelay(100);
> - }
> + if (!dw_pcie_wait_for_link(pp))
> + return 0;
>
> - dev_err(pp->dev, "link Fail\n");
> return -EINVAL;
> }
>
> --
> 1.8.1.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 11+ messages in thread