Skip to content

Commit

Permalink
Merge branch 'pci/host-designware' into next
Browse files Browse the repository at this point in the history
* pci/host-designware:
  PCI: designware: Add driver for prototyping kits based on ARC SDP
  PCI: designware: Add default link up check if sub-driver doesn't override
  PCI: designware: Add generic dw_pcie_wait_for_link()
  ARC: Add PCI support
  • Loading branch information
bjorn-helgaas committed Mar 15, 2016
2 parents c334f9c + 5a3aa2a commit 562df5c
Show file tree
Hide file tree
Showing 21 changed files with 319 additions and 77 deletions.
17 changes: 17 additions & 0 deletions Documentation/devicetree/bindings/pci/designware-pcie.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
};
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8367,6 +8367,13 @@ L: [email protected]
S: Maintained
F: drivers/pci/host/*designware*

PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE
M: Joao Pinto <[email protected]>
L: [email protected]
S: Maintained
F: Documentation/devicetree/bindings/pci/designware-pcie.txt
F: drivers/pci/host/pcie-designware-plat.c

PCI DRIVER FOR GENERIC OF HOSTS
M: Will Deacon <[email protected]>
L: [email protected]
Expand Down
26 changes: 26 additions & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ config ARC
select GENERIC_FIND_FIRST_BIT
# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
select GENERIC_PENDING_IRQ if SMP
select GENERIC_SMP_IDLE_THREAD
select HAVE_ARCH_KGDB
Expand All @@ -39,6 +40,9 @@ config ARC
select PERF_USE_VMALLOC
select HAVE_DEBUG_STACKOVERFLOW

config MIGHT_HAVE_PCI
bool

config TRACE_IRQFLAGS_SUPPORT
def_bool y

Expand Down Expand Up @@ -568,6 +572,28 @@ endmenu # "ARC Architecture Configuration"
source "mm/Kconfig"
source "net/Kconfig"
source "drivers/Kconfig"

menu "Bus Support"

config PCI
bool "PCI support" if MIGHT_HAVE_PCI
help
PCI is the name of a bus system, i.e., the way the CPU talks to
the other stuff inside your box. Find out if your board/platform
has PCI.

Note: PCIe support for Synopsys Device will be available only
when HAPS DX is configured with PCIe RC bitmap. If you have PCI,
say Y, otherwise N.

config PCI_SYSCALL
def_bool PCI

source "drivers/pci/Kconfig"
source "drivers/pci/pcie/Kconfig"

endmenu

source "fs/Kconfig"
source "arch/arc/Kconfig.debug"
source "security/Kconfig"
Expand Down
5 changes: 5 additions & 0 deletions arch/arc/include/asm/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@
#define ASM_ARC_DMA_H

#define MAX_DMA_ADDRESS 0xC0000000
#ifdef CONFIG_PCI
extern int isa_dma_bridge_buggy;
#else
#define isa_dma_bridge_buggy 0
#endif

#endif
9 changes: 9 additions & 0 deletions arch/arc/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@
extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
unsigned long flags);
static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
return (void __iomem *)port;
}

static inline void ioport_unmap(void __iomem *addr)
{
}

extern void iounmap(const void __iomem *addr);

#define ioremap_nocache(phy, sz) ioremap(phy, sz)
Expand Down
28 changes: 28 additions & 0 deletions arch/arc/include/asm/pci.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2015-2016 Synopsys, Inc. (www.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.
*/

#ifndef _ASM_ARC_PCI_H
#define _ASM_ARC_PCI_H

#ifdef __KERNEL__
#include <linux/ioport.h>

#define PCIBIOS_MIN_IO 0x100
#define PCIBIOS_MIN_MEM 0x100000

#define pcibios_assign_all_busses() 1
/*
* The PCI address space does equal the physical memory address space.
* The networking and block device layers use this boolean for bounce
* buffer decisions.
*/
#define PCI_DMA_BUS_IS_PHYS 1

#endif /* __KERNEL__ */

#endif /* _ASM_ARC_PCI_H */
1 change: 1 addition & 0 deletions arch/arc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o
obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o
obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
obj-$(CONFIG_PCI) += pcibios.o

obj-$(CONFIG_MODULES) += arcksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
Expand Down
22 changes: 22 additions & 0 deletions arch/arc/kernel/pcibios.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (C) 2014-2015 Synopsys, Inc. (www.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/pci.h>

/*
* We don't have to worry about legacy ISA devices, so nothing to do here
*/
resource_size_t pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align)
{
return res->start;
}

void pcibios_fixup_bus(struct pci_bus *bus)
{
}
1 change: 1 addition & 0 deletions arch/arc/plat-axs10x/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ menuconfig ARC_PLAT_AXS10X
select DW_APB_ICTL
select GPIO_DWAPB
select OF_GPIO
select MIGHT_HAVE_PCI
select GENERIC_IRQ_CHIP
select ARCH_REQUIRE_GPIOLIB
help
Expand Down
1 change: 1 addition & 0 deletions drivers/pci/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
# Some architectures use the generic PCI setup functions
#
obj-$(CONFIG_ALPHA) += setup-irq.o
obj-$(CONFIG_ARC) += setup-irq.o
obj-$(CONFIG_ARM) += setup-irq.o
obj-$(CONFIG_ARM64) += setup-irq.o
obj-$(CONFIG_UNICORE32) += setup-irq.o
Expand Down
12 changes: 12 additions & 0 deletions drivers/pci/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ config PCI_MVEBU
depends on ARCH_MVEBU || ARCH_DOVE
depends on OF


config PCIE_XILINX_NWL
bool "NWL PCIe Core"
depends on ARCH_ZYNQMP
Expand All @@ -26,6 +27,17 @@ config PCIE_XILINX_NWL
or End Point. The current option selection will only
support root port enabling.

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 a 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

Expand Down
1 change: 1 addition & 0 deletions drivers/pci/host/Makefile
Original file line number Diff line number Diff line change
@@ -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
Expand Down
11 changes: 1 addition & 10 deletions drivers/pci/host/pci-dra7xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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");
Expand All @@ -119,14 +117,7 @@ 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);
}

dev_err(pp->dev, "link is not up\n");
return -EINVAL;
return dw_pcie_wait_for_link(pp);
}

static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
Expand Down
13 changes: 3 additions & 10 deletions drivers/pci/host/pci-exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand All @@ -372,8 +366,7 @@ 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;
return -ETIMEDOUT;
}

static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp)
Expand Down
33 changes: 7 additions & 26 deletions drivers/pci/host/pci-imx6.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,33 +357,14 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)

static int imx6_pcie_wait_for_link(struct pcie_port *pp)
{
unsigned int retries;
/* check if the link is up or not */
if (!dw_pcie_wait_for_link(pp))
return 0;

/*
* Test if the PHY reports that the link is up and also that the LTSSM
* training finished. There are three possible states of the link when
* this code is called:
* 1) The link is DOWN (unlikely)
* The link didn't come up yet for some reason. This usually means
* we have a real problem somewhere, if it happens with a peripheral
* connected. This state calls for inspection of the DEBUG registers.
* 2) The link is UP, but still in LTSSM training
* Wait for the training to finish, which should take a very short
* time. If the training does not finish, we have a problem and we
* need to inspect the DEBUG registers. If the training does finish,
* the link is up and operating correctly.
* 3) The link is UP and no longer in LTSSM training
* The link is up and operating correctly.
*/
for (retries = 0; retries < 200; retries++) {
u32 reg = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
if ((reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) &&
!(reg & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING))
return 0;
usleep_range(1000, 2000);
}

return -EINVAL;
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));
return -ETIMEDOUT;
}

static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
Expand Down
10 changes: 4 additions & 6 deletions drivers/pci/host/pci-keystone.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,15 @@ static int ks_pcie_establish_link(struct keystone_pcie *ks_pcie)
return 0;
}

ks_dw_pcie_initiate_link_train(ks_pcie);
/* check if the link is up or not */
for (retries = 0; retries < 200; retries++) {
if (dw_pcie_link_up(pp))
return 0;
usleep_range(100, 1000);
for (retries = 0; retries < 5; retries++) {
ks_dw_pcie_initiate_link_train(ks_pcie);
if (!dw_pcie_wait_for_link(pp))
return 0;
}

dev_err(pp->dev, "phy link never came up\n");
return -EINVAL;
return -ETIMEDOUT;
}

static void ks_pcie_msi_irq_handler(struct irq_desc *desc)
Expand Down
Loading

0 comments on commit 562df5c

Please sign in to comment.