bcm53xx: rename patches that were not upstreamed to 3xx
[openwrt/openwrt.git] / target / linux / bcm53xx / patches-3.14 / 170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch
1 From cc2cda651fcbc498bf513a6b802dca19944bcb37 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Mon, 12 May 2014 11:55:20 +0200
4 Subject: [PATCH 13/17] pcie2-bcma: add new PCIe2 driver for bcma
5
6 This driver supports the PCIe controller found on the BCM4708 and
7 similar SoCs. The controller itself is automatically detected by bcma.
8
9 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
10 ---
11 arch/arm/mach-bcm/Kconfig | 2 +
12 drivers/pci/host/Kconfig | 7 +
13 drivers/pci/host/Makefile | 1 +
14 drivers/pci/host/pcie2-bcma.c | 591 ++++++++++++++++++++++++++++++++++++++++++
15 4 files changed, 601 insertions(+)
16 create mode 100644 drivers/pci/host/pcie2-bcma.c
17
18 --- a/arch/arm/mach-bcm/Kconfig
19 +++ b/arch/arm/mach-bcm/Kconfig
20 @@ -46,6 +46,7 @@ config ARCH_BCM_5301X
21 select ARM_GLOBAL_TIMER
22 select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
23 select MIGHT_HAVE_PCI
24 + select PCI_DOMAINS if PCI
25 help
26 Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
27
28 --- a/drivers/pci/host/Kconfig
29 +++ b/drivers/pci/host/Kconfig
30 @@ -33,4 +33,11 @@ config PCI_RCAR_GEN2
31 There are 3 internal PCI controllers available with a single
32 built-in EHCI/OHCI host controller present on each one.
33
34 +config PCI_BCMA
35 + bool "BCMA PCIe2 host controller"
36 + depends on BCMA && OF
37 + help
38 + Say Y here if you want to support a simple generic PCI host
39 + controller, such as the one emulated by kvmtool.
40 +
41 endmenu
42 --- a/drivers/pci/host/Makefile
43 +++ b/drivers/pci/host/Makefile
44 @@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
45 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
46 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
47 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
48 +obj-$(CONFIG_PCI_BCMA) += pcie2-bcma.o
49 --- /dev/null
50 +++ b/drivers/pci/host/pcie2-bcma.c
51 @@ -0,0 +1,619 @@
52 +/*
53 + * Northstar PCI-Express driver
54 + * Only supports Root-Complex (RC) mode
55 + *
56 + * Notes:
57 + * PCI Domains are being used to identify the PCIe port 1:1.
58 + *
59 + * Only MEM access is supported, PAX does not support IO.
60 + *
61 + * TODO:
62 + * MSI interrupts,
63 + * DRAM > 128 MBytes (e.g. DMA zones)
64 + */
65 +
66 +#include <linux/kernel.h>
67 +#include <linux/module.h>
68 +#include <linux/bug.h>
69 +#include <linux/delay.h>
70 +#include <linux/pci.h>
71 +#include <linux/io.h>
72 +#include <linux/ioport.h>
73 +#include <linux/interrupt.h>
74 +#include <linux/bcma/bcma.h>
75 +
76 +#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */
77 +
78 +/*
79 + * Register offset definitions
80 + */
81 +#define SOC_PCIE_CONTROL 0x000 /* a.k.a. CLK_CONTROL reg */
82 +#define SOC_PCIE_PM_STATUS 0x008
83 +#define SOC_PCIE_PM_CONTROL 0x00c /* in EP mode only ! */
84 +
85 +#define SOC_PCIE_EXT_CFG_ADDR 0x120
86 +#define SOC_PCIE_EXT_CFG_DATA 0x124
87 +#define SOC_PCIE_CFG_ADDR 0x1f8
88 +#define SOC_PCIE_CFG_DATA 0x1fc
89 +
90 +#define SOC_PCIE_SYS_RC_INTX_EN 0x330
91 +#define SOC_PCIE_SYS_RC_INTX_CSR 0x334
92 +#define SOC_PCIE_SYS_HOST_INTR_EN 0x344
93 +#define SOC_PCIE_SYS_HOST_INTR_CSR 0x348
94 +
95 +#define SOC_PCIE_HDR_OFF 0x400 /* 256 bytes per function */
96 +
97 +/* 32-bit 4KB in-bound mapping windows for Function 0..3, n=0..7 */
98 +#define SOC_PCIE_SYS_IMAP0(f, n) (0xc00 + ((f) << 9)((n) << 2))
99 +/* 64-bit in-bound mapping windows for func 0..3 */
100 +#define SOC_PCIE_SYS_IMAP1(f) (0xc80 + ((f) << 3))
101 +#define SOC_PCIE_SYS_IMAP2(f) (0xcc0 + ((f) << 3))
102 +/* 64-bit in-bound address range n=0..2 */
103 +#define SOC_PCIE_SYS_IARR(n) (0xd00 + ((n) << 3))
104 +/* 64-bit out-bound address filter n=0..2 */
105 +#define SOC_PCIE_SYS_OARR(n) (0xd20 + ((n) << 3))
106 +/* 64-bit out-bound mapping windows n=0..2 */
107 +#define SOC_PCIE_SYS_OMAP(n) (0xd40 + ((n) << 3))
108 +
109 +#define BCM4360_D11AC_ID 0x43a0
110 +#define BCM4360_D11AC2G_ID 0x43a1
111 +#define BCM4360_D11AC5G_ID 0x43a2
112 +#define BCM4352_D11AC_ID 0x43b1 /* 4352 802.11ac dualband device */
113 +#define BCM4352_D11AC2G_ID 0x43b2 /* 4352 802.11ac 2.4G device */
114 +#define BCM4352_D11AC5G_ID 0x43b3 /* 4352 802.11ac 5G device */
115 +
116 +static struct pci_ops bcma_pcie2_ops;
117 +
118 +static int bcma_pcie2_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
119 +{
120 + struct pci_sys_data *sys = pdev->sysdata;
121 + struct bcma_device *bdev = sys->private_data;
122 +
123 + return bdev->irq;
124 +}
125 +
126 +static u32 bcma_pcie2_cfg_base(struct bcma_device *bdev, int busno,
127 + unsigned int devfn, int where)
128 +{
129 + int slot = PCI_SLOT(devfn);
130 + int fn = PCI_FUNC(devfn);
131 + u32 addr_reg;
132 +
133 + if (busno == 0) {
134 + if (slot >= 1)
135 + return 0;
136 + bcma_write32(bdev, SOC_PCIE_EXT_CFG_ADDR, where & 0xffc);
137 + return SOC_PCIE_EXT_CFG_DATA;
138 + }
139 + if (fn > 1)
140 + return 0;
141 + addr_reg = (busno & 0xff) << 20 | (slot << 15) | (fn << 12) |
142 + (where & 0xffc) | (1 & 0x3);
143 +
144 + bcma_write32(bdev, SOC_PCIE_CFG_ADDR, addr_reg);
145 + return SOC_PCIE_CFG_DATA;
146 +}
147 +
148 +static u32 bcma_pcie2_read_config(struct bcma_device *bdev, int busno,
149 + unsigned int devfn, int where, int size)
150 +{
151 + u32 base;
152 + u32 data_reg;
153 + u32 mask;
154 + int shift;
155 +
156 + base = bcma_pcie2_cfg_base(bdev, busno, devfn, where);
157 +
158 + if (!base)
159 + return ~0UL;
160 +
161 + data_reg = bcma_read32(bdev, base);
162 +
163 + /* NS: CLASS field is R/O, and set to wrong 0x200 value */
164 + if (busno == 0 && devfn == 0) {
165 + /*
166 + * RC's class is 0x0280, but Linux PCI driver needs 0x604
167 + * for a PCIe bridge. So we must fixup the class code
168 + * to 0x604 here.
169 + */
170 + if ((where & 0xffc) == PCI_CLASS_REVISION) {
171 + data_reg &= 0xff;
172 + data_reg |= 0x604 << 16;
173 + }
174 + }
175 + /* HEADER_TYPE=00 indicates the port in EP mode */
176 +
177 + if (size == 4)
178 + return data_reg;
179 +
180 + mask = (1 << (size * 8)) - 1;
181 + shift = (where % 4) * 8;
182 + return (data_reg >> shift) & mask;
183 +}
184 +
185 +static void bcma_pcie2_write_config(struct bcma_device *bdev, int busno,
186 + unsigned int devfn, int where, int size,
187 + u32 val)
188 +{
189 + u32 base;
190 + u32 data_reg;
191 +
192 + base = bcma_pcie2_cfg_base(bdev, busno, devfn, where);
193 +
194 + if (!base)
195 + return;
196 +
197 + if (size < 4) {
198 + u32 mask = (1 << (size * 8)) - 1;
199 + int shift = (where % 4) * 8;
200 +
201 + data_reg = bcma_read32(bdev, base);
202 + data_reg &= ~(mask << shift);
203 + data_reg |= (val & mask) << shift;
204 + } else {
205 + data_reg = val;
206 + }
207 +
208 + bcma_write32(bdev, base, data_reg);
209 +}
210 +
211 +static u8 bcma_pcie2_read_config8(struct bcma_device *bdev, int busno,
212 + unsigned int devfn, int where)
213 +{
214 + return bcma_pcie2_read_config(bdev, busno, devfn, where, 1);
215 +}
216 +
217 +static u16 bcma_pcie2_read_config16(struct bcma_device *bdev, int busno,
218 + unsigned int devfn, int where)
219 +{
220 + return bcma_pcie2_read_config(bdev, busno, devfn, where, 2);
221 +}
222 +
223 +static u32 bcma_pcie2_read_config32(struct bcma_device *bdev, int busno,
224 + unsigned int devfn, int where)
225 +{
226 + return bcma_pcie2_read_config(bdev, busno, devfn, where, 4);
227 +}
228 +
229 +static void bcma_pcie2_write_config8(struct bcma_device *bdev, int busno,
230 + unsigned int devfn, int where, u8 val)
231 +{
232 + return bcma_pcie2_write_config(bdev, busno, devfn, where, 1, val);
233 +}
234 +
235 +static void bcma_pcie2_write_config16(struct bcma_device *bdev, int busno,
236 + unsigned int devfn, int where, u16 val)
237 +{
238 + return bcma_pcie2_write_config(bdev, busno, devfn, where, 2, val);
239 +}
240 +
241 +static void bcma_pcie2_write_config32(struct bcma_device *bdev, int busno,
242 + unsigned int devfn, int where, u32 val)
243 +{
244 + return bcma_pcie2_write_config(bdev, busno, devfn, where, 4, val);
245 +}
246 +
247 +static int bcma_pcie2_read_config_pci(struct pci_bus *bus, unsigned int devfn,
248 + int where, int size, u32 *val)
249 +{
250 + struct pci_sys_data *sys = bus->sysdata;
251 + struct bcma_device *bdev = sys->private_data;
252 +
253 + *val = bcma_pcie2_read_config(bdev, bus->number, devfn, where, size);
254 +
255 + return PCIBIOS_SUCCESSFUL;
256 +}
257 +
258 +static int bcma_pcie2_write_config_pci(struct pci_bus *bus, unsigned int devfn,
259 + int where, int size, u32 val)
260 +{
261 + struct pci_sys_data *sys = bus->sysdata;
262 + struct bcma_device *bdev = sys->private_data;
263 +
264 + bcma_pcie2_write_config(bdev, bus->number, devfn, where, size, val);
265 +
266 + return PCIBIOS_SUCCESSFUL;
267 +}
268 +
269 +/*
270 + * Check link status, return 0 if link is up in RC mode,
271 + * otherwise return non-zero
272 + */
273 +static int bcma_pcie2_check_link(struct bcma_device *bdev,
274 + struct pci_sys_data *sys, u32 allow_gen2)
275 +{
276 + u32 devfn = 0;
277 + u32 tmp32;
278 + u16 tmp16;
279 + u8 tmp8;
280 + int pos;
281 + bool link = false;
282 + /*
283 + * Setup callback (bcma_pcie2_setup) is called in pcibios_init_hw before
284 + * creating bus root, so we don't have it here yet. On the other hand
285 + * we really want to use pci_bus_find_capability helper to check NLW.
286 + * Let's fake simple pci_bus just to query for capabilities.
287 + */
288 + struct pci_bus bus = {
289 + .number = 0,
290 + .ops = &bcma_pcie2_ops,
291 + .sysdata = sys,
292 + };
293 +
294 + tmp32 = bcma_pcie2_read_config32(bdev, 0, devfn, 0xdc);
295 + tmp32 &= ~0xf;
296 + if (allow_gen2)
297 + tmp32 |= 2;
298 + else {
299 + /* force PCIE GEN1 */
300 + tmp32 |= 1;
301 + }
302 + bcma_pcie2_write_config32(bdev, 0, devfn, 0xdc, tmp32);
303 +
304 + /* See if the port is in EP mode, indicated by header type 00 */
305 + tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_HEADER_TYPE);
306 + if (tmp8 != PCI_HEADER_TYPE_BRIDGE) {
307 + dev_info(&bdev->dev, "Port %d in End-Point mode - ignored\n",
308 + bdev->core_unit);
309 + return -ENODEV;
310 + }
311 +
312 + /* NS PAX only changes NLW field when card is present */
313 + pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
314 + if (pos) {
315 + u8 nlw;
316 +
317 + pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_LNKSTA,
318 + &tmp16);
319 + nlw = (tmp16 & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT;
320 + link = (tmp16 & PCI_EXP_LNKSTA_DLLLA) || nlw != 0;
321 + }
322 +
323 + return link ? 0 : -ENODEV;
324 +}
325 +
326 +/*
327 + * Initializte the PCIe controller
328 + */
329 +static void bcma_pcie2_hw_init(struct bcma_device *bdev)
330 +{
331 + u32 devfn = 0;
332 + u32 tmp32;
333 + u16 tmp16;
334 +
335 + /* Change MPS and MRRS to 512 */
336 + tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, 0x4d4);
337 + tmp16 &= ~7;
338 + tmp16 |= 2;
339 + bcma_pcie2_write_config16(bdev, 0, devfn, 0x4d4, tmp16);
340 +
341 + tmp32 = bcma_pcie2_read_config32(bdev, 0, devfn, 0xb4);
342 + tmp32 &= ~((7 << 12) | (7 << 5));
343 + tmp32 |= (2 << 12) | (2 << 5);
344 + bcma_pcie2_write_config32(bdev, 0, devfn, 0xb4, tmp32);
345 +
346 + /* Turn-on Root-Complex (RC) mode, from reset defailt of EP */
347 +
348 + /* The mode is set by straps, can be overwritten via DMU
349 + register <cru_straps_control> bit 5, "1" means RC
350 + */
351 +
352 + /* Send a downstream reset */
353 + bcma_write32(bdev, SOC_PCIE_CONTROL, 0x3);
354 + udelay(250);
355 + bcma_write32(bdev, SOC_PCIE_CONTROL, 0x1);
356 + mdelay(250);
357 +
358 + /* TBD: take care of PM, check we're on */
359 +}
360 +
361 +/*
362 + * Setup the address translation
363 + */
364 +static void bcma_pcie2_map_init(struct bcma_device *bdev)
365 +{
366 + unsigned size, i;
367 + u32 addr;
368 +
369 + /*
370 + * NOTE:
371 + * All PCI-to-CPU address mapping are 1:1 for simplicity
372 + */
373 +
374 + /* Outbound address translation setup */
375 + size = SZ_128M;
376 + addr = bdev->addr_s[0];
377 + BUG_ON(!addr);
378 + BUG_ON(addr & ((1 << 25) - 1)); /* 64MB alignment */
379 +
380 + for (i = 0; i < 3; i++) {
381 + const unsigned win_size = SZ_64M;
382 + /* 64-bit LE regs, write low word, high is 0 at reset */
383 + bcma_write32(bdev, SOC_PCIE_SYS_OMAP(i), addr);
384 + bcma_write32(bdev, SOC_PCIE_SYS_OARR(i), addr|0x1);
385 + addr += win_size;
386 + if (size >= win_size)
387 + size -= win_size;
388 + if (size == 0)
389 + break;
390 + }
391 + WARN_ON(size > 0);
392 +
393 + /*
394 + * Inbound address translation setup
395 + * Northstar only maps up to 128 MiB inbound, DRAM could be up to 1 GiB.
396 + *
397 + * For now allow access to entire DRAM, assuming it is less than 128MiB,
398 + * otherwise DMA bouncing mechanism may be required.
399 + * Also consider DMA mask to limit DMA physical address
400 + */
401 + size = SZ_128M;
402 + addr = PHYS_OFFSET;
403 +
404 + size >>= 20; /* In MB */
405 + size &= 0xff; /* Size is an 8-bit field */
406 +
407 + WARN_ON(size == 0);
408 + /* 64-bit LE regs, write low word, high is 0 at reset */
409 + bcma_write32(bdev, SOC_PCIE_SYS_IMAP1(0), addr | 0x1);
410 + bcma_write32(bdev, SOC_PCIE_SYS_IARR(1), addr | size);
411 +
412 +#ifdef CONFIG_SPARSEMEM
413 + addr = PHYS_OFFSET2;
414 + bcma_write32(bdev, SOC_PCIE_SYS_IMAP2(0), addr | 0x1);
415 + bcma_write32(bdev, SOC_PCIE_SYS_IARR(2), addr | size);
416 +#endif
417 +}
418 +
419 +/*
420 + * Setup PCIE Host bridge
421 + */
422 +static void bcma_pcie2_bridge_init(struct bcma_device *bdev)
423 +{
424 + u32 devfn = 0;
425 + u8 tmp8;
426 + u16 tmp16;
427 +
428 + bcma_pcie2_write_config8(bdev, 0, devfn, PCI_PRIMARY_BUS, 0);
429 + bcma_pcie2_write_config8(bdev, 0, devfn, PCI_SECONDARY_BUS, 1);
430 + bcma_pcie2_write_config8(bdev, 0, devfn, PCI_SUBORDINATE_BUS, 4);
431 +
432 + tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_PRIMARY_BUS);
433 + tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_SECONDARY_BUS);
434 + tmp8 = bcma_pcie2_read_config8(bdev, 0, devfn, PCI_SUBORDINATE_BUS);
435 +
436 + /* MEM_BASE, MEM_LIM require 1MB alignment */
437 + BUG_ON((bdev->addr_s[0] >> 16) & 0xf);
438 + bcma_pcie2_write_config16(bdev, 0, devfn, PCI_MEMORY_BASE,
439 + bdev->addr_s[0] >> 16);
440 + BUG_ON(((bdev->addr_s[0] + SZ_128M) >> 16) & 0xf);
441 + bcma_pcie2_write_config16(bdev, 0, devfn, PCI_MEMORY_LIMIT,
442 + (bdev->addr_s[0] + SZ_128M) >> 16);
443 +
444 + /* These registers are not supported on the NS */
445 + bcma_pcie2_write_config16(bdev, 0, devfn, PCI_IO_BASE_UPPER16, 0);
446 + bcma_pcie2_write_config16(bdev, 0, devfn, PCI_IO_LIMIT_UPPER16, 0);
447 +
448 + /* Force class to that of a Bridge */
449 + bcma_pcie2_write_config16(bdev, 0, devfn, PCI_CLASS_DEVICE,
450 + PCI_CLASS_BRIDGE_PCI);
451 +
452 + tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, PCI_CLASS_DEVICE);
453 + tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, PCI_MEMORY_BASE);
454 + tmp16 = bcma_pcie2_read_config16(bdev, 0, devfn, PCI_MEMORY_LIMIT);
455 +}
456 +
457 +static int bcma_pcie2_allow_gen2_rc(struct bcma_device *bdev)
458 +{
459 + u32 vendorid, devid, chipid, chiprev;
460 + u32 val, bar;
461 + void __iomem *base;
462 + int allow = 1;
463 +
464 + /* Read PCI vendor/device ID's */
465 + bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x0);
466 + val = bcma_read32(bdev, SOC_PCIE_CFG_DATA);
467 + vendorid = val & 0xffff;
468 + devid = val >> 16;
469 + if (vendorid == PCI_VENDOR_ID_BROADCOM &&
470 + (devid == BCMA_CHIP_ID_BCM4360 || devid == BCM4360_D11AC_ID ||
471 + devid == BCM4360_D11AC2G_ID || devid == BCM4360_D11AC5G_ID ||
472 + devid == BCM4352_D11AC_ID || devid == BCM4352_D11AC2G_ID ||
473 + devid == BCM4352_D11AC5G_ID)) {
474 + /* Config BAR0 */
475 + bar = bdev->addr_s[0];
476 + bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x10);
477 + bcma_write32(bdev, SOC_PCIE_CFG_DATA, bar);
478 + /* Config BAR0 window to access chipc */
479 + bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x80);
480 + bcma_write32(bdev, SOC_PCIE_CFG_DATA, SI_ENUM_BASE);
481 +
482 + /* Enable memory resource */
483 + bcma_write32(bdev, SOC_PCIE_CFG_ADDR, 0x4);
484 + val = bcma_read32(bdev, SOC_PCIE_CFG_DATA);
485 + val |= PCI_COMMAND_MEMORY;
486 + bcma_write32(bdev, SOC_PCIE_CFG_DATA, val);
487 + /* Enable memory and bus master */
488 + bcma_write32(bdev, SOC_PCIE_HDR_OFF + 4, 0x6);
489 +
490 + /* Read CHIP ID */
491 + base = ioremap(bar, 0x1000);
492 + val = __raw_readl(base);
493 + iounmap(base);
494 + chipid = val & 0xffff;
495 + chiprev = (val >> 16) & 0xf;
496 + if ((chipid == BCMA_CHIP_ID_BCM4360 ||
497 + chipid == BCMA_CHIP_ID_BCM43460 ||
498 + chipid == BCMA_CHIP_ID_BCM4352) && (chiprev < 3))
499 + allow = 0;
500 + }
501 + return allow;
502 +}
503 +
504 +static void bcma_pcie2_3rd_init(struct bcma_bus *bus)
505 +{
506 + /* PCIE PLL block register (base 0x8000) */
507 + bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x00000088, 0x57fe8000);
508 + /* Check PCIE PLL lock status */
509 + bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x00000088, 0x67c60000);
510 +}
511 +
512 +/* To improve PCIE phy jitter */
513 +static void bcma_pcie2_improve_phy_jitter(struct bcma_bus *bus, int phyaddr)
514 +{
515 + u32 val;
516 +
517 + /* Change blkaddr */
518 + val = (1 << 30) | (1 << 28) | (phyaddr << 23) | (0x1f << 18) |
519 + (2 << 16) | (0x863 << 4);
520 + bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x0000009a, val);
521 +
522 + /* Write 0x0190 to 0x13 regaddr */
523 + val = (1 << 30) | (1 << 28) | (phyaddr << 23) | (0x13 << 18) |
524 + (2 << 16) | 0x0190;
525 + bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x0000009a, val);
526 +
527 + /* Write 0x0191 to 0x19 regaddr */
528 + val = (1 << 30) | (1 << 28) | (phyaddr << 23) | (0x19 << 18) |
529 + (2 << 16) | 0x0191;
530 + bcma_chipco_b_mii_write(&bus->drv_cc_b, 0x0000009a, val);
531 +}
532 +
533 +static int bcma_pcie2_setup(int nr, struct pci_sys_data *sys)
534 +{
535 + struct bcma_device *bdev = sys->private_data;
536 + struct bcma_bus *bus = bdev->bus;
537 + struct resource *res;
538 + struct bcma_device *arm_core;
539 + u32 cru_straps_ctrl;
540 + int allow_gen2, linkfail;
541 + int phyaddr;
542 +
543 + if (bdev->core_unit == 2) {
544 + arm_core = bcma_find_core(bus, BCMA_CORE_ARMCA9);
545 + cru_straps_ctrl = bcma_read32(arm_core, 0x2a0);
546 +
547 + /* 3rd PCIE is not selected */
548 + if (cru_straps_ctrl & 0x10)
549 + return -ENODEV;
550 +
551 + bcma_pcie2_3rd_init(bus);
552 + phyaddr = 0xf;
553 + } else {
554 + phyaddr = bdev->core_unit;
555 + }
556 + bcma_pcie2_improve_phy_jitter(bus, phyaddr);
557 +
558 + /* create mem resource */
559 + res = devm_kzalloc(&bdev->dev, sizeof(*res), GFP_KERNEL);
560 + if (!res)
561 + return -EINVAL;
562 +
563 + res->start = bdev->addr_s[0];
564 + res->end = res->start + SZ_128M - 1;
565 + res->name = "PCIe Configuration Space";
566 + res->flags = IORESOURCE_MEM;
567 +
568 + pci_add_resource(&sys->resources, res);
569 +
570 + /* This PCIe controller does not support IO Mem, so use a dummy one. */
571 + res = devm_kzalloc(&bdev->dev, sizeof(*res), GFP_KERNEL);
572 + if (!res)
573 + return -EINVAL;
574 +
575 + res->start = bdev->addr_s[0];
576 + res->end = res->start + SZ_128M - 1;
577 + res->name = "PCIe Configuration Space";
578 + res->flags = IORESOURCE_IO;
579 +
580 + pci_add_resource(&sys->resources, res);
581 +
582 + for (allow_gen2 = 0; allow_gen2 <= 1; allow_gen2++) {
583 + bcma_pcie2_hw_init(bdev);
584 + bcma_pcie2_map_init(bdev);
585 +
586 + /*
587 + * Skip inactive ports -
588 + * will need to change this for hot-plugging
589 + */
590 + linkfail = bcma_pcie2_check_link(bdev, sys, allow_gen2);
591 + if (linkfail)
592 + break;
593 +
594 + bcma_pcie2_bridge_init(bdev);
595 +
596 + if (allow_gen2 == 0) {
597 + if (bcma_pcie2_allow_gen2_rc(bdev) == 0)
598 + break;
599 + dev_info(&bdev->dev, "switching to GEN2\n");
600 + }
601 + }
602 +
603 + if (linkfail)
604 + return -1;
605 +
606 + return 1;
607 +}
608 +
609 +/*
610 + * Methods for accessing configuration registers
611 + */
612 +static struct pci_ops bcma_pcie2_ops = {
613 + .read = bcma_pcie2_read_config_pci,
614 + .write = bcma_pcie2_write_config_pci,
615 +};
616 +
617 +static int bcma_pcie2_probe(struct bcma_device *bdev)
618 +{
619 + struct hw_pci hw;
620 +
621 + dev_info(&bdev->dev, "scanning bus\n");
622 +
623 + hw = (struct hw_pci) {
624 + .nr_controllers = 1,
625 + .domain = bdev->core_unit,
626 + .private_data = (void **)&bdev,
627 + .setup = bcma_pcie2_setup,
628 + .map_irq = bcma_pcie2_map_irq,
629 + .ops = &bcma_pcie2_ops,
630 + };
631 +
632 + /* Announce this port to ARM/PCI common code */
633 + pci_common_init_dev(&bdev->dev, &hw);
634 +
635 + /* Setup virtual-wire interrupts */
636 + bcma_write32(bdev, SOC_PCIE_SYS_RC_INTX_EN, 0xf);
637 +
638 + /* Enable memory and bus master */
639 + bcma_write32(bdev, SOC_PCIE_HDR_OFF + 4, 0x6);
640 +
641 + return 0;
642 +}
643 +
644 +static const struct bcma_device_id bcma_pcie2_table[] = {
645 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_PCIEG2, BCMA_ANY_REV, BCMA_ANY_CLASS),
646 + BCMA_CORETABLE_END
647 +};
648 +MODULE_DEVICE_TABLE(bcma, bcma_pcie2_table);
649 +
650 +static struct bcma_driver bcma_pcie2_driver = {
651 + .name = KBUILD_MODNAME,
652 + .id_table = bcma_pcie2_table,
653 + .probe = bcma_pcie2_probe,
654 +};
655 +
656 +static int __init bcma_pcie2_init(void)
657 +{
658 + return bcma_driver_register(&bcma_pcie2_driver);
659 +}
660 +module_init(bcma_pcie2_init);
661 +
662 +static void __exit bcma_pcie2_exit(void)
663 +{
664 + bcma_driver_unregister(&bcma_pcie2_driver);
665 +}
666 +module_exit(bcma_pcie2_exit);
667 +
668 +MODULE_AUTHOR("Hauke Mehrtens");
669 +MODULE_DESCRIPTION("PCIe Gen2 driver for BCMA");
670 +MODULE_LICENSE("GPLv2");