1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Support for Intel IXP4xx PCI host controller |
4 | * |
5 | * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> |
6 | * |
7 | * Based on the IXP4xx arch/arm/mach-ixp4xx/common-pci.c driver |
8 | * Copyright (C) 2002 Intel Corporation |
9 | * Copyright (C) 2003 Greg Ungerer <gerg@linux-m68k.org> |
10 | * Copyright (C) 2003-2004 MontaVista Software, Inc. |
11 | * Copyright (C) 2005 Deepak Saxena <dsaxena@plexity.net> |
12 | * Copyright (C) 2005 Alessandro Zummo <a.zummo@towertech.it> |
13 | * |
14 | * TODO: |
15 | * - Test IO-space access |
16 | * - DMA support |
17 | */ |
18 | |
19 | #include <linux/init.h> |
20 | #include <linux/io.h> |
21 | #include <linux/kernel.h> |
22 | #include <linux/of.h> |
23 | #include <linux/of_pci.h> |
24 | #include <linux/pci.h> |
25 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> |
27 | #include <linux/bits.h> |
28 | #include "../pci.h" |
29 | |
30 | /* Register offsets */ |
31 | #define IXP4XX_PCI_NP_AD 0x00 |
32 | #define IXP4XX_PCI_NP_CBE 0x04 |
33 | #define IXP4XX_PCI_NP_WDATA 0x08 |
34 | #define IXP4XX_PCI_NP_RDATA 0x0c |
35 | #define IXP4XX_PCI_CRP_AD_CBE 0x10 |
36 | #define IXP4XX_PCI_CRP_WDATA 0x14 |
37 | #define IXP4XX_PCI_CRP_RDATA 0x18 |
38 | #define IXP4XX_PCI_CSR 0x1c |
39 | #define IXP4XX_PCI_ISR 0x20 |
40 | #define IXP4XX_PCI_INTEN 0x24 |
41 | #define IXP4XX_PCI_DMACTRL 0x28 |
42 | #define IXP4XX_PCI_AHBMEMBASE 0x2c |
43 | #define IXP4XX_PCI_AHBIOBASE 0x30 |
44 | #define IXP4XX_PCI_PCIMEMBASE 0x34 |
45 | #define IXP4XX_PCI_AHBDOORBELL 0x38 |
46 | #define IXP4XX_PCI_PCIDOORBELL 0x3c |
47 | #define IXP4XX_PCI_ATPDMA0_AHBADDR 0x40 |
48 | #define IXP4XX_PCI_ATPDMA0_PCIADDR 0x44 |
49 | #define IXP4XX_PCI_ATPDMA0_LENADDR 0x48 |
50 | #define IXP4XX_PCI_ATPDMA1_AHBADDR 0x4c |
51 | #define IXP4XX_PCI_ATPDMA1_PCIADDR 0x50 |
52 | #define IXP4XX_PCI_ATPDMA1_LENADDR 0x54 |
53 | |
54 | /* CSR bit definitions */ |
55 | #define IXP4XX_PCI_CSR_HOST BIT(0) |
56 | #define IXP4XX_PCI_CSR_ARBEN BIT(1) |
57 | #define IXP4XX_PCI_CSR_ADS BIT(2) |
58 | #define IXP4XX_PCI_CSR_PDS BIT(3) |
59 | #define IXP4XX_PCI_CSR_ABE BIT(4) |
60 | #define IXP4XX_PCI_CSR_DBT BIT(5) |
61 | #define IXP4XX_PCI_CSR_ASE BIT(8) |
62 | #define IXP4XX_PCI_CSR_IC BIT(15) |
63 | #define IXP4XX_PCI_CSR_PRST BIT(16) |
64 | |
65 | /* ISR (Interrupt status) Register bit definitions */ |
66 | #define IXP4XX_PCI_ISR_PSE BIT(0) |
67 | #define IXP4XX_PCI_ISR_PFE BIT(1) |
68 | #define IXP4XX_PCI_ISR_PPE BIT(2) |
69 | #define IXP4XX_PCI_ISR_AHBE BIT(3) |
70 | #define IXP4XX_PCI_ISR_APDC BIT(4) |
71 | #define IXP4XX_PCI_ISR_PADC BIT(5) |
72 | #define IXP4XX_PCI_ISR_ADB BIT(6) |
73 | #define IXP4XX_PCI_ISR_PDB BIT(7) |
74 | |
75 | /* INTEN (Interrupt Enable) Register bit definitions */ |
76 | #define IXP4XX_PCI_INTEN_PSE BIT(0) |
77 | #define IXP4XX_PCI_INTEN_PFE BIT(1) |
78 | #define IXP4XX_PCI_INTEN_PPE BIT(2) |
79 | #define IXP4XX_PCI_INTEN_AHBE BIT(3) |
80 | #define IXP4XX_PCI_INTEN_APDC BIT(4) |
81 | #define IXP4XX_PCI_INTEN_PADC BIT(5) |
82 | #define IXP4XX_PCI_INTEN_ADB BIT(6) |
83 | #define IXP4XX_PCI_INTEN_PDB BIT(7) |
84 | |
85 | /* Shift value for byte enable on NP cmd/byte enable register */ |
86 | #define IXP4XX_PCI_NP_CBE_BESL 4 |
87 | |
88 | /* PCI commands supported by NP access unit */ |
89 | #define NP_CMD_IOREAD 0x2 |
90 | #define NP_CMD_IOWRITE 0x3 |
91 | #define NP_CMD_CONFIGREAD 0xa |
92 | #define NP_CMD_CONFIGWRITE 0xb |
93 | #define NP_CMD_MEMREAD 0x6 |
94 | #define NP_CMD_MEMWRITE 0x7 |
95 | |
96 | /* Constants for CRP access into local config space */ |
97 | #define CRP_AD_CBE_BESL 20 |
98 | #define CRP_AD_CBE_WRITE 0x00010000 |
99 | |
100 | /* Special PCI configuration space registers for this controller */ |
101 | #define IXP4XX_PCI_RTOTTO 0x40 |
102 | |
103 | struct ixp4xx_pci { |
104 | struct device *dev; |
105 | void __iomem *base; |
106 | bool errata_hammer; |
107 | bool host_mode; |
108 | }; |
109 | |
110 | /* |
111 | * The IXP4xx has a peculiar address bus that will change the |
112 | * byte order on SoC peripherals depending on whether the device |
113 | * operates in big-endian or little-endian mode. That means that |
114 | * readl() and writel() that always use little-endian access |
115 | * will not work for SoC peripherals such as the PCI controller |
116 | * when used in big-endian mode. The accesses to the individual |
117 | * PCI devices on the other hand, are always little-endian and |
118 | * can use readl() and writel(). |
119 | * |
120 | * For local AHB bus access we need to use __raw_[readl|writel]() |
121 | * to make sure that we access the SoC devices in the CPU native |
122 | * endianness. |
123 | */ |
124 | static inline u32 ixp4xx_readl(struct ixp4xx_pci *p, u32 reg) |
125 | { |
126 | return __raw_readl(addr: p->base + reg); |
127 | } |
128 | |
129 | static inline void ixp4xx_writel(struct ixp4xx_pci *p, u32 reg, u32 val) |
130 | { |
131 | __raw_writel(val, addr: p->base + reg); |
132 | } |
133 | |
134 | static int ixp4xx_pci_check_master_abort(struct ixp4xx_pci *p) |
135 | { |
136 | u32 isr = ixp4xx_readl(p, IXP4XX_PCI_ISR); |
137 | |
138 | if (isr & IXP4XX_PCI_ISR_PFE) { |
139 | /* Make sure the master abort bit is reset */ |
140 | ixp4xx_writel(p, IXP4XX_PCI_ISR, IXP4XX_PCI_ISR_PFE); |
141 | dev_dbg(p->dev, "master abort detected\n" ); |
142 | return -EINVAL; |
143 | } |
144 | |
145 | return 0; |
146 | } |
147 | |
148 | static int ixp4xx_pci_read_indirect(struct ixp4xx_pci *p, u32 addr, u32 cmd, u32 *data) |
149 | { |
150 | ixp4xx_writel(p, IXP4XX_PCI_NP_AD, val: addr); |
151 | |
152 | if (p->errata_hammer) { |
153 | int i; |
154 | |
155 | /* |
156 | * PCI workaround - only works if NP PCI space reads have |
157 | * no side effects. Hammer the register and read twice 8 |
158 | * times. last one will be good. |
159 | */ |
160 | for (i = 0; i < 8; i++) { |
161 | ixp4xx_writel(p, IXP4XX_PCI_NP_CBE, val: cmd); |
162 | *data = ixp4xx_readl(p, IXP4XX_PCI_NP_RDATA); |
163 | *data = ixp4xx_readl(p, IXP4XX_PCI_NP_RDATA); |
164 | } |
165 | } else { |
166 | ixp4xx_writel(p, IXP4XX_PCI_NP_CBE, val: cmd); |
167 | *data = ixp4xx_readl(p, IXP4XX_PCI_NP_RDATA); |
168 | } |
169 | |
170 | return ixp4xx_pci_check_master_abort(p); |
171 | } |
172 | |
173 | static int ixp4xx_pci_write_indirect(struct ixp4xx_pci *p, u32 addr, u32 cmd, u32 data) |
174 | { |
175 | ixp4xx_writel(p, IXP4XX_PCI_NP_AD, val: addr); |
176 | |
177 | /* Set up the write */ |
178 | ixp4xx_writel(p, IXP4XX_PCI_NP_CBE, val: cmd); |
179 | |
180 | /* Execute the write by writing to NP_WDATA */ |
181 | ixp4xx_writel(p, IXP4XX_PCI_NP_WDATA, val: data); |
182 | |
183 | return ixp4xx_pci_check_master_abort(p); |
184 | } |
185 | |
186 | static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where) |
187 | { |
188 | /* Root bus is always 0 in this hardware */ |
189 | if (bus_num == 0) { |
190 | /* type 0 */ |
191 | return (PCI_CONF1_ADDRESS(0, 0, PCI_FUNC(devfn), where) & |
192 | ~PCI_CONF1_ENABLE) | BIT(32-PCI_SLOT(devfn)); |
193 | } else { |
194 | /* type 1 */ |
195 | return (PCI_CONF1_ADDRESS(bus_num, PCI_SLOT(devfn), |
196 | PCI_FUNC(devfn), where) & |
197 | ~PCI_CONF1_ENABLE) | 1; |
198 | } |
199 | } |
200 | |
201 | /* |
202 | * CRP functions are "Controller Configuration Port" accesses |
203 | * initiated from within this driver itself to read/write PCI |
204 | * control information in the config space. |
205 | */ |
206 | static u32 ixp4xx_crp_byte_lane_enable_bits(u32 n, int size) |
207 | { |
208 | if (size == 1) |
209 | return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL; |
210 | if (size == 2) |
211 | return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL; |
212 | if (size == 4) |
213 | return 0; |
214 | return 0xffffffff; |
215 | } |
216 | |
217 | static int ixp4xx_crp_read_config(struct ixp4xx_pci *p, int where, int size, |
218 | u32 *value) |
219 | { |
220 | u32 n, cmd, val; |
221 | |
222 | n = where % 4; |
223 | cmd = where & ~3; |
224 | |
225 | dev_dbg(p->dev, "%s from %d size %d cmd %08x\n" , |
226 | __func__, where, size, cmd); |
227 | |
228 | ixp4xx_writel(p, IXP4XX_PCI_CRP_AD_CBE, val: cmd); |
229 | val = ixp4xx_readl(p, IXP4XX_PCI_CRP_RDATA); |
230 | |
231 | val >>= (8*n); |
232 | switch (size) { |
233 | case 1: |
234 | val &= U8_MAX; |
235 | dev_dbg(p->dev, "%s read byte %02x\n" , __func__, val); |
236 | break; |
237 | case 2: |
238 | val &= U16_MAX; |
239 | dev_dbg(p->dev, "%s read word %04x\n" , __func__, val); |
240 | break; |
241 | case 4: |
242 | val &= U32_MAX; |
243 | dev_dbg(p->dev, "%s read long %08x\n" , __func__, val); |
244 | break; |
245 | default: |
246 | /* Should not happen */ |
247 | dev_err(p->dev, "%s illegal size\n" , __func__); |
248 | return PCIBIOS_DEVICE_NOT_FOUND; |
249 | } |
250 | *value = val; |
251 | |
252 | return PCIBIOS_SUCCESSFUL; |
253 | } |
254 | |
255 | static int ixp4xx_crp_write_config(struct ixp4xx_pci *p, int where, int size, |
256 | u32 value) |
257 | { |
258 | u32 n, cmd, val; |
259 | |
260 | n = where % 4; |
261 | cmd = ixp4xx_crp_byte_lane_enable_bits(n, size); |
262 | if (cmd == 0xffffffff) |
263 | return PCIBIOS_BAD_REGISTER_NUMBER; |
264 | cmd |= where & ~3; |
265 | cmd |= CRP_AD_CBE_WRITE; |
266 | |
267 | val = value << (8*n); |
268 | |
269 | dev_dbg(p->dev, "%s to %d size %d cmd %08x val %08x\n" , |
270 | __func__, where, size, cmd, val); |
271 | |
272 | ixp4xx_writel(p, IXP4XX_PCI_CRP_AD_CBE, val: cmd); |
273 | ixp4xx_writel(p, IXP4XX_PCI_CRP_WDATA, val); |
274 | |
275 | return PCIBIOS_SUCCESSFUL; |
276 | } |
277 | |
278 | /* |
279 | * Then follows the functions that read and write from the common PCI |
280 | * configuration space. |
281 | */ |
282 | static u32 ixp4xx_byte_lane_enable_bits(u32 n, int size) |
283 | { |
284 | if (size == 1) |
285 | return (0xf & ~BIT(n)) << 4; |
286 | if (size == 2) |
287 | return (0xf & ~(BIT(n) | BIT(n+1))) << 4; |
288 | if (size == 4) |
289 | return 0; |
290 | return 0xffffffff; |
291 | } |
292 | |
293 | static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, |
294 | int where, int size, u32 *value) |
295 | { |
296 | struct ixp4xx_pci *p = bus->sysdata; |
297 | u32 n, addr, val, cmd; |
298 | u8 bus_num = bus->number; |
299 | int ret; |
300 | |
301 | *value = 0xffffffff; |
302 | n = where % 4; |
303 | cmd = ixp4xx_byte_lane_enable_bits(n, size); |
304 | if (cmd == 0xffffffff) |
305 | return PCIBIOS_BAD_REGISTER_NUMBER; |
306 | |
307 | addr = ixp4xx_config_addr(bus_num, devfn, where); |
308 | cmd |= NP_CMD_CONFIGREAD; |
309 | dev_dbg(p->dev, "read_config from %d size %d dev %d:%d:%d address: %08x cmd: %08x\n" , |
310 | where, size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn), addr, cmd); |
311 | |
312 | ret = ixp4xx_pci_read_indirect(p, addr, cmd, data: &val); |
313 | if (ret) |
314 | return PCIBIOS_DEVICE_NOT_FOUND; |
315 | |
316 | val >>= (8*n); |
317 | switch (size) { |
318 | case 1: |
319 | val &= U8_MAX; |
320 | dev_dbg(p->dev, "%s read byte %02x\n" , __func__, val); |
321 | break; |
322 | case 2: |
323 | val &= U16_MAX; |
324 | dev_dbg(p->dev, "%s read word %04x\n" , __func__, val); |
325 | break; |
326 | case 4: |
327 | val &= U32_MAX; |
328 | dev_dbg(p->dev, "%s read long %08x\n" , __func__, val); |
329 | break; |
330 | default: |
331 | /* Should not happen */ |
332 | dev_err(p->dev, "%s illegal size\n" , __func__); |
333 | return PCIBIOS_DEVICE_NOT_FOUND; |
334 | } |
335 | *value = val; |
336 | |
337 | return PCIBIOS_SUCCESSFUL; |
338 | } |
339 | |
340 | static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, |
341 | int where, int size, u32 value) |
342 | { |
343 | struct ixp4xx_pci *p = bus->sysdata; |
344 | u32 n, addr, val, cmd; |
345 | u8 bus_num = bus->number; |
346 | int ret; |
347 | |
348 | n = where % 4; |
349 | cmd = ixp4xx_byte_lane_enable_bits(n, size); |
350 | if (cmd == 0xffffffff) |
351 | return PCIBIOS_BAD_REGISTER_NUMBER; |
352 | |
353 | addr = ixp4xx_config_addr(bus_num, devfn, where); |
354 | cmd |= NP_CMD_CONFIGWRITE; |
355 | val = value << (8*n); |
356 | |
357 | dev_dbg(p->dev, "write_config_byte %#x to %d size %d dev %d:%d:%d addr: %08x cmd %08x\n" , |
358 | value, where, size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn), addr, cmd); |
359 | |
360 | ret = ixp4xx_pci_write_indirect(p, addr, cmd, data: val); |
361 | if (ret) |
362 | return PCIBIOS_DEVICE_NOT_FOUND; |
363 | |
364 | return PCIBIOS_SUCCESSFUL; |
365 | } |
366 | |
367 | static struct pci_ops ixp4xx_pci_ops = { |
368 | .read = ixp4xx_pci_read_config, |
369 | .write = ixp4xx_pci_write_config, |
370 | }; |
371 | |
372 | static u32 ixp4xx_pci_addr_to_64mconf(phys_addr_t addr) |
373 | { |
374 | u8 base; |
375 | |
376 | base = ((addr & 0xff000000) >> 24); |
377 | return (base << 24) | ((base + 1) << 16) |
378 | | ((base + 2) << 8) | (base + 3); |
379 | } |
380 | |
381 | static int ixp4xx_pci_parse_map_ranges(struct ixp4xx_pci *p) |
382 | { |
383 | struct device *dev = p->dev; |
384 | struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv: p); |
385 | struct resource_entry *win; |
386 | struct resource *res; |
387 | phys_addr_t addr; |
388 | |
389 | win = resource_list_first_type(list: &bridge->windows, IORESOURCE_MEM); |
390 | if (win) { |
391 | u32 pcimembase; |
392 | |
393 | res = win->res; |
394 | addr = res->start - win->offset; |
395 | |
396 | if (res->flags & IORESOURCE_PREFETCH) |
397 | res->name = "IXP4xx PCI PRE-MEM" ; |
398 | else |
399 | res->name = "IXP4xx PCI NON-PRE-MEM" ; |
400 | |
401 | dev_dbg(dev, "%s window %pR, bus addr %pa\n" , |
402 | res->name, res, &addr); |
403 | if (resource_size(res) != SZ_64M) { |
404 | dev_err(dev, "memory range is not 64MB\n" ); |
405 | return -EINVAL; |
406 | } |
407 | |
408 | pcimembase = ixp4xx_pci_addr_to_64mconf(addr); |
409 | /* Commit configuration */ |
410 | ixp4xx_writel(p, IXP4XX_PCI_PCIMEMBASE, val: pcimembase); |
411 | } else { |
412 | dev_err(dev, "no AHB memory mapping defined\n" ); |
413 | } |
414 | |
415 | win = resource_list_first_type(list: &bridge->windows, IORESOURCE_IO); |
416 | if (win) { |
417 | res = win->res; |
418 | |
419 | addr = pci_pio_to_address(pio: res->start); |
420 | if (addr & 0xff) { |
421 | dev_err(dev, "IO mem at uneven address: %pa\n" , &addr); |
422 | return -EINVAL; |
423 | } |
424 | |
425 | res->name = "IXP4xx PCI IO MEM" ; |
426 | /* |
427 | * Setup I/O space location for PCI->AHB access, the |
428 | * upper 24 bits of the address goes into the lower |
429 | * 24 bits of this register. |
430 | */ |
431 | ixp4xx_writel(p, IXP4XX_PCI_AHBIOBASE, val: (addr >> 8)); |
432 | } else { |
433 | dev_info(dev, "no IO space AHB memory mapping defined\n" ); |
434 | } |
435 | |
436 | return 0; |
437 | } |
438 | |
439 | static int ixp4xx_pci_parse_map_dma_ranges(struct ixp4xx_pci *p) |
440 | { |
441 | struct device *dev = p->dev; |
442 | struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv: p); |
443 | struct resource_entry *win; |
444 | struct resource *res; |
445 | phys_addr_t addr; |
446 | u32 ahbmembase; |
447 | |
448 | win = resource_list_first_type(list: &bridge->dma_ranges, IORESOURCE_MEM); |
449 | if (win) { |
450 | res = win->res; |
451 | addr = res->start - win->offset; |
452 | |
453 | if (resource_size(res) != SZ_64M) { |
454 | dev_err(dev, "DMA memory range is not 64MB\n" ); |
455 | return -EINVAL; |
456 | } |
457 | |
458 | dev_dbg(dev, "DMA MEM BASE: %pa\n" , &addr); |
459 | /* |
460 | * 4 PCI-to-AHB windows of 16 MB each, write the 8 high bits |
461 | * into each byte of the PCI_AHBMEMBASE register. |
462 | */ |
463 | ahbmembase = ixp4xx_pci_addr_to_64mconf(addr); |
464 | /* Commit AHB membase */ |
465 | ixp4xx_writel(p, IXP4XX_PCI_AHBMEMBASE, val: ahbmembase); |
466 | } else { |
467 | dev_err(dev, "no DMA memory range defined\n" ); |
468 | } |
469 | |
470 | return 0; |
471 | } |
472 | |
473 | /* Only used to get context for abort handling */ |
474 | static struct ixp4xx_pci *ixp4xx_pci_abort_singleton; |
475 | |
476 | static int ixp4xx_pci_abort_handler(unsigned long addr, unsigned int fsr, |
477 | struct pt_regs *regs) |
478 | { |
479 | struct ixp4xx_pci *p = ixp4xx_pci_abort_singleton; |
480 | u32 isr, status; |
481 | int ret; |
482 | |
483 | isr = ixp4xx_readl(p, IXP4XX_PCI_ISR); |
484 | ret = ixp4xx_crp_read_config(p, PCI_STATUS, size: 2, value: &status); |
485 | if (ret) { |
486 | dev_err(p->dev, "unable to read abort status\n" ); |
487 | return -EINVAL; |
488 | } |
489 | |
490 | dev_err(p->dev, |
491 | "PCI: abort_handler addr = %#lx, isr = %#x, status = %#x\n" , |
492 | addr, isr, status); |
493 | |
494 | /* Make sure the Master Abort bit is reset */ |
495 | ixp4xx_writel(p, IXP4XX_PCI_ISR, IXP4XX_PCI_ISR_PFE); |
496 | status |= PCI_STATUS_REC_MASTER_ABORT; |
497 | ret = ixp4xx_crp_write_config(p, PCI_STATUS, size: 2, value: status); |
498 | if (ret) |
499 | dev_err(p->dev, "unable to clear abort status bit\n" ); |
500 | |
501 | /* |
502 | * If it was an imprecise abort, then we need to correct the |
503 | * return address to be _after_ the instruction. |
504 | */ |
505 | if (fsr & (1 << 10)) { |
506 | dev_err(p->dev, "imprecise abort\n" ); |
507 | regs->ARM_pc += 4; |
508 | } |
509 | |
510 | return 0; |
511 | } |
512 | |
513 | static int __init ixp4xx_pci_probe(struct platform_device *pdev) |
514 | { |
515 | struct device *dev = &pdev->dev; |
516 | struct device_node *np = dev->of_node; |
517 | struct ixp4xx_pci *p; |
518 | struct pci_host_bridge *host; |
519 | int ret; |
520 | u32 val; |
521 | phys_addr_t addr; |
522 | u32 basereg[4] = { |
523 | PCI_BASE_ADDRESS_0, |
524 | PCI_BASE_ADDRESS_1, |
525 | PCI_BASE_ADDRESS_2, |
526 | PCI_BASE_ADDRESS_3, |
527 | }; |
528 | int i; |
529 | |
530 | host = devm_pci_alloc_host_bridge(dev, priv: sizeof(*p)); |
531 | if (!host) |
532 | return -ENOMEM; |
533 | |
534 | host->ops = &ixp4xx_pci_ops; |
535 | p = pci_host_bridge_priv(bridge: host); |
536 | host->sysdata = p; |
537 | p->dev = dev; |
538 | dev_set_drvdata(dev, data: p); |
539 | |
540 | /* |
541 | * Set up quirk for erratic behaviour in the 42x variant |
542 | * when accessing config space. |
543 | */ |
544 | if (of_device_is_compatible(device: np, "intel,ixp42x-pci" )) { |
545 | p->errata_hammer = true; |
546 | dev_info(dev, "activate hammering errata\n" ); |
547 | } |
548 | |
549 | p->base = devm_platform_ioremap_resource(pdev, index: 0); |
550 | if (IS_ERR(ptr: p->base)) |
551 | return PTR_ERR(ptr: p->base); |
552 | |
553 | val = ixp4xx_readl(p, IXP4XX_PCI_CSR); |
554 | p->host_mode = !!(val & IXP4XX_PCI_CSR_HOST); |
555 | dev_info(dev, "controller is in %s mode\n" , |
556 | p->host_mode ? "host" : "option" ); |
557 | |
558 | /* Hook in our fault handler for PCI errors */ |
559 | ixp4xx_pci_abort_singleton = p; |
560 | hook_fault_code(16+6, ixp4xx_pci_abort_handler, SIGBUS, 0, |
561 | "imprecise external abort" ); |
562 | |
563 | ret = ixp4xx_pci_parse_map_ranges(p); |
564 | if (ret) |
565 | return ret; |
566 | |
567 | ret = ixp4xx_pci_parse_map_dma_ranges(p); |
568 | if (ret) |
569 | return ret; |
570 | |
571 | /* This is only configured in host mode */ |
572 | if (p->host_mode) { |
573 | addr = __pa(PAGE_OFFSET); |
574 | /* This is a noop (0x00) but explains what is going on */ |
575 | addr |= PCI_BASE_ADDRESS_SPACE_MEMORY; |
576 | |
577 | for (i = 0; i < 4; i++) { |
578 | /* Write this directly into the config space */ |
579 | ret = ixp4xx_crp_write_config(p, where: basereg[i], size: 4, value: addr); |
580 | if (ret) |
581 | dev_err(dev, "failed to set up PCI_BASE_ADDRESS_%d\n" , i); |
582 | else |
583 | dev_info(dev, "set PCI_BASE_ADDR_%d to %pa\n" , i, &addr); |
584 | addr += SZ_16M; |
585 | } |
586 | |
587 | /* |
588 | * Enable CSR window at 64 MiB to allow PCI masters to continue |
589 | * prefetching past the 64 MiB boundary, if all AHB to PCI |
590 | * windows are consecutive. |
591 | */ |
592 | ret = ixp4xx_crp_write_config(p, PCI_BASE_ADDRESS_4, size: 4, value: addr); |
593 | if (ret) |
594 | dev_err(dev, "failed to set up PCI_BASE_ADDRESS_4\n" ); |
595 | else |
596 | dev_info(dev, "set PCI_BASE_ADDR_4 to %pa\n" , &addr); |
597 | |
598 | /* |
599 | * Put the IO memory window at the very end of physical memory |
600 | * at 0xfffffc00. This is when the system is trying to access IO |
601 | * memory over AHB. |
602 | */ |
603 | addr = 0xfffffc00; |
604 | addr |= PCI_BASE_ADDRESS_SPACE_IO; |
605 | ret = ixp4xx_crp_write_config(p, PCI_BASE_ADDRESS_5, size: 4, value: addr); |
606 | if (ret) |
607 | dev_err(dev, "failed to set up PCI_BASE_ADDRESS_5\n" ); |
608 | else |
609 | dev_info(dev, "set PCI_BASE_ADDR_5 to %pa\n" , &addr); |
610 | |
611 | /* |
612 | * Retry timeout to 0x80 |
613 | * Transfer ready timeout to 0xff |
614 | */ |
615 | ret = ixp4xx_crp_write_config(p, IXP4XX_PCI_RTOTTO, size: 4, |
616 | value: 0x000080ff); |
617 | if (ret) |
618 | dev_err(dev, "failed to set up TRDY limit\n" ); |
619 | else |
620 | dev_info(dev, "set TRDY limit to 0x80ff\n" ); |
621 | } |
622 | |
623 | /* Clear interrupts */ |
624 | val = IXP4XX_PCI_ISR_PSE | IXP4XX_PCI_ISR_PFE | IXP4XX_PCI_ISR_PPE | IXP4XX_PCI_ISR_AHBE; |
625 | ixp4xx_writel(p, IXP4XX_PCI_ISR, val); |
626 | |
627 | /* |
628 | * Set Initialize Complete in PCI Control Register: allow IXP4XX to |
629 | * generate PCI configuration cycles. Specify that the AHB bus is |
630 | * operating in big-endian mode. Set up byte lane swapping between |
631 | * little-endian PCI and the big-endian AHB bus. |
632 | */ |
633 | val = IXP4XX_PCI_CSR_IC | IXP4XX_PCI_CSR_ABE; |
634 | if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) |
635 | val |= (IXP4XX_PCI_CSR_PDS | IXP4XX_PCI_CSR_ADS); |
636 | ixp4xx_writel(p, IXP4XX_PCI_CSR, val); |
637 | |
638 | ret = ixp4xx_crp_write_config(p, PCI_COMMAND, size: 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); |
639 | if (ret) |
640 | dev_err(dev, "unable to initialize master and command memory\n" ); |
641 | else |
642 | dev_info(dev, "initialized as master\n" ); |
643 | |
644 | pci_host_probe(bridge: host); |
645 | |
646 | return 0; |
647 | } |
648 | |
649 | static const struct of_device_id ixp4xx_pci_of_match[] = { |
650 | { |
651 | .compatible = "intel,ixp42x-pci" , |
652 | }, |
653 | { |
654 | .compatible = "intel,ixp43x-pci" , |
655 | }, |
656 | {}, |
657 | }; |
658 | |
659 | /* |
660 | * This driver needs to be a builtin module with suppressed bind |
661 | * attributes since the probe() is initializing a hard exception |
662 | * handler and this can only be done from __init-tagged code |
663 | * sections. This module cannot be removed and inserted at all. |
664 | */ |
665 | static struct platform_driver ixp4xx_pci_driver = { |
666 | .driver = { |
667 | .name = "ixp4xx-pci" , |
668 | .suppress_bind_attrs = true, |
669 | .of_match_table = ixp4xx_pci_of_match, |
670 | }, |
671 | }; |
672 | builtin_platform_driver_probe(ixp4xx_pci_driver, ixp4xx_pci_probe); |
673 | |