[PATCH][v2] powerpc/pci: Fix IMMRBAR address

2014-01-20 Thread Minghuan Lian
For PEXCSRBAR, bit 3-0 indicate prefetchable and address type.
So when getting base address, these bits should be masked,
otherwise we may get incorrect base address.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Change log:
v2:
Use PCI_BASE_ADDRESS_MEM_MASK instead of 0xfff0

 arch/powerpc/sysdev/fsl_pci.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4dfd61d..252716d 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -868,6 +868,14 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
 
pci_bus_read_config_dword(hose-bus,
PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, base);
+
+   /*
+* For PEXCSRBAR, bit 3-0 indicate prefetchable and
+* address type. So when getting base address, these
+* bits should be masked
+*/
+   base = PCI_BASE_ADDRESS_MEM_MASK;
+
return base;
}
 #endif
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 02/12][v4] pci: fsl: add structure fsl_pci

2014-01-07 Thread Minghuan Lian
PowerPC uses structure pci_controller to describe PCI controller,
but ARM uses structure pci_sys_data. In order to support PowerPC
and ARM simultaneously, the patch adds a structure fsl_pci that
contains most of the members of the pci_controller and pci_sys_data.
Meanwhile, it defines a interface fsl_arch_sys_to_pci() which should
be implemented in architecture-specific PCI controller driver to
convert pci_controller or pci_sys_data to fsl_pci.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
Added indirect type macro
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 include/linux/fsl/pci-common.h | 48 ++
 1 file changed, 48 insertions(+)

diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 5e4f683..7ea20a1 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -102,5 +102,53 @@ struct ccsr_pci {
 
 };
 
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct fsl_pci {
+   struct list_head node;
+   bool is_pcie;
+   struct device_node *dn;
+   struct device *dev;
+
+   int first_busno;
+   int last_busno;
+   int self_busno;
+   struct resource busn;
+
+   struct pci_ops *ops;
+   struct ccsr_pci __iomem *regs;
+
+#define INDIRECT_TYPE_SET_CFG_TYPE 0x0001
+#define INDIRECT_TYPE_EXT_REG  0x0002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x0004
+#define INDIRECT_TYPE_NO_PCIE_LINK 0x0008
+#define INDIRECT_TYPE_BIG_ENDIAN   0x0010
+#define INDIRECT_TYPE_BROKEN_MRM   0x0020
+#define INDIRECT_TYPE_FSL_CFG_REG_LINK 0x0040
+   u32 indirect_type;
+
+   struct resource io_resource;
+   resource_size_t io_base_phys;
+   resource_size_t pci_io_size;
+
+   struct resource mem_resources[3];
+   resource_size_t mem_offset[3];
+
+   int global_number;  /* PCI domain number */
+
+   resource_size_t dma_window_base_cur;
+   resource_size_t dma_window_size;
+
+   void *sys;
+};
+
+/*
+ * Convert architecture specific pci controller structure to fsl_pci
+ * PowerPC uses structure pci_controller and ARM uses structure pci_sys_data
+ * to describe pci controller.
+ */
+extern struct fsl_pci *fsl_arch_sys_to_pci(void *sys);
+
 #endif /* __PCI_COMMON_H */
 #endif /* __KERNEL__ */
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 03/12][v4] pci: fsl: add PCI indirect access support

2014-01-07 Thread Minghuan Lian
The patch adds PCI indirect read/write functions. The main code
is ported from arch/powerpc/sysdev/indirect_pci.c. We use general
IO API iowrite32be/ioread32be instead of out_be32/in_be32, and
use structure fsl_Pci instead of PowerPC's pci_controller.
The patch also provides fsl_pcie_check_link() to check PCI link.
The weak function fsl_arch_pci_exclude_device() is provided to
call ppc_md.pci_exclude_device() for PowerPC architecture.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
moved indirect type macro to header file
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 163 --
 include/linux/fsl/pci-common.h|   6 ++
 2 files changed, 145 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 69d338b..d1846ee 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -35,52 +35,167 @@
 #include sysdev/fsl_soc.h
 #include sysdev/fsl_pci.h
 
-static int fsl_pcie_check_link(struct pci_controller *hose)
+
+int __weak fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   return PCIBIOS_SUCCESSFUL;
+}
+
+static int fsl_pci_read_config(struct fsl_pci *pci, int bus, int devfn,
+   int offset, int len, u32 *val)
+{
+   u32 bus_no, reg, data;
+
+   if (pci-indirect_type  INDIRECT_TYPE_NO_PCIE_LINK) {
+   if (bus != pci-first_busno)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   if (devfn != 0)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   }
+
+   if (fsl_arch_pci_exclude_device(pci, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   bus_no = (bus == pci-first_busno) ? pci-self_busno : bus;
+
+   if (pci-indirect_type  INDIRECT_TYPE_EXT_REG)
+   reg = ((offset  0xf00)  16) | (offset  0xfc);
+   else
+   reg = offset  0xfc;
+
+   if (pci-indirect_type  INDIRECT_TYPE_BIG_ENDIAN)
+   iowrite32be(0x8000 | (bus_no  16) | (devfn  8) | reg,
+   pci-regs-config_addr);
+   else
+   iowrite32(0x8000 | (bus_no  16) | (devfn  8) | reg,
+ pci-regs-config_addr);
+
+   /*
+* Note: the caller has already checked that offset is
+* suitably aligned and that len is 1, 2 or 4.
+*/
+   data = ioread32(pci-regs-config_data);
+   switch (len) {
+   case 1:
+   *val = (data  (8 * (offset  3)))  0xff;
+   break;
+   case 2:
+   *val = (data  (8 * (offset  3)))  0x;
+   break;
+   default:
+   *val = data;
+   break;
+   }
+
+   return PCIBIOS_SUCCESSFUL;
+}
+
+static int fsl_pci_write_config(struct fsl_pci *pci, int bus, int devfn,
+int offset, int len, u32 val)
+{
+   void __iomem *cfg_data;
+   u32 bus_no, reg;
+
+   if (pci-indirect_type  INDIRECT_TYPE_NO_PCIE_LINK) {
+   if (bus != pci-first_busno)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   if (devfn != 0)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   }
+
+   if (fsl_arch_pci_exclude_device(pci, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   bus_no = (bus == pci-first_busno) ?
+   pci-self_busno : bus;
+
+   if (pci-indirect_type  INDIRECT_TYPE_EXT_REG)
+   reg = ((offset  0xf00)  16) | (offset  0xfc);
+   else
+   reg = offset  0xfc;
+
+   if (pci-indirect_type  INDIRECT_TYPE_BIG_ENDIAN)
+   iowrite32be(0x8000 | (bus_no  16) | (devfn  8) | reg,
+   pci-regs-config_addr);
+   else
+   iowrite32(0x8000 | (bus_no  16) | (devfn  8) | reg,
+ pci-regs-config_addr);
+
+   /* suppress setting of PCI_PRIMARY_BUS */
+   if (pci-indirect_type  INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+   if ((offset == PCI_PRIMARY_BUS) 
+   (bus == pci-first_busno))
+   val = 0xff00;
+
+   /*
+* Note: the caller has already checked that offset is
+* suitably aligned and that len is 1, 2 or 4.
+*/
+   cfg_data = ((void *) (pci-regs-config_data)) + (offset  3);
+   switch (len) {
+   case 1:
+   iowrite8(val, cfg_data);
+   break;
+   case 2:
+   iowrite16(val, cfg_data);
+   break;
+   default:
+   iowrite32(val, cfg_data);
+   break;
+   }
+   return PCIBIOS_SUCCESSFUL;
+}
+
+bool fsl_pci_check_link(struct fsl_pci *pci)
 {
u32 val = 0

[PATCH 04/12][v4] pci: fsl: add early PCI indirect access support

2014-01-07 Thread Minghuan Lian
The driver needs to read/write PCI configuration very early, at
that time architecture-specific PCI controller structure and
PCI bus have not been created. The patch provides an interface
fsl_arch_fake_pci_bus which should be implemented in
architecture-specific PCI driver to fake a PCI controller structure
and PCI bus. Using the fake PCI controller and PCI bus, the patch
provides the early indirect read/write functions.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 26 ++
 include/linux/fsl/pci-common.h|  7 +++
 2 files changed, 33 insertions(+)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index d1846ee..a706100 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -198,6 +198,32 @@ static struct pci_ops fsl_indirect_pci_ops = {
.write = fsl_indirect_write_config,
 };
 
+#define EARLY_FSL_PCI_OP(rw, size, type)   \
+int early_fsl_##rw##_config_##size(struct fsl_pci *pci, int bus,   \
+  int devfn, int offset, type value)   \
+{  \
+   return pci_bus_##rw##_config_##size(fsl_arch_fake_pci_bus(pci, bus),\
+   devfn, offset, value);  \
+}
+
+EARLY_FSL_PCI_OP(read, byte, u8 *)
+EARLY_FSL_PCI_OP(read, word, u16 *)
+EARLY_FSL_PCI_OP(read, dword, u32 *)
+EARLY_FSL_PCI_OP(write, byte, u8)
+EARLY_FSL_PCI_OP(write, word, u16)
+EARLY_FSL_PCI_OP(write, dword, u32)
+
+static int early_fsl_find_capability(struct fsl_pci *pci,
+int busnr, int devfn, int cap)
+{
+   struct pci_bus *bus = fsl_arch_fake_pci_bus(pci, busnr);
+
+   if (!bus)
+   return 0;
+
+   return pci_bus_find_capability(bus, devfn, cap);
+}
+
 static int setup_one_atmu(struct ccsr_pci __iomem *pci,
unsigned int index, const struct resource *res,
resource_size_t offset)
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 726f27b..fd6c497 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -156,5 +156,12 @@ bool fsl_pci_check_link(struct fsl_pci *pci);
 /* To avoid touching specified devices */
 int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn);
 
+/*
+ * To fake a PCI bus
+ * it is called by early_fsl_*(), at that time the architecture-dependent
+ * pci controller and pci bus have not been created.
+ */
+extern struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr);
+
 #endif /* __PCI_COMMON_H */
 #endif /* __KERNEL__ */
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 01/12][v4] pci: fsl: derive the common PCI driver to drivers/pci/host

2014-01-07 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pci-fsl-common.c and leaves the architecture
specific functions which should be implemented in arch related files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v2-v4:
no change
v1-v2:
1. rename pci.h to pci-common.h 
2. rename pci-fsl.c to pci-fsl-common.c

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c  | 521 +-
 arch/powerpc/sysdev/fsl_pci.h  |  89 
 .../fsl_pci.c = drivers/pci/host/pci-fsl-common.c | 592 +
 .../fsl_pci.h = include/linux/fsl/pci-common.h|  45 +-
 4 files changed, 7 insertions(+), 1240 deletions(-)
 copy arch/powerpc/sysdev/fsl_pci.c = drivers/pci/host/pci-fsl-common.c (54%)
 copy arch/powerpc/sysdev/fsl_pci.h = include/linux/fsl/pci-common.h (79%)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4dfd61d..0764385 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -27,6 +27,7 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/fsl/pci-common.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -58,57 +59,8 @@ static void quirk_fsl_pcie_early(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
-
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = hose-first_busno;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
-
-   return 0;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
-{
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
-}
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
 #define MAX_PHYS_ADDR_BITS 40
 static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
 
@@ -132,291 +84,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
return 0;
 }
 
-static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
-{
-   resource_size_t pci_addr = res-start - offset;
-   resource_size_t phys_addr = res-start;
-   resource_size_t size = resource_size(res);
-   u32 flags = 0x80044000; /* enable  mem R/W */
-   unsigned int i;
-
-   pr_debug(PCI MEM resource start 0x%016llx, size 0x%016llx.\n,
-   (u64)res-start, (u64)size);
-
-   if (res-flags  IORESOURCE_PREFETCH)
-   flags |= 0x1000; /* enable relaxed ordering */
-
-   for (i = 0; size  0; i++) {
-   unsigned int bits = min(ilog2(size),
-   __ffs(pci_addr | phys_addr));
-
-   if (index + i = 5)
-   return -1;
-
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
-
-   pci_addr += (resource_size_t)1U  bits;
-   phys_addr += (resource_size_t)1U  bits;
-   size -= (resource_size_t)1U  bits

[PATCH 05/12][v4] pci: fsl: port PCI ATMU related code

2014-01-07 Thread Minghuan Lian
The patch ports PCI ATMU related code, just uses general IO API
iowrite32be/ioread32be instead of out_be32/in_be32, uses structure
fsl_pci instead of PowerPC's pci_controller and uses dev_*()
instead of pr_*() to output the information.
The patch also provides the weak function
fsl_arch_pci64_dma_offset(), the architecture-specific driver may
return different offset.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 190 --
 include/linux/fsl/pci-common.h|   3 +
 2 files changed, 103 insertions(+), 90 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index a706100..26ee4c3 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -35,6 +35,10 @@
 #include sysdev/fsl_soc.h
 #include sysdev/fsl_pci.h
 
+u64 __weak fsl_arch_pci64_dma_offset(void)
+{
+   return 0;
+}
 
 int __weak fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
 {
@@ -225,8 +229,8 @@ static int early_fsl_find_capability(struct fsl_pci *pci,
 }
 
 static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
+ unsigned int index, const struct resource *res,
+ resource_size_t offset)
 {
resource_size_t pci_addr = res-start - offset;
resource_size_t phys_addr = res-start;
@@ -247,10 +251,10 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
if (index + i = 5)
return -1;
 
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
+   iowrite32be(pci_addr  12, pci-pow[index + i].potar);
+   iowrite32be((u64)pci_addr  44, pci-pow[index + i].potear);
+   iowrite32be(phys_addr  12, pci-pow[index + i].powbar);
+   iowrite32be(flags | (bits - 1), pci-pow[index + i].powar);
 
pci_addr += (resource_size_t)1U  bits;
phys_addr += (resource_size_t)1U  bits;
@@ -261,21 +265,19 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 }
 
 /* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose)
+static void setup_pci_atmu(struct fsl_pci *pci)
 {
-   struct ccsr_pci __iomem *pci = hose-private_data;
int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
u64 mem, sz, paddr_hi = 0;
u64 offset = 0, paddr_lo = ULLONG_MAX;
u32 pcicsrbar = 0, pcicsrbar_sz;
u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
-   const char *name = hose-dn-full_name;
const u64 *reg;
int len;
 
-   if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
-   if (in_be32(pci-block_rev1) = PCIE_IP_REV_2_2) {
+   if (pci-is_pcie) {
+   if (in_be32(pci-regs-block_rev1) = PCIE_IP_REV_2_2) {
win_idx = 2;
start_idx = 0;
end_idx = 3;
@@ -283,47 +285,54 @@ static void setup_pci_atmu(struct pci_controller *hose)
}
 
/* Disable all windows (except powar0 since it's ignored) */
-   for(i = 1; i  5; i++)
-   out_be32(pci-pow[i].powar, 0);
+   for (i = 1; i  5; i++)
+   iowrite32be(0, pci-regs-pow[i].powar);
for (i = start_idx; i  end_idx; i++)
-   out_be32(pci-piw[i].piwar, 0);
+   iowrite32be(0, pci-regs-piw[i].piwar);
 
/* Setup outbound MEM window */
-   for(i = 0, j = 1; i  3; i++) {
-   if (!(hose-mem_resources[i].flags  IORESOURCE_MEM))
+   for (i = 0, j = 1; i  3; i++) {
+   if (!(pci-mem_resources[i].flags  IORESOURCE_MEM))
continue;
 
-   paddr_lo = min(paddr_lo, (u64)hose-mem_resources[i].start);
-   paddr_hi = max(paddr_hi, (u64)hose-mem_resources[i].end);
+   paddr_lo = min_t(u64, paddr_lo, pci-mem_resources[i].start);
+   paddr_hi = max_t(u64, paddr_hi, pci-mem_resources[i].end);
 
/* We assume all memory resources have the same offset */
-   offset = hose-mem_offset[i];
-   n = setup_one_atmu(pci, j, hose-mem_resources[i], offset);
+   offset = pci-mem_offset[i];
+   n = setup_one_atmu(pci-regs, j, pci-mem_resources[i],
+  offset

[PATCH 07/12][v4] pci: fsl: port PCI platform driver

2014-01-07 Thread Minghuan Lian
1. The patch ports FSL PCI platform driver. probe function
initialize fsl_pci and register it to architecture PCI system,
remove function removes fsl_pci from architecture PCI system.
fsl_arch_pci_sys_register() and fsl_arch_pci_sys_remove() should
be implemented in architecture-specific driver to provide
register/remove functionality.
2. Remove architecture-specific header and unnecessary header.
3. Change Kconfig and Makefile to support FSL PCI common driver

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/Kconfig  |  1 +
 drivers/pci/host/Kconfig  | 10 +
 drivers/pci/host/Makefile |  1 +
 drivers/pci/host/pci-fsl-common.c | 43 +++
 include/linux/fsl/pci-common.h|  6 ++
 5 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b44b52c..c708d80 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -694,6 +694,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCI_FSL_COMMON if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 47d46c6..290afaa 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -33,4 +33,14 @@ config PCI_RCAR_GEN2
  There are 3 internal PCI controllers available with a single
  built-in EHCI/OHCI host controller present on each one.
 
+config PCI_FSL_COMMON
+   bool Common driver for Freescale PCI/PCIe controller
+   depends on FSL_SOC_BOOKE || PPC_86xx
+   help
+ This driver provides common support for PCI/PCIE controller
+ on Freescale embedded processors 85xx/86xx/QorIQ/Layerscape.
+ Additional drivers must be enabled in order to provide some
+ architecture-dependent functions and register the controller
+ to PCI subsystem.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 13fb333..1f8de80 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
+obj-$(CONFIG_PCI_FSL_COMMON) += pci-fsl-common.o
diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 7184ac7..d608550 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -16,16 +16,12 @@
  */
 #include linux/kernel.h
 #include linux/pci.h
-#include linux/delay.h
-#include linux/string.h
 #include linux/init.h
-#include linux/bootmem.h
 #include linux/memblock.h
 #include linux/log2.h
-#include linux/slab.h
-#include linux/uaccess.h
 #include linux/of_address.h
 #include linux/of_pci.h
+#include linux/fsl/pci-common.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -665,12 +661,40 @@ static const struct of_device_id pci_ids[] = {
 static int fsl_pci_probe(struct platform_device *pdev)
 {
int ret;
-   struct device_node *node;
+   struct fsl_pci *pci;
 
-   node = pdev-dev.of_node;
-   ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+   if (!of_device_is_available(pdev-dev.of_node)) {
+   dev_dbg(pdev-dev, disabled\n);
+   return -ENODEV;
+   }
+
+   pci = devm_kzalloc(pdev-dev, sizeof(*pci), GFP_KERNEL);
+   if (!pci) {
+   dev_err(pdev-dev, no memory for fsl_pci\n);
+   return -ENOMEM;
+   }
+
+   ret = fsl_pci_setup(pdev, pci);
+   if (ret)
+   return ret;
+
+   ret = fsl_arch_pci_sys_register(pci);
+   if (ret) {
+   dev_err(pdev-dev, failed to register pcie to Arch\n);
+   return ret;
+   }
+
+   return 0;
+}
+
+static int fsl_pci_remove(struct platform_device *pdev)
+{
+   struct fsl_pci *pci = platform_get_drvdata(pdev);
+
+   if (!pci)
+   return -ENODEV;
 
-   mpc85xx_pci_err_probe(pdev);
+   fsl_arch_pci_sys_remove(pci);
 
return 0;
 }
@@ -714,6 +738,7 @@ static struct platform_driver fsl_pci_driver = {
.of_match_table = pci_ids,
},
.probe = fsl_pci_probe,
+   .remove = fsl_pci_remove,
 };
 
 static int __init fsl_pci_init(void)
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 02bcf5b..8d33354 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -166,5 +166,11 @@ extern struct pci_bus *fsl_arch_fake_pci_bus(struct 
fsl_pci *pci, int busnr);
 /* Return PCI64 DMA offset */
 u64 fsl_arch_pci64_dma_offset(void);
 
+/* Register PCI/PCIe controller to architecture system */
+extern

[PATCH 08/12][v4] pci: fsl: add PowerPC PCI driver

2014-01-07 Thread Minghuan Lian
1. Implement fsl_arch_pci64_dma_offset() to return PowerPC PCI64
DMA offset
2. Implement fsl_arch_sys_to_pci() to convert pci_controller
to fsl_pci
3. Implement fsl_arch_fake_pci_bus() to fake pci_controller
and PCI bus.
4. Implement fsl_arch_pci_exclude_device() to call
ppc_md.pci_exclude_device()
5. Implement fsl_arch_pci_sys_register() to initialize pci_controller
according to fsl_pci, add register PCI controller to PowerPC PCI
subsystem.
6. Implement fsl_arch_pci_sys_remove() to remove PCI controller from
PowerPC PCI subsystem.
7. Add mpc83xx_pcie_check_link() because pci-fsl-common dose not
support mpc83xx.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c | 142 +++---
 1 file changed, 135 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 0764385..38e8dca 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -62,7 +62,11 @@ static void quirk_fsl_pcie_early(struct pci_dev *dev)
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
 #define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
+
+u64 fsl_arch_pci64_dma_offset(void)
+{
+   return 1ull  MAX_PHYS_ADDR_BITS;
+}
 
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
@@ -77,17 +81,44 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
if ((dev-bus == pci_bus_type) 
dma_mask = DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, dma_direct_ops);
-   set_dma_offset(dev, pci64_dma_offset);
+   set_dma_offset(dev, fsl_arch_pci64_dma_offset());
}
 
*dev-dma_mask = dma_mask;
return 0;
 }
 
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
+{
+   struct pci_controller *hose = sys;
+   struct fsl_pci *pci = hose-private_data;
+
+   /* Update the first bus number */
+   if (pci-first_busno != hose-first_busno)
+   pci-first_busno = hose-first_busno;
+
+   return pci;
+}
+
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+   static struct pci_bus bus;
+   static struct pci_controller hose;
+
+   bus.number = busnr;
+   bus.sysdata = hose;
+   hose.private_data = pci;
+   bus.ops = pci-ops;
+
+   return bus;
+}
+
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
-   int i, is_pcie = 0, no_link;
+   bool is_pcie, no_link;
+   int i;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(hose);
 
/* The root complex bridge comes up with bogus resources,
 * we copy the PHB ones in.
@@ -97,9 +128,8 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 * tricky.
 */
 
-   if (fsl_pcie_bus_fixup)
-   is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
-   no_link = !!(hose-indirect_type  PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+   is_pcie = pci-is_pcie;
+   no_link = !fsl_pci_check_link(pci);
 
if (bus-parent == hose-bus  (is_pcie || no_link)) {
for (i = 0; i  PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -121,6 +151,94 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
 }
 
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   struct pci_controller *hose = pci-sys;
+
+   if (!hose)
+   return PCIBIOS_SUCCESSFUL;
+
+   if (ppc_md.pci_exclude_device)
+   if (ppc_md.pci_exclude_device(hose, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   return PCIBIOS_SUCCESSFUL;
+}
+
+int fsl_arch_pci_sys_register(struct fsl_pci *pci)
+{
+   struct pci_controller *hose;
+
+   pci_add_flags(PCI_REASSIGN_ALL_BUS);
+   hose = pcibios_alloc_controller(pci-dn);
+   if (!hose)
+   return -ENOMEM;
+
+   /* set platform device as the parent */
+   hose-private_data = pci;
+   hose-parent = pci-dev;
+   hose-first_busno = pci-first_busno;
+   hose-last_busno = pci-last_busno;
+   hose-ops = pci-ops;
+
+#ifdef CONFIG_PPC32
+   /* On 32 bits, limit I/O space to 16MB */
+   if (pci-pci_io_size  0x0100)
+   pci-pci_io_size = 0x0100;
+
+   /* 32 bits needs to map IOs here */
+   hose-io_base_virt = ioremap(pci-io_base_phys + pci-io_resource.start,
+pci-pci_io_size);
+
+   /* Expect trouble if pci_addr is not 0 */
+   if (fsl_pci_primary == pci-dn)
+   isa_io_base = (unsigned long)hose-io_base_virt;
+#endif /* CONFIG_PPC32 */
+
+   hose-pci_io_size = pci-io_resource.start + pci-pci_io_size

[PATCH 06/12][v4] pci: fsl: port PCI controller setup code

2014-01-07 Thread Minghuan Lian
PCI controller setup code will initialize structure fsl_pci
according to PCI dts node and initialize PCI command register
and ATMU. The patch uses general API of_pci_parse_bus_range
to parse PCI bus range, uses general of_address's API to parse
PCI IO/MEM ranges.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 179 +-
 1 file changed, 97 insertions(+), 82 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 26ee4c3..7184ac7 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -24,6 +24,8 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/of_address.h
+#include linux/of_pci.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -498,131 +500,144 @@ static void setup_pci_atmu(struct fsl_pci *pci)
}
 }
 
-static void __init setup_pci_cmd(struct pci_controller *hose)
+static void __init setup_pci_cmd(struct fsl_pci *pci)
 {
u16 cmd;
int cap_x;
 
-   early_read_config_word(hose, 0, 0, PCI_COMMAND, cmd);
+   early_fsl_read_config_word(pci, 0, 0, PCI_COMMAND, cmd);
cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
| PCI_COMMAND_IO;
-   early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
+   early_fsl_write_config_word(pci, 0, 0, PCI_COMMAND, cmd);
 
-   cap_x = early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX);
+   cap_x = early_fsl_find_capability(pci, 0, 0, PCI_CAP_ID_PCIX);
if (cap_x) {
int pci_x_cmd = cap_x + PCI_X_CMD;
cmd = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
-   early_write_config_word(hose, 0, 0, pci_x_cmd, cmd);
-   } else {
-   early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
-   }
+   early_fsl_write_config_word(pci, 0, 0, pci_x_cmd, cmd);
+   } else
+   early_fsl_write_config_byte(pci, 0, 0, PCI_LATENCY_TIMER,
+   0x80);
 }
 
-int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
+static int __init
+fsl_pci_setup(struct platform_device *pdev, struct fsl_pci *pci)
 {
-   int len;
-   struct pci_controller *hose;
-   struct resource rsrc;
-   const int *bus_range;
+   struct resource *rsrc;
u8 hdr_type, progif;
-   struct device_node *dev;
-   struct ccsr_pci __iomem *pci;
-
-   dev = pdev-dev.of_node;
+   struct device_node *dn;
+   struct of_pci_range range;
+   struct of_pci_range_parser parser;
+   int mem = 0;
 
-   if (!of_device_is_available(dev)) {
-   pr_warning(%s: disabled\n, dev-full_name);
-   return -ENODEV;
-   }
+   dn = pdev-dev.of_node;
+   pci-dn = dn;
+   pci-dev = pdev-dev;
 
-   pr_debug(Adding PCI host bridge %s\n, dev-full_name);
+   dev_info(pdev-dev, Find controller %s\n, dn-full_name);
 
/* Fetch host bridge registers address */
-   if (of_address_to_resource(dev, 0, rsrc)) {
-   printk(KERN_WARNING Can't get pci register base!);
-   return -ENOMEM;
+   rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!rsrc) {
+   dev_err(pdev-dev, Can't get pci register base!);
+   return -EINVAL;
}
+   dev_info(pdev-dev, REG 0x%016llx..0x%016llx\n,
+(u64)rsrc-start, (u64)rsrc-end);
 
-   /* Get bus range if any */
-   bus_range = of_get_property(dev, bus-range, len);
-   if (bus_range == NULL || len  2 * sizeof(int))
-   printk(KERN_WARNING Can't get bus-range for %s, assume
-bus 0\n, dev-full_name);
-
-   pci_add_flags(PCI_REASSIGN_ALL_BUS);
-   hose = pcibios_alloc_controller(dev);
-   if (!hose)
-   return -ENOMEM;
+   /* Parse pci range resources from device tree */
+   if (of_pci_range_parser_init(parser, dn)) {
+   dev_err(pdev-dev, missing ranges property\n);
+   return -EINVAL;
+   }
 
-   /* set platform device as the parent */
-   hose-parent = pdev-dev;
-   hose-first_busno = bus_range ? bus_range[0] : 0x0;
-   hose-last_busno = bus_range ? bus_range[1] : 0xff;
+   /* Get the I/O and memory ranges from device tree */
+   for_each_of_pci_range(parser, range) {
+   unsigned long restype = range.flags  IORESOURCE_TYPE_BITS;
+   if (restype == IORESOURCE_IO) {
+   of_pci_range_to_resource(range, dn,
+pci-io_resource

[PATCH 11/12][v4] pci: fsl: update PCI EDAC driver

2014-01-07 Thread Minghuan Lian
1. The pci-fsl-common driver has set fsl_pci to device as drvdata,
so EDAC driver can not call dev_set_drvdata() again. fsl_pci
contains regs field to point PCI CCSR, so EDAC may directly use
the pointer and not need to call devm_ioremap().
2. Add mpc85xx_pci_err_remove() to disable PCI error interrupt
and delete PCI EDAC from EDAC subsystem.
3. AER uses the same IRQ, so change IRQ handling mode as shared
to avoid AER can not request IRQ.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
Changed IRQ handling mode as shared to avoid aer can not request IRQ.
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/
Added mpc85xx_pci_err_remove()

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.h |  6 +
 drivers/edac/mpc85xx_edac.c   | 61 +--
 drivers/edac/mpc85xx_edac.h   |  1 +
 4 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 6d9bec4..2e3455e 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -236,6 +236,7 @@ void fsl_arch_pci_sys_remove(struct fsl_pci *pci)
if (!hose)
return;
 
+   mpc85xx_pci_err_remove(to_platform_device(pci-dev));
pcibios_free_controller(hose);
 }
 
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index ce77aad..ae4dbe2 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -35,11 +35,17 @@ static inline void fsl_pci_assign_primary(void) {}
 
 #ifdef CONFIG_EDAC_MPC85XX
 int mpc85xx_pci_err_probe(struct platform_device *op);
+int mpc85xx_pci_err_remove(struct platform_device *op);
 #else
 static inline int mpc85xx_pci_err_probe(struct platform_device *op)
 {
return -ENOTSUPP;
 }
+static inline int mpc85xx_pci_err_remove(struct platform_device *op)
+{
+   return -ENOTSUPP;
+}
+
 #endif
 
 #ifdef CONFIG_FSL_PCI
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index fd46b0b..ea37db9 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -21,6 +21,7 @@
 
 #include linux/of_platform.h
 #include linux/of_device.h
+#include linux/fsl/pci-common.h
 #include edac_module.h
 #include edac_core.h
 #include mpc85xx_edac.h
@@ -214,11 +215,13 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
 
 int mpc85xx_pci_err_probe(struct platform_device *op)
 {
+   struct fsl_pci *fslpci;
struct edac_pci_ctl_info *pci;
struct mpc85xx_pci_pdata *pdata;
-   struct resource r;
int res = 0;
 
+   fslpci = platform_get_drvdata(op);
+
if (!devres_open_group(op-dev, mpc85xx_pci_err_probe, GFP_KERNEL))
return -ENOMEM;
 
@@ -239,7 +242,6 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
pdata = pci-pvt_info;
pdata-name = mpc85xx_pci_err;
pdata-irq = NO_IRQ;
-   dev_set_drvdata(op-dev, pci);
pci-dev = op-dev;
pci-mod_name = EDAC_MOD_STR;
pci-ctl_name = pdata-name;
@@ -250,30 +252,8 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
 
pdata-edac_idx = edac_pci_idx++;
 
-   res = of_address_to_resource(op-dev.of_node, 0, r);
-   if (res) {
-   printk(KERN_ERR %s: Unable to get resource for 
-  PCI err regs\n, __func__);
-   goto err;
-   }
-
/* we only need the error registers */
-   r.start += 0xe00;
-
-   if (!devm_request_mem_region(op-dev, r.start, resource_size(r),
-   pdata-name)) {
-   printk(KERN_ERR %s: Error while requesting mem region\n,
-  __func__);
-   res = -EBUSY;
-   goto err;
-   }
-
-   pdata-pci_vbase = devm_ioremap(op-dev, r.start, resource_size(r));
-   if (!pdata-pci_vbase) {
-   printk(KERN_ERR %s: Unable to setup PCI err regs\n, __func__);
-   res = -ENOMEM;
-   goto err;
-   }
+   pdata-pci_vbase = (void *)fslpci-regs + MPC85XX_PCI_ERR_OFFSET;
 
orig_pci_err_cap_dr =
in_be32(pdata-pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
@@ -297,7 +277,8 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
if (edac_op_state == EDAC_OPSTATE_INT) {
pdata-irq = irq_of_parse_and_map(op-dev.of_node, 0);
res = devm_request_irq(op-dev, pdata-irq,
-  mpc85xx_pci_isr, IRQF_DISABLED,
+  mpc85xx_pci_isr,
+  IRQF_DISABLED | IRQF_SHARED,
   [EDAC] PCI err, pci);
if (res  0) {
printk(KERN_ERR
@@ -327,6 +308,34 @@ err:
 }
 EXPORT_SYMBOL(mpc85xx_pci_err_probe);
 
+int mpc85xx_pci_err_remove(struct

[PATCH 12/12][v4] pci: fsl: fix function check_pci_ctl_endpt_part

2014-01-07 Thread Minghuan Lian
The new FSL PCI driver does not use cfg_addr of pci_controller,
we may directly access PCI CCSR using fsl_pci-regs.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
The new patch to fix function check_pci_ctl_endpt_part

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.h   | 5 -
 drivers/iommu/fsl_pamu_domain.c | 6 --
 include/linux/fsl/pci-common.h  | 1 +
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index ae4dbe2..3176eb2 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -16,11 +16,6 @@
 
 struct platform_device;
 
-
-/* FSL PCI controller BRR1 register */
-#define PCI_FSL_BRR1  0xbf8
-#define PCI_FSL_BRR1_VER 0x
-
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
 extern int mpc83xx_add_bridge(struct device_node *dev);
 u64 fsl_pci_immrbar_base(struct pci_controller *hose);
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index c857c30..dd7bc25 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -36,6 +36,7 @@
 
 #include asm/pci-bridge.h
 #include sysdev/fsl_pci.h
+#include linux/fsl/pci-common.h
 
 #include fsl_pamu_domain.h
 #include pci.h
@@ -908,10 +909,11 @@ static struct iommu_group *get_device_iommu_group(struct 
device *dev)
 static  bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl)
 {
u32 version;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(pci_ctl);
 
/* Check the PCI controller version number by readding BRR1 register */
-   version = in_be32(pci_ctl-cfg_addr + (PCI_FSL_BRR1  2));
-   version = PCI_FSL_BRR1_VER;
+   version = in_be32(pci-regs-block_rev1);
+   version = PCIE_IP_REV_MASK;
/* If PCI controller version is = 0x204 we can partition endpoints*/
if (version = 0x204)
return 1;
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 3247682..4e4191e 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -18,6 +18,7 @@
 #define PCIE_LTSSM_L0  0x16/* L0 state */
 #define PCIE_IP_REV_2_20x02080202 /* PCIE IP block version 
Rev2.2 */
 #define PCIE_IP_REV_3_00x02080300 /* PCIE IP block version 
Rev3.0 */
+#define PCIE_IP_REV_MASK   0x
 #define PIWAR_EN   0x8000  /* Enable */
 #define PIWAR_PF   0x2000  /* prefetch */
 #define PIWAR_TGI_LOCAL0x00f0  /* target - local 
memory */
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 09/12][v4] pci: fsl: update PCI PM driver

2014-01-07 Thread Minghuan Lian
The patch updates PCI PM driver, uses fsl_pci instead of
pci_controller.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index d608550..e3696eb 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -702,19 +702,12 @@ static int fsl_pci_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int fsl_pci_resume(struct device *dev)
 {
-   struct pci_controller *hose;
-   struct resource pci_rsrc;
+   struct fsl_pci *pci = dev_get_drvdata(dev);
 
-   hose = pci_find_hose_for_OF_device(dev-of_node);
-   if (!hose)
+   if (!pci)
return -ENODEV;
 
-   if (of_address_to_resource(dev-of_node, 0, pci_rsrc)) {
-   dev_err(dev, Get pci register base failed.);
-   return -ENODEV;
-   }
-
-   setup_pci_atmu(hose);
+   setup_pci_atmu(pci);
 
return 0;
 }
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 10/12][v4] pci: fsl: support function fsl_pci_assign_primary

2014-01-07 Thread Minghuan Lian
Change pci_ids to fsl_pci_ids Freescale-specific name and change
static to extern modifier for using in fsl_pci_assign_primary().

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v4:
no change
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c | 5 +++--
 drivers/pci/host/pci-fsl-common.c | 4 ++--
 include/linux/fsl/pci-common.h| 2 ++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 38e8dca..6d9bec4 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -736,7 +736,8 @@ void fsl_pci_assign_primary(void)
of_node_put(np);
np = fsl_pci_primary;
 
-   if (of_match_node(pci_ids, np)  of_device_is_available(np))
+   if (of_match_node(fsl_pci_ids, np) 
+   of_device_is_available(np))
return;
}
 
@@ -745,7 +746,7 @@ void fsl_pci_assign_primary(void)
 * designate one as primary.  This can go away once
 * various bugs with primary-less systems are fixed.
 */
-   for_each_matching_node(np, pci_ids) {
+   for_each_matching_node(np, fsl_pci_ids) {
if (of_device_is_available(np)) {
fsl_pci_primary = np;
of_node_put(np);
diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index e3696eb..0be7bc0 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -637,7 +637,7 @@ no_bridge:
return -ENODEV;
 }
 
-static const struct of_device_id pci_ids[] = {
+const struct of_device_id fsl_pci_ids[] = {
{ .compatible = fsl,mpc8540-pci, },
{ .compatible = fsl,mpc8548-pcie, },
{ .compatible = fsl,mpc8610-pci, },
@@ -728,7 +728,7 @@ static struct platform_driver fsl_pci_driver = {
.driver = {
.name = fsl-pci,
.pm = PCI_PM_OPS,
-   .of_match_table = pci_ids,
+   .of_match_table = fsl_pci_ids,
},
.probe = fsl_pci_probe,
.remove = fsl_pci_remove,
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 8d33354..3247682 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -143,6 +143,8 @@ struct fsl_pci {
void *sys;
 };
 
+extern const struct of_device_id fsl_pci_ids[];
+
 /*
  * Convert architecture specific pci controller structure to fsl_pci
  * PowerPC uses structure pci_controller and ARM uses structure pci_sys_data
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 02/12][v3] pci: fsl: add structure fsl_pci

2013-10-23 Thread Minghuan Lian
PowerPC uses structure pci_controller to describe PCI controller,
but ARM uses structure pci_sys_data. In order to support PowerPC
and ARM simultaneously, the patch adds a structure fsl_pci that
contains most of the members of the pci_controller and pci_sys_data.
Meanwhile, it defines a interface fsl_arch_sys_to_pci() which should
be implemented in architecture-specific PCI controller driver to
convert pci_controller or pci_sys_data to fsl_pci.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 include/linux/fsl/pci-common.h | 41 +
 1 file changed, 41 insertions(+)

diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 5e4f683..e56a040 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -102,5 +102,46 @@ struct ccsr_pci {
 
 };
 
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct fsl_pci {
+   struct list_head node;
+   bool is_pcie;
+   struct device_node *dn;
+   struct device *dev;
+
+   int first_busno;
+   int last_busno;
+   int self_busno;
+   struct resource busn;
+
+   struct pci_ops *ops;
+   struct ccsr_pci __iomem *regs;
+
+   u32 indirect_type;
+
+   struct resource io_resource;
+   resource_size_t io_base_phys;
+   resource_size_t pci_io_size;
+
+   struct resource mem_resources[3];
+   resource_size_t mem_offset[3];
+
+   int global_number;  /* PCI domain number */
+
+   resource_size_t dma_window_base_cur;
+   resource_size_t dma_window_size;
+
+   void *sys;
+};
+
+/*
+ * Convert architecture specific pci controller structure to fsl_pci
+ * PowerPC uses structure pci_controller and ARM uses structure pci_sys_data
+ * to describe pci controller.
+ */
+extern struct fsl_pci *fsl_arch_sys_to_pci(void *sys);
+
 #endif /* __PCI_COMMON_H */
 #endif /* __KERNEL__ */
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 01/12][v3] pci: fsl: derive the common PCI driver to drivers/pci/host

2013-10-23 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pci-fsl-common.c and leaves the architecture
specific functions which should be implemented in arch related files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v2-v3:
no change
v1-v2:
1. rename pci.h to pci-common.h 
2. rename pci-fsl.c to pci-fsl-common.c

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c  | 521 +-
 arch/powerpc/sysdev/fsl_pci.h  |  89 
 .../fsl_pci.c = drivers/pci/host/pci-fsl-common.c | 591 +
 .../fsl_pci.h = include/linux/fsl/pci-common.h|  45 +-
 4 files changed, 7 insertions(+), 1239 deletions(-)
 copy arch/powerpc/sysdev/fsl_pci.c = drivers/pci/host/pci-fsl-common.c (54%)
 copy arch/powerpc/sysdev/fsl_pci.h = include/linux/fsl/pci-common.h (79%)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ccfb50d..26039e3 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -27,6 +27,7 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/fsl/pci-common.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -58,57 +59,8 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
-
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = hose-first_busno;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
-
-   return 0;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
-{
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
-}
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
 #define MAX_PHYS_ADDR_BITS 40
 static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
 
@@ -132,291 +84,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
return 0;
 }
 
-static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
-{
-   resource_size_t pci_addr = res-start - offset;
-   resource_size_t phys_addr = res-start;
-   resource_size_t size = resource_size(res);
-   u32 flags = 0x80044000; /* enable  mem R/W */
-   unsigned int i;
-
-   pr_debug(PCI MEM resource start 0x%016llx, size 0x%016llx.\n,
-   (u64)res-start, (u64)size);
-
-   if (res-flags  IORESOURCE_PREFETCH)
-   flags |= 0x1000; /* enable relaxed ordering */
-
-   for (i = 0; size  0; i++) {
-   unsigned int bits = min(ilog2(size),
-   __ffs(pci_addr | phys_addr));
-
-   if (index + i = 5)
-   return -1;
-
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
-
-   pci_addr += (resource_size_t)1U  bits;
-   phys_addr += (resource_size_t)1U  bits;
-   size -= (resource_size_t)1U  bits

[PATCH 04/12][v3] pci: fsl: add early PCI indirect access support

2013-10-23 Thread Minghuan Lian
The driver needs to read/write PCI configuration very early, at
that time architecture-specific PCI controller structure and
PCI bus have not been created. The patch provides an interface
fsl_arch_fake_pci_bus which should be implemented in
architecture-specific PCI driver to fake a PCI controller structure
and PCI bus. Using the fake PCI controller and PCI bus, the patch
provides the early indirect read/write functions.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 26 ++
 include/linux/fsl/pci-common.h|  7 +++
 2 files changed, 33 insertions(+)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 8bc9a64..505a6a1 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -204,6 +204,32 @@ static struct pci_ops fsl_indirect_pci_ops = {
.write = fsl_indirect_write_config,
 };
 
+#define EARLY_FSL_PCI_OP(rw, size, type)   \
+int early_fsl_##rw##_config_##size(struct fsl_pci *pci, int bus,   \
+  int devfn, int offset, type value)   \
+{  \
+   return pci_bus_##rw##_config_##size(fsl_arch_fake_pci_bus(pci, bus),\
+   devfn, offset, value);  \
+}
+
+EARLY_FSL_PCI_OP(read, byte, u8 *)
+EARLY_FSL_PCI_OP(read, word, u16 *)
+EARLY_FSL_PCI_OP(read, dword, u32 *)
+EARLY_FSL_PCI_OP(write, byte, u8)
+EARLY_FSL_PCI_OP(write, word, u16)
+EARLY_FSL_PCI_OP(write, dword, u32)
+
+static int early_fsl_find_capability(struct fsl_pci *pci,
+int busnr, int devfn, int cap)
+{
+   struct pci_bus *bus = fsl_arch_fake_pci_bus(pci, busnr);
+
+   if (!bus)
+   return 0;
+
+   return pci_bus_find_capability(bus, devfn, cap);
+}
+
 static int setup_one_atmu(struct ccsr_pci __iomem *pci,
unsigned int index, const struct resource *res,
resource_size_t offset)
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 7df4355..a3aca29 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -149,5 +149,12 @@ bool fsl_pci_check_link(struct fsl_pci *pci);
 /* To avoid touching specified devices */
 int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn);
 
+/*
+ * To fake a PCI bus
+ * it is called by early_fsl_*(), at that time the architecture-dependent
+ * pci controller and pci bus have not been created.
+ */
+extern struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr);
+
 #endif /* __PCI_COMMON_H */
 #endif /* __KERNEL__ */
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 05/12][v3] pci: fsl: port PCI ATMU related code

2013-10-23 Thread Minghuan Lian
The patch ports PCI ATMU related code, just uses general IO API
iowrite32be/ioread32be instead of out_be32/in_be32, uses structure
fsl_pci instead of PowerPC's pci_controller and uses dev_*()
instead of pr_*() to output the information.
The patch also provides the weak function
fsl_arch_pci64_dma_offset(), the architecture-specific driver may
return different offset.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 191 --
 include/linux/fsl/pci-common.h|   3 +
 2 files changed, 104 insertions(+), 90 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 505a6a1..f15b605 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -42,6 +42,11 @@
 #define INDIRECT_TYPE_BIG_ENDIAN   0x0010
 #define INDIRECT_TYPE_FSL_CFG_REG_LINK 0x0040
 
+u64 __weak fsl_arch_pci64_dma_offset(void)
+{
+   return 0;
+}
+
 int __weak fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
 {
return PCIBIOS_SUCCESSFUL;
@@ -231,8 +236,8 @@ static int early_fsl_find_capability(struct fsl_pci *pci,
 }
 
 static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
+ unsigned int index, const struct resource *res,
+ resource_size_t offset)
 {
resource_size_t pci_addr = res-start - offset;
resource_size_t phys_addr = res-start;
@@ -253,10 +258,10 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
if (index + i = 5)
return -1;
 
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
+   iowrite32be(pci_addr  12, pci-pow[index + i].potar);
+   iowrite32be((u64)pci_addr  44, pci-pow[index + i].potear);
+   iowrite32be(phys_addr  12, pci-pow[index + i].powbar);
+   iowrite32be(flags | (bits - 1), pci-pow[index + i].powar);
 
pci_addr += (resource_size_t)1U  bits;
phys_addr += (resource_size_t)1U  bits;
@@ -267,21 +272,19 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 }
 
 /* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose)
+static void setup_pci_atmu(struct fsl_pci *pci)
 {
-   struct ccsr_pci __iomem *pci = hose-private_data;
int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
u64 mem, sz, paddr_hi = 0;
u64 offset = 0, paddr_lo = ULLONG_MAX;
u32 pcicsrbar = 0, pcicsrbar_sz;
u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
-   const char *name = hose-dn-full_name;
const u64 *reg;
int len;
 
-   if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
-   if (in_be32(pci-block_rev1) = PCIE_IP_REV_2_2) {
+   if (pci-is_pcie) {
+   if (in_be32(pci-regs-block_rev1) = PCIE_IP_REV_2_2) {
win_idx = 2;
start_idx = 0;
end_idx = 3;
@@ -289,47 +292,54 @@ static void setup_pci_atmu(struct pci_controller *hose)
}
 
/* Disable all windows (except powar0 since it's ignored) */
-   for(i = 1; i  5; i++)
-   out_be32(pci-pow[i].powar, 0);
+   for (i = 1; i  5; i++)
+   iowrite32be(0, pci-regs-pow[i].powar);
for (i = start_idx; i  end_idx; i++)
-   out_be32(pci-piw[i].piwar, 0);
+   iowrite32be(0, pci-regs-piw[i].piwar);
 
/* Setup outbound MEM window */
-   for(i = 0, j = 1; i  3; i++) {
-   if (!(hose-mem_resources[i].flags  IORESOURCE_MEM))
+   for (i = 0, j = 1; i  3; i++) {
+   if (!(pci-mem_resources[i].flags  IORESOURCE_MEM))
continue;
 
-   paddr_lo = min(paddr_lo, (u64)hose-mem_resources[i].start);
-   paddr_hi = max(paddr_hi, (u64)hose-mem_resources[i].end);
+   paddr_lo = min_t(u64, paddr_lo, pci-mem_resources[i].start);
+   paddr_hi = max_t(u64, paddr_hi, pci-mem_resources[i].end);
 
/* We assume all memory resources have the same offset */
-   offset = hose-mem_offset[i];
-   n = setup_one_atmu(pci, j, hose-mem_resources[i], offset);
+   offset = pci-mem_offset[i];
+   n = setup_one_atmu(pci-regs, j

[PATCH 03/12][v3] pci: fsl: add PCI indirect access support

2013-10-23 Thread Minghuan Lian
The patch adds PCI indirect read/write functions. The main code
is ported from arch/powerpc/sysdev/indirect_pci.c. We use general
IO API iowrite32be/ioread32be instead of out_be32/in_be32, and
use structure fsl_Pci instead of PowerPC's pci_controller.
The patch also provides fsl_pcie_check_link() to check PCI link.
The weak function fsl_arch_pci_exclude_device() is provided to
call ppc_md.pci_exclude_device() for PowerPC architecture.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 169 --
 include/linux/fsl/pci-common.h|   6 ++
 2 files changed, 151 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 69d338b..8bc9a64 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -35,52 +35,173 @@
 #include sysdev/fsl_soc.h
 #include sysdev/fsl_pci.h
 
-static int fsl_pcie_check_link(struct pci_controller *hose)
+/* Indirect type */
+#define INDIRECT_TYPE_EXT_REG  0x0002
+#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x0004
+#define INDIRECT_TYPE_NO_PCIE_LINK 0x0008
+#define INDIRECT_TYPE_BIG_ENDIAN   0x0010
+#define INDIRECT_TYPE_FSL_CFG_REG_LINK 0x0040
+
+int __weak fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   return PCIBIOS_SUCCESSFUL;
+}
+
+static int fsl_pci_read_config(struct fsl_pci *pci, int bus, int devfn,
+   int offset, int len, u32 *val)
+{
+   u32 bus_no, reg, data;
+
+   if (pci-indirect_type  INDIRECT_TYPE_NO_PCIE_LINK) {
+   if (bus != pci-first_busno)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   if (devfn != 0)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   }
+
+   if (fsl_arch_pci_exclude_device(pci, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   bus_no = (bus == pci-first_busno) ? pci-self_busno : bus;
+
+   if (pci-indirect_type  INDIRECT_TYPE_EXT_REG)
+   reg = ((offset  0xf00)  16) | (offset  0xfc);
+   else
+   reg = offset  0xfc;
+
+   if (pci-indirect_type  INDIRECT_TYPE_BIG_ENDIAN)
+   iowrite32be(0x8000 | (bus_no  16) | (devfn  8) | reg,
+   pci-regs-config_addr);
+   else
+   iowrite32(0x8000 | (bus_no  16) | (devfn  8) | reg,
+ pci-regs-config_addr);
+
+   /*
+* Note: the caller has already checked that offset is
+* suitably aligned and that len is 1, 2 or 4.
+*/
+   data = ioread32(pci-regs-config_data);
+   switch (len) {
+   case 1:
+   *val = (data  (8 * (offset  3)))  0xff;
+   break;
+   case 2:
+   *val = (data  (8 * (offset  3)))  0x;
+   break;
+   default:
+   *val = data;
+   break;
+   }
+
+   return PCIBIOS_SUCCESSFUL;
+}
+
+static int fsl_pci_write_config(struct fsl_pci *pci, int bus, int devfn,
+int offset, int len, u32 val)
+{
+   void __iomem *cfg_data;
+   u32 bus_no, reg;
+
+   if (pci-indirect_type  INDIRECT_TYPE_NO_PCIE_LINK) {
+   if (bus != pci-first_busno)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   if (devfn != 0)
+   return PCIBIOS_DEVICE_NOT_FOUND;
+   }
+
+   if (fsl_arch_pci_exclude_device(pci, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   bus_no = (bus == pci-first_busno) ?
+   pci-self_busno : bus;
+
+   if (pci-indirect_type  INDIRECT_TYPE_EXT_REG)
+   reg = ((offset  0xf00)  16) | (offset  0xfc);
+   else
+   reg = offset  0xfc;
+
+   if (pci-indirect_type  INDIRECT_TYPE_BIG_ENDIAN)
+   iowrite32be(0x8000 | (bus_no  16) | (devfn  8) | reg,
+   pci-regs-config_addr);
+   else
+   iowrite32(0x8000 | (bus_no  16) | (devfn  8) | reg,
+ pci-regs-config_addr);
+
+   /* suppress setting of PCI_PRIMARY_BUS */
+   if (pci-indirect_type  INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
+   if ((offset == PCI_PRIMARY_BUS) 
+   (bus == pci-first_busno))
+   val = 0xff00;
+
+   /*
+* Note: the caller has already checked that offset is
+* suitably aligned and that len is 1, 2 or 4.
+*/
+   cfg_data = ((void *) (pci-regs-config_data)) + (offset  3);
+   switch (len) {
+   case 1:
+   iowrite8(val, cfg_data);
+   break;
+   case 2

[PATCH 09/12][v3] pci: fsl: update PCI PM driver

2013-10-23 Thread Minghuan Lian
The patch updates PCI PM driver, uses fsl_pci instead of
pci_controller.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index c7bc472..729a5f4 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -699,19 +699,12 @@ static int fsl_pci_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int fsl_pci_resume(struct device *dev)
 {
-   struct pci_controller *hose;
-   struct resource pci_rsrc;
+   struct fsl_pci *pci = dev_get_drvdata(dev);
 
-   hose = pci_find_hose_for_OF_device(dev-of_node);
-   if (!hose)
+   if (!pci)
return -ENODEV;
 
-   if (of_address_to_resource(dev-of_node, 0, pci_rsrc)) {
-   dev_err(dev, Get pci register base failed.);
-   return -ENODEV;
-   }
-
-   setup_pci_atmu(hose);
+   setup_pci_atmu(pci);
 
return 0;
 }
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 07/12][v3] pci: fsl: port PCI platform driver

2013-10-23 Thread Minghuan Lian
1. The patch ports FSL PCI platform driver. probe function
initialize fsl_pci and register it to architecture PCI system,
remove function removes fsl_pci from architecture PCI system.
fsl_arch_pci_sys_register() and fsl_arch_pci_sys_remove() should
be implemented in architecture-specific driver to provide
register/remove functionality.
2. Remove architecture-specific header and unnecessary header.
3. Change Kconfig and Makefile to support FSL PCI common driver

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/Kconfig  |  1 +
 drivers/pci/host/Kconfig  | 10 
 drivers/pci/host/Makefile |  1 +
 drivers/pci/host/pci-fsl-common.c | 53 +--
 include/linux/fsl/pci-common.h|  6 +
 5 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 38f3b7e..7447d97d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -690,6 +690,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCI_FSL_COMMON if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 3d95048..48242b33 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -19,4 +19,14 @@ config PCI_TEGRA
bool NVIDIA Tegra PCIe controller
depends on ARCH_TEGRA
 
+config PCI_FSL_COMMON
+   bool Common driver for Freescale PCI/PCIe controller
+   depends on FSL_SOC_BOOKE || PPC_86xx
+   help
+ This driver provides common support for PCI/PCIE controller
+ on Freescale embedded processors 85xx/86xx/QorIQ/Layerscape.
+ Additional drivers must be enabled in order to provide some
+ architecture-dependent functions and register the controller
+ to PCI subsystem.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index c9a997b..7c338a7 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
+obj-$(CONFIG_PCI_FSL_COMMON) += pci-fsl-common.o
diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index e09a0ec..c7bc472 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -16,26 +16,12 @@
  */
 #include linux/kernel.h
 #include linux/pci.h
-#include linux/delay.h
-#include linux/string.h
 #include linux/init.h
-#include linux/bootmem.h
 #include linux/memblock.h
 #include linux/log2.h
-#include linux/slab.h
-#include linux/uaccess.h
 #include linux/of_address.h
 #include linux/of_pci.h
-
-#include asm/io.h
-#include asm/prom.h
-#include asm/pci-bridge.h
-#include asm/ppc-pci.h
-#include asm/machdep.h
-#include asm/disassemble.h
-#include asm/ppc-opcode.h
-#include sysdev/fsl_soc.h
-#include sysdev/fsl_pci.h
+#include linux/fsl/pci-common.h
 
 /* Indirect type */
 #define INDIRECT_TYPE_EXT_REG  0x0002
@@ -672,12 +658,40 @@ static const struct of_device_id pci_ids[] = {
 static int fsl_pci_probe(struct platform_device *pdev)
 {
int ret;
-   struct device_node *node;
+   struct fsl_pci *pci;
+
+   if (!of_device_is_available(pdev-dev.of_node)) {
+   dev_dbg(pdev-dev, disabled\n);
+   return -ENODEV;
+   }
+
+   pci = devm_kzalloc(pdev-dev, sizeof(*pci), GFP_KERNEL);
+   if (!pci) {
+   dev_err(pdev-dev, no memory for fsl_pci\n);
+   return -ENOMEM;
+   }
+
+   ret = fsl_pci_setup(pdev, pci);
+   if (ret)
+   return ret;
+
+   ret = fsl_arch_pci_sys_register(pci);
+   if (ret) {
+   dev_err(pdev-dev, failed to register pcie to Arch\n);
+   return ret;
+   }
+
+   return 0;
+}
 
-   node = pdev-dev.of_node;
-   ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+static int fsl_pci_remove(struct platform_device *pdev)
+{
+   struct fsl_pci *pci = platform_get_drvdata(pdev);
+
+   if (!pci)
+   return -ENODEV;
 
-   mpc85xx_pci_err_probe(pdev);
+   fsl_arch_pci_sys_remove(pci);
 
return 0;
 }
@@ -721,6 +735,7 @@ static struct platform_driver fsl_pci_driver = {
.of_match_table = pci_ids,
},
.probe = fsl_pci_probe,
+   .remove = fsl_pci_remove,
 };
 
 static int __init fsl_pci_init(void)
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 490ee53..bfb1f03 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -159,5 +159,11 @@ extern struct pci_bus

[PATCH 10/12][v3] pci: fsl: support function fsl_pci_assign_primary

2013-10-23 Thread Minghuan Lian
Change pci_ids to fsl_pci_ids Freescale-specific name and change
static to extern modifier for using in fsl_pci_assign_primary().

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c | 5 +++--
 drivers/pci/host/pci-fsl-common.c | 4 ++--
 include/linux/fsl/pci-common.h| 2 ++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 0a0c240..40d2e1d 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -735,7 +735,8 @@ void fsl_pci_assign_primary(void)
of_node_put(np);
np = fsl_pci_primary;
 
-   if (of_match_node(pci_ids, np)  of_device_is_available(np))
+   if (of_match_node(fsl_pci_ids, np) 
+   of_device_is_available(np))
return;
}
 
@@ -744,7 +745,7 @@ void fsl_pci_assign_primary(void)
 * designate one as primary.  This can go away once
 * various bugs with primary-less systems are fixed.
 */
-   for_each_matching_node(np, pci_ids) {
+   for_each_matching_node(np, fsl_pci_ids) {
if (of_device_is_available(np)) {
fsl_pci_primary = np;
of_node_put(np);
diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index 729a5f4..8b4f793 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -634,7 +634,7 @@ no_bridge:
return -ENODEV;
 }
 
-static const struct of_device_id pci_ids[] = {
+const struct of_device_id fsl_pci_ids[] = {
{ .compatible = fsl,mpc8540-pci, },
{ .compatible = fsl,mpc8548-pcie, },
{ .compatible = fsl,mpc8610-pci, },
@@ -725,7 +725,7 @@ static struct platform_driver fsl_pci_driver = {
.driver = {
.name = fsl-pci,
.pm = PCI_PM_OPS,
-   .of_match_table = pci_ids,
+   .of_match_table = fsl_pci_ids,
},
.probe = fsl_pci_probe,
.remove = fsl_pci_remove,
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index bfb1f03..84b0801 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -136,6 +136,8 @@ struct fsl_pci {
void *sys;
 };
 
+extern const struct of_device_id fsl_pci_ids[];
+
 /*
  * Convert architecture specific pci controller structure to fsl_pci
  * PowerPC uses structure pci_controller and ARM uses structure pci_sys_data
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 08/12][v3] pci: fsl: add PowerPC PCI driver

2013-10-23 Thread Minghuan Lian
1. Implement fsl_arch_pci64_dma_offset() to return PowerPC PCI64
DMA offset
2. Implement fsl_arch_sys_to_pci() to convert pci_controller
to fsl_pci
3. Implement fsl_arch_fake_pci_bus() to fake pci_controller
and PCI bus.
4. Implement fsl_arch_pci_exclude_device() to call
ppc_md.pci_exclude_device()
5. Implement fsl_arch_pci_sys_register() to initialize pci_controller
according to fsl_pci, add register PCI controller to PowerPC PCI
subsystem.
6. Implement fsl_arch_pci_sys_remove() to remove PCI controller from
PowerPC PCI subsystem.
7. Add mpc83xx_pcie_check_link() because pci-fsl-common dose not
support mpc83xx.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c | 142 +++---
 1 file changed, 135 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 26039e3..0a0c240 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -62,7 +62,11 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
 #define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
+
+u64 fsl_arch_pci64_dma_offset(void)
+{
+   return 1ull  MAX_PHYS_ADDR_BITS;
+}
 
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
@@ -77,17 +81,44 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
if ((dev-bus == pci_bus_type) 
dma_mask = DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, dma_direct_ops);
-   set_dma_offset(dev, pci64_dma_offset);
+   set_dma_offset(dev, fsl_arch_pci64_dma_offset());
}
 
*dev-dma_mask = dma_mask;
return 0;
 }
 
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
+{
+   struct pci_controller *hose = sys;
+   struct fsl_pci *pci = hose-private_data;
+
+   /* Update the first bus number */
+   if (pci-first_busno != hose-first_busno)
+   pci-first_busno = hose-first_busno;
+
+   return pci;
+}
+
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+   static struct pci_bus bus;
+   static struct pci_controller hose;
+
+   bus.number = busnr;
+   bus.sysdata = hose;
+   hose.private_data = pci;
+   bus.ops = pci-ops;
+
+   return bus;
+}
+
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
-   int i, is_pcie = 0, no_link;
+   bool is_pcie, no_link;
+   int i;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(hose);
 
/* The root complex bridge comes up with bogus resources,
 * we copy the PHB ones in.
@@ -97,9 +128,8 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 * tricky.
 */
 
-   if (fsl_pcie_bus_fixup)
-   is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
-   no_link = !!(hose-indirect_type  PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+   is_pcie = pci-is_pcie;
+   no_link = !fsl_pci_check_link(pci);
 
if (bus-parent == hose-bus  (is_pcie || no_link)) {
for (i = 0; i  PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -121,6 +151,94 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
 }
 
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   struct pci_controller *hose = pci-sys;
+
+   if (!hose)
+   return PCIBIOS_SUCCESSFUL;
+
+   if (ppc_md.pci_exclude_device)
+   if (ppc_md.pci_exclude_device(hose, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   return PCIBIOS_SUCCESSFUL;
+}
+
+int fsl_arch_pci_sys_register(struct fsl_pci *pci)
+{
+   struct pci_controller *hose;
+
+   pci_add_flags(PCI_REASSIGN_ALL_BUS);
+   hose = pcibios_alloc_controller(pci-dn);
+   if (!hose)
+   return -ENOMEM;
+
+   /* set platform device as the parent */
+   hose-private_data = pci;
+   hose-parent = pci-dev;
+   hose-first_busno = pci-first_busno;
+   hose-last_busno = pci-last_busno;
+   hose-ops = pci-ops;
+
+#ifdef CONFIG_PPC32
+   /* On 32 bits, limit I/O space to 16MB */
+   if (pci-pci_io_size  0x0100)
+   pci-pci_io_size = 0x0100;
+
+   /* 32 bits needs to map IOs here */
+   hose-io_base_virt = ioremap(pci-io_base_phys + pci-io_resource.start,
+pci-pci_io_size);
+
+   /* Expect trouble if pci_addr is not 0 */
+   if (fsl_pci_primary == pci-dn)
+   isa_io_base = (unsigned long)hose-io_base_virt;
+#endif /* CONFIG_PPC32 */
+
+   hose-pci_io_size = pci-io_resource.start + pci-pci_io_size;
+   hose

[PATCH 06/12][v3] pci: fsl: port PCI controller setup code

2013-10-23 Thread Minghuan Lian
PCI controller setup code will initialize structure fsl_pci
according to PCI dts node and initialize PCI command register
and ATMU. The patch uses general API of_pci_parse_bus_range
to parse PCI bus range, uses general of_address's API to parse
PCI IO/MEM ranges.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 drivers/pci/host/pci-fsl-common.c | 179 +-
 1 file changed, 97 insertions(+), 82 deletions(-)

diff --git a/drivers/pci/host/pci-fsl-common.c 
b/drivers/pci/host/pci-fsl-common.c
index f15b605..e09a0ec 100644
--- a/drivers/pci/host/pci-fsl-common.c
+++ b/drivers/pci/host/pci-fsl-common.c
@@ -24,6 +24,8 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/of_address.h
+#include linux/of_pci.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -505,131 +507,144 @@ static void setup_pci_atmu(struct fsl_pci *pci)
}
 }
 
-static void __init setup_pci_cmd(struct pci_controller *hose)
+static void __init setup_pci_cmd(struct fsl_pci *pci)
 {
u16 cmd;
int cap_x;
 
-   early_read_config_word(hose, 0, 0, PCI_COMMAND, cmd);
+   early_fsl_read_config_word(pci, 0, 0, PCI_COMMAND, cmd);
cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
| PCI_COMMAND_IO;
-   early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
+   early_fsl_write_config_word(pci, 0, 0, PCI_COMMAND, cmd);
 
-   cap_x = early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX);
+   cap_x = early_fsl_find_capability(pci, 0, 0, PCI_CAP_ID_PCIX);
if (cap_x) {
int pci_x_cmd = cap_x + PCI_X_CMD;
cmd = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
-   early_write_config_word(hose, 0, 0, pci_x_cmd, cmd);
-   } else {
-   early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
-   }
+   early_fsl_write_config_word(pci, 0, 0, pci_x_cmd, cmd);
+   } else
+   early_fsl_write_config_byte(pci, 0, 0, PCI_LATENCY_TIMER,
+   0x80);
 }
 
-int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
+static int __init
+fsl_pci_setup(struct platform_device *pdev, struct fsl_pci *pci)
 {
-   int len;
-   struct pci_controller *hose;
-   struct resource rsrc;
-   const int *bus_range;
+   struct resource *rsrc;
u8 hdr_type, progif;
-   struct device_node *dev;
-   struct ccsr_pci __iomem *pci;
-
-   dev = pdev-dev.of_node;
+   struct device_node *dn;
+   struct of_pci_range range;
+   struct of_pci_range_parser parser;
+   int mem = 0;
 
-   if (!of_device_is_available(dev)) {
-   pr_warning(%s: disabled\n, dev-full_name);
-   return -ENODEV;
-   }
+   dn = pdev-dev.of_node;
+   pci-dn = dn;
+   pci-dev = pdev-dev;
 
-   pr_debug(Adding PCI host bridge %s\n, dev-full_name);
+   dev_info(pdev-dev, Find controller %s\n, dn-full_name);
 
/* Fetch host bridge registers address */
-   if (of_address_to_resource(dev, 0, rsrc)) {
-   printk(KERN_WARNING Can't get pci register base!);
-   return -ENOMEM;
+   rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!rsrc) {
+   dev_err(pdev-dev, Can't get pci register base!);
+   return -EINVAL;
}
+   dev_info(pdev-dev, REG 0x%016llx..0x%016llx\n,
+(u64)rsrc-start, (u64)rsrc-end);
 
-   /* Get bus range if any */
-   bus_range = of_get_property(dev, bus-range, len);
-   if (bus_range == NULL || len  2 * sizeof(int))
-   printk(KERN_WARNING Can't get bus-range for %s, assume
-bus 0\n, dev-full_name);
-
-   pci_add_flags(PCI_REASSIGN_ALL_BUS);
-   hose = pcibios_alloc_controller(dev);
-   if (!hose)
-   return -ENOMEM;
+   /* Parse pci range resources from device tree */
+   if (of_pci_range_parser_init(parser, dn)) {
+   dev_err(pdev-dev, missing ranges property\n);
+   return -EINVAL;
+   }
 
-   /* set platform device as the parent */
-   hose-parent = pdev-dev;
-   hose-first_busno = bus_range ? bus_range[0] : 0x0;
-   hose-last_busno = bus_range ? bus_range[1] : 0xff;
+   /* Get the I/O and memory ranges from device tree */
+   for_each_of_pci_range(parser, range) {
+   unsigned long restype = range.flags  IORESOURCE_TYPE_BITS;
+   if (restype == IORESOURCE_IO) {
+   of_pci_range_to_resource(range, dn,
+pci-io_resource

[PATCH 11/12][v3] pci: fsl: update PCI EDAC driver

2013-10-23 Thread Minghuan Lian
1. The pci-fsl-common driver has set fsl_pci to device as drvdata,
so EDAC driver can not call dev_set_drvdata() again. fsl_pci
contains regs field to point PCI CCSR, so EDAC may directly use
the pointer and not need to call devm_ioremap().
2. Add mpc85xx_pci_err_remove() to disable PCI error interrupt
and delete PCI EDAC from EDAC subsystem.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
Derived from http://patchwork.ozlabs.org/patch/278965/
Added mpc85xx_pci_err_remove()

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c |  1 +
 arch/powerpc/sysdev/fsl_pci.h |  6 ++
 drivers/edac/mpc85xx_edac.c   | 46 +++
 drivers/edac/mpc85xx_edac.h   |  1 +
 4 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 40d2e1d..4a03e1a 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -236,6 +236,7 @@ void fsl_arch_pci_sys_remove(struct fsl_pci *pci)
if (!hose)
return;
 
+   mpc85xx_pci_err_remove(to_platform_device(pci-dev));
pcibios_free_controller(hose);
 }
 
diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index ce77aad..ae4dbe2 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -35,11 +35,17 @@ static inline void fsl_pci_assign_primary(void) {}
 
 #ifdef CONFIG_EDAC_MPC85XX
 int mpc85xx_pci_err_probe(struct platform_device *op);
+int mpc85xx_pci_err_remove(struct platform_device *op);
 #else
 static inline int mpc85xx_pci_err_probe(struct platform_device *op)
 {
return -ENOTSUPP;
 }
+static inline int mpc85xx_pci_err_remove(struct platform_device *op)
+{
+   return -ENOTSUPP;
+}
+
 #endif
 
 #ifdef CONFIG_FSL_PCI
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 3eb32f6..14a4116 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -21,6 +21,7 @@
 
 #include linux/of_platform.h
 #include linux/of_device.h
+#include linux/fsl/pci-common.h
 #include edac_module.h
 #include edac_core.h
 #include mpc85xx_edac.h
@@ -214,11 +215,13 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id)
 
 int mpc85xx_pci_err_probe(struct platform_device *op)
 {
+   struct fsl_pci *fslpci;
struct edac_pci_ctl_info *pci;
struct mpc85xx_pci_pdata *pdata;
-   struct resource r;
int res = 0;
 
+   fslpci = platform_get_drvdata(op);
+
if (!devres_open_group(op-dev, mpc85xx_pci_err_probe, GFP_KERNEL))
return -ENOMEM;
 
@@ -239,7 +242,6 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
pdata = pci-pvt_info;
pdata-name = mpc85xx_pci_err;
pdata-irq = NO_IRQ;
-   dev_set_drvdata(op-dev, pci);
pci-dev = op-dev;
pci-mod_name = EDAC_MOD_STR;
pci-ctl_name = pdata-name;
@@ -250,30 +252,8 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
 
pdata-edac_idx = edac_pci_idx++;
 
-   res = of_address_to_resource(op-dev.of_node, 0, r);
-   if (res) {
-   printk(KERN_ERR %s: Unable to get resource for 
-  PCI err regs\n, __func__);
-   goto err;
-   }
-
/* we only need the error registers */
-   r.start += 0xe00;
-
-   if (!devm_request_mem_region(op-dev, r.start, resource_size(r),
-   pdata-name)) {
-   printk(KERN_ERR %s: Error while requesting mem region\n,
-  __func__);
-   res = -EBUSY;
-   goto err;
-   }
-
-   pdata-pci_vbase = devm_ioremap(op-dev, r.start, resource_size(r));
-   if (!pdata-pci_vbase) {
-   printk(KERN_ERR %s: Unable to setup PCI err regs\n, __func__);
-   res = -ENOMEM;
-   goto err;
-   }
+   pdata-pci_vbase = (void *)fslpci-regs + MPC85XX_PCI_ERR_OFFSET;
 
orig_pci_err_cap_dr =
in_be32(pdata-pci_vbase + MPC85XX_PCI_ERR_CAP_DR);
@@ -327,20 +307,25 @@ err:
 }
 EXPORT_SYMBOL(mpc85xx_pci_err_probe);
 
-static int mpc85xx_pci_err_remove(struct platform_device *op)
+int mpc85xx_pci_err_remove(struct platform_device *op)
 {
-   struct edac_pci_ctl_info *pci = dev_get_drvdata(op-dev);
-   struct mpc85xx_pci_pdata *pdata = pci-pvt_info;
+   struct edac_pci_ctl_info *pci;
+   struct mpc85xx_pci_pdata *pdata;
 
edac_dbg(0, \n);
 
+   pci = edac_pci_del_device(op-dev);
+
+   if (!pci)
+   return -EINVAL;
+
+   pdata = pci-pvt_info;
+
out_be32(pdata-pci_vbase + MPC85XX_PCI_ERR_CAP_DR,
 orig_pci_err_cap_dr);
 
out_be32(pdata-pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en);
 
-   edac_pci_del_device(pci-dev);
-
if (edac_op_state == EDAC_OPSTATE_INT

[PATCH 12/12][v3] pci: fsl: fix function check_pci_ctl_endpt_part

2013-10-23 Thread Minghuan Lian
The new FSL PCI driver does not use cfg_addr of pci_controller,
we may directly access PCI CCSR using fsl_pci-regs.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v3:
The new patch to fix function check_pci_ctl_endpt_part

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.h   | 5 -
 drivers/iommu/fsl_pamu_domain.c | 6 --
 include/linux/fsl/pci-common.h  | 1 +
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h
index ae4dbe2..3176eb2 100644
--- a/arch/powerpc/sysdev/fsl_pci.h
+++ b/arch/powerpc/sysdev/fsl_pci.h
@@ -16,11 +16,6 @@
 
 struct platform_device;
 
-
-/* FSL PCI controller BRR1 register */
-#define PCI_FSL_BRR1  0xbf8
-#define PCI_FSL_BRR1_VER 0x
-
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
 extern int mpc83xx_add_bridge(struct device_node *dev);
 u64 fsl_pci_immrbar_base(struct pci_controller *hose);
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index c857c30..dd7bc25 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -36,6 +36,7 @@
 
 #include asm/pci-bridge.h
 #include sysdev/fsl_pci.h
+#include linux/fsl/pci-common.h
 
 #include fsl_pamu_domain.h
 #include pci.h
@@ -908,10 +909,11 @@ static struct iommu_group *get_device_iommu_group(struct 
device *dev)
 static  bool check_pci_ctl_endpt_part(struct pci_controller *pci_ctl)
 {
u32 version;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(pci_ctl);
 
/* Check the PCI controller version number by readding BRR1 register */
-   version = in_be32(pci_ctl-cfg_addr + (PCI_FSL_BRR1  2));
-   version = PCI_FSL_BRR1_VER;
+   version = in_be32(pci-regs-block_rev1);
+   version = PCIE_IP_REV_MASK;
/* If PCI controller version is = 0x204 we can partition endpoints*/
if (version = 0x204)
return 1;
diff --git a/include/linux/fsl/pci-common.h b/include/linux/fsl/pci-common.h
index 84b0801..6112adf 100644
--- a/include/linux/fsl/pci-common.h
+++ b/include/linux/fsl/pci-common.h
@@ -18,6 +18,7 @@
 #define PCIE_LTSSM_L0  0x16/* L0 state */
 #define PCIE_IP_REV_2_20x02080202 /* PCIE IP block version 
Rev2.2 */
 #define PCIE_IP_REV_3_00x02080300 /* PCIE IP block version 
Rev3.0 */
+#define PCIE_IP_REV_MASK   0x
 #define PIWAR_EN   0x8000  /* Enable */
 #define PIWAR_PF   0x2000  /* prefetch */
 #define PIWAR_TGI_LOCAL0x00f0  /* target - local 
memory */
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2][v2] pci: fsl: derive the common PCI driver to drivers/pci/host

2013-09-30 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pci-fsl-common.c and leaves the architecture
specific functions which should be implemented in arch related files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v2:
1. rename pci.h to pci-common.h 
2. rename pci-fsl.c to pci-fsl-common.c

Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c  | 521 +-
 arch/powerpc/sysdev/fsl_pci.h  |  89 
 .../fsl_pci.c = drivers/pci/host/pci-fsl-common.c | 591 +
 .../fsl_pci.h = include/linux/fsl/pci-common.h|  45 +-
 4 files changed, 7 insertions(+), 1239 deletions(-)
 copy arch/powerpc/sysdev/fsl_pci.c = drivers/pci/host/pci-fsl-common.c (54%)
 copy arch/powerpc/sysdev/fsl_pci.h = include/linux/fsl/pci-common.h (79%)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ccfb50d..26039e3 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -27,6 +27,7 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/fsl/pci-common.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -58,57 +59,8 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
-
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = hose-first_busno;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
-
-   return 0;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
-{
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
-}
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
 #define MAX_PHYS_ADDR_BITS 40
 static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
 
@@ -132,291 +84,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
return 0;
 }
 
-static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
-{
-   resource_size_t pci_addr = res-start - offset;
-   resource_size_t phys_addr = res-start;
-   resource_size_t size = resource_size(res);
-   u32 flags = 0x80044000; /* enable  mem R/W */
-   unsigned int i;
-
-   pr_debug(PCI MEM resource start 0x%016llx, size 0x%016llx.\n,
-   (u64)res-start, (u64)size);
-
-   if (res-flags  IORESOURCE_PREFETCH)
-   flags |= 0x1000; /* enable relaxed ordering */
-
-   for (i = 0; size  0; i++) {
-   unsigned int bits = min(ilog2(size),
-   __ffs(pci_addr | phys_addr));
-
-   if (index + i = 5)
-   return -1;
-
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
-
-   pci_addr += (resource_size_t)1U  bits;
-   phys_addr += (resource_size_t)1U  bits;
-   size -= (resource_size_t)1U  bits

[PATCH 2/2][v2] pci: fsl: rework PCI driver compatible with Layerscape

2013-09-30 Thread Minghuan Lian
The Freescale's Layerscape series processors will use the same PCI
controller but change cores from PowerPC to ARM. This patch is to
rework FSL PCI driver to support PowerPC and ARM simultaneously.
PowerPC uses structure pci_controller to describe PCI controller,
but arm uses structure hw_pci and pci_sys_data. They also have
different architecture implementation and initialization flow.
The architecture-dependent driver will bridge the gap, get the
settings from the common driver and initialize the corresponding
structure and call the related interface to register PCI controller.
The common driver pci-fsl-common.c removes all the architecture-specific
code and provides structure fsl_pci to store all the controller
settings and the common functionalities that include reading/writing
PCI configuration space, parsing dts node and getting the MEM/IO and
bus number ranges, setting ATMU and check link status.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
change log:
v1-v2:
1. change the driver name from pci-fsl to pci-fsl-common in order to
avoid confusion between fsl-pci and pci-fsl.
2. change type of is_pcie and fsl_pci_check_link() to bool.
3. remove  __exit macro from fsl_pci_remove().
4. remove __weak macro from fsl_arch_pci_sys_register() and
fsl_arch_pci_sys_remove() because every supported arch must
contain the two implementations.

Based on upstream master
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274488/
The function has been tested on MPC8315ERDB MPC8572DS P5020DS P3041DS
and T4240QDS boards

 arch/powerpc/Kconfig  |   1 +
 arch/powerpc/sysdev/fsl_pci.c | 147 -
 drivers/edac/mpc85xx_edac.c   |  16 +-
 drivers/pci/host/Kconfig  |  10 +
 drivers/pci/host/Makefile |   1 +
 drivers/pci/host/pci-fsl-common.c | 652 +-
 include/linux/fsl/pci-common.h|  71 +
 7 files changed, 654 insertions(+), 244 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 38f3b7e..7447d97d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -690,6 +690,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCI_FSL_COMMON if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 26039e3..40d2e1d 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -62,7 +62,11 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
 #define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
+
+u64 fsl_arch_pci64_dma_offset(void)
+{
+   return 1ull  MAX_PHYS_ADDR_BITS;
+}
 
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
@@ -77,17 +81,44 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
if ((dev-bus == pci_bus_type) 
dma_mask = DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, dma_direct_ops);
-   set_dma_offset(dev, pci64_dma_offset);
+   set_dma_offset(dev, fsl_arch_pci64_dma_offset());
}
 
*dev-dma_mask = dma_mask;
return 0;
 }
 
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
+{
+   struct pci_controller *hose = sys;
+   struct fsl_pci *pci = hose-private_data;
+
+   /* Update the first bus number */
+   if (pci-first_busno != hose-first_busno)
+   pci-first_busno = hose-first_busno;
+
+   return pci;
+}
+
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+   static struct pci_bus bus;
+   static struct pci_controller hose;
+
+   bus.number = busnr;
+   bus.sysdata = hose;
+   hose.private_data = pci;
+   bus.ops = pci-ops;
+
+   return bus;
+}
+
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
-   int i, is_pcie = 0, no_link;
+   bool is_pcie, no_link;
+   int i;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(hose);
 
/* The root complex bridge comes up with bogus resources,
 * we copy the PHB ones in.
@@ -97,9 +128,8 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 * tricky.
 */
 
-   if (fsl_pcie_bus_fixup)
-   is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
-   no_link = !!(hose-indirect_type  PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+   is_pcie = pci-is_pcie;
+   no_link = !fsl_pci_check_link(pci);
 
if (bus-parent == hose-bus  (is_pcie || no_link)) {
for (i = 0; i  PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -121,6 +151,94 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
 }
 
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   struct pci_controller *hose = pci-sys;
+
+   if (!hose

[PATCH 1/2] pci: fsl: derive the common PCI driver to drivers/pci/host

2013-09-18 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pci-fsl.c and leaves the architecture-specific
functions which should be implemented in arch related files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Based on upstream master.
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274487/

 arch/powerpc/sysdev/fsl_pci.c  | 521 +-
 arch/powerpc/sysdev/fsl_pci.h  |  89 
 .../sysdev/fsl_pci.c = drivers/pci/host/pci-fsl.c | 591 +
 .../sysdev/fsl_pci.h = include/linux/fsl/pci.h|  45 +-
 4 files changed, 7 insertions(+), 1239 deletions(-)
 copy arch/powerpc/sysdev/fsl_pci.c = drivers/pci/host/pci-fsl.c (54%)
 copy arch/powerpc/sysdev/fsl_pci.h = include/linux/fsl/pci.h (79%)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ccfb50d..a189ff0 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -27,6 +27,7 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/fsl/pci.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -58,57 +59,8 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
-
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = hose-first_busno;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
-
-   return 0;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
-{
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
-}
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
 #define MAX_PHYS_ADDR_BITS 40
 static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
 
@@ -132,291 +84,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
return 0;
 }
 
-static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
-{
-   resource_size_t pci_addr = res-start - offset;
-   resource_size_t phys_addr = res-start;
-   resource_size_t size = resource_size(res);
-   u32 flags = 0x80044000; /* enable  mem R/W */
-   unsigned int i;
-
-   pr_debug(PCI MEM resource start 0x%016llx, size 0x%016llx.\n,
-   (u64)res-start, (u64)size);
-
-   if (res-flags  IORESOURCE_PREFETCH)
-   flags |= 0x1000; /* enable relaxed ordering */
-
-   for (i = 0; size  0; i++) {
-   unsigned int bits = min(ilog2(size),
-   __ffs(pci_addr | phys_addr));
-
-   if (index + i = 5)
-   return -1;
-
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
-
-   pci_addr += (resource_size_t)1U  bits;
-   phys_addr += (resource_size_t)1U  bits;
-   size -= (resource_size_t)1U  bits;
-   }
-
-   return i;
-}
-
-/* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose

[PATCH 2/2] pci: fsl: rework PCI driver compatible with Layerscape

2013-09-18 Thread Minghuan Lian
The Freescale's Layerscape series processors will use the same PCI
controller but change cores from PowerPC to ARM. This patch is to
rework FSL PCI driver to support PowerPC and ARM simultaneously.
PowerPC uses structure pci_controller to describe PCI controller,
but arm uses structure hw_pci and pci_sys_data. They also have
different architecture implementation and initialization flow.
The architecture-dependent driver will bridge the gap, get the
settings from the common driver and initialize the corresponding
structure and call the related interface to register PCI controller.
The common driver pci-fsl.c removes all the architecture-specific
code and provides structure fsl_pci to store all the controller
settings and the common functionalities that include reading/writing
PCI configuration space, parsing dts node and getting the MEM/IO and
bus number ranges, setting ATMU and check link status.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Based on upstream master
Based on the discussion of RFC version here
http://patchwork.ozlabs.org/patch/274488/
The function has been tested on MPC8315ERDB MPC8572DS P5020DS P3041DS
and T4240QDS boards 

 arch/powerpc/Kconfig  |   1 +
 arch/powerpc/sysdev/fsl_pci.c | 147 +-
 drivers/edac/mpc85xx_edac.c   |  16 +-
 drivers/pci/host/Kconfig  |   7 +
 drivers/pci/host/Makefile |   1 +
 drivers/pci/host/pci-fsl.c| 653 +++---
 include/linux/fsl/pci.h   |  69 +
 7 files changed, 653 insertions(+), 241 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 38f3b7e..6fd6348 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -690,6 +690,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCI_FSL if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a189ff0..1413257 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -62,7 +62,11 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
 #define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
+
+u64 fsl_arch_pci64_dma_offset(void)
+{
+   return 1ull  MAX_PHYS_ADDR_BITS;
+}
 
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
@@ -77,17 +81,43 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
if ((dev-bus == pci_bus_type) 
dma_mask = DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, dma_direct_ops);
-   set_dma_offset(dev, pci64_dma_offset);
+   set_dma_offset(dev, fsl_arch_pci64_dma_offset());
}
 
*dev-dma_mask = dma_mask;
return 0;
 }
 
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
+{
+   struct pci_controller *hose = sys;
+   struct fsl_pci *pci = hose-private_data;
+
+   /* Update the first bus number */
+   if (pci-first_busno != hose-first_busno)
+   pci-first_busno = hose-first_busno;
+
+   return pci;
+}
+
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+   static struct pci_bus bus;
+   static struct pci_controller hose;
+
+   bus.number = busnr;
+   bus.sysdata = hose;
+   hose.private_data = pci;
+   bus.ops = pci-ops;
+
+   return bus;
+}
+
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
-   int i, is_pcie = 0, no_link;
+   int i, is_pcie, no_link;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(hose);
 
/* The root complex bridge comes up with bogus resources,
 * we copy the PHB ones in.
@@ -97,9 +127,8 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 * tricky.
 */
 
-   if (fsl_pcie_bus_fixup)
-   is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
-   no_link = !!(hose-indirect_type  PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+   is_pcie = pci-is_pcie;
+   no_link = fsl_pci_check_link(pci);
 
if (bus-parent == hose-bus  (is_pcie || no_link)) {
for (i = 0; i  PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -121,6 +150,94 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
 }
 
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   struct pci_controller *hose = pci-sys;
+
+   if (!hose)
+   return PCIBIOS_SUCCESSFUL;
+
+   if (ppc_md.pci_exclude_device)
+   if (ppc_md.pci_exclude_device(hose, bus, devfn))
+   return PCIBIOS_DEVICE_NOT_FOUND;
+
+   return PCIBIOS_SUCCESSFUL;
+}
+
+int fsl_arch_pci_sys_register(struct fsl_pci *pci)
+{
+   struct pci_controller *hose;
+
+   pci_add_flags(PCI_REASSIGN_ALL_BUS);
+   hose = pcibios_alloc_controller(pci-dn);
+   if (!hose

[PATCH 1/2][RFC][v3] pci: fsl: derive the common PCI driver to drivers/pci/host

2013-09-12 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pci-fsl.c and leaves the architecture-specific
functions which should be implemented in arch related files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Based on upstream master

Change log:
v3:
1. Add the new patch that only contains the code movement.
V2:
NULL

 arch/powerpc/sysdev/fsl_pci.c  | 521 +-
 arch/powerpc/sysdev/fsl_pci.h  |  89 
 .../sysdev/fsl_pci.c = drivers/pci/host/pci-fsl.c | 591 +
 .../sysdev/fsl_pci.h = include/linux/fsl/pci.h|  40 +-
 4 files changed, 7 insertions(+), 1234 deletions(-)
 copy arch/powerpc/sysdev/fsl_pci.c = drivers/pci/host/pci-fsl.c (54%)
 copy arch/powerpc/sysdev/fsl_pci.h = include/linux/fsl/pci.h (81%)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ccfb50d..a189ff0 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -27,6 +27,7 @@
 #include linux/log2.h
 #include linux/slab.h
 #include linux/uaccess.h
+#include linux/fsl/pci.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -58,57 +59,8 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
-
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = hose-first_busno;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
-
-   return 0;
-}
-
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
-{
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
-}
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
 #define MAX_PHYS_ADDR_BITS 40
 static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
 
@@ -132,291 +84,6 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
return 0;
 }
 
-static int setup_one_atmu(struct ccsr_pci __iomem *pci,
-   unsigned int index, const struct resource *res,
-   resource_size_t offset)
-{
-   resource_size_t pci_addr = res-start - offset;
-   resource_size_t phys_addr = res-start;
-   resource_size_t size = resource_size(res);
-   u32 flags = 0x80044000; /* enable  mem R/W */
-   unsigned int i;
-
-   pr_debug(PCI MEM resource start 0x%016llx, size 0x%016llx.\n,
-   (u64)res-start, (u64)size);
-
-   if (res-flags  IORESOURCE_PREFETCH)
-   flags |= 0x1000; /* enable relaxed ordering */
-
-   for (i = 0; size  0; i++) {
-   unsigned int bits = min(ilog2(size),
-   __ffs(pci_addr | phys_addr));
-
-   if (index + i = 5)
-   return -1;
-
-   out_be32(pci-pow[index + i].potar, pci_addr  12);
-   out_be32(pci-pow[index + i].potear, (u64)pci_addr  44);
-   out_be32(pci-pow[index + i].powbar, phys_addr  12);
-   out_be32(pci-pow[index + i].powar, flags | (bits - 1));
-
-   pci_addr += (resource_size_t)1U  bits;
-   phys_addr += (resource_size_t)1U  bits;
-   size -= (resource_size_t)1U  bits;
-   }
-
-   return i;
-}
-
-/* atmu setup for fsl pci/pcie controller */
-static void setup_pci_atmu(struct pci_controller *hose

[PATCH 2/2][RFC][v3] pci: fsl: rework PCI driver compatible with Layerscape

2013-09-12 Thread Minghuan Lian
The Freescale's Layerscape series processors will use the same PCI
controller but change cores from PowerPC to ARM. This patch is to
rework FSL PCI driver to support PowerPC and ARM simultaneously.
PowerPC uses structure pci_controller to describe PCI controller,
but arm uses structure hw_pci and pci_sys_data. They also have
different architecture implementation and initialization flow.
The architecture-dependent driver will bridge the gap, get the
settings from the common driver and initialize the corresponding
structure and call the related interface to register PCI controller.
The common driver pci-fsl.c removes all the architecture-specific
code and provides structure fsl_pci to store all the controller
settings and the common functionalities that include reading/writing
PCI configuration space, parsing dts node and getting the MEM/IO and
bus number ranges, setting ATMU and check link status.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Based on upstream master
The function has been tested on MPC8315ERDB MPC8572DS P5020DS P3041DS
and T4240QDS boards 

Change log:
v3:
1. use 'fsl_arch' as function name prefix of all the
   architecture-specific hooks.
2. Move PCI compatible definitions from arch/powerpc/sysdev/fsl_pci.c
   to driver/pci/host/pci-fsl.c 

v2:
1. Use 'pci' instead of 'pcie' in new file name and file contents. 
2. Use iowrite32be()/iowrite32() instead of out_be32/le32()
3. Fix ppc_md.dma_set_mask setting
4. Synchronizes host-first_busno and pci-first_busno.
5. Fix PCI IO space settings
6. Some small changes according to Scott's comments.


 arch/powerpc/Kconfig  |   1 +
 arch/powerpc/sysdev/fsl_pci.c | 150 +-
 drivers/edac/mpc85xx_edac.c   |   9 -
 drivers/pci/host/Kconfig  |   4 +
 drivers/pci/host/Makefile |   1 +
 drivers/pci/host/pci-fsl.c| 656 +++---
 include/linux/fsl/pci.h   |  69 +
 7 files changed, 648 insertions(+), 242 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6b7530f..657d90f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -691,6 +691,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCI_FSL if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index a189ff0..4cb12e8 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -62,7 +62,11 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
 #define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
+
+u64 fsl_arch_pci64_dma_offset(void)
+{
+   return 1ull  MAX_PHYS_ADDR_BITS;
+}
 
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
@@ -77,17 +81,43 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
if ((dev-bus == pci_bus_type) 
dma_mask = DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, dma_direct_ops);
-   set_dma_offset(dev, pci64_dma_offset);
+   set_dma_offset(dev, fsl_arch_pci64_dma_offset());
}
 
*dev-dma_mask = dma_mask;
return 0;
 }
 
+struct fsl_pci *fsl_arch_sys_to_pci(void *sys)
+{
+   struct pci_controller *hose = sys;
+   struct fsl_pci *pci = hose-private_data;
+
+   /* Update the first bus number */
+   if (pci-first_busno != hose-first_busno)
+   pci-first_busno = hose-first_busno;
+
+   return pci;
+}
+
+struct pci_bus *fsl_arch_fake_pci_bus(struct fsl_pci *pci, int busnr)
+{
+   static struct pci_bus bus;
+   static struct pci_controller hose;
+
+   bus.number = busnr;
+   bus.sysdata = hose;
+   hose.private_data = pci;
+   bus.ops = pci-ops;
+
+   return bus;
+}
+
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
struct pci_controller *hose = pci_bus_to_host(bus);
-   int i, is_pcie = 0, no_link;
+   int i, is_pcie, no_link;
+   struct fsl_pci *pci = fsl_arch_sys_to_pci(hose);
 
/* The root complex bridge comes up with bogus resources,
 * we copy the PHB ones in.
@@ -97,9 +127,8 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 * tricky.
 */
 
-   if (fsl_pcie_bus_fixup)
-   is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
-   no_link = !!(hose-indirect_type  PPC_INDIRECT_TYPE_NO_PCIE_LINK);
+   is_pcie = pci-is_pcie;
+   no_link = fsl_pci_check_link(pci);
 
if (bus-parent == hose-bus  (is_pcie || no_link)) {
for (i = 0; i  PCI_BRIDGE_RESOURCE_NUM; ++i) {
@@ -121,6 +150,94 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus)
}
 }
 
+int fsl_arch_pci_exclude_device(struct fsl_pci *pci, u8 bus, u8 devfn)
+{
+   struct pci_controller *hose = pci-sys;
+
+   if (!hose)
+   return PCIBIOS_SUCCESSFUL

[PATCH][RFC][v2] pci: fsl: rework PCIe driver compatible with Layerscape

2013-08-28 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pcie-fsl.c and leaves several platform-dependent
functions which should be implemented in platform files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Based on upstream master 3.11-rc7
The function has been tested on MPC8315ERDB MPC8572DS P5020DS P3041DS
and T4240QDS boards 

Change log:
v2:
1. Use 'pci' instead of 'pcie' in new file name and file contents. 
2. Use iowrite32be()/iowrite32() instead of out_be32/le32()
3. Fix ppc_md.dma_set_mask setting
4. Synchronizes host-first_busno and pci-first_busno.
5. Fix PCI IO space settings
6. Some small changes according to Scott's comments.


 arch/powerpc/Kconfig   |   1 +
 arch/powerpc/sysdev/fsl_pci.c  | 610 -
 arch/powerpc/sysdev/fsl_pci.h  |  91 ---
 drivers/edac/mpc85xx_edac.c|  10 -
 drivers/pci/host/Kconfig   |   4 +
 drivers/pci/host/Makefile  |   1 +
 drivers/pci/host/pci-fsl.c | 736 +
 .../sysdev/fsl_pci.h = include/linux/fsl/pci.h| 107 ++-
 8 files changed, 932 insertions(+), 628 deletions(-)
 create mode 100644 drivers/pci/host/pci-fsl.c
 copy arch/powerpc/sysdev/fsl_pci.h = include/linux/fsl/pci.h (67%)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9cf59816d..f78484c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -671,6 +671,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCI_FSL if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 46ac1dd..b3ff28b 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1,7 +1,7 @@
 /*
  * MPC83xx/85xx/86xx PCI/PCIE support routing.
  *
- * Copyright 2007-2012 Freescale Semiconductor, Inc.
+ * Copyright 2007-2013 Freescale Semiconductor, Inc.
  * Copyright 2008-2009 MontaVista Software, Inc.
  *
  * Initial author: Xianghua Xiao x.x...@freescale.com
@@ -26,6 +26,7 @@
 #include linux/memblock.h
 #include linux/log2.h
 #include linux/slab.h
+#include linux/fsl/pci.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -54,60 +55,17 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, 
quirk_fsl_pcie_header);
 
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = 0;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
+#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-   return 0;
-}
+#define MAX_PHYS_ADDR_BITS 40
 
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
+u64 fsl_pci64_dma_offset(void)
 {
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
+   return 1ull  MAX_PHYS_ADDR_BITS;
 }
 
-#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
-#define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
-
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
if (!dev-dma_mask || !dma_supported(dev, dma_mask

[PATCH][RFC] pci: fsl: rework PCIe driver compatible with Layerscape

2013-08-19 Thread Minghuan Lian
The Freescale's Layerscape series processors will use ARM cores.
The LS1's PCIe controllers is the same as T4240's. So it's better
the PCIe controller driver can support PowerPC and ARM
simultaneously. This patch is for this purpose. It derives
the common functions from arch/powerpc/sysdev/fsl_pci.c to
drivers/pci/host/pcie-fsl.c and leaves several platform-dependent
functions which should be implemented in platform files.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
Based on upstream master 3.11-rc6
The function has been tested  on P5020DS and P3041DS and T4240QDS boards 
For mpc83xx and mpc86xx, I only did compile test.

 arch/powerpc/Kconfig  |   1 +
 arch/powerpc/sysdev/fsl_pci.c | 591 ++
 arch/powerpc/sysdev/fsl_pci.h |  91 --
 drivers/edac/mpc85xx_edac.c   |  10 -
 drivers/pci/host/Kconfig  |   4 +
 drivers/pci/host/Makefile |   1 +
 drivers/pci/host/pcie-fsl.c   | 734 ++
 include/linux/fsl/fsl-pcie.h  | 176 ++
 8 files changed, 1008 insertions(+), 600 deletions(-)
 create mode 100644 drivers/pci/host/pcie-fsl.c
 create mode 100644 include/linux/fsl/fsl-pcie.h

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index dbd9d3c..66b51a8 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -671,6 +671,7 @@ config FSL_SOC
 
 config FSL_PCI
bool
+   select PCIE_FSL if FSL_SOC_BOOKE || PPC_86xx
select PPC_INDIRECT_PCI
select PCI_QUIRKS
 
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 46ac1dd..a05a9e1 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1,7 +1,7 @@
 /*
  * MPC83xx/85xx/86xx PCI/PCIE support routing.
  *
- * Copyright 2007-2012 Freescale Semiconductor, Inc.
+ * Copyright 2007-2013 Freescale Semiconductor, Inc.
  * Copyright 2008-2009 MontaVista Software, Inc.
  *
  * Initial author: Xianghua Xiao x.x...@freescale.com
@@ -26,6 +26,7 @@
 #include linux/memblock.h
 #include linux/log2.h
 #include linux/slab.h
+#include linux/fsl/fsl-pcie.h
 
 #include asm/io.h
 #include asm/prom.h
@@ -54,60 +55,17 @@ static void quirk_fsl_pcie_header(struct pci_dev *dev)
return;
 }
 
-static int fsl_indirect_read_config(struct pci_bus *, unsigned int,
-   int, int, u32 *);
-
-static int fsl_pcie_check_link(struct pci_controller *hose)
-{
-   u32 val = 0;
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, 
quirk_fsl_pcie_header);
 
-   if (hose-indirect_type  PPC_INDIRECT_TYPE_FSL_CFG_REG_LINK) {
-   if (hose-ops-read == fsl_indirect_read_config) {
-   struct pci_bus bus;
-   bus.number = 0;
-   bus.sysdata = hose;
-   bus.ops = hose-ops;
-   indirect_read_config(bus, 0, PCIE_LTSSM, 4, val);
-   } else
-   early_read_config_dword(hose, 0, 0, PCIE_LTSSM, val);
-   if (val  PCIE_LTSSM_L0)
-   return 1;
-   } else {
-   struct ccsr_pci __iomem *pci = hose-private_data;
-   /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
-   val = (in_be32(pci-pex_csr0)  PEX_CSR0_LTSSM_MASK)
-PEX_CSR0_LTSSM_SHIFT;
-   if (val != PEX_CSR0_LTSSM_L0)
-   return 1;
-   }
+#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 
-   return 0;
-}
+#define MAX_PHYS_ADDR_BITS 40
 
-static int fsl_indirect_read_config(struct pci_bus *bus, unsigned int devfn,
-   int offset, int len, u32 *val)
+u64 fsl_pci64_dma_offset(void)
 {
-   struct pci_controller *hose = pci_bus_to_host(bus);
-
-   if (fsl_pcie_check_link(hose))
-   hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-   else
-   hose-indirect_type = ~PPC_INDIRECT_TYPE_NO_PCIE_LINK;
-
-   return indirect_read_config(bus, devfn, offset, len, val);
+   return 1ull  MAX_PHYS_ADDR_BITS;
 }
 
-#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
-
-static struct pci_ops fsl_indirect_pcie_ops =
-{
-   .read = fsl_indirect_read_config,
-   .write = indirect_write_config,
-};
-
-#define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull  MAX_PHYS_ADDR_BITS;
-
 static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 {
if (!dev-dma_mask || !dma_supported(dev, dma_mask))
@@ -121,300 +79,36 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 
dma_mask)
if ((dev-bus == pci_bus_type) 
dma_mask = DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
set_dma_ops(dev, dma_direct_ops);
-   set_dma_offset(dev, pci64_dma_offset);
+   set_dma_offset(dev, fsl_pci64_dma_offset());
}
 
*dev-dma_mask = dma_mask;
return 0

[PATCH] powerpc/dts: fix sRIO error interrupt for b4860

2013-07-30 Thread Minghuan Lian
For B4 platform, MPIC EISR register is in reversed bitmap order,
instead of Error interrupt source 0-31. Bit 0 represents SRC0.
the correct ordering is Error interrupt source 0-31. Bit 0
represents SRC31. This patch is to fix sRIO EISR bit value
of error interrupt in dts node.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
index e5cf6c8..9813975 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
@@ -41,7 +41,7 @@
 
 rio {
compatible = fsl,srio;
-   interrupts = 16 2 1 11;
+   interrupts = 16 2 1 20;
#address-cells = 2;
#size-cells = 2;
fsl,iommu-parent = pamu0;
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/3 v2] powerpc/dts: update MSI bindings doc for MPIC v4.3

2013-06-21 Thread Minghuan Lian
Add compatible fsl,mpic-msi-v4.3 for MPIC v4.3. MPIC v4.3 contains
MSIIR and MSIIR1. MSIIR supports 8 MSI registers and MSIIR1 supports
16 MSI registers, but uses different IBS and SRS shift. When using
MSIR1, the interrupt number is not consecutive. It is hard to use
'msi-available-ranges' to describe the ranges of the available
interrupt, so MPIC v4.3 does not support this property.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
v2 log:
1. move msi-available-ranges to optional properties.

 .../devicetree/bindings/powerpc/fsl/msi-pic.txt| 51 +-
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt 
b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
index 5693877..d82b080 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
@@ -1,21 +1,20 @@
 * Freescale MSI interrupt controller
 
 Required properties:
-- compatible : compatible list, contains 2 entries,
+- compatible : compatible list, may contains one or two entries,
   first is fsl,CHIP-msi, where CHIP is the processor(mpc8610, mpc8572,
-  etc.) and the second is fsl,mpic-msi or fsl,ipic-msi depending on
-  the parent type.
+  etc.) and the second is fsl,mpic-msi or fsl,ipic-msi or
+  fsl,mpic-msi-v4.3 depending on the parent type and version. If mpic
+  version is 4.3, the number of MSI registers is increased to 16, MSIIR1 is
+  provided to access these 16 registers, compatible fsl,mpic-msi-v4.3
+  should be used. The first entry is optional, the second entry must be
+  required.
 
 - reg : It may contain one or two regions. The first region should contain
   the address and the length of the shared message interrupt register set.
-  The second region should contain the address of aliased MSIIR register for
-  platforms that have such an alias.
-
-- msi-available-ranges: use start count style section to define which
-  msi interrupt can be used in the 256 msi interrupts. This property is
-  optional, without this, all the 256 MSI interrupts can be used.
-  Each available range must begin and end on a multiple of 32 (i.e.
-  no splitting an individual MSI register or the associated PIC interrupt).
+  The second region should contain the address of aliased MSIIR or MSIIR1
+  register for platforms that have such an alias, if using MSIIR1, the second
+  region must be added because different MSI group has different MSIIR1 offset.
 
 - interrupts : each one of the interrupts here is one entry per 32 MSIs,
   and routed to the host interrupt controller. the interrupts should
@@ -28,6 +27,14 @@ Required properties:
   to MPIC.
 
 Optional properties:
+- msi-available-ranges: use start count style section to define which
+  msi interrupt can be used in the 256 msi interrupts. This property is
+  optional, without this, all the MSI interrupts can be used.
+  Each available range must begin and end on a multiple of 32 (i.e.
+  no splitting an individual MSI register or the associated PIC interrupt).
+  MPIC v4.3 does not support this property because the 32 interrupts of an
+  individual register are not continuous when using MSIIR1.
+
 - msi-address-64: 64-bit PCI address of the MSIIR register. The MSIIR register
   is used for MSI messaging.  The address of MSIIR in PCI address space is
   the MSI message address.
@@ -54,6 +61,28 @@ Example:
interrupt-parent = mpic;
};
 
+   msi@41600 {
+   compatible = fsl,mpic-msi-v4.3;
+   reg = 0x41600 0x200 0x44148 4;
+   interrupts = 
+   0xe0 0 0 0
+   0xe1 0 0 0
+   0xe2 0 0 0
+   0xe3 0 0 0
+   0xe4 0 0 0
+   0xe5 0 0 0
+   0xe6 0 0 0
+   0xe7 0 0 0
+   0x100 0 0 0
+   0x101 0 0 0
+   0x102 0 0 0
+   0x103 0 0 0
+   0x104 0 0 0
+   0x105 0 0 0
+   0x106 0 0 0
+   0x107 0 0 0;
+   };
+
 The Freescale hypervisor and msi-address-64
 ---
 Normally, PCI devices have access to all of CCSR via an ATMU mapping.  The
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/3 v2] powerpc/fsl_msi: add MSIIR1 support for MPIC v4.3

2013-06-21 Thread Minghuan Lian
The original MPIC MSI bank contains 8 registers, MPIC v4.3 MSI bank
contains 16 registers, and this patch adds NR_MSI_REG_MAX and
NR_MSI_IRQS_MAX to describe the maximum capability of MSI bank.
MPIC v4.3 provides MSIIR1 to index these 16 MSI registers. MSIIR1
uses different bits definition than MSIIR. This patch adds
ibs_shift and srs_shift to indicate the bits definition of the
MSIIR and MSIIR1, so the same code can handle the MSIIR and MSIIR1
simultaneously.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
v2 log:
1. remove 'msiregs' support.

 arch/powerpc/sysdev/fsl_msi.c | 132 ++
 arch/powerpc/sysdev/fsl_msi.h |  10 +++-
 2 files changed, 101 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ab02db3..76d453e 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -28,6 +28,18 @@
 #include fsl_msi.h
 #include fsl_pci.h
 
+#define MSIIR_OFFSET_MASK  0xf
+#define MSIIR_IBS_SHIFT0
+#define MSIIR_SRS_SHIFT5
+#define MSIIR1_IBS_SHIFT   4
+#define MSIIR1_SRS_SHIFT   0
+#define MSI_SRS_MASK   0xf
+#define MSI_IBS_MASK   0x1f
+
+#define msi_hwirq(msi, msir_index, intr_index) \
+   ((msir_index)  (msi)-srs_shift | \
+((intr_index)  (msi)-ibs_shift))
+
 static LIST_HEAD(msi_head);
 
 struct fsl_msi_feature {
@@ -80,18 +92,19 @@ static const struct irq_domain_ops fsl_msi_host_ops = {
 
 static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
 {
-   int rc;
+   int rc, hwirq;
 
-   rc = msi_bitmap_alloc(msi_data-bitmap, NR_MSI_IRQS,
+   rc = msi_bitmap_alloc(msi_data-bitmap, NR_MSI_IRQS_MAX,
  msi_data-irqhost-of_node);
if (rc)
return rc;
 
-   rc = msi_bitmap_reserve_dt_hwirqs(msi_data-bitmap);
-   if (rc  0) {
-   msi_bitmap_free(msi_data-bitmap);
-   return rc;
-   }
+   /*
+* Reserve all the hwirqs
+* The available hwirqs will be released in fsl_msi_setup_hwirq()
+*/
+   for (hwirq = 0; hwirq  NR_MSI_IRQS_MAX; hwirq++)
+   msi_bitmap_reserve_hwirq(msi_data-bitmap, hwirq);
 
return 0;
 }
@@ -144,8 +157,9 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int 
hwirq,
 
msg-data = hwirq;
 
-   pr_debug(%s: allocated srs: %d, ibs: %d\n,
-   __func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG);
+   pr_debug(%s: allocated srs: %d, ibs: %d\n, __func__,
+(hwirq  msi_data-srs_shift)  MSI_SRS_MASK,
+(hwirq  msi_data-ibs_shift)  MSI_IBS_MASK);
 }
 
 static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
@@ -255,7 +269,7 @@ static void fsl_msi_cascade(unsigned int irq, struct 
irq_desc *desc)
 
msir_index = cascade_data-index;
 
-   if (msir_index = NR_MSI_REG)
+   if (msir_index = NR_MSI_REG_MAX)
cascade_irq = NO_IRQ;
 
irqd_set_chained_irq_inprogress(idata);
@@ -285,8 +299,8 @@ static void fsl_msi_cascade(unsigned int irq, struct 
irq_desc *desc)
intr_index = ffs(msir_value) - 1;
 
cascade_irq = irq_linear_revmap(msi_data-irqhost,
-   msir_index * IRQS_PER_MSI_REG +
-   intr_index + have_shift);
+   msi_hwirq(msi_data, msir_index,
+ intr_index + have_shift));
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
have_shift += intr_index + 1;
@@ -316,7 +330,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev)
 
if (msi-list.prev != NULL)
list_del(msi-list);
-   for (i = 0; i  NR_MSI_REG; i++) {
+   for (i = 0; i  NR_MSI_REG_MAX; i++) {
virq = msi-msi_virqs[i];
if (virq != NO_IRQ) {
cascade_data = irq_get_handler_data(virq);
@@ -339,7 +353,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct 
platform_device *dev,
   int offset, int irq_index)
 {
struct fsl_msi_cascade_data *cascade_data = NULL;
-   int virt_msir;
+   int virt_msir, i;
 
virt_msir = irq_of_parse_and_map(dev-dev.of_node, irq_index);
if (virt_msir == NO_IRQ) {
@@ -360,6 +374,11 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct 
platform_device *dev,
irq_set_handler_data(virt_msir, cascade_data);
irq_set_chained_handler(virt_msir, fsl_msi_cascade);
 
+   /* Release the hwirqs corresponding to this MSI register */
+   for (i = 0; i  IRQS_PER_MSI_REG; i++)
+   msi_bitmap_free_hwirqs(msi-bitmap,
+  msi_hwirq(msi, offset, i), 1);
+
return 0;
 }
 
@@ -368,14 +387,13

[PATCH 1/5] powerpc/dts: add MPIC v4.3 dts node

2013-06-14 Thread Minghuan Lian
For the latest platform T4 and B4, MPIC controller has been updated
to v4.3. This patch adds a new file to describe the latest MPIC.
The MSI blocks number is increased to four, the registers number
of each block is increased to sixteen. MSIIR1 has been added to
access these sixteen MSI registers.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 arch/powerpc/boot/dts/fsl/b4si-post.dtsi |   2 +-
 arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi | 153 +++
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi  |   2 +-
 3 files changed, 155 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi

diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
index 7399154..4c617bf 100644
--- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
@@ -204,7 +204,7 @@
};
};
 
-/include/ qoriq-mpic.dtsi
+/include/ qoriq-mpic4.3.dtsi
 
guts: global-utilities@e {
compatible = fsl,b4-device-config;
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi 
b/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi
new file mode 100644
index 000..e2665b8
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi
@@ -0,0 +1,153 @@
+/*
+ * QorIQ MPIC device tree stub [ controller @ offset 0x4 ]
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ *   names of its contributors may be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License (GPL) as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+mpic: pic@4 {
+   interrupt-controller;
+   #address-cells = 0;
+   #interrupt-cells = 4;
+   reg = 0x4 0x4;
+   compatible = fsl,mpic;
+   device_type = open-pic;
+   clock-frequency = 0x0;
+};
+
+timer@41100 {
+   compatible = fsl,mpic-global-timer;
+   reg = 0x41100 0x100 0x41300 4;
+   interrupts = 0 0 3 0
+ 1 0 3 0
+ 2 0 3 0
+ 3 0 3 0;
+};
+
+msi0: msi@41600 {
+   compatible = fsl,mpic-msi, fsl,mpic-msi-v4.3;
+   reg = 0x41600 0x200 0x44148 4;
+   msi-available-ranges = 0 0x200;
+   interrupts = 
+   0xe0 0 0 0
+   0xe1 0 0 0
+   0xe2 0 0 0
+   0xe3 0 0 0
+   0xe4 0 0 0
+   0xe5 0 0 0
+   0xe6 0 0 0
+   0xe7 0 0 0
+   0x100 0 0 0
+   0x101 0 0 0
+   0x102 0 0 0
+   0x103 0 0 0
+   0x104 0 0 0
+   0x105 0 0 0
+   0x106 0 0 0
+   0x107 0 0 0;
+};
+
+msi1: msi@41800 {
+   compatible = fsl,mpic-msi, fsl,mpic-msi-v4.3;
+   reg = 0x41800 0x200 0x45148 4;
+   msi-available-ranges = 0 0x200;
+   interrupts = 
+   0xe8 0 0 0
+   0xe9 0 0 0
+   0xea 0 0 0
+   0xeb 0 0 0
+   0xec 0 0 0
+   0xed 0 0 0
+   0xee 0 0 0
+   0xef 0 0 0
+   0x108 0 0 0
+   0x109 0 0 0
+   0x10a 0 0 0
+   0x10b 0 0 0
+   0x10c 0 0 0
+   0x10d 0 0 0
+   0x10e 0 0 0
+   0x10f 0 0 0;
+};
+
+msi2: msi@41a00 {
+   compatible = fsl,mpic-msi, fsl,mpic-msi

[PATCH 2/5] powerpc/fsl_msi: add MSIIR1 support for MPIC v4.3

2013-06-14 Thread Minghuan Lian
MPIC controller v4.3 provides MSIIR1 to index 16 MSI registers.
MSIIR can only index 8 MSI registers. MSIIR1 uses different bits
definition than MSIIR. This patch adds ibs_shift and srs_shift to
indicate the bits definition of the MSIIR and MSIIR1, so the same
code can handle the MSIIR and MSIIR1 simultaneously.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 arch/powerpc/sysdev/fsl_msi.c | 62 ++-
 arch/powerpc/sysdev/fsl_msi.h |  4 ++-
 2 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ab02db3..34510b7 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -28,6 +28,18 @@
 #include fsl_msi.h
 #include fsl_pci.h
 
+#define MSIIR_OFFSET_MASK  0xf
+#define MSIIR_IBS_SHIFT0
+#define MSIIR_SRS_SHIFT5
+#define MSIIR1_IBS_SHIFT   4
+#define MSIIR1_SRS_SHIFT   0
+#define MSI_SRS_MASK   0xf
+#define MSI_IBS_MASK   0x1f
+
+#define msi_hwirq(msi, msir_index, intr_index) \
+   ((msir_index)  (msi)-srs_shift | \
+((intr_index)  (msi)-ibs_shift))
+
 static LIST_HEAD(msi_head);
 
 struct fsl_msi_feature {
@@ -80,18 +92,19 @@ static const struct irq_domain_ops fsl_msi_host_ops = {
 
 static int fsl_msi_init_allocator(struct fsl_msi *msi_data)
 {
-   int rc;
+   int rc, hwirq;
 
rc = msi_bitmap_alloc(msi_data-bitmap, NR_MSI_IRQS,
  msi_data-irqhost-of_node);
if (rc)
return rc;
 
-   rc = msi_bitmap_reserve_dt_hwirqs(msi_data-bitmap);
-   if (rc  0) {
-   msi_bitmap_free(msi_data-bitmap);
-   return rc;
-   }
+   /*
+* Reserve all the hwirqs
+* The available hwirqs will be released in fsl_msi_setup_hwirq()
+*/
+   for (hwirq = 0; hwirq  NR_MSI_IRQS; hwirq++)
+   msi_bitmap_reserve_hwirq(msi_data-bitmap, hwirq);
 
return 0;
 }
@@ -144,8 +157,9 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int 
hwirq,
 
msg-data = hwirq;
 
-   pr_debug(%s: allocated srs: %d, ibs: %d\n,
-   __func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG);
+   pr_debug(%s: allocated srs: %d, ibs: %d\n, __func__,
+(hwirq  msi_data-srs_shift)  MSI_SRS_MASK,
+(hwirq  msi_data-ibs_shift)  MSI_IBS_MASK);
 }
 
 static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
@@ -285,8 +299,8 @@ static void fsl_msi_cascade(unsigned int irq, struct 
irq_desc *desc)
intr_index = ffs(msir_value) - 1;
 
cascade_irq = irq_linear_revmap(msi_data-irqhost,
-   msir_index * IRQS_PER_MSI_REG +
-   intr_index + have_shift);
+   msi_hwirq(msi_data, msir_index,
+ intr_index + have_shift));
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
have_shift += intr_index + 1;
@@ -339,7 +353,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct 
platform_device *dev,
   int offset, int irq_index)
 {
struct fsl_msi_cascade_data *cascade_data = NULL;
-   int virt_msir;
+   int virt_msir, i;
 
virt_msir = irq_of_parse_and_map(dev-dev.of_node, irq_index);
if (virt_msir == NO_IRQ) {
@@ -360,6 +374,11 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct 
platform_device *dev,
irq_set_handler_data(virt_msir, cascade_data);
irq_set_chained_handler(virt_msir, fsl_msi_cascade);
 
+   /* Release the hwirqs corresponding to this MSI register */
+   for (i = 0; i  IRQS_PER_MSI_REG; i++)
+   msi_bitmap_free_hwirqs(msi-bitmap,
+  msi_hwirq(msi, offset, i), 1);
+
return 0;
 }
 
@@ -368,7 +387,7 @@ static int fsl_of_msi_probe(struct platform_device *dev)
 {
const struct of_device_id *match;
struct fsl_msi *msi;
-   struct resource res;
+   struct resource res, msiir;
int err, i, j, irq_index, count;
int rc;
const u32 *p;
@@ -421,10 +440,29 @@ static int fsl_of_msi_probe(struct platform_device *dev)
}
msi-msiir_offset =
features-msiir_offset + (res.start  0xf);
+
+   /*
+* First read the MSIIR/MSIIR1 offset from dts
+* If failure use the hardcode MSIIR offset
+*/
+   if (of_address_to_resource(dev-dev.of_node, 1, msiir))
+   msi-msiir_offset = features-msiir_offset +
+   (res.start  MSIIR_OFFSET_MASK);
+   else
+   msi-msiir_offset = msiir.start

[PATCH 3/5] powerpc/dts: update MSI bindings doc for MPIC v4.3

2013-06-14 Thread Minghuan Lian
Add compatible fsl,mpic-msi-v4.3 for MPIC v4.3. MPIC v4.3 contains
MSIIR and MSIIR1. MSIIR supports 8 MSI registers and MSIIR1 supports
16 MSI registers, but uses different IBS and SRS shift. When using
MSIR1, the interrupt number is not consecutive. It is hard to use
'msi-available-ranges' to describe the ranges of the available
interrupt and the ranges are related to the application, rather than
the description of the hardware. this patch also removes
'msi-available-ranges' property.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 .../devicetree/bindings/powerpc/fsl/msi-pic.txt| 49 ++
 1 file changed, 22 insertions(+), 27 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt 
b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
index 5693877..e851e93 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
@@ -1,26 +1,23 @@
 * Freescale MSI interrupt controller
 
 Required properties:
-- compatible : compatible list, contains 2 entries,
+- compatible : compatible list, may contains one or two entries,
   first is fsl,CHIP-msi, where CHIP is the processor(mpc8610, mpc8572,
-  etc.) and the second is fsl,mpic-msi or fsl,ipic-msi depending on
-  the parent type.
+  etc.) and the second is fsl,mpic-msi or fsl,ipic-msi or
+  fsl,mpic-msi-v4.3 depending on the parent type and version. If mpic
+  version is 4.3, the number of MSI registers is increased to 16, MSIIR1 is
+  provided to access these 16 registers, compatible fsl,mpic-msi-v4.3
+  should be used.
 
 - reg : It may contain one or two regions. The first region should contain
   the address and the length of the shared message interrupt register set.
-  The second region should contain the address of aliased MSIIR register for
-  platforms that have such an alias.
-
-- msi-available-ranges: use start count style section to define which
-  msi interrupt can be used in the 256 msi interrupts. This property is
-  optional, without this, all the 256 MSI interrupts can be used.
-  Each available range must begin and end on a multiple of 32 (i.e.
-  no splitting an individual MSI register or the associated PIC interrupt).
+  The second region should contain the address of aliased MSIIR or MSIIR1
+  register for platforms that have such an alias, if using MSIIR1, the second
+  region must be added because different MSI group has different MSIRR1 offset.
 
 - interrupts : each one of the interrupts here is one entry per 32 MSIs,
   and routed to the host interrupt controller. the interrupts should
-  be set as edge sensitive.  If msi-available-ranges is present, only
-  the interrupts that correspond to available ranges shall be present.
+  be set as edge sensitive.
 
 - interrupt-parent: the phandle for the interrupt controller
   that services interrupts for this device. for 83xx cpu, the interrupts
@@ -39,20 +36,18 @@ Optional properties:
 
 Example:
msi@41600 {
-   compatible = fsl,mpc8610-msi, fsl,mpic-msi;
-   reg = 0x41600 0x80;
-   msi-available-ranges = 0 0x100;
-   interrupts = 
-   0xe0 0
-   0xe1 0
-   0xe2 0
-   0xe3 0
-   0xe4 0
-   0xe5 0
-   0xe6 0
-   0xe7 0;
-   interrupt-parent = mpic;
-   };
+   compatible = fsl,mpic-msi;
+   reg = 0x41600 0x200 0x44140 4;
+   interrupts = 
+   0xe0 0 0 0
+   0xe1 0 0 0
+   0xe2 0 0 0
+   0xe3 0 0 0
+   0xe4 0 0 0
+   0xe5 0 0 0
+   0xe6 0 0 0
+   0xe7 0 0 0;
+};
 
 The Freescale hypervisor and msi-address-64
 ---
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 5/5] powerpc/fsl_msi: add 'msiregs' kernel parameter

2013-06-14 Thread Minghuan Lian
1. Only MSIIR1 can index 16 MSI registers, but when using MSIIR1
the IRQs of a register are not continuous. for example, the first
register irq values are 0x0, 0x10, 0x20, 0x30 ... 0x1f0. So it
is hard to use 'msi-available-ranges' property to indicate the
available ranges and 'msi-available-ranges' property has been
removed from dts node, so this patch removes the related code.

2. Add 'msiregs' kernel parameter instead of 'msi-available-ranges'
functionality. 'msiregs' is used to indicate the available MSI
registers ranges and uses a colon ':' to separate the multiple
banks. The range representation format is 'start-end', 'start'
and 'end' are integers describe the start and end register index,
the available registers lies between start and end and not include
end. For example, the available register x satisfying
start = x  end.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 arch/powerpc/sysdev/fsl_msi.c | 118 --
 arch/powerpc/sysdev/fsl_msi.h |   1 +
 2 files changed, 80 insertions(+), 39 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 34510b7..db382ef9b 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -52,6 +52,60 @@ struct fsl_msi_cascade_data {
int index;
 };
 
+struct msi_reg_range {
+   u32 start;
+   u32 end;
+};
+
+static struct msi_reg_range msiregs[NR_MSI_BANK] = {
+   {.start = 0, .end = NR_MSI_REG },
+   {.start = 0, .end = NR_MSI_REG },
+   {.start = 0, .end = NR_MSI_REG },
+   {.start = 0, .end = NR_MSI_REG },
+};
+
+/*
+ * Handle 'msiregs' parameter.
+ * msiregs is used to indicate the available MSI registers range and
+ * uses colon ':' to separate the multiple banks ranges.
+ * For each bank, the registers range format is 'start-end'
+ * start and end are integers, used to the indicate the start and end
+ * register index. The range is a set of real numbers that lies between
+ * start and end but not include end. For example, the set of all numbers
+ * x satisfying start = x  end.
+ * if no range specified, driver will use the default range including all
+ * the registers.
+ * if you do no want to use this bank, you can set range as '0-0'
+ * For example msiregs=0-16:0-0::0-2
+ */
+static int msi_regs_setup(char *s)
+{
+   int bank = 0;
+   char *p;
+   struct msi_reg_range *range;
+
+   while ((p = strsep(s, :)) != NULL) {
+   int start = 0, end = NR_MSI_REG;
+
+   if (bank = NR_MSI_BANK)
+   break;
+   range = msiregs[bank];
+
+   if ((*p != '\0')  (sscanf(p, %d-%d, start, end)  1))
+   pr_err(msiregs correct format is: start-end\n);
+
+   /* Ok, gets the specified value */
+   range-start = start;
+   range-end = end;
+   pr_info(MSI bank%d available regs range is %d-%d\n,
+bank, range-start, range-end);
+   bank++;
+   }
+   return 1;
+}
+
+__setup(msiregs=, msi_regs_setup);
+
 static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
 {
return in_be32(base + (reg  2));
@@ -350,7 +404,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev)
 static struct lock_class_key fsl_msi_irq_class;
 
 static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device 
*dev,
-  int offset, int irq_index)
+  int irq_index)
 {
struct fsl_msi_cascade_data *cascade_data = NULL;
int virt_msir, i;
@@ -369,7 +423,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct 
platform_device *dev,
}
irq_set_lockdep_class(virt_msir, fsl_msi_irq_class);
msi-msi_virqs[irq_index] = virt_msir;
-   cascade_data-index = offset;
+   cascade_data-index = irq_index;
cascade_data-msi_data = msi;
irq_set_handler_data(virt_msir, cascade_data);
irq_set_chained_handler(virt_msir, fsl_msi_cascade);
@@ -377,7 +431,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct 
platform_device *dev,
/* Release the hwirqs corresponding to this MSI register */
for (i = 0; i  IRQS_PER_MSI_REG; i++)
msi_bitmap_free_hwirqs(msi-bitmap,
-  msi_hwirq(msi, offset, i), 1);
+  msi_hwirq(msi, irq_index, i), 1);
 
return 0;
 }
@@ -387,21 +441,29 @@ static int fsl_of_msi_probe(struct platform_device *dev)
 {
const struct of_device_id *match;
struct fsl_msi *msi;
+   static int bank;
+   struct msi_reg_range *range;
struct resource res, msiir;
-   int err, i, j, irq_index, count;
+   int err, irq_index, count;
int rc;
-   const u32 *p;
const struct fsl_msi_feature *features;
-   int len;
-   u32 offset;
-   static const u32 all_avail

[PATCH 4/5] powerpc/dts: remove msi-available-ranges property

2013-06-14 Thread Minghuan Lian
For MPIC v4.3 MSIIR supports 8 MSI registers and MSIIR1 supports
16 MSI registers, but uses different IBS and SRS shift. For the
first register, when using MSIIR we will get the irqs 0x0 0x1 0x2
...0x1f, but when using MSIIR1, the irqs are 0x0 0x10 0x20 ... 0x1f0
It is hard to describe the available irqs using property
'msi-available-ranges'. The patch removes this property.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi  | 1 -
 arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi| 3 ---
 arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi | 4 
 3 files changed, 8 deletions(-)

diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi 
b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi
index 71c30eb..1ac4f23 100644
--- a/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi
+++ b/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi
@@ -66,7 +66,6 @@ message@41400 {
 msi@41600 {
compatible = fsl,mpic-msi;
reg = 0x41600 0x80;
-   msi-available-ranges = 0 0x100;
interrupts = 
0xe0 0 0 0
0xe1 0 0 0
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi 
b/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi
index 08f4227..cf7355c 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-mpic.dtsi
@@ -54,7 +54,6 @@ timer@41100 {
 msi0: msi@41600 {
compatible = fsl,mpic-msi;
reg = 0x41600 0x200 0x44140 4;
-   msi-available-ranges = 0 0x100;
interrupts = 
0xe0 0 0 0
0xe1 0 0 0
@@ -69,7 +68,6 @@ msi0: msi@41600 {
 msi1: msi@41800 {
compatible = fsl,mpic-msi;
reg = 0x41800 0x200 0x45140 4;
-   msi-available-ranges = 0 0x100;
interrupts = 
0xe8 0 0 0
0xe9 0 0 0
@@ -84,7 +82,6 @@ msi1: msi@41800 {
 msi2: msi@41a00 {
compatible = fsl,mpic-msi;
reg = 0x41a00 0x200 0x46140 4;
-   msi-available-ranges = 0 0x100;
interrupts = 
0xf0 0 0 0
0xf1 0 0 0
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi 
b/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi
index e2665b8..8a997ea 100644
--- a/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi
+++ b/arch/powerpc/boot/dts/fsl/qoriq-mpic4.3.dtsi
@@ -54,7 +54,6 @@ timer@41100 {
 msi0: msi@41600 {
compatible = fsl,mpic-msi, fsl,mpic-msi-v4.3;
reg = 0x41600 0x200 0x44148 4;
-   msi-available-ranges = 0 0x200;
interrupts = 
0xe0 0 0 0
0xe1 0 0 0
@@ -77,7 +76,6 @@ msi0: msi@41600 {
 msi1: msi@41800 {
compatible = fsl,mpic-msi, fsl,mpic-msi-v4.3;
reg = 0x41800 0x200 0x45148 4;
-   msi-available-ranges = 0 0x200;
interrupts = 
0xe8 0 0 0
0xe9 0 0 0
@@ -100,7 +98,6 @@ msi1: msi@41800 {
 msi2: msi@41a00 {
compatible = fsl,mpic-msi, fsl,mpic-msi-v4.3;
reg = 0x41a00 0x200 0x46148 4;
-   msi-available-ranges = 0 0x200;
interrupts = 
0xf0 0 0 0
0xf1 0 0 0
@@ -123,7 +120,6 @@ msi2: msi@41a00 {
 msi3: msi@41c00 {
compatible = fsl,mpic-msi, fsl,mpic-msi-v4.3;
reg = 0x41c00 0x200 0x47148 4;
-   msi-available-ranges = 0 0x200;
interrupts = 
0xf8 0 0 0
0xf9 0 0 0
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc/fsl: add property 'reg' to pcie@0 node

2013-05-09 Thread Minghuan Lian
The property 'reg' is used to identify the PCIe device. if there is
no 'reg' the PCI driver can not find PCI device node corresponding
to PCI controller, and can not map the interrupts. So all the INTx
interrupts can not be used.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
---
 arch/powerpc/boot/dts/fsl/b4si-post.dtsi| 1 +
 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 4 
 2 files changed, 5 insertions(+)

diff --git a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
index 7399154..d82c8da 100644
--- a/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4si-post.dtsi
@@ -49,6 +49,7 @@
interrupts = 20 2 0 0;
fsl,iommu-parent = pamu0;
pcie@0 {
+   reg = 0 0 0 0 0;
#interrupt-cells = 1;
#size-cells = 2;
#address-cells = 3;
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi 
b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index bd611a9..3a6179f 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -48,6 +48,7 @@
bus-range = 0x0 0xff;
interrupts = 20 2 0 0;
pcie@0 {
+   reg = 0 0 0 0 0;
#interrupt-cells = 1;
#size-cells = 2;
#address-cells = 3;
@@ -74,6 +75,7 @@
bus-range = 0 0xff;
interrupts = 21 2 0 0;
pcie@0 {
+   reg = 0 0 0 0 0;
#interrupt-cells = 1;
#size-cells = 2;
#address-cells = 3;
@@ -100,6 +102,7 @@
bus-range = 0x0 0xff;
interrupts = 22 2 0 0;
pcie@0 {
+   reg = 0 0 0 0 0;
#interrupt-cells = 1;
#size-cells = 2;
#address-cells = 3;
@@ -126,6 +129,7 @@
bus-range = 0x0 0xff;
interrupts = 23 2 0 0;
pcie@0 {
+   reg = 0 0 0 0 0;
#interrupt-cells = 1;
#size-cells = 2;
#address-cells = 3;
-- 
1.8.1.2


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH][v2] powerpc/fsl-pci: use 'Header Type' to identify PCIE mode

2012-09-23 Thread Minghuan Lian
The original code uses 'Programming Interface' field to judge if PCIE is
EP or RC mode, however, some latest silicons do not support this functionality.
According to PCIE specification, 'Header Type' offset 0x0e is used to
indicate header type, so change code to use 'Header Type' field to
judge PCIE mode. Because FSL PCI controller does not support 'Header Type',
patch still uses 'Programming Interface' to identify PCI mode.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
Signed-off-by: Roy Zang tie-fei.z...@freescale.com
---
Change log:
v2 - 
keep the original PCI initialization order according to kumar's recommendations.

 arch/powerpc/sysdev/fsl_pci.c |   37 -
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index c37f461..468e76c 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
 
 static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
 {
-   u8 progif;
+   u8 hdr_type;
 
/* if we aren't a PCIe don't bother */
if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
return;
 
/* if we aren't in host mode don't bother */
-   pci_read_config_byte(dev, PCI_CLASS_PROG, progif);
-   if (progif  0x1)
+   pci_read_config_byte(dev, PCI_HEADER_TYPE, hdr_type);
+   if ((hdr_type  0x7f) != PCI_HEADER_TYPE_BRIDGE)
return;
 
dev-class = PCI_CLASS_BRIDGE_PCI  8;
@@ -425,7 +425,7 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
struct pci_controller *hose;
struct resource rsrc;
const int *bus_range;
-   u8 progif;
+   u8 hdr_type, progif;
 
if (!of_device_is_available(dev)) {
pr_warning(%s: disabled\n, dev-full_name);
@@ -457,15 +457,17 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
PPC_INDIRECT_TYPE_BIG_ENDIAN);
 
-   early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, progif);
-   if ((progif  1) == 1) {
-   /* unmap cfg_data  cfg_addr separately if not on same page */
-   if (((unsigned long)hose-cfg_data  PAGE_MASK) !=
-   ((unsigned long)hose-cfg_addr  PAGE_MASK))
-   iounmap(hose-cfg_data);
-   iounmap(hose-cfg_addr);
-   pcibios_free_controller(hose);
-   return -ENODEV;
+   if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+   /* For PCIE read HEADER_TYPE to identify controler mode */
+   early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, hdr_type);
+   if ((hdr_type  0x7f) != PCI_HEADER_TYPE_BRIDGE)
+   goto no_bridge;
+
+   } else {
+   /* For PCI read PROG to identify controller mode */
+   early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, progif);
+   if ((progif  1) == 1)
+   goto no_bridge;
}
 
setup_pci_cmd(hose);
@@ -494,6 +496,15 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
setup_pci_atmu(hose, rsrc);
 
return 0;
+
+no_bridge:
+   /* unmap cfg_data  cfg_addr separately if not on same page */
+   if (((unsigned long)hose-cfg_data  PAGE_MASK) !=
+   ((unsigned long)hose-cfg_addr  PAGE_MASK))
+   iounmap(hose-cfg_data);
+   iounmap(hose-cfg_addr);
+   pcibios_free_controller(hose);
+   return -ENODEV;
 }
 #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
 
-- 
1.7.9.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] powerpc/fsl-pci: use 'Header Type' to identify PCIE mode

2012-09-19 Thread Minghuan Lian
The original code uses 'Programming Interface' field to judge if PCIE is
EP or RC mode, however, some latest silicons do not support this functionality.
According to PCIE specification, 'Header Type' offset 0x0e is used to
indicate header type, so change code to use 'Header Type' field to
judge PCIE mode. Because FSL PCI controller does not support 'Header Type',
patch still uses 'Programming Interface' to identify PCI mode.

Signed-off-by: Minghuan Lian minghuan.l...@freescale.com
Signed-off-by: Roy Zang tie-fei.z...@freescale.com
---
 arch/powerpc/sysdev/fsl_pci.c |   38 +++---
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index c37f461..43d30df 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -38,15 +38,15 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
 
 static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev)
 {
-   u8 progif;
+   u8 hdr_type;
 
/* if we aren't a PCIe don't bother */
if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
return;
 
/* if we aren't in host mode don't bother */
-   pci_read_config_byte(dev, PCI_CLASS_PROG, progif);
-   if (progif  0x1)
+   pci_read_config_byte(dev, PCI_HEADER_TYPE, hdr_type);
+   if ((hdr_type  0x7f) != PCI_HEADER_TYPE_BRIDGE)
return;
 
dev-class = PCI_CLASS_BRIDGE_PCI  8;
@@ -425,7 +425,7 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
struct pci_controller *hose;
struct resource rsrc;
const int *bus_range;
-   u8 progif;
+   u8 hdr_type, progif;
 
if (!of_device_is_available(dev)) {
pr_warning(%s: disabled\n, dev-full_name);
@@ -457,25 +457,24 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
PPC_INDIRECT_TYPE_BIG_ENDIAN);
 
-   early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, progif);
-   if ((progif  1) == 1) {
-   /* unmap cfg_data  cfg_addr separately if not on same page */
-   if (((unsigned long)hose-cfg_data  PAGE_MASK) !=
-   ((unsigned long)hose-cfg_addr  PAGE_MASK))
-   iounmap(hose-cfg_data);
-   iounmap(hose-cfg_addr);
-   pcibios_free_controller(hose);
-   return -ENODEV;
-   }
-
setup_pci_cmd(hose);
 
/* check PCI express link status */
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+   /* For PCIE read HEADER_TYPE to identify controler mode */
+   early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, hdr_type);
+   if ((hdr_type  0x7f) != PCI_HEADER_TYPE_BRIDGE)
+   goto no_bridge;
+
hose-indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
if (fsl_pcie_check_link(hose))
hose-indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+   } else {
+   /* For PCI read PROG to identify controller mode */
+   early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, progif);
+   if ((progif  1) == 1)
+   goto no_bridge;
}
 
printk(KERN_INFO Found FSL PCI host bridge at 0x%016llx. 
@@ -494,6 +493,15 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
setup_pci_atmu(hose, rsrc);
 
return 0;
+
+no_bridge:
+   /* unmap cfg_data  cfg_addr separately if not on same page */
+   if (((unsigned long)hose-cfg_data  PAGE_MASK) !=
+   ((unsigned long)hose-cfg_addr  PAGE_MASK))
+   iounmap(hose-cfg_data);
+   iounmap(hose-cfg_addr);
+   pcibios_free_controller(hose);
+   return -ENODEV;
 }
 #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
 
-- 
1.7.9.5


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev