BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / shared / hndpci.c
blob10b957e452569e59308399c005beb411d397fada
1 /*
2 * Low-Level PCI and SI support for BCM47xx
4 * Copyright (C) 2011, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: hndpci.c 319422 2012-03-08 01:30:26Z $
21 #include <bcm_cfg.h>
22 #include <typedefs.h>
23 #include <osl.h>
24 #include <pcicfg.h>
25 #include <bcmdevs.h>
26 #include <hndsoc.h>
27 #include <bcmutils.h>
28 #include <siutils.h>
29 #include <pci_core.h>
30 #include <pcie_core.h>
31 #include <bcmendian.h>
32 #include <bcmnvram.h>
33 #include <hndcpu.h>
34 #include <hndpci.h>
35 #include <nicpci.h>
36 #include <sbchipc.h>
38 /* For now we need some real Silicon Backplane utils */
39 #include "siutils_priv.h"
41 /* debug/trace */
42 #define PCI_MSG(args)
44 /* to free some function memory after boot */
45 #ifndef linux
46 #define __init
47 #endif /* linux */
49 /* Emulated configuration space */
50 typedef struct {
51 int n;
52 uint size[PCI_BAR_MAX];
53 } si_bar_cfg_t;
54 static pci_config_regs si_config_regs[SI_MAXCORES];
55 static si_bar_cfg_t si_bar_cfg[SI_MAXCORES];
57 /* Links to emulated and real PCI configuration spaces */
58 #define MAXFUNCS 2
59 typedef struct {
60 pci_config_regs *emu; /* emulated PCI config */
61 pci_config_regs *pci; /* real PCI config */
62 si_bar_cfg_t *bar; /* region sizes */
63 } si_pci_cfg_t;
64 static si_pci_cfg_t si_pci_cfg[SI_MAXCORES][MAXFUNCS];
66 /* Special emulated config space for non-existing device */
67 static pci_config_regs si_pci_null = { 0xffff, 0xffff };
69 /* Banned cores */
70 static uint16 pci_ban[SI_MAXCORES] = { 0 };
71 static uint pci_banned = 0;
73 /* CardBus mode */
74 static bool cardbus = FALSE;
76 /* The OS's enumerated bus numbers for supported PCI/PCIe core units */
77 static uint pci_busid[SI_PCI_MAXCORES] = { 0, };
79 static uint32 pci_membase_cfg[SI_PCI_MAXCORES] = {
80 SI_PCI_CFG,
83 static uint32 pci_membase[SI_PCI_MAXCORES] = {
84 SI_PCI_DMA,
87 static uint32 pci_membase_1G[SI_PCI_MAXCORES] = {
88 SI_PCI_DMA,
91 /* Disable PCI host core */
92 static bool pci_disabled[SI_PCI_MAXCORES] = { FALSE };
94 /* Host bridge slot #, default to 0 */
95 static uint8 pci_hbslot = 0;
97 /* Internal macros */
98 #define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
99 #define PCI_HBSBCFG_REV 8 /* MIN corerev to access host bridge PCI cfg space from SB */
101 /* Functions for accessing external PCI configuration space, Assume one-hot slot wiring */
102 #define PCI_SLOT_MAX 16 /* Max. PCI Slots */
104 static void
105 hndpci_set_busid(uint busid)
106 { int i;
108 for (i = 0; i < SI_PCI_MAXCORES; i++) {
109 if (pci_busid[i] == 0) {
110 pci_busid[i] = busid;
111 printf("PCI/PCIe coreunit %d is set to bus %d.\n", i, pci_busid[i]);
112 return;
114 if (busid == pci_busid[i])
115 return;
119 static int
120 hndpci_pci_coreunit(uint bus)
121 { uint i;
123 ASSERT(bus >= 1);
124 for (i = SI_PCI_MAXCORES - 1; i >= 0; i--) {
125 if (pci_busid[i] && bus >= pci_busid[i])
126 return i;
128 return -1;
131 bool
132 hndpci_is_hostbridge(uint bus, uint dev)
133 { uint i;
135 ASSERT(bus >= 1);
136 if (dev != pci_hbslot)
137 return FALSE;
139 for (i = 0; i < SI_PCI_MAXCORES; i++)
140 if (bus == pci_busid[i])
141 return TRUE;
143 return FALSE;
146 uint32 hndpci_get_membase(uint bus)
148 int coreunit;
150 coreunit = hndpci_pci_coreunit(bus);
151 ASSERT(coreunit >= 0);
152 ASSERT(pci_membase[coreunit]);
153 return pci_membase[coreunit];
156 static uint32
157 config_cmd(si_t *sih, uint coreunit, uint bus, uint dev, uint func, uint off)
159 uint coreidx;
160 sbpciregs_t *pci;
161 uint32 addr = 0, *sbtopci1;
162 osl_t *osh;
164 /* CardBusMode supports only one device */
165 if (cardbus && dev > 1)
166 return 0;
168 osh = si_osh(sih);
170 coreidx = si_coreidx(sih);
171 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
173 if (pci) {
174 sbtopci1 = &pci->sbtopci1;
175 } else {
176 sbpcieregs_t *pcie;
178 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
180 /* Issue config commands only when the data link is up (atleast
181 * one external pcie device is present).
183 if (pcie && (dev < 2) &&
184 (pcie_readreg(sih, pcie, PCIE_PCIEREGS,
185 PCIE_DLLP_LSREG) & PCIE_DLLP_LSREG_LINKUP)) {
186 sbtopci1 = &pcie->sbtopcie1;
187 } else {
188 si_setcoreidx(sih, coreidx);
189 return 0;
194 /* Type 0 transaction */
195 if (!hndpci_is_hostbridge(bus, dev)) {
196 /* Skip unwired slots */
197 if (dev < PCI_SLOT_MAX) {
198 /* Slide the PCI window to the appropriate slot */
199 if (pci) {
200 uint32 win;
202 win = (SBTOPCI_CFG0 |
203 ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
204 W_REG(osh, sbtopci1, win);
205 addr = (pci_membase_cfg[coreunit] |
206 ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
207 (func << PCICFG_FUN_SHIFT) |
208 (off & ~3));
209 } else {
210 W_REG(osh, sbtopci1, SBTOPCI_CFG0);
211 addr = (pci_membase_cfg[coreunit] |
212 (dev << PCIECFG_SLOT_SHIFT) |
213 (func << PCIECFG_FUN_SHIFT) |
214 (off & ~3));
217 } else {
218 /* Type 1 transaction */
219 W_REG(osh, sbtopci1, SBTOPCI_CFG1);
220 addr = (pci_membase_cfg[coreunit] |
221 (pci ? PCI_CONFIG_ADDR(bus, dev, func, (off & ~3)) :
222 PCIE_CONFIG_ADDR((bus - 1), dev, func, (off & ~3))));
225 si_setcoreidx(sih, coreidx);
227 return addr;
231 * Read host bridge PCI config registers from Silicon Backplane ( >= rev8 ).
233 * It returns TRUE to indicate that access to the host bridge's pci config
234 * from SI is ok, and values in 'addr' and 'val' are valid.
236 * It can only read registers at multiple of 4-bytes. Callers must pick up
237 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
238 * the register address where value in 'val' is read.
240 static bool
241 si_pcihb_read_config(si_t *sih, uint coreunit, uint bus, uint dev, uint func,
242 uint off, uint32 **addr, uint32 *val)
244 sbpciregs_t *pci;
245 osl_t *osh;
246 uint coreidx;
247 bool ret = FALSE;
249 /* sanity check */
250 ASSERT(hndpci_is_hostbridge(bus, dev));
252 /* we support only two functions on device 0 */
253 if (func > 1)
254 return FALSE;
256 osh = si_osh(sih);
258 /* read pci config when core rev >= 8 */
259 coreidx = si_coreidx(sih);
260 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
261 if (pci) {
262 if (si_corerev(sih) >= PCI_HBSBCFG_REV) {
263 *addr = (uint32 *)&pci->pcicfg[func][off >> 2];
264 *val = R_REG(osh, *addr);
265 ret = TRUE;
267 } else {
268 sbpcieregs_t *pcie;
270 /* read pcie config */
271 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
272 if (pcie != NULL) {
273 /* accesses to config registers with offsets >= 256
274 * requires indirect access.
276 if (off >= 256)
277 *val = pcie_readreg(sih, pcie, PCIE_CONFIGREGS,
278 PCIE_CONFIG_INDADDR(func, off));
279 else {
280 *addr = (uint32 *)&pcie->pciecfg[func][off >> 2];
281 *val = R_REG(osh, *addr);
283 ret = TRUE;
287 si_setcoreidx(sih, coreidx);
289 return ret;
293 extpci_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
295 uint32 addr = 0, *reg = NULL, val;
296 int ret = 0;
297 int coreunit = hndpci_pci_coreunit(bus);
299 if (coreunit < 0)
300 return -1;
303 * Set value to -1 when:
304 * flag 'pci_disabled' is true;
305 * value of 'addr' is zero;
306 * REG_MAP() fails;
307 * BUSPROBE() fails;
309 if (pci_disabled[coreunit])
310 val = 0xffffffff;
311 else if (hndpci_is_hostbridge(bus, dev)) {
312 if (!si_pcihb_read_config(sih, coreunit, bus, dev, func, off, &reg, &val))
313 return -1;
314 } else if (((addr = config_cmd(sih, coreunit, bus, dev, func, off)) == 0) ||
315 ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
316 (BUSPROBE(val, reg) != 0)) {
317 PCI_MSG(("%s: Failed to read!\n", __FUNCTION__));
318 val = 0xffffffff;
321 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
322 __FUNCTION__, val, reg, addr, len, off, buf));
324 val >>= 8 * (off & 3);
325 if (len == 4)
326 *((uint32 *)buf) = val;
327 else if (len == 2)
328 *((uint16 *)buf) = (uint16) val;
329 else if (len == 1)
330 *((uint8 *)buf) = (uint8) val;
331 else
332 ret = -1;
334 if (reg && addr)
335 REG_UNMAP(reg);
337 return ret;
341 extpci_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
343 osl_t *osh;
344 uint32 addr = 0, *reg = NULL, val;
345 int ret = 0;
346 bool is_hostbridge;
347 int coreunit = hndpci_pci_coreunit(bus);
349 if (coreunit < 0)
350 return -1;
352 osh = si_osh(sih);
355 * Ignore write attempt when:
356 * flag 'pci_disabled' is true;
357 * value of 'addr' is zero;
358 * REG_MAP() fails;
359 * BUSPROBE() fails;
361 if (pci_disabled[coreunit])
362 return 0;
363 if ((is_hostbridge = hndpci_is_hostbridge(bus, dev))) {
364 if (!si_pcihb_read_config(sih, coreunit, bus, dev, func, off, &reg, &val))
365 return -1;
366 } else if (((addr = config_cmd(sih, coreunit, bus, dev, func, off)) == 0) ||
367 ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
368 (BUSPROBE(val, reg) != 0)) {
369 PCI_MSG(("%s: Failed to write!\n", __FUNCTION__));
370 goto done;
373 if (len == 4)
374 val = *((uint32 *)buf);
375 else if (len == 2) {
376 val &= ~(0xffff << (8 * (off & 3)));
377 val |= *((uint16 *)buf) << (8 * (off & 3));
378 } else if (len == 1) {
379 val &= ~(0xff << (8 * (off & 3)));
380 val |= *((uint8 *)buf) << (8 * (off & 3));
381 } else {
382 ret = -1;
383 goto done;
386 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg));
388 if (is_hostbridge && reg == NULL) {
389 sbpcieregs_t *pcie;
390 uint coreidx;
392 coreidx = si_coreidx(sih);
394 /* read pcie config */
395 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
396 if (pcie != NULL)
397 /* accesses to config registers with offsets >= 256
398 * requires indirect access.
400 pcie_writereg(sih, pcie, PCIE_CONFIGREGS,
401 PCIE_CONFIG_INDADDR(func, off), val);
403 si_setcoreidx(sih, coreidx);
404 } else {
405 W_REG(osh, reg, val);
407 if ((CHIPID(sih->chip) == BCM4716_CHIP_ID) ||
408 (CHIPID(sih->chip) == BCM4748_CHIP_ID))
409 (void)R_REG(osh, reg);
413 done:
414 if (reg && addr)
415 REG_UNMAP(reg);
417 return ret;
421 * Must access emulated PCI configuration at these locations even when
422 * the real PCI config space exists and is accessible.
424 * PCI_CFG_VID (0x00)
425 * PCI_CFG_DID (0x02)
426 * PCI_CFG_PROGIF (0x09)
427 * PCI_CFG_SUBCL (0x0a)
428 * PCI_CFG_BASECL (0x0b)
429 * PCI_CFG_HDR (0x0e)
430 * PCI_CFG_INT (0x3c)
431 * PCI_CFG_PIN (0x3d)
433 #define FORCE_EMUCFG(off, len) \
434 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
435 (off == PCI_CFG_PROGIF) || \
436 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
437 (off == PCI_CFG_HDR) || \
438 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
440 /* Sync the emulation registers and the real PCI config registers. */
441 static void
442 si_pcid_read_config(si_t *sih, uint coreidx, si_pci_cfg_t *cfg, uint off, uint len)
444 osl_t *osh;
445 uint oldidx;
447 ASSERT(cfg);
448 ASSERT(cfg->emu);
449 ASSERT(cfg->pci);
451 /* decide if real PCI config register access is necessary */
452 if (FORCE_EMUCFG(off, len))
453 return;
455 osh = si_osh(sih);
457 /* access to the real pci config space only when the core is up */
458 oldidx = si_coreidx(sih);
459 si_setcoreidx(sih, coreidx);
460 if (si_iscoreup(sih)) {
461 if (len == 4)
462 *(uint32 *)((ulong)cfg->emu + off) =
463 htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off)));
464 else if (len == 2)
465 *(uint16 *)((ulong)cfg->emu + off) =
466 htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off)));
467 else if (len == 1)
468 *(uint8 *)((ulong)cfg->emu + off) =
469 R_REG(osh, (uint8 *)((ulong)cfg->pci + off));
471 si_setcoreidx(sih, oldidx);
474 static void
475 si_pcid_write_config(si_t *sih, uint coreidx, si_pci_cfg_t *cfg, uint off, uint len)
477 osl_t *osh;
478 uint oldidx;
480 ASSERT(cfg);
481 ASSERT(cfg->emu);
482 ASSERT(cfg->pci);
484 osh = si_osh(sih);
486 /* decide if real PCI config register access is necessary */
487 if (FORCE_EMUCFG(off, len))
488 return;
490 /* access to the real pci config space only when the core is up */
491 oldidx = si_coreidx(sih);
492 si_setcoreidx(sih, coreidx);
493 if (si_iscoreup(sih)) {
494 if (len == 4)
495 W_REG(osh, (uint32 *)((ulong)cfg->pci + off),
496 ltoh32(*(uint32 *)((ulong)cfg->emu + off)));
497 else if (len == 2)
498 W_REG(osh, (uint16 *)((ulong)cfg->pci + off),
499 ltoh16(*(uint16 *)((ulong)cfg->emu + off)));
500 else if (len == 1)
501 W_REG(osh, (uint8 *)((ulong)cfg->pci + off),
502 *(uint8 *)((ulong)cfg->emu + off));
504 si_setcoreidx(sih, oldidx);
508 * Functions for accessing translated SI configuration space
510 static int
511 si_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
513 pci_config_regs *cfg;
515 if (dev >= SI_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
516 return -1;
518 cfg = si_pci_cfg[dev][func].emu;
520 ASSERT(ISALIGNED(off, len));
521 ASSERT(ISALIGNED(buf, len));
523 /* use special config space if the device does not exist */
524 if (!cfg)
525 cfg = &si_pci_null;
526 /* sync emulation with real PCI config if necessary */
527 else if (si_pci_cfg[dev][func].pci)
528 si_pcid_read_config(sih, dev, &si_pci_cfg[dev][func], off, len);
530 if (len == 4)
531 *((uint32 *)buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
532 else if (len == 2)
533 *((uint16 *)buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
534 else if (len == 1)
535 *((uint8 *)buf) = *((uint8 *)((ulong) cfg + off));
536 else
537 return -1;
539 return 0;
542 static int
543 si_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
545 uint coreidx;
546 void *regs;
547 pci_config_regs *cfg;
548 osl_t *osh;
549 si_bar_cfg_t *bar;
551 if (dev >= SI_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
552 return -1;
553 cfg = si_pci_cfg[dev][func].emu;
554 if (!cfg)
555 return -1;
557 ASSERT(ISALIGNED(off, len));
558 ASSERT(ISALIGNED(buf, len));
560 osh = si_osh(sih);
562 if (cfg->header_type == PCI_HEADER_BRIDGE) {
563 uint busid = 0;
564 if (off == OFFSETOF(ppb_config_regs, prim_bus) && len >= 2)
565 busid = (*((uint16 *)buf) & 0xff00) >> 8;
566 else if (off == OFFSETOF(ppb_config_regs, sec_bus))
567 busid = *((uint8 *)buf);
568 if (busid)
569 hndpci_set_busid(busid);
572 /* Emulate BAR sizing */
573 if (off >= OFFSETOF(pci_config_regs, base[0]) &&
574 off <= OFFSETOF(pci_config_regs, base[3]) &&
575 len == 4 && *((uint32 *)buf) == ~0) {
576 coreidx = si_coreidx(sih);
577 if ((regs = si_setcoreidx(sih, dev))) {
578 bar = si_pci_cfg[dev][func].bar;
579 /* Highest numbered address match register */
580 if (off == OFFSETOF(pci_config_regs, base[0]))
581 cfg->base[0] = ~(bar->size[0] - 1);
582 else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1)
583 cfg->base[1] = ~(bar->size[1] - 1);
584 else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2)
585 cfg->base[2] = ~(bar->size[2] - 1);
586 else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3)
587 cfg->base[3] = ~(bar->size[3] - 1);
589 si_setcoreidx(sih, coreidx);
590 } else if (len == 4)
591 *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *)buf));
592 else if (len == 2)
593 *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *)buf));
594 else if (len == 1)
595 *((uint8 *)((ulong) cfg + off)) = *((uint8 *)buf);
596 else
597 return -1;
599 /* sync emulation with real PCI config if necessary */
600 if (si_pci_cfg[dev][func].pci)
601 si_pcid_write_config(sih, dev, &si_pci_cfg[dev][func], off, len);
603 return 0;
607 hndpci_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
609 if (bus == 0)
610 return si_read_config(sih, bus, dev, func, off, buf, len);
611 else
612 return extpci_read_config(sih, bus, dev, func, off, buf, len);
616 hndpci_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len)
618 if (bus == 0)
619 return si_write_config(sih, bus, dev, func, off, buf, len);
620 else
621 return extpci_write_config(sih, bus, dev, func, off, buf, len);
624 void
625 hndpci_ban(uint16 core)
627 if (pci_banned < ARRAYSIZE(pci_ban))
628 pci_ban[pci_banned++] = core;
631 /* return cap_offset if requested capability exists in the PCI config space */
632 uint8
633 hndpci_find_pci_capability(si_t *sih, uint bus, uint dev, uint func,
634 uint8 req_cap_id, uchar *buf, uint32 *buflen)
636 uint8 cap_id;
637 uint8 cap_ptr = 0;
638 uint32 bufsize;
639 uint8 byte_val;
641 /* check for Header type 0 */
642 hndpci_read_config(sih, bus, dev, func, PCI_CFG_HDR, &byte_val, sizeof(uint8));
643 if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
644 return (cap_ptr);
646 /* check if the capability pointer field exists */
647 hndpci_read_config(sih, bus, dev, func, PCI_CFG_STAT, &byte_val, sizeof(uint8));
648 if (!(byte_val & PCI_CAPPTR_PRESENT))
649 return (cap_ptr);
651 /* check if the capability pointer is 0x00 */
652 hndpci_read_config(sih, bus, dev, func, PCI_CFG_CAPPTR, &cap_ptr, sizeof(uint8));
653 if (cap_ptr == 0x00)
654 return (cap_ptr);
656 /* loop thr'u the capability list and see if the requested capabilty exists */
657 hndpci_read_config(sih, bus, dev, func, cap_ptr, &cap_id, sizeof(uint8));
658 while (cap_id != req_cap_id) {
659 hndpci_read_config(sih, bus, dev, func, cap_ptr + 1, &cap_ptr, sizeof(uint8));
660 if (cap_ptr == 0x00)
661 return (cap_ptr);
662 hndpci_read_config(sih, bus, dev, func, cap_ptr, &cap_id, sizeof(uint8));
665 /* found the caller requested capability */
666 if ((buf != NULL) && (buflen != NULL)) {
667 uint8 cap_data;
669 bufsize = *buflen;
670 if (!bufsize)
671 return (cap_ptr);
673 *buflen = 0;
675 /* copy the cpability data excluding cap ID and next ptr */
676 cap_data = cap_ptr + 2;
677 if ((bufsize + cap_data) > SZPCR)
678 bufsize = SZPCR - cap_data;
679 *buflen = bufsize;
680 while (bufsize--) {
681 hndpci_read_config(sih, bus, dev, func, cap_data, buf, sizeof(uint8));
682 cap_data++;
683 buf++;
687 return (cap_ptr);
692 * Initiliaze PCI core.
693 * Return 0 after a successful initialization.
694 * Otherwise return -1 to indicate there is no PCI core and
695 * return 1 to indicate PCI core is disabled.
697 int __init
698 BCMATTACHFN(hndpci_init_pci)(si_t *sih, uint coreunit)
700 uint chip, chiprev, chippkg, host;
701 uint32 boardflags;
702 sbpciregs_t *pci;
703 sbpcieregs_t *pcie = NULL;
704 uint32 val;
705 int ret = 0;
706 const char *hbslot;
707 osl_t *osh;
708 int bus;
710 chip = sih->chip;
711 chiprev = sih->chiprev;
712 chippkg = sih->chippkg;
714 osh = si_osh(sih);
716 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
717 if (pci == NULL) {
718 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
719 if (pcie == NULL) {
720 printf("PCI: no core\n");
721 pci_disabled[coreunit] = TRUE;
722 return -1;
726 if ((CHIPID(chip) == BCM4706_CHIP_ID) && (coreunit == 1)) {
727 /* Check if PCIE 1 is disabled */
728 if (sih->chipst & CST4706_PCIE1_DISABLE) {
729 pci_disabled[coreunit] = TRUE;
730 host = 0;
731 PCI_MSG(("PCIE port %d is disabled\n", port));
735 boardflags = (uint32)getintvar(NULL, "boardflags");
738 * The NOPCI boardflag indicates we should not touch the PCI core,
739 * it may not be bonded out or the pins may be floating.
740 * The 200-pin BCM4712 package does not bond out PCI, and routers
741 * based on it did not use the boardflag.
743 if ((boardflags & BFL_NOPCI) ||
744 ((chip == BCM4712_CHIP_ID) &&
745 ((chippkg == BCM4712SMALL_PKG_ID) || (chippkg == BCM4712MID_PKG_ID)))) {
746 pci_disabled[coreunit] = TRUE;
747 host = 0;
748 } else {
749 /* Enable the core */
750 si_core_reset(sih, 0, 0);
752 /* Figure out if it is in host mode:
753 * In host mode, it returns 0, in client mode, this register access will trap
754 * Trap handler must be implemented to support this like hndrte_mips.c
756 host = !BUSPROBE(val, (pci ? &pci->control : &pcie->control));
759 if (!host) {
760 ret = 1;
762 /* Disable PCI interrupts in client mode */
763 si_setint(sih, -1);
765 /* Disable the PCI bridge in client mode */
766 hndpci_ban(pci? PCI_CORE_ID : PCIE_CORE_ID);
768 /* Make sure the core is disabled */
769 si_core_disable(sih, 0);
771 /* On 4716 (and other AXI chips?) make sure the slave wrapper
772 * is also put in reset.
774 if ((chip == BCM4716_CHIP_ID) || (chip == BCM4748_CHIP_ID) ||
775 (chip == BCM4706_CHIP_ID)) {
776 uint32 *resetctrl;
778 resetctrl = (uint32 *)OSL_UNCACHED(SI_WRAP_BASE + (9 * SI_CORE_SIZE) +
779 AI_RESETCTRL);
780 W_REG(osh, resetctrl, AIRC_RESET);
783 printf("PCI: Disabled\n");
784 } else {
785 printf("PCI: Initializing host\n");
787 /* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */
788 if (chip == BCM4785_CHIP_ID && chiprev < 2) {
789 sbconfig_t *sb;
790 sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
791 AND_REG(osh, &sb->sbimconfiglow, ~0x00000070);
792 sb_commit(sih);
795 if (pci) {
796 /* Reset the external PCI bus and enable the clock */
797 W_REG(osh, &pci->control, 0x5); /* enable tristate drivers */
798 W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */
799 OSL_DELAY(150); /* delay > 100 us */
800 W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */
801 /* Use internal arbiter and park REQ/GRNT at external master 0
802 * We will set it later after the bus has been probed
804 W_REG(osh, &pci->arbcontrol, PCI_INT_ARB);
805 OSL_DELAY(1); /* delay 1 us */
806 } else {
807 printf("PCI: Reset RC\n");
808 OSL_DELAY(3000);
809 W_REG(osh, &pcie->control, PCIE_RST_OE);
810 OSL_DELAY(50000); /* delay 50 ms */
811 W_REG(osh, &pcie->control, PCIE_RST | PCIE_RST_OE);
814 /* Enable CardBusMode */
815 cardbus = getintvar(NULL, "cardbus") == 1;
816 if (cardbus) {
817 printf("PCI: Enabling CardBus\n");
818 /* GPIO 1 resets the CardBus device on bcm94710ap */
819 si_gpioout(sih, 1, 1, GPIO_DRV_PRIORITY);
820 si_gpioouten(sih, 1, 1, GPIO_DRV_PRIORITY);
821 W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400);
824 /* Host bridge slot # nvram overwrite */
825 if ((hbslot = nvram_get("pcihbslot"))) {
826 pci_hbslot = bcm_strtoul(hbslot, NULL, 0);
827 ASSERT(pci_hbslot < PCI_MAX_DEVICES);
830 bus = pci_busid[coreunit] = coreunit + 1;
831 if (pci) {
832 /* 64 MB I/O access window */
833 W_REG(osh, &pci->sbtopci0, SBTOPCI_IO);
834 /* 64 MB configuration access window */
835 W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0);
836 /* 1 GB memory access window */
837 W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SI_PCI_DMA);
838 } else {
839 uint8 cap_ptr, root_ctrl, root_cap, dev;
840 uint16 val16;
842 /* 64 MB I/O access window. On 4716, use
843 * sbtopcie0 to access the device registers. We
844 * can't use address match 2 (1 GB window) region
845 * as mips can't generate 64-bit address on the
846 * backplane.
848 if ((chip == BCM4716_CHIP_ID) || (chip == BCM4748_CHIP_ID))
849 W_REG(osh, &pcie->sbtopcie0, SBTOPCIE_MEM |
850 (pci_membase[coreunit] = SI_PCI_MEM));
851 else if (chip == BCM4706_CHIP_ID) {
852 if (coreunit == 0) {
853 pci_membase[coreunit] = SI_PCI_MEM;
854 pci_membase_1G[coreunit] = SI_PCIE_DMA_H32;
855 } else if (coreunit == 1) {
856 pci_membase_cfg[coreunit] = SI_PCI1_CFG;
857 pci_membase[coreunit] = SI_PCI1_MEM;
858 pci_membase_1G[coreunit] = SI_PCIE1_DMA_H32;
860 W_REG(osh, &pcie->sbtopcie0,
861 SBTOPCIE_MEM | SBTOPCIE_PF | SBTOPCIE_WR_BURST |
862 pci_membase[coreunit]);
864 else
865 W_REG(osh, &pcie->sbtopcie0, SBTOPCIE_IO);
867 /* 64 MB configuration access window */
868 W_REG(osh, &pcie->sbtopcie1, SBTOPCIE_CFG0);
870 /* 1 GB memory access window */
871 W_REG(osh, &pcie->sbtopcie2, SBTOPCIE_MEM |
872 pci_membase_1G[coreunit]);
874 /* As per PCI Express Base Spec 1.1 we need to wait for
875 * at least 100 ms from the end of a reset (cold/warm/hot)
876 * before issuing configuration requests to PCI Express
877 * devices.
879 OSL_DELAY(100000);
881 /* If the root port is capable of returning Config Request
882 * Retry Status (CRS) Completion Status to software then
883 * enable the feature.
885 cap_ptr = hndpci_find_pci_capability(sih, bus, pci_hbslot, 0,
886 PCI_CAP_PCIECAP_ID, NULL, NULL);
887 ASSERT(cap_ptr);
889 root_cap = cap_ptr + OFFSETOF(pciconfig_cap_pcie, root_cap);
890 hndpci_read_config(sih, bus, pci_hbslot, 0, root_cap,
891 &val16, sizeof(uint16));
892 if (val16 & PCIE_RC_CRS_VISIBILITY) {
893 /* Enable CRS software visibility */
894 root_ctrl = cap_ptr + OFFSETOF(pciconfig_cap_pcie, root_ctrl);
895 val16 = PCIE_RC_CRS_EN;
896 hndpci_write_config(sih, bus, pci_hbslot, 0, root_ctrl,
897 &val16, sizeof(uint16));
899 /* Initiate a configuration request to read the vendor id
900 * field of the device function's config space header after
901 * 100 ms wait time from the end of Reset. If the device is
902 * not done with its internal initialization, it must at
903 * least return a completion TLP, with a completion status
904 * of "Configuration Request Retry Status (CRS)". The root
905 * complex must complete the request to the host by returning
906 * a read-data value of 0001h for the Vendor ID field and
907 * all 1s for any additional bytes included in the request.
908 * Poll using the config reads for max wait time of 1 sec or
909 * until we receive the successful completion status. Repeat
910 * the procedure for all the devices.
912 for (dev = pci_hbslot + 1; dev < PCI_MAX_DEVICES; dev++) {
913 SPINWAIT((hndpci_read_config(sih, bus, dev, 0,
914 PCI_CFG_VID, &val16, sizeof(val16)),
915 (val16 == 0x1)), 1000000);
916 if (val16 == 0x1)
917 printf("PCI: Broken device in slot %d\n", dev);
922 if ((chip == BCM4706_CHIP_ID) || (chip == BCM4716_CHIP_ID)) {
923 uint16 val16;
924 hndpci_read_config(sih, bus, pci_hbslot, 0, PCI_CFG_DEVCTRL,
925 &val16, sizeof(val16));
926 val16 |= (2 << 5); /* Max payload size of 512 */
927 val16 |= (2 << 12); /* MRRS 512 */
928 hndpci_write_config(sih, bus, pci_hbslot, 0, PCI_CFG_DEVCTRL,
929 &val16, sizeof(val16));
932 /* Enable PCI bridge BAR0 memory & master access */
933 val = PCI_CMD_MASTER | PCI_CMD_MEMORY;
934 hndpci_write_config(sih, bus, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val));
936 /* Enable PCI interrupts */
937 if (pci)
938 W_REG(osh, &pci->intmask, PCI_INTA);
939 else
940 W_REG(osh, &pcie->intmask, PCI_INTA);
943 /* Reset busid to 0. Bus number will be assigned by OS later */
944 pci_busid[coreunit] = 0;
945 return ret;
948 void
949 hndpci_arb_park(si_t *sih, uint parkid)
951 sbpciregs_t *pci;
952 uint pcirev;
953 uint32 arb;
955 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, 0);
956 if ((pci == NULL) || pci_disabled[0]) {
957 /* Should not happen */
958 PCI_MSG(("%s: no PCI core\n", __FUNCTION__));
959 return;
962 pcirev = si_corerev(sih);
964 /* Nothing to do, not supported for these revs */
965 if (pcirev < 8)
966 return;
968 /* Get parkid from NVRAM */
969 if (parkid == PCI_PARK_NVRAM) {
970 parkid = getintvar(NULL, "parkid");
971 if (getvar(NULL, "parkid") == NULL)
972 /* Not present in NVRAM use defaults */
973 parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST;
976 /* Check the parkid is valid, if not set it to default */
977 if (parkid > ((pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST)) {
978 printf("%s: Invalid parkid %d\n", __FUNCTION__, parkid);
979 parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST;
982 /* Now set the parkid */
983 arb = R_REG(si_osh(sih), &pci->arbcontrol);
984 arb &= ~PCI_PARKID_MASK;
985 arb |= parkid << PCI_PARKID_SHIFT;
986 W_REG(si_osh(sih), &pci->arbcontrol, arb);
987 OSL_DELAY(1);
991 hndpci_deinit_pci(si_t *sih, uint coreunit)
993 int coreidx;
994 sbpciregs_t *pci;
995 sbpcieregs_t *pcie = NULL;
997 if (pci_disabled[coreunit])
998 return 0;
1000 coreidx = si_coreidx(sih);
1001 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit);
1002 if (pci == NULL) {
1003 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit);
1004 if (pcie == NULL) {
1005 printf("PCI: no core\n");
1006 return -1;
1010 if (pci)
1011 W_REG(si_osh(sih), &pci->control, PCI_RST_OE);
1012 else
1013 W_REG(si_osh(sih), &pcie->control, PCIE_RST_OE);
1015 si_core_disable(sih, 0);
1016 si_setcoreidx(sih, coreidx);
1017 return 0;
1021 * Deinitialize PCI cores
1023 void
1024 hndpci_deinit(si_t *sih)
1026 int coreunit;
1028 for (coreunit = 0; coreunit < SI_PCI_MAXCORES; coreunit++)
1029 hndpci_deinit_pci(sih, coreunit);
1033 * Get the PCI region address and size information.
1035 static void __init
1036 BCMATTACHFN(hndpci_init_regions)(si_t *sih, uint func, pci_config_regs *cfg, si_bar_cfg_t *bar)
1038 bool issb = sih->socitype == SOCI_SB;
1039 uint i, n;
1041 if (si_coreid(sih) == USB20H_CORE_ID) {
1042 uint32 base, base1;
1044 base = htol32(si_addrspace(sih, 0));
1045 if (issb) {
1046 base1 = base + 0x800; /* OHCI/EHCI */
1047 } else {
1048 /* In AI chips EHCI is addrspace 0, OHCI is 1 */
1049 base1 = base;
1050 if (((CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
1051 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) &&
1052 CHIPREV(sih->chiprev) == 0)
1053 base = 0x18009000;
1054 else
1055 base = htol32(si_addrspace(sih, 1));
1058 i = bar->n = 1;
1059 cfg->base[0] = func == 0 ? base : base1;
1060 bar->size[0] = issb ? 0x800 : 0x1000;
1061 } else {
1062 bar->n = n = si_numaddrspaces(sih);
1063 for (i = 0; i < n; i++) {
1064 int size = si_addrspacesize(sih, i);
1066 if (size) {
1067 cfg->base[i] = htol32(si_addrspace(sih, i));
1068 bar->size[i] = size;
1072 for (; i < PCI_BAR_MAX; i++) {
1073 cfg->base[i] = 0;
1074 bar->size[i] = 0;
1079 * Construct PCI config spaces for SB cores to be accessed as if they were PCI devices.
1081 void __init
1082 BCMATTACHFN(hndpci_init_cores)(si_t *sih)
1084 uint chiprev, coreidx, i;
1085 pci_config_regs *cfg, *pci;
1086 si_bar_cfg_t *bar;
1087 void *regs;
1088 osl_t *osh;
1089 uint16 vendor, device;
1090 uint16 coreid;
1091 uint8 class, subclass, progif;
1092 uint dev;
1093 uint8 header;
1094 uint func;
1096 chiprev = sih->chiprev;
1097 coreidx = si_coreidx(sih);
1099 osh = si_osh(sih);
1101 /* Scan the SI bus */
1102 bzero(si_config_regs, sizeof(si_config_regs));
1103 bzero(si_bar_cfg, sizeof(si_bar_cfg));
1104 bzero(si_pci_cfg, sizeof(si_pci_cfg));
1105 memset(&si_pci_null, -1, sizeof(si_pci_null));
1106 cfg = si_config_regs;
1107 bar = si_bar_cfg;
1108 for (dev = 0; dev < SI_MAXCORES; dev ++) {
1109 /* Check if the core exists */
1110 if (!(regs = si_setcoreidx(sih, dev)))
1111 continue;
1113 /* Check if this core is banned */
1114 coreid = si_coreid(sih);
1115 for (i = 0; i < pci_banned; i++)
1116 if (coreid == pci_ban[i])
1117 break;
1118 if (i < pci_banned)
1119 continue;
1121 if (coreid == USB20H_CORE_ID) {
1122 if (((CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
1123 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) &&
1124 (sih->chippkg == BCM5357_PKG_ID)) {
1125 printf("PCI: skip disabled USB20H\n");
1126 continue;
1130 if ((CHIPID(sih->chip) == BCM4706_CHIP_ID)) {
1131 if (coreid == GMAC_CORE_ID) {
1132 /* Only GMAC core 0 is used by 4706 */
1133 if (si_coreunit(sih) > 0) {
1134 continue;
1139 for (func = 0; func < MAXFUNCS; ++func) {
1140 /* Make sure we won't go beyond the limit */
1141 if (cfg >= &si_config_regs[SI_MAXCORES]) {
1142 printf("PCI: too many emulated devices\n");
1143 goto done;
1146 /* Convert core id to pci id */
1147 if (si_corepciid(sih, func, &vendor, &device, &class, &subclass,
1148 &progif, &header))
1149 continue;
1152 * Differentiate real PCI config from emulated.
1153 * non zero 'pci' indicate there is a real PCI config space
1154 * for this device.
1156 switch (device) {
1157 case BCM47XX_GIGETH_ID:
1158 pci = (pci_config_regs *)((uint32)regs + 0x800);
1159 break;
1160 case BCM47XX_SATAXOR_ID:
1161 pci = (pci_config_regs *)((uint32)regs + 0x400);
1162 break;
1163 case BCM47XX_ATA100_ID:
1164 pci = (pci_config_regs *)((uint32)regs + 0x800);
1165 break;
1166 default:
1167 pci = NULL;
1168 break;
1170 /* Supported translations */
1171 cfg->vendor = htol16(vendor);
1172 cfg->device = htol16(device);
1173 cfg->rev_id = chiprev;
1174 cfg->prog_if = progif;
1175 cfg->sub_class = subclass;
1176 cfg->base_class = class;
1177 cfg->header_type = header;
1178 hndpci_init_regions(sih, func, cfg, bar);
1179 /* Save core interrupt flag */
1180 cfg->int_pin = si_flag(sih);
1181 /* Save core interrupt assignment */
1182 cfg->int_line = si_irq(sih);
1183 /* Indicate there is no SROM */
1184 *((uint32 *)&cfg->sprom_control) = 0xffffffff;
1186 /* Point to the PCI config spaces */
1187 si_pci_cfg[dev][func].emu = cfg;
1188 si_pci_cfg[dev][func].pci = pci;
1189 si_pci_cfg[dev][func].bar = bar;
1190 cfg ++;
1191 bar ++;
1195 done:
1196 si_setcoreidx(sih, coreidx);
1200 * Initialize PCI core and construct PCI config spaces for SI cores.
1201 * Must propagate hndpci_init_pci() return value to the caller to let
1202 * them know the PCI core initialization status.
1204 int __init
1205 BCMATTACHFN(hndpci_init)(si_t *sih)
1207 int coreunit, status = 0;
1209 for (coreunit = 0; coreunit < SI_PCI_MAXCORES; coreunit++)
1210 status |= hndpci_init_pci(sih, coreunit);
1211 hndpci_init_cores(sih);
1212 return status;