aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2017-09-26 14:02:20 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-10-05 16:52:55 -0400
commit68a15eb7bd0cf180eb214c79aa4e1662c5eeb97c (patch)
treee7ea01aa305367f6aa7204d0ef6d77d2af268dab
parentaf37bed303e2b8fbdbe62e8c2c60900eb62a7fea (diff)
PCI: v3-semi: Add V3 Semiconductor PCI host driver
This PCI host bridge from V3 Semiconductor needs no further introduction. An ancient driver for it has been sitting in arch/arm/mach-integrator/pci_v3.* since before v2.6.12 and the initial migration to git. But we need to get the drivers out of arch/arm/* and get proper handling of the old drivers, rewrite and clean up so the PCI maintainer can control the mass of drivers without having to run all over the kernel. We also switch swiftly to all the new infrastructure found in the PCI hosts as of late. Some code is preserved so I have added an extensive list of authors in the top comment section. This driver probes with the following result: OF: PCI: host bridge /pciv3@62000000 ranges: OF: PCI: No bus range found for /pciv3@62000000, using [bus 00-ff] OF: PCI: IO 0x60000000..0x6000ffff -> 0x00000000 OF: PCI: MEM 0x40000000..0x4fffffff -> 0x40000000 OF: PCI: MEM 0x50000000..0x5fffffff -> 0x50000000 pci-v3-semi 62000000.pciv3: initialized PCI V3 Integrator/AP integration pci-v3-semi 62000000.pciv3: PCI host bridge to bus 0000:00 pci_bus 0000:00: root bus resource [bus 00-ff] pci_bus 0000:00: root bus resource [io 0x0000-0xffff] pci_bus 0000:00: root bus resource [mem 0x40000000-0x4fffffff] pci_bus 0000:00: root bus resource [mem 0x50000000-0x5fffffff pref] pci-v3-semi 62000000.pciv3: parity error interrupt pci-v3-semi 62000000.pciv3: master abort error interrupt pci-v3-semi 62000000.pciv3: PCI target LB->PCI READ abort interrupt pci-v3-semi 62000000.pciv3: master abort error interrupt (repeats a few times) pci 0000:00:09.0: [1011:0024] type 01 class 0x060400 pci-v3-semi 62000000.pciv3: master abort error interrupt pci-v3-semi 62000000.pciv3: PCI target LB->PCI READ abort interrupt pci 0000:00:0b.0: [8086:1229] type 00 class 0x020000 pci 0000:00:0b.0: reg 0x10: [mem 0x00000000-0x00000fff pref] pci 0000:00:0b.0: reg 0x14: [io 0x0000-0x001f] pci 0000:00:0b.0: reg 0x18: [mem 0x00000000-0x000fffff] pci 0000:00:0b.0: reg 0x30: [mem 0x00000000-0x000fffff pref] pci 0000:00:0b.0: supports D1 D2 pci 0000:00:0b.0: PME# supported from D0 D1 D2 D3hot pci 0000:00:0c.0: [5333:8811] type 00 class 0x030000 pci 0000:00:0c.0: reg 0x10: [mem 0x00000000-0x03ffffff] pci 0000:00:0c.0: reg 0x30: [mem 0x00000000-0x0000ffff pref] pci 0000:00:0c.0: vgaarb: VGA device added: decodes=io+mem,owns=io,locks=none PCI: bus0: Fast back to back transfers disabled PCI: bus1: Fast back to back transfers enabled pci 0000:00:0c.0: BAR 0: assigned [mem 0x40000000-0x43ffffff] pci 0000:00:0b.0: BAR 2: assigned [mem 0x44000000-0x440fffff] pci 0000:00:0b.0: BAR 6: assigned [mem 0x50000000-0x500fffff pref] pci 0000:00:0c.0: BAR 6: assigned [mem 0x50100000-0x5010ffff pref] pci 0000:00:0b.0: BAR 0: assigned [mem 0x50110000-0x50110fff pref] pci 0000:00:0b.0: BAR 1: assigned [io 0x1000-0x101f] pci 0000:00:09.0: PCI bridge to [bus 01] pci 0000:00:0b.0: Firmware left e100 interrupts enabled; disabling (...) e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI e100: Copyright(c) 1999-2006 Intel Corporation e100 0000:00:0b.0: enabling device (0146 -> 0147) e100 0000:00:0b.0 eth0: addr 0x50110000, irq 31, MAC addr 00:08:c7:99:d2:57 > lspci 00:0b.0 Class 0200: 8086:1229 00:09.0 Class 0604: 1011:0024 00:0c.0 Class 0300: 5333:8811 > cat /proc/iomem 40000000-4fffffff : V3 PCI NON-PRE-MEM 40000000-43ffffff : 0000:00:0c.0 44000000-440fffff : 0000:00:0b.0 44000000-440fffff : e100 50000000-5fffffff : V3 PCI PRE-MEM 50000000-500fffff : 0000:00:0b.0 50100000-5010ffff : 0000:00:0c.0 50110000-50110fff : 0000:00:0b.0 50110000-50110fff : e100 61000000-61ffffff : /pciv3@62000000 62000000-6200ffff : /pciv3@62000000 Signed-off-by: Linus Walleij <linus.walleij@linaro.org> [bhelgaas: fold in %pR fixes from Arnd Bergmann <arnd@arndb.de>: http://lkml.kernel.org/r/20171011140224.3770968-1-arnd@arndb.de] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/pci/host/Kconfig6
-rw-r--r--drivers/pci/host/Makefile1
-rw-r--r--drivers/pci/host/pci-v3-semi.c959
4 files changed, 973 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 65b0c88d5ee0..5cb4bf4a06cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10503,6 +10503,13 @@ S: Maintained
10503F: Documentation/devicetree/bindings/pci/rockchip-pcie.txt 10503F: Documentation/devicetree/bindings/pci/rockchip-pcie.txt
10504F: drivers/pci/host/pcie-rockchip.c 10504F: drivers/pci/host/pcie-rockchip.c
10505 10505
10506PCI DRIVER FOR V3 SEMICONDUCTOR V360EPC
10507M: Linus Walleij <linus.walleij@linaro.org>
10508L: linux-pci@vger.kernel.org
10509S: Maintained
10510F: Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt
10511F: drivers/pci/host/pci-v3-semi.c
10512
10506PCIE DRIVER FOR ST SPEAR13XX 10513PCIE DRIVER FOR ST SPEAR13XX
10507M: Pratyush Anand <pratyush.anand@gmail.com> 10514M: Pratyush Anand <pratyush.anand@gmail.com>
10508L: linux-pci@vger.kernel.org 10515L: linux-pci@vger.kernel.org
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index b868803792d8..38d12980db0f 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -95,6 +95,12 @@ config PCI_XGENE_MSI
95 Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC. 95 Say Y here if you want PCIe MSI support for the APM X-Gene v1 SoC.
96 This MSI driver supports 5 PCIe ports on the APM X-Gene v1 SoC. 96 This MSI driver supports 5 PCIe ports on the APM X-Gene v1 SoC.
97 97
98config PCI_V3_SEMI
99 bool "V3 Semiconductor PCI controller"
100 depends on OF
101 depends on ARM
102 default ARCH_INTEGRATOR_AP
103
98config PCI_VERSATILE 104config PCI_VERSATILE
99 bool "ARM Versatile PB PCI controller" 105 bool "ARM Versatile PB PCI controller"
100 depends on ARCH_VERSATILE 106 depends on ARCH_VERSATILE
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 12382785e02a..ee7cd492bb7f 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
9obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o 9obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
10obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o 10obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
11obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o 11obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o
12obj-$(CONFIG_PCI_V3_SEMI) += pci-v3-semi.o
12obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o 13obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
13obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o 14obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
14obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o 15obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
diff --git a/drivers/pci/host/pci-v3-semi.c b/drivers/pci/host/pci-v3-semi.c
new file mode 100644
index 000000000000..02f6e1e3a421
--- /dev/null
+++ b/drivers/pci/host/pci-v3-semi.c
@@ -0,0 +1,959 @@
1/*
2 * Support for V3 Semiconductor PCI Local Bus to PCI Bridge
3 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
4 *
5 * Based on the code from arch/arm/mach-integrator/pci_v3.c
6 * Copyright (C) 1999 ARM Limited
7 * Copyright (C) 2000-2001 Deep Blue Solutions Ltd
8 *
9 * Contributors to the old driver include:
10 * Russell King <linux@armlinux.org.uk>
11 * David A. Rusling <david.rusling@linaro.org> (uHAL, ARM Firmware suite)
12 * Rob Herring <robh@kernel.org>
13 * Liviu Dudau <Liviu.Dudau@arm.com>
14 * Grant Likely <grant.likely@secretlab.ca>
15 * Arnd Bergmann <arnd@arndb.de>
16 * Bjorn Helgaas <bhelgaas@google.com>
17 */
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/io.h>
21#include <linux/kernel.h>
22#include <linux/of_address.h>
23#include <linux/of_device.h>
24#include <linux/of_irq.h>
25#include <linux/of_pci.h>
26#include <linux/pci.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29#include <linux/bitops.h>
30#include <linux/irq.h>
31#include <linux/mfd/syscon.h>
32#include <linux/regmap.h>
33#include <linux/clk.h>
34
35#define V3_PCI_VENDOR 0x00000000
36#define V3_PCI_DEVICE 0x00000002
37#define V3_PCI_CMD 0x00000004
38#define V3_PCI_STAT 0x00000006
39#define V3_PCI_CC_REV 0x00000008
40#define V3_PCI_HDR_CFG 0x0000000C
41#define V3_PCI_IO_BASE 0x00000010
42#define V3_PCI_BASE0 0x00000014
43#define V3_PCI_BASE1 0x00000018
44#define V3_PCI_SUB_VENDOR 0x0000002C
45#define V3_PCI_SUB_ID 0x0000002E
46#define V3_PCI_ROM 0x00000030
47#define V3_PCI_BPARAM 0x0000003C
48#define V3_PCI_MAP0 0x00000040
49#define V3_PCI_MAP1 0x00000044
50#define V3_PCI_INT_STAT 0x00000048
51#define V3_PCI_INT_CFG 0x0000004C
52#define V3_LB_BASE0 0x00000054
53#define V3_LB_BASE1 0x00000058
54#define V3_LB_MAP0 0x0000005E
55#define V3_LB_MAP1 0x00000062
56#define V3_LB_BASE2 0x00000064
57#define V3_LB_MAP2 0x00000066
58#define V3_LB_SIZE 0x00000068
59#define V3_LB_IO_BASE 0x0000006E
60#define V3_FIFO_CFG 0x00000070
61#define V3_FIFO_PRIORITY 0x00000072
62#define V3_FIFO_STAT 0x00000074
63#define V3_LB_ISTAT 0x00000076
64#define V3_LB_IMASK 0x00000077
65#define V3_SYSTEM 0x00000078
66#define V3_LB_CFG 0x0000007A
67#define V3_PCI_CFG 0x0000007C
68#define V3_DMA_PCI_ADR0 0x00000080
69#define V3_DMA_PCI_ADR1 0x00000090
70#define V3_DMA_LOCAL_ADR0 0x00000084
71#define V3_DMA_LOCAL_ADR1 0x00000094
72#define V3_DMA_LENGTH0 0x00000088
73#define V3_DMA_LENGTH1 0x00000098
74#define V3_DMA_CSR0 0x0000008B
75#define V3_DMA_CSR1 0x0000009B
76#define V3_DMA_CTLB_ADR0 0x0000008C
77#define V3_DMA_CTLB_ADR1 0x0000009C
78#define V3_DMA_DELAY 0x000000E0
79#define V3_MAIL_DATA 0x000000C0
80#define V3_PCI_MAIL_IEWR 0x000000D0
81#define V3_PCI_MAIL_IERD 0x000000D2
82#define V3_LB_MAIL_IEWR 0x000000D4
83#define V3_LB_MAIL_IERD 0x000000D6
84#define V3_MAIL_WR_STAT 0x000000D8
85#define V3_MAIL_RD_STAT 0x000000DA
86#define V3_QBA_MAP 0x000000DC
87
88/* PCI STATUS bits */
89#define V3_PCI_STAT_PAR_ERR BIT(15)
90#define V3_PCI_STAT_SYS_ERR BIT(14)
91#define V3_PCI_STAT_M_ABORT_ERR BIT(13)
92#define V3_PCI_STAT_T_ABORT_ERR BIT(12)
93
94/* LB ISTAT bits */
95#define V3_LB_ISTAT_MAILBOX BIT(7)
96#define V3_LB_ISTAT_PCI_RD BIT(6)
97#define V3_LB_ISTAT_PCI_WR BIT(5)
98#define V3_LB_ISTAT_PCI_INT BIT(4)
99#define V3_LB_ISTAT_PCI_PERR BIT(3)
100#define V3_LB_ISTAT_I2O_QWR BIT(2)
101#define V3_LB_ISTAT_DMA1 BIT(1)
102#define V3_LB_ISTAT_DMA0 BIT(0)
103
104/* PCI COMMAND bits */
105#define V3_COMMAND_M_FBB_EN BIT(9)
106#define V3_COMMAND_M_SERR_EN BIT(8)
107#define V3_COMMAND_M_PAR_EN BIT(6)
108#define V3_COMMAND_M_MASTER_EN BIT(2)
109#define V3_COMMAND_M_MEM_EN BIT(1)
110#define V3_COMMAND_M_IO_EN BIT(0)
111
112/* SYSTEM bits */
113#define V3_SYSTEM_M_RST_OUT BIT(15)
114#define V3_SYSTEM_M_LOCK BIT(14)
115#define V3_SYSTEM_UNLOCK 0xa05f
116
117/* PCI CFG bits */
118#define V3_PCI_CFG_M_I2O_EN BIT(15)
119#define V3_PCI_CFG_M_IO_REG_DIS BIT(14)
120#define V3_PCI_CFG_M_IO_DIS BIT(13)
121#define V3_PCI_CFG_M_EN3V BIT(12)
122#define V3_PCI_CFG_M_RETRY_EN BIT(10)
123#define V3_PCI_CFG_M_AD_LOW1 BIT(9)
124#define V3_PCI_CFG_M_AD_LOW0 BIT(8)
125/*
126 * This is the value applied to C/BE[3:1], with bit 0 always held 0
127 * during DMA access.
128 */
129#define V3_PCI_CFG_M_RTYPE_SHIFT 5
130#define V3_PCI_CFG_M_WTYPE_SHIFT 1
131#define V3_PCI_CFG_TYPE_DEFAULT 0x3
132
133/* PCI BASE bits (PCI -> Local Bus) */
134#define V3_PCI_BASE_M_ADR_BASE 0xFFF00000U
135#define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00U
136#define V3_PCI_BASE_M_PREFETCH BIT(3)
137#define V3_PCI_BASE_M_TYPE (3 << 1)
138#define V3_PCI_BASE_M_IO BIT(0)
139
140/* PCI MAP bits (PCI -> Local bus) */
141#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000U
142#define V3_PCI_MAP_M_RD_POST_INH BIT(15)
143#define V3_PCI_MAP_M_ROM_SIZE (3 << 10)
144#define V3_PCI_MAP_M_SWAP (3 << 8)
145#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0U
146#define V3_PCI_MAP_M_REG_EN BIT(1)
147#define V3_PCI_MAP_M_ENABLE BIT(0)
148
149/* LB_BASE0,1 bits (Local bus -> PCI) */
150#define V3_LB_BASE_ADR_BASE 0xfff00000U
151#define V3_LB_BASE_SWAP (3 << 8)
152#define V3_LB_BASE_ADR_SIZE (15 << 4)
153#define V3_LB_BASE_PREFETCH BIT(3)
154#define V3_LB_BASE_ENABLE BIT(0)
155
156#define V3_LB_BASE_ADR_SIZE_1MB (0 << 4)
157#define V3_LB_BASE_ADR_SIZE_2MB (1 << 4)
158#define V3_LB_BASE_ADR_SIZE_4MB (2 << 4)
159#define V3_LB_BASE_ADR_SIZE_8MB (3 << 4)
160#define V3_LB_BASE_ADR_SIZE_16MB (4 << 4)
161#define V3_LB_BASE_ADR_SIZE_32MB (5 << 4)
162#define V3_LB_BASE_ADR_SIZE_64MB (6 << 4)
163#define V3_LB_BASE_ADR_SIZE_128MB (7 << 4)
164#define V3_LB_BASE_ADR_SIZE_256MB (8 << 4)
165#define V3_LB_BASE_ADR_SIZE_512MB (9 << 4)
166#define V3_LB_BASE_ADR_SIZE_1GB (10 << 4)
167#define V3_LB_BASE_ADR_SIZE_2GB (11 << 4)
168
169#define v3_addr_to_lb_base(a) ((a) & V3_LB_BASE_ADR_BASE)
170
171/* LB_MAP0,1 bits (Local bus -> PCI) */
172#define V3_LB_MAP_MAP_ADR 0xfff0U
173#define V3_LB_MAP_TYPE (7 << 1)
174#define V3_LB_MAP_AD_LOW_EN BIT(0)
175
176#define V3_LB_MAP_TYPE_IACK (0 << 1)
177#define V3_LB_MAP_TYPE_IO (1 << 1)
178#define V3_LB_MAP_TYPE_MEM (3 << 1)
179#define V3_LB_MAP_TYPE_CONFIG (5 << 1)
180#define V3_LB_MAP_TYPE_MEM_MULTIPLE (6 << 1)
181
182#define v3_addr_to_lb_map(a) (((a) >> 16) & V3_LB_MAP_MAP_ADR)
183
184/* LB_BASE2 bits (Local bus -> PCI IO) */
185#define V3_LB_BASE2_ADR_BASE 0xff00U
186#define V3_LB_BASE2_SWAP_AUTO (3 << 6)
187#define V3_LB_BASE2_ENABLE BIT(0)
188
189#define v3_addr_to_lb_base2(a) (((a) >> 16) & V3_LB_BASE2_ADR_BASE)
190
191/* LB_MAP2 bits (Local bus -> PCI IO) */
192#define V3_LB_MAP2_MAP_ADR 0xff00U
193
194#define v3_addr_to_lb_map2(a) (((a) >> 16) & V3_LB_MAP2_MAP_ADR)
195
196/* FIFO priority bits */
197#define V3_FIFO_PRIO_LOCAL BIT(12)
198#define V3_FIFO_PRIO_LB_RD1_FLUSH_EOB BIT(10)
199#define V3_FIFO_PRIO_LB_RD1_FLUSH_AP1 BIT(11)
200#define V3_FIFO_PRIO_LB_RD1_FLUSH_ANY (BIT(10)|BIT(11))
201#define V3_FIFO_PRIO_LB_RD0_FLUSH_EOB BIT(8)
202#define V3_FIFO_PRIO_LB_RD0_FLUSH_AP1 BIT(9)
203#define V3_FIFO_PRIO_LB_RD0_FLUSH_ANY (BIT(8)|BIT(9))
204#define V3_FIFO_PRIO_PCI BIT(4)
205#define V3_FIFO_PRIO_PCI_RD1_FLUSH_EOB BIT(2)
206#define V3_FIFO_PRIO_PCI_RD1_FLUSH_AP1 BIT(3)
207#define V3_FIFO_PRIO_PCI_RD1_FLUSH_ANY (BIT(2)|BIT(3))
208#define V3_FIFO_PRIO_PCI_RD0_FLUSH_EOB BIT(0)
209#define V3_FIFO_PRIO_PCI_RD0_FLUSH_AP1 BIT(1)
210#define V3_FIFO_PRIO_PCI_RD0_FLUSH_ANY (BIT(0)|BIT(1))
211
212/* Local bus configuration bits */
213#define V3_LB_CFG_LB_TO_64_CYCLES 0x0000
214#define V3_LB_CFG_LB_TO_256_CYCLES BIT(13)
215#define V3_LB_CFG_LB_TO_512_CYCLES BIT(14)
216#define V3_LB_CFG_LB_TO_1024_CYCLES (BIT(13)|BIT(14))
217#define V3_LB_CFG_LB_RST BIT(12)
218#define V3_LB_CFG_LB_PPC_RDY BIT(11)
219#define V3_LB_CFG_LB_LB_INT BIT(10)
220#define V3_LB_CFG_LB_ERR_EN BIT(9)
221#define V3_LB_CFG_LB_RDY_EN BIT(8)
222#define V3_LB_CFG_LB_BE_IMODE BIT(7)
223#define V3_LB_CFG_LB_BE_OMODE BIT(6)
224#define V3_LB_CFG_LB_ENDIAN BIT(5)
225#define V3_LB_CFG_LB_PARK_EN BIT(4)
226#define V3_LB_CFG_LB_FBB_DIS BIT(2)
227
228/* ARM Integrator-specific extended control registers */
229#define INTEGRATOR_SC_PCI_OFFSET 0x18
230#define INTEGRATOR_SC_PCI_ENABLE BIT(0)
231#define INTEGRATOR_SC_PCI_INTCLR BIT(1)
232#define INTEGRATOR_SC_LBFADDR_OFFSET 0x20
233#define INTEGRATOR_SC_LBFCODE_OFFSET 0x24
234
235struct v3_pci {
236 struct device *dev;
237 void __iomem *base;
238 void __iomem *config_base;
239 struct pci_bus *bus;
240 u32 config_mem;
241 u32 io_mem;
242 u32 non_pre_mem;
243 u32 pre_mem;
244 phys_addr_t io_bus_addr;
245 phys_addr_t non_pre_bus_addr;
246 phys_addr_t pre_bus_addr;
247 struct regmap *map;
248};
249
250/*
251 * The V3 PCI interface chip in Integrator provides several windows from
252 * local bus memory into the PCI memory areas. Unfortunately, there
253 * are not really enough windows for our usage, therefore we reuse
254 * one of the windows for access to PCI configuration space. On the
255 * Integrator/AP, the memory map is as follows:
256 *
257 * Local Bus Memory Usage
258 *
259 * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable
260 * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable
261 * 60000000 - 60FFFFFF PCI IO. 16M
262 * 61000000 - 61FFFFFF PCI Configuration. 16M
263 *
264 * There are three V3 windows, each described by a pair of V3 registers.
265 * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
266 * Base0 and Base1 can be used for any type of PCI memory access. Base2
267 * can be used either for PCI I/O or for I20 accesses. By default, uHAL
268 * uses this only for PCI IO space.
269 *
270 * Normally these spaces are mapped using the following base registers:
271 *
272 * Usage Local Bus Memory Base/Map registers used
273 *
274 * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
275 * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1
276 * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
277 * Cfg 61000000 - 61FFFFFF
278 *
279 * This means that I20 and PCI configuration space accesses will fail.
280 * When PCI configuration accesses are needed (via the uHAL PCI
281 * configuration space primitives) we must remap the spaces as follows:
282 *
283 * Usage Local Bus Memory Base/Map registers used
284 *
285 * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
286 * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0
287 * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
288 * Cfg 61000000 - 61FFFFFF LB_BASE1/LB_MAP1
289 *
290 * To make this work, the code depends on overlapping windows working.
291 * The V3 chip translates an address by checking its range within
292 * each of the BASE/MAP pairs in turn (in ascending register number
293 * order). It will use the first matching pair. So, for example,
294 * if the same address is mapped by both LB_BASE0/LB_MAP0 and
295 * LB_BASE1/LB_MAP1, the V3 will use the translation from
296 * LB_BASE0/LB_MAP0.
297 *
298 * To allow PCI Configuration space access, the code enlarges the
299 * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes
300 * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
301 * be remapped for use by configuration cycles.
302 *
303 * At the end of the PCI Configuration space accesses,
304 * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window
305 * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
306 * reveal the now restored LB_BASE1/LB_MAP1 window.
307 *
308 * NOTE: We do not set up I2O mapping. I suspect that this is only
309 * for an intelligent (target) device. Using I2O disables most of
310 * the mappings into PCI memory.
311 */
312static void __iomem *v3_map_bus(struct pci_bus *bus,
313 unsigned int devfn, int offset)
314{
315 struct v3_pci *v3 = bus->sysdata;
316 unsigned int address, mapaddress, busnr;
317
318 busnr = bus->number;
319 if (busnr == 0) {
320 int slot = PCI_SLOT(devfn);
321
322 /*
323 * local bus segment so need a type 0 config cycle
324 *
325 * build the PCI configuration "address" with one-hot in
326 * A31-A11
327 *
328 * mapaddress:
329 * 3:1 = config cycle (101)
330 * 0 = PCI A1 & A0 are 0 (0)
331 */
332 address = PCI_FUNC(devfn) << 8;
333 mapaddress = V3_LB_MAP_TYPE_CONFIG;
334
335 if (slot > 12)
336 /*
337 * high order bits are handled by the MAP register
338 */
339 mapaddress |= BIT(slot - 5);
340 else
341 /*
342 * low order bits handled directly in the address
343 */
344 address |= BIT(slot + 11);
345 } else {
346 /*
347 * not the local bus segment so need a type 1 config cycle
348 *
349 * address:
350 * 23:16 = bus number
351 * 15:11 = slot number (7:3 of devfn)
352 * 10:8 = func number (2:0 of devfn)
353 *
354 * mapaddress:
355 * 3:1 = config cycle (101)
356 * 0 = PCI A1 & A0 from host bus (1)
357 */
358 mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
359 address = (busnr << 16) | (devfn << 8);
360 }
361
362 /*
363 * Set up base0 to see all 512Mbytes of memory space (not
364 * prefetchable), this frees up base1 for re-use by
365 * configuration memory
366 */
367 writel(v3_addr_to_lb_base(v3->non_pre_mem) |
368 V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE,
369 v3->base + V3_LB_BASE0);
370
371 /*
372 * Set up base1/map1 to point into configuration space.
373 * The config mem is always 16MB.
374 */
375 writel(v3_addr_to_lb_base(v3->config_mem) |
376 V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE,
377 v3->base + V3_LB_BASE1);
378 writew(mapaddress, v3->base + V3_LB_MAP1);
379
380 return v3->config_base + address + offset;
381}
382
383static void v3_unmap_bus(struct v3_pci *v3)
384{
385 /*
386 * Reassign base1 for use by prefetchable PCI memory
387 */
388 writel(v3_addr_to_lb_base(v3->pre_mem) |
389 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
390 V3_LB_BASE_ENABLE,
391 v3->base + V3_LB_BASE1);
392 writew(v3_addr_to_lb_map(v3->pre_bus_addr) |
393 V3_LB_MAP_TYPE_MEM, /* was V3_LB_MAP_TYPE_MEM_MULTIPLE */
394 v3->base + V3_LB_MAP1);
395
396 /*
397 * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
398 */
399 writel(v3_addr_to_lb_base(v3->non_pre_mem) |
400 V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE,
401 v3->base + V3_LB_BASE0);
402}
403
404static int v3_pci_read_config(struct pci_bus *bus, unsigned int fn,
405 int config, int size, u32 *value)
406{
407 struct v3_pci *v3 = bus->sysdata;
408 int ret;
409
410 dev_dbg(&bus->dev,
411 "[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
412 PCI_SLOT(fn), PCI_FUNC(fn), config, size, *value);
413 ret = pci_generic_config_read(bus, fn, config, size, value);
414 v3_unmap_bus(v3);
415 return ret;
416}
417
418static int v3_pci_write_config(struct pci_bus *bus, unsigned int fn,
419 int config, int size, u32 value)
420{
421 struct v3_pci *v3 = bus->sysdata;
422 int ret;
423
424 dev_dbg(&bus->dev,
425 "[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n",
426 PCI_SLOT(fn), PCI_FUNC(fn), config, size, value);
427 ret = pci_generic_config_write(bus, fn, config, size, value);
428 v3_unmap_bus(v3);
429 return ret;
430}
431
432static struct pci_ops v3_pci_ops = {
433 .map_bus = v3_map_bus,
434 .read = v3_pci_read_config,
435 .write = v3_pci_write_config,
436};
437
438static irqreturn_t v3_irq(int irq, void *data)
439{
440 struct v3_pci *v3 = data;
441 struct device *dev = v3->dev;
442 u32 status;
443
444 status = readw(v3->base + V3_PCI_STAT);
445 if (status & V3_PCI_STAT_PAR_ERR)
446 dev_err(dev, "parity error interrupt\n");
447 if (status & V3_PCI_STAT_SYS_ERR)
448 dev_err(dev, "system error interrupt\n");
449 if (status & V3_PCI_STAT_M_ABORT_ERR)
450 dev_err(dev, "master abort error interrupt\n");
451 if (status & V3_PCI_STAT_T_ABORT_ERR)
452 dev_err(dev, "target abort error interrupt\n");
453 writew(status, v3->base + V3_PCI_STAT);
454
455 status = readb(v3->base + V3_LB_ISTAT);
456 if (status & V3_LB_ISTAT_MAILBOX)
457 dev_info(dev, "PCI mailbox interrupt\n");
458 if (status & V3_LB_ISTAT_PCI_RD)
459 dev_err(dev, "PCI target LB->PCI READ abort interrupt\n");
460 if (status & V3_LB_ISTAT_PCI_WR)
461 dev_err(dev, "PCI target LB->PCI WRITE abort interrupt\n");
462 if (status & V3_LB_ISTAT_PCI_INT)
463 dev_info(dev, "PCI pin interrupt\n");
464 if (status & V3_LB_ISTAT_PCI_PERR)
465 dev_err(dev, "PCI parity error interrupt\n");
466 if (status & V3_LB_ISTAT_I2O_QWR)
467 dev_info(dev, "I2O inbound post queue interrupt\n");
468 if (status & V3_LB_ISTAT_DMA1)
469 dev_info(dev, "DMA channel 1 interrupt\n");
470 if (status & V3_LB_ISTAT_DMA0)
471 dev_info(dev, "DMA channel 0 interrupt\n");
472 /* Clear all possible interrupts on the local bus */
473 writeb(0, v3->base + V3_LB_ISTAT);
474 if (v3->map)
475 regmap_write(v3->map, INTEGRATOR_SC_PCI_OFFSET,
476 INTEGRATOR_SC_PCI_ENABLE |
477 INTEGRATOR_SC_PCI_INTCLR);
478
479 return IRQ_HANDLED;
480}
481
482static int v3_integrator_init(struct v3_pci *v3)
483{
484 unsigned int val;
485
486 v3->map =
487 syscon_regmap_lookup_by_compatible("arm,integrator-ap-syscon");
488 if (IS_ERR(v3->map)) {
489 dev_err(v3->dev, "no syscon\n");
490 return -ENODEV;
491 }
492
493 regmap_read(v3->map, INTEGRATOR_SC_PCI_OFFSET, &val);
494 /* Take the PCI bridge out of reset, clear IRQs */
495 regmap_write(v3->map, INTEGRATOR_SC_PCI_OFFSET,
496 INTEGRATOR_SC_PCI_ENABLE |
497 INTEGRATOR_SC_PCI_INTCLR);
498
499 if (!(val & INTEGRATOR_SC_PCI_ENABLE)) {
500 /* If we were in reset we need to sleep a bit */
501 msleep(230);
502
503 /* Set the physical base for the controller itself */
504 writel(0x6200, v3->base + V3_LB_IO_BASE);
505
506 /* Wait for the mailbox to settle after reset */
507 do {
508 writeb(0xaa, v3->base + V3_MAIL_DATA);
509 writeb(0x55, v3->base + V3_MAIL_DATA + 4);
510 } while (readb(v3->base + V3_MAIL_DATA) != 0xaa &&
511 readb(v3->base + V3_MAIL_DATA) != 0x55);
512 }
513
514 dev_info(v3->dev, "initialized PCI V3 Integrator/AP integration\n");
515
516 return 0;
517}
518
519static int v3_pci_setup_resource(struct v3_pci *v3,
520 resource_size_t io_base,
521 struct pci_host_bridge *host,
522 struct resource_entry *win)
523{
524 struct device *dev = v3->dev;
525 struct resource *mem;
526 struct resource *io;
527 int ret;
528
529 switch (resource_type(win->res)) {
530 case IORESOURCE_IO:
531 io = win->res;
532 io->name = "V3 PCI I/O";
533 v3->io_mem = io_base;
534 v3->io_bus_addr = io->start - win->offset;
535 dev_dbg(dev, "I/O window %pR, bus addr %pap\n",
536 io, &v3->io_bus_addr);
537 ret = pci_remap_iospace(io, io_base);
538 if (ret) {
539 dev_warn(dev,
540 "error %d: failed to map resource %pR\n",
541 ret, io);
542 return ret;
543 }
544 /* Setup window 2 - PCI I/O */
545 writel(v3_addr_to_lb_base2(v3->io_mem) |
546 V3_LB_BASE2_ENABLE,
547 v3->base + V3_LB_BASE2);
548 writew(v3_addr_to_lb_map2(v3->io_bus_addr),
549 v3->base + V3_LB_MAP2);
550 break;
551 case IORESOURCE_MEM:
552 mem = win->res;
553 if (mem->flags & IORESOURCE_PREFETCH) {
554 mem->name = "V3 PCI PRE-MEM";
555 v3->pre_mem = mem->start;
556 v3->pre_bus_addr = mem->start - win->offset;
557 dev_dbg(dev, "PREFETCHABLE MEM window %pR, bus addr %pap\n",
558 mem, &v3->pre_bus_addr);
559 if (resource_size(mem) != SZ_256M) {
560 dev_err(dev, "prefetchable memory range is not 256MB\n");
561 return -EINVAL;
562 }
563 if (v3->non_pre_mem &&
564 (mem->start != v3->non_pre_mem + SZ_256M)) {
565 dev_err(dev,
566 "prefetchable memory is not adjacent to non-prefetchable memory\n");
567 return -EINVAL;
568 }
569 /* Setup window 1 - PCI prefetchable memory */
570 writel(v3_addr_to_lb_base(v3->pre_mem) |
571 V3_LB_BASE_ADR_SIZE_256MB |
572 V3_LB_BASE_PREFETCH |
573 V3_LB_BASE_ENABLE,
574 v3->base + V3_LB_BASE1);
575 writew(v3_addr_to_lb_map(v3->pre_bus_addr) |
576 V3_LB_MAP_TYPE_MEM, /* Was V3_LB_MAP_TYPE_MEM_MULTIPLE */
577 v3->base + V3_LB_MAP1);
578 } else {
579 mem->name = "V3 PCI NON-PRE-MEM";
580 v3->non_pre_mem = mem->start;
581 v3->non_pre_bus_addr = mem->start - win->offset;
582 dev_dbg(dev, "NON-PREFETCHABLE MEM window %pR, bus addr %pap\n",
583 mem, &v3->non_pre_bus_addr);
584 if (resource_size(mem) != SZ_256M) {
585 dev_err(dev,
586 "non-prefetchable memory range is not 256MB\n");
587 return -EINVAL;
588 }
589 /* Setup window 0 - PCI non-prefetchable memory */
590 writel(v3_addr_to_lb_base(v3->non_pre_mem) |
591 V3_LB_BASE_ADR_SIZE_256MB |
592 V3_LB_BASE_ENABLE,
593 v3->base + V3_LB_BASE0);
594 writew(v3_addr_to_lb_map(v3->non_pre_bus_addr) |
595 V3_LB_MAP_TYPE_MEM,
596 v3->base + V3_LB_MAP0);
597 }
598 break;
599 case IORESOURCE_BUS:
600 dev_dbg(dev, "BUS %pR\n", win->res);
601 host->busnr = win->res->start;
602 break;
603 default:
604 dev_info(dev, "Unknown resource type %lu\n",
605 resource_type(win->res));
606 break;
607 }
608
609 return 0;
610}
611
612static int v3_get_dma_range_config(struct v3_pci *v3,
613 struct of_pci_range *range,
614 u32 *pci_base, u32 *pci_map)
615{
616 struct device *dev = v3->dev;
617 u64 cpu_end = range->cpu_addr + range->size - 1;
618 u64 pci_end = range->pci_addr + range->size - 1;
619 u32 val;
620
621 if (range->pci_addr & ~V3_PCI_BASE_M_ADR_BASE) {
622 dev_err(dev, "illegal range, only PCI bits 31..20 allowed\n");
623 return -EINVAL;
624 }
625 val = ((u32)range->pci_addr) & V3_PCI_BASE_M_ADR_BASE;
626 *pci_base = val;
627
628 if (range->cpu_addr & ~V3_PCI_MAP_M_MAP_ADR) {
629 dev_err(dev, "illegal range, only CPU bits 31..20 allowed\n");
630 return -EINVAL;
631 }
632 val = ((u32)range->cpu_addr) & V3_PCI_MAP_M_MAP_ADR;
633
634 switch (range->size) {
635 case SZ_1M:
636 val |= V3_LB_BASE_ADR_SIZE_1MB;
637 break;
638 case SZ_2M:
639 val |= V3_LB_BASE_ADR_SIZE_2MB;
640 break;
641 case SZ_4M:
642 val |= V3_LB_BASE_ADR_SIZE_4MB;
643 break;
644 case SZ_8M:
645 val |= V3_LB_BASE_ADR_SIZE_8MB;
646 break;
647 case SZ_16M:
648 val |= V3_LB_BASE_ADR_SIZE_16MB;
649 break;
650 case SZ_32M:
651 val |= V3_LB_BASE_ADR_SIZE_32MB;
652 break;
653 case SZ_64M:
654 val |= V3_LB_BASE_ADR_SIZE_64MB;
655 break;
656 case SZ_128M:
657 val |= V3_LB_BASE_ADR_SIZE_128MB;
658 break;
659 case SZ_256M:
660 val |= V3_LB_BASE_ADR_SIZE_256MB;
661 break;
662 case SZ_512M:
663 val |= V3_LB_BASE_ADR_SIZE_512MB;
664 break;
665 case SZ_1G:
666 val |= V3_LB_BASE_ADR_SIZE_1GB;
667 break;
668 case SZ_2G:
669 val |= V3_LB_BASE_ADR_SIZE_2GB;
670 break;
671 default:
672 dev_err(v3->dev, "illegal dma memory chunk size\n");
673 return -EINVAL;
674 break;
675 };
676 val |= V3_PCI_MAP_M_REG_EN | V3_PCI_MAP_M_ENABLE;
677 *pci_map = val;
678
679 dev_dbg(dev,
680 "DMA MEM CPU: 0x%016llx -> 0x%016llx => "
681 "PCI: 0x%016llx -> 0x%016llx base %08x map %08x\n",
682 range->cpu_addr, cpu_end,
683 range->pci_addr, pci_end,
684 *pci_base, *pci_map);
685
686 return 0;
687}
688
689static int v3_pci_parse_map_dma_ranges(struct v3_pci *v3,
690 struct device_node *np)
691{
692 struct of_pci_range range;
693 struct of_pci_range_parser parser;
694 struct device *dev = v3->dev;
695 int i = 0;
696
697 if (of_pci_dma_range_parser_init(&parser, np)) {
698 dev_err(dev, "missing dma-ranges property\n");
699 return -EINVAL;
700 }
701
702 /*
703 * Get the dma-ranges from the device tree
704 */
705 for_each_of_pci_range(&parser, &range) {
706 int ret;
707 u32 pci_base, pci_map;
708
709 ret = v3_get_dma_range_config(v3, &range, &pci_base, &pci_map);
710 if (ret)
711 return ret;
712
713 if (i == 0) {
714 writel(pci_base, v3->base + V3_PCI_BASE0);
715 writel(pci_map, v3->base + V3_PCI_MAP0);
716 } else if (i == 1) {
717 writel(pci_base, v3->base + V3_PCI_BASE1);
718 writel(pci_map, v3->base + V3_PCI_MAP1);
719 } else {
720 dev_err(dev, "too many ranges, only two supported\n");
721 dev_err(dev, "range %d ignored\n", i);
722 }
723 i++;
724 }
725 return 0;
726}
727
728static int v3_pci_probe(struct platform_device *pdev)
729{
730 struct device *dev = &pdev->dev;
731 struct device_node *np = dev->of_node;
732 resource_size_t io_base;
733 struct resource *regs;
734 struct resource_entry *win;
735 struct v3_pci *v3;
736 struct pci_host_bridge *host;
737 struct clk *clk;
738 u16 val;
739 int irq;
740 int ret;
741 LIST_HEAD(res);
742
743 host = pci_alloc_host_bridge(sizeof(*v3));
744 if (!host)
745 return -ENOMEM;
746
747 host->dev.parent = dev;
748 host->ops = &v3_pci_ops;
749 host->busnr = 0;
750 host->msi = NULL;
751 host->map_irq = of_irq_parse_and_map_pci;
752 host->swizzle_irq = pci_common_swizzle;
753 v3 = pci_host_bridge_priv(host);
754 host->sysdata = v3;
755 v3->dev = dev;
756
757 /* Get and enable host clock */
758 clk = devm_clk_get(dev, NULL);
759 if (IS_ERR(clk)) {
760 dev_err(dev, "clock not found\n");
761 return PTR_ERR(clk);
762 }
763 ret = clk_prepare_enable(clk);
764 if (ret) {
765 dev_err(dev, "unable to enable clock\n");
766 return ret;
767 }
768
769 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
770 v3->base = devm_ioremap_resource(dev, regs);
771 if (IS_ERR(v3->base))
772 return PTR_ERR(v3->base);
773 /*
774 * The hardware has a register with the physical base address
775 * of the V3 controller itself, verify that this is the same
776 * as the physical memory we've remapped it from.
777 */
778 if (readl(v3->base + V3_LB_IO_BASE) != (regs->start >> 16))
779 dev_err(dev, "V3_LB_IO_BASE = %08x but device is @%pR\n",
780 readl(v3->base + V3_LB_IO_BASE), regs);
781
782 /* Configuration space is 16MB directly mapped */
783 regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
784 if (resource_size(regs) != SZ_16M) {
785 dev_err(dev, "config mem is not 16MB!\n");
786 return -EINVAL;
787 }
788 v3->config_mem = regs->start;
789 v3->config_base = devm_ioremap_resource(dev, regs);
790 if (IS_ERR(v3->config_base))
791 return PTR_ERR(v3->config_base);
792
793 ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &io_base);
794 if (ret)
795 return ret;
796
797 ret = devm_request_pci_bus_resources(dev, &res);
798 if (ret)
799 return ret;
800
801 /* Get and request error IRQ resource */
802 irq = platform_get_irq(pdev, 0);
803 if (irq <= 0) {
804 dev_err(dev, "unable to obtain PCIv3 error IRQ\n");
805 return -ENODEV;
806 }
807 ret = devm_request_irq(dev, irq, v3_irq, 0,
808 "PCIv3 error", v3);
809 if (ret < 0) {
810 dev_err(dev,
811 "unable to request PCIv3 error IRQ %d (%d)\n",
812 irq, ret);
813 return ret;
814 }
815
816 /*
817 * Unlock V3 registers, but only if they were previously locked.
818 */
819 if (readw(v3->base + V3_SYSTEM) & V3_SYSTEM_M_LOCK)
820 writew(V3_SYSTEM_UNLOCK, v3->base + V3_SYSTEM);
821
822 /* Disable all slave access while we set up the windows */
823 val = readw(v3->base + V3_PCI_CMD);
824 val &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
825 writew(val, v3->base + V3_PCI_CMD);
826
827 /* Put the PCI bus into reset */
828 val = readw(v3->base + V3_SYSTEM);
829 val &= ~V3_SYSTEM_M_RST_OUT;
830 writew(val, v3->base + V3_SYSTEM);
831
832 /* Retry until we're ready */
833 val = readw(v3->base + V3_PCI_CFG);
834 val |= V3_PCI_CFG_M_RETRY_EN;
835 writew(val, v3->base + V3_PCI_CFG);
836
837 /* Set up the local bus protocol */
838 val = readw(v3->base + V3_LB_CFG);
839 val |= V3_LB_CFG_LB_BE_IMODE; /* Byte enable input */
840 val |= V3_LB_CFG_LB_BE_OMODE; /* Byte enable output */
841 val &= ~V3_LB_CFG_LB_ENDIAN; /* Little endian */
842 val &= ~V3_LB_CFG_LB_PPC_RDY; /* TODO: when using on PPC403Gx, set to 1 */
843 writew(val, v3->base + V3_LB_CFG);
844
845 /* Enable the PCI bus master */
846 val = readw(v3->base + V3_PCI_CMD);
847 val |= PCI_COMMAND_MASTER;
848 writew(val, v3->base + V3_PCI_CMD);
849
850 /* Get the I/O and memory ranges from DT */
851 resource_list_for_each_entry(win, &res) {
852 ret = v3_pci_setup_resource(v3, io_base, host, win);
853 if (ret) {
854 dev_err(dev, "error setting up resources\n");
855 return ret;
856 }
857 }
858 ret = v3_pci_parse_map_dma_ranges(v3, np);
859 if (ret)
860 return ret;
861
862 /*
863 * Disable PCI to host IO cycles, enable I/O buffers @3.3V,
864 * set AD_LOW0 to 1 if one of the LB_MAP registers choose
865 * to use this (should be unused).
866 */
867 writel(0x00000000, v3->base + V3_PCI_IO_BASE);
868 val = V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS |
869 V3_PCI_CFG_M_EN3V | V3_PCI_CFG_M_AD_LOW0;
870 /*
871 * DMA read and write from PCI bus commands types
872 */
873 val |= V3_PCI_CFG_TYPE_DEFAULT << V3_PCI_CFG_M_RTYPE_SHIFT;
874 val |= V3_PCI_CFG_TYPE_DEFAULT << V3_PCI_CFG_M_WTYPE_SHIFT;
875 writew(val, v3->base + V3_PCI_CFG);
876
877 /*
878 * Set the V3 FIFO such that writes have higher priority than
879 * reads, and local bus write causes local bus read fifo flush
880 * on aperture 1. Same for PCI.
881 */
882 writew(V3_FIFO_PRIO_LB_RD1_FLUSH_AP1 |
883 V3_FIFO_PRIO_LB_RD0_FLUSH_AP1 |
884 V3_FIFO_PRIO_PCI_RD1_FLUSH_AP1 |
885 V3_FIFO_PRIO_PCI_RD0_FLUSH_AP1,
886 v3->base + V3_FIFO_PRIORITY);
887
888
889 /*
890 * Clear any error interrupts, and enable parity and write error
891 * interrupts
892 */
893 writeb(0, v3->base + V3_LB_ISTAT);
894 val = readw(v3->base + V3_LB_CFG);
895 val |= V3_LB_CFG_LB_LB_INT;
896 writew(val, v3->base + V3_LB_CFG);
897 writeb(V3_LB_ISTAT_PCI_WR | V3_LB_ISTAT_PCI_PERR,
898 v3->base + V3_LB_IMASK);
899
900 /* Special Integrator initialization */
901 if (of_device_is_compatible(np, "arm,integrator-ap-pci")) {
902 ret = v3_integrator_init(v3);
903 if (ret)
904 return ret;
905 }
906
907 /* Post-init: enable PCI memory and invalidate (master already on) */
908 val = readw(v3->base + V3_PCI_CMD);
909 val |= PCI_COMMAND_MEMORY | PCI_COMMAND_INVALIDATE;
910 writew(val, v3->base + V3_PCI_CMD);
911
912 /* Clear pending interrupts */
913 writeb(0, v3->base + V3_LB_ISTAT);
914 /* Read or write errors and parity errors cause interrupts */
915 writeb(V3_LB_ISTAT_PCI_RD | V3_LB_ISTAT_PCI_WR | V3_LB_ISTAT_PCI_PERR,
916 v3->base + V3_LB_IMASK);
917
918 /* Take the PCI bus out of reset so devices can initialize */
919 val = readw(v3->base + V3_SYSTEM);
920 val |= V3_SYSTEM_M_RST_OUT;
921 writew(val, v3->base + V3_SYSTEM);
922
923 /*
924 * Re-lock the system register.
925 */
926 val = readw(v3->base + V3_SYSTEM);
927 val |= V3_SYSTEM_M_LOCK;
928 writew(val, v3->base + V3_SYSTEM);
929
930 list_splice_init(&res, &host->windows);
931 ret = pci_scan_root_bus_bridge(host);
932 if (ret) {
933 dev_err(dev, "failed to register host: %d\n", ret);
934 return ret;
935 }
936 v3->bus = host->bus;
937
938 pci_bus_assign_resources(v3->bus);
939 pci_bus_add_devices(v3->bus);
940
941 return 0;
942}
943
944static const struct of_device_id v3_pci_of_match[] = {
945 {
946 .compatible = "v3,v360epc-pci",
947 },
948 {},
949};
950
951static struct platform_driver v3_pci_driver = {
952 .driver = {
953 .name = "pci-v3-semi",
954 .of_match_table = of_match_ptr(v3_pci_of_match),
955 .suppress_bind_attrs = true,
956 },
957 .probe = v3_pci_probe,
958};
959builtin_platform_driver(v3_pci_driver);