convert brcm-2.4 to the new target structure
[openwrt.git] / target / linux / brcm-2.4 / files / arch / mips / bcm947xx / sbpci.c
1 /*
2 * Low-Level PCI and SB support for BCM47xx
3 *
4 * Copyright 2006, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id: hndpci.c,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $
13 */
14
15 #include <typedefs.h>
16 #include <osl.h>
17 #include <pcicfg.h>
18 #include <bcmdevs.h>
19 #include <sbconfig.h>
20 #include <bcmutils.h>
21 #include <sbutils.h>
22 #include <sbpci.h>
23 #include <bcmendian.h>
24 #include <bcmnvram.h>
25 #include <hndcpu.h>
26 #include <hndmips.h>
27 #include <hndpci.h>
28
29 /* debug/trace */
30 #ifdef BCMDBG_PCI
31 #define PCI_MSG(args) printf args
32 #else
33 #define PCI_MSG(args)
34 #endif /* BCMDBG_PCI */
35
36 /* Can free sbpci_init() memory after boot */
37 #ifndef linux
38 #define __init
39 #endif /* linux */
40
41 /* Emulated configuration space */
42 typedef struct {
43 int n;
44 uint size0;
45 uint size1;
46 uint size2;
47 uint size3;
48 } sb_bar_cfg_t;
49 static pci_config_regs sb_config_regs[SB_MAXCORES];
50 static sb_bar_cfg_t sb_bar_cfg[SB_MAXCORES];
51
52 /* Links to emulated and real PCI configuration spaces */
53 #define MAXFUNCS 2
54 typedef struct {
55 pci_config_regs *emu; /* emulated PCI config */
56 pci_config_regs *pci; /* real PCI config */
57 sb_bar_cfg_t *bar; /* region sizes */
58 } sb_pci_cfg_t;
59 static sb_pci_cfg_t sb_pci_cfg[SB_MAXCORES][MAXFUNCS];
60
61 /* Special emulated config space for non-existing device */
62 static pci_config_regs sb_pci_null = { 0xffff, 0xffff };
63
64 /* Banned cores */
65 static uint16 pci_ban[SB_MAXCORES] = { 0 };
66 static uint pci_banned = 0;
67
68 /* CardBus mode */
69 static bool cardbus = FALSE;
70
71 /* Disable PCI host core */
72 static bool pci_disabled = FALSE;
73
74 /* Host bridge slot #, default to 0 */
75 static uint8 pci_hbslot = 0;
76
77 /* Internal macros */
78 #define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
79 #define PCI_HBSBCFG_REV 8 /* MIN. core rev. required to
80 * access host bridge PCI cfg space
81 * from SB
82 */
83
84 /*
85 * Functions for accessing external PCI configuration space
86 */
87
88 /* Assume one-hot slot wiring */
89 #define PCI_SLOT_MAX 16 /* Max. PCI Slots */
90
91 static uint32
92 config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
93 {
94 uint coreidx;
95 sbpciregs_t *regs;
96 uint32 addr = 0;
97 osl_t *osh;
98
99 /* CardBusMode supports only one device */
100 if (cardbus && dev > 1)
101 return 0;
102
103 osh = sb_osh(sbh);
104
105 coreidx = sb_coreidx(sbh);
106 regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
107
108 /* Type 0 transaction */
109 if (bus == 1) {
110 /* Skip unwired slots */
111 if (dev < PCI_SLOT_MAX) {
112 uint32 win;
113
114 /* Slide the PCI window to the appropriate slot */
115 win = (SBTOPCI_CFG0 | ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
116 W_REG(osh, &regs->sbtopci1, win);
117 addr = SB_PCI_CFG |
118 ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
119 (func << PCICFG_FUN_SHIFT) |
120 (off & ~3);
121 }
122 } else {
123 /* Type 1 transaction */
124 W_REG(osh, &regs->sbtopci1, SBTOPCI_CFG1);
125 addr = SB_PCI_CFG |
126 (bus << PCICFG_BUS_SHIFT) |
127 (dev << PCICFG_SLOT_SHIFT) |
128 (func << PCICFG_FUN_SHIFT) |
129 (off & ~3);
130 }
131
132 sb_setcoreidx(sbh, coreidx);
133
134 return addr;
135 }
136
137 /*
138 * Read host bridge PCI config registers from Silicon Backplane (>=rev8).
139 *
140 * It returns TRUE to indicate that access to the host bridge's pci config
141 * from SB is ok, and values in 'addr' and 'val' are valid.
142 *
143 * It can only read registers at multiple of 4-bytes. Callers must pick up
144 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
145 * the register address where value in 'val' is read.
146 */
147 static bool
148 sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off,
149 uint32 **addr, uint32 *val)
150 {
151 sbpciregs_t *regs;
152 osl_t *osh;
153 uint coreidx;
154 bool ret = FALSE;
155
156 /* sanity check */
157 ASSERT(bus == 1);
158 ASSERT(dev == pci_hbslot);
159 ASSERT(func == 0);
160
161 osh = sb_osh(sbh);
162
163 /* read pci config when core rev >= 8 */
164 coreidx = sb_coreidx(sbh);
165 regs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
166 if (regs && sb_corerev(sbh) >= PCI_HBSBCFG_REV) {
167 *addr = (uint32 *)&regs->pcicfg[func][off >> 2];
168 *val = R_REG(osh, *addr);
169 ret = TRUE;
170 }
171 sb_setcoreidx(sbh, coreidx);
172
173 return ret;
174 }
175
176 int
177 extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
178 {
179 uint32 addr = 0, *reg = NULL, val;
180 int ret = 0;
181
182 /*
183 * Set value to -1 when:
184 * flag 'pci_disabled' is true;
185 * value of 'addr' is zero;
186 * REG_MAP() fails;
187 * BUSPROBE() fails;
188 */
189 if (pci_disabled)
190 val = 0xffffffff;
191 else if (bus == 1 && dev == pci_hbslot && func == 0 &&
192 sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
193 ;
194 else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
195 ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
196 (BUSPROBE(val, reg) != 0))
197 val = 0xffffffff;
198
199 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
200 __FUNCTION__, val, reg, addr, len, off, buf));
201
202 val >>= 8 * (off & 3);
203 if (len == 4)
204 *((uint32 *) buf) = val;
205 else if (len == 2)
206 *((uint16 *) buf) = (uint16) val;
207 else if (len == 1)
208 *((uint8 *) buf) = (uint8) val;
209 else
210 ret = -1;
211
212 if (reg && addr)
213 REG_UNMAP(reg);
214
215 return ret;
216 }
217
218 int
219 extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
220 {
221 osl_t *osh;
222 uint32 addr = 0, *reg = NULL, val;
223 int ret = 0;
224
225 osh = sb_osh(sbh);
226
227 /*
228 * Ignore write attempt when:
229 * flag 'pci_disabled' is true;
230 * value of 'addr' is zero;
231 * REG_MAP() fails;
232 * BUSPROBE() fails;
233 */
234 if (pci_disabled)
235 return 0;
236 else if (bus == 1 && dev == pci_hbslot && func == 0 &&
237 sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
238 ;
239 else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
240 ((reg = (uint32 *) REG_MAP(addr, len)) == 0) ||
241 (BUSPROBE(val, reg) != 0))
242 goto done;
243
244 if (len == 4)
245 val = *((uint32 *) buf);
246 else if (len == 2) {
247 val &= ~(0xffff << (8 * (off & 3)));
248 val |= *((uint16 *) buf) << (8 * (off & 3));
249 } else if (len == 1) {
250 val &= ~(0xff << (8 * (off & 3)));
251 val |= *((uint8 *) buf) << (8 * (off & 3));
252 } else {
253 ret = -1;
254 goto done;
255 }
256
257 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg));
258
259 W_REG(osh, reg, val);
260
261 done:
262 if (reg && addr)
263 REG_UNMAP(reg);
264
265 return ret;
266 }
267
268 /*
269 * Must access emulated PCI configuration at these locations even when
270 * the real PCI config space exists and is accessible.
271 *
272 * PCI_CFG_VID (0x00)
273 * PCI_CFG_DID (0x02)
274 * PCI_CFG_PROGIF (0x09)
275 * PCI_CFG_SUBCL (0x0a)
276 * PCI_CFG_BASECL (0x0b)
277 * PCI_CFG_HDR (0x0e)
278 * PCI_CFG_INT (0x3c)
279 * PCI_CFG_PIN (0x3d)
280 */
281 #define FORCE_EMUCFG(off, len) \
282 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
283 (off == PCI_CFG_PROGIF) || \
284 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
285 (off == PCI_CFG_HDR) || \
286 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
287
288 /* Sync the emulation registers and the real PCI config registers. */
289 static void
290 sb_pcid_read_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
291 uint off, uint len)
292 {
293 osl_t *osh;
294 uint oldidx;
295
296 ASSERT(cfg);
297 ASSERT(cfg->emu);
298 ASSERT(cfg->pci);
299
300 /* decide if real PCI config register access is necessary */
301 if (FORCE_EMUCFG(off, len))
302 return;
303
304 osh = sb_osh(sbh);
305
306 /* access to the real pci config space only when the core is up */
307 oldidx = sb_coreidx(sbh);
308 sb_setcoreidx(sbh, coreidx);
309 if (sb_iscoreup(sbh)) {
310 if (len == 4)
311 *(uint32 *)((ulong)cfg->emu + off) =
312 htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off)));
313 else if (len == 2)
314 *(uint16 *)((ulong)cfg->emu + off) =
315 htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off)));
316 else if (len == 1)
317 *(uint8 *)((ulong)cfg->emu + off) =
318 R_REG(osh, (uint8 *)((ulong)cfg->pci + off));
319 }
320 sb_setcoreidx(sbh, oldidx);
321 }
322
323 static void
324 sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
325 uint off, uint len)
326 {
327 osl_t *osh;
328 uint oldidx;
329
330 ASSERT(cfg);
331 ASSERT(cfg->emu);
332 ASSERT(cfg->pci);
333
334 osh = sb_osh(sbh);
335
336 /* decide if real PCI config register access is necessary */
337 if (FORCE_EMUCFG(off, len))
338 return;
339
340 /* access to the real pci config space only when the core is up */
341 oldidx = sb_coreidx(sbh);
342 sb_setcoreidx(sbh, coreidx);
343 if (sb_iscoreup(sbh)) {
344 if (len == 4)
345 W_REG(osh, (uint32 *)((ulong)cfg->pci + off),
346 ltoh32(*(uint32 *)((ulong)cfg->emu + off)));
347 else if (len == 2)
348 W_REG(osh, (uint16 *)((ulong)cfg->pci + off),
349 ltoh16(*(uint16 *)((ulong)cfg->emu + off)));
350 else if (len == 1)
351 W_REG(osh, (uint8 *)((ulong)cfg->pci + off),
352 *(uint8 *)((ulong)cfg->emu + off));
353 }
354 sb_setcoreidx(sbh, oldidx);
355 }
356
357 /*
358 * Functions for accessing translated SB configuration space
359 */
360 static int
361 sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
362 {
363 pci_config_regs *cfg;
364
365 if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
366 return -1;
367 cfg = sb_pci_cfg[dev][func].emu;
368
369 ASSERT(ISALIGNED(off, len));
370 ASSERT(ISALIGNED((uintptr)buf, len));
371
372 /* use special config space if the device does not exist */
373 if (!cfg)
374 cfg = &sb_pci_null;
375 /* sync emulation with real PCI config if necessary */
376 else if (sb_pci_cfg[dev][func].pci)
377 sb_pcid_read_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
378
379 if (len == 4)
380 *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
381 else if (len == 2)
382 *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
383 else if (len == 1)
384 *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off));
385 else
386 return -1;
387
388 return 0;
389 }
390
391 static int
392 sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
393 {
394 uint coreidx;
395 void *regs;
396 pci_config_regs *cfg;
397 osl_t *osh;
398 sb_bar_cfg_t *bar;
399
400 if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
401 return -1;
402 cfg = sb_pci_cfg[dev][func].emu;
403 if (!cfg)
404 return -1;
405
406 ASSERT(ISALIGNED(off, len));
407 ASSERT(ISALIGNED((uintptr)buf, len));
408
409 osh = sb_osh(sbh);
410
411 /* Emulate BAR sizing */
412 if (off >= OFFSETOF(pci_config_regs, base[0]) &&
413 off <= OFFSETOF(pci_config_regs, base[3]) &&
414 len == 4 && *((uint32 *) buf) == ~0) {
415 coreidx = sb_coreidx(sbh);
416 if ((regs = sb_setcoreidx(sbh, dev))) {
417 bar = sb_pci_cfg[dev][func].bar;
418 /* Highest numbered address match register */
419 if (off == OFFSETOF(pci_config_regs, base[0]))
420 cfg->base[0] = ~(bar->size0 - 1);
421 else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1)
422 cfg->base[1] = ~(bar->size1 - 1);
423 else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2)
424 cfg->base[2] = ~(bar->size2 - 1);
425 else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3)
426 cfg->base[3] = ~(bar->size3 - 1);
427 }
428 sb_setcoreidx(sbh, coreidx);
429 }
430 else if (len == 4)
431 *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf));
432 else if (len == 2)
433 *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf));
434 else if (len == 1)
435 *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf);
436 else
437 return -1;
438
439 /* sync emulation with real PCI config if necessary */
440 if (sb_pci_cfg[dev][func].pci)
441 sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
442
443 return 0;
444 }
445
446 int
447 sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
448 {
449 if (bus == 0)
450 return sb_read_config(sbh, bus, dev, func, off, buf, len);
451 else
452 return extpci_read_config(sbh, bus, dev, func, off, buf, len);
453 }
454
455 int
456 sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
457 {
458 if (bus == 0)
459 return sb_write_config(sbh, bus, dev, func, off, buf, len);
460 else
461 return extpci_write_config(sbh, bus, dev, func, off, buf, len);
462 }
463
464 void
465 sbpci_ban(uint16 core)
466 {
467 if (pci_banned < ARRAYSIZE(pci_ban))
468 pci_ban[pci_banned++] = core;
469 }
470
471 /*
472 * Initiliaze PCI core. Return 0 after a successful initialization.
473 * Otherwise return -1 to indicate there is no PCI core and return 1
474 * to indicate PCI core is disabled.
475 */
476 int __init
477 sbpci_init_pci(sb_t *sbh)
478 {
479 uint chip, chiprev, chippkg, host;
480 uint32 boardflags;
481 sbpciregs_t *pci;
482 sbconfig_t *sb;
483 uint32 val;
484 int ret = 0;
485 char *hbslot;
486 osl_t *osh;
487
488 chip = sb_chip(sbh);
489 chiprev = sb_chiprev(sbh);
490 chippkg = sb_chippkg(sbh);
491
492 osh = sb_osh(sbh);
493
494 if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) {
495 printk("PCI: no core\n");
496 pci_disabled = TRUE;
497 return -1;
498 }
499
500 if ((chip == 0x4310) && (chiprev == 0))
501 pci_disabled = TRUE;
502
503 sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
504
505 boardflags = (uint32) getintvar(NULL, "boardflags");
506
507 /*
508 * The 200-pin BCM4712 package does not bond out PCI. Even when
509 * PCI is bonded out, some boards may leave the pins
510 * floating.
511 */
512 if (((chip == BCM4712_CHIP_ID) &&
513 ((chippkg == BCM4712SMALL_PKG_ID) ||
514 (chippkg == BCM4712MID_PKG_ID))) ||
515 (boardflags & BFL_NOPCI))
516 pci_disabled = TRUE;
517
518 /* Enable the core */
519 sb_core_reset(sbh, 0, 0);
520
521 /*
522 * If the PCI core should not be touched (disabled, not bonded
523 * out, or pins floating), do not even attempt to access core
524 * registers. Otherwise, try to determine if it is in host
525 * mode.
526 */
527 if (pci_disabled)
528 host = 0;
529 else
530 host = !BUSPROBE(val, &pci->control);
531
532 if (!host) {
533 ret = 1;
534
535 /* Disable PCI interrupts in client mode */
536 W_REG(osh, &sb->sbintvec, 0);
537
538 /* Disable the PCI bridge in client mode */
539 sbpci_ban(SB_PCI);
540 sb_core_disable(sbh, 0);
541
542 printk("PCI: Disabled\n");
543 } else {
544 printk("PCI: Initializing host\n");
545
546 /* Disable PCI SBReqeustTimeout for BCM4785 */
547 if (chip == BCM4785_CHIP_ID) {
548 AND_REG(osh, &sb->sbimconfiglow, ~0x00000070);
549 sb_commit(sbh);
550 }
551
552 /* Reset the external PCI bus and enable the clock */
553 W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */
554 W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */
555 OSL_DELAY(150); /* delay > 100 us */
556 W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */
557 /* Use internal arbiter and park REQ/GRNT at external master 0 */
558 W_REG(osh, &pci->arbcontrol, PCI_INT_ARB);
559 OSL_DELAY(1); /* delay 1 us */
560 if (sb_corerev(sbh) >= 8) {
561 val = getintvar(NULL, "parkid");
562 ASSERT(val <= PCI_PARKID_LAST);
563 OR_REG(osh, &pci->arbcontrol, val << PCI_PARKID_SHIFT);
564 OSL_DELAY(1);
565 }
566
567 /* Enable CardBusMode */
568 cardbus = getintvar(NULL, "cardbus") == 1;
569 if (cardbus) {
570 printk("PCI: Enabling CardBus\n");
571 /* GPIO 1 resets the CardBus device on bcm94710ap */
572 sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY);
573 sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY);
574 W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400);
575 }
576
577 /* 64 MB I/O access window */
578 W_REG(osh, &pci->sbtopci0, SBTOPCI_IO);
579 /* 64 MB configuration access window */
580 W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0);
581 /* 1 GB memory access window */
582 W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA);
583
584 /* Host bridge slot # nvram overwrite */
585 if ((hbslot = nvram_get("pcihbslot"))) {
586 pci_hbslot = bcm_strtoul(hbslot, NULL, 0);
587 ASSERT(pci_hbslot < PCI_MAX_DEVICES);
588 }
589
590 /* Enable PCI bridge BAR0 prefetch and burst */
591 val = 6;
592 sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val));
593
594 /* Enable PCI interrupts */
595 W_REG(osh, &pci->intmask, PCI_INTA);
596 }
597
598 return ret;
599 }
600
601 /*
602 * Get the PCI region address and size information.
603 */
604 static void __init
605 sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar)
606 {
607 osl_t *osh;
608 uint16 coreid;
609 void *regs;
610 sbconfig_t *sb;
611 uint32 base;
612
613 osh = sb_osh(sbh);
614 coreid = sb_coreid(sbh);
615 regs = sb_coreregs(sbh);
616 sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
617
618 switch (coreid) {
619 case SB_USB20H:
620 base = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
621
622 cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */
623 cfg->base[1] = 0;
624 cfg->base[2] = 0;
625 cfg->base[3] = 0;
626 cfg->base[4] = 0;
627 cfg->base[5] = 0;
628 bar->n = 1;
629 bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */
630 bar->size1 = 0;
631 bar->size2 = 0;
632 bar->size3 = 0;
633 break;
634 default:
635 cfg->base[0] = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
636 cfg->base[1] = htol32(sb_base(R_REG(osh, &sb->sbadmatch1)));
637 cfg->base[2] = htol32(sb_base(R_REG(osh, &sb->sbadmatch2)));
638 cfg->base[3] = htol32(sb_base(R_REG(osh, &sb->sbadmatch3)));
639 cfg->base[4] = 0;
640 cfg->base[5] = 0;
641 bar->n = (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
642 bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0));
643 bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1));
644 bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2));
645 bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3));
646 break;
647 }
648 }
649
650 /*
651 * Construct PCI config spaces for SB cores so that they
652 * can be accessed as if they were PCI devices.
653 */
654 static void __init
655 sbpci_init_cores(sb_t *sbh)
656 {
657 uint chiprev, coreidx, i;
658 sbconfig_t *sb;
659 pci_config_regs *cfg, *pci;
660 sb_bar_cfg_t *bar;
661 void *regs;
662 osl_t *osh;
663 uint16 vendor, device;
664 uint16 coreid;
665 uint8 class, subclass, progif;
666 uint dev;
667 uint8 header;
668 uint func;
669
670 chiprev = sb_chiprev(sbh);
671 coreidx = sb_coreidx(sbh);
672
673 osh = sb_osh(sbh);
674
675 /* Scan the SB bus */
676 bzero(sb_config_regs, sizeof(sb_config_regs));
677 bzero(sb_bar_cfg, sizeof(sb_bar_cfg));
678 bzero(sb_pci_cfg, sizeof(sb_pci_cfg));
679 memset(&sb_pci_null, -1, sizeof(sb_pci_null));
680 cfg = sb_config_regs;
681 bar = sb_bar_cfg;
682 for (dev = 0; dev < SB_MAXCORES; dev ++) {
683 /* Check if the core exists */
684 if (!(regs = sb_setcoreidx(sbh, dev)))
685 continue;
686 sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
687
688 /* Check if this core is banned */
689 coreid = sb_coreid(sbh);
690 for (i = 0; i < pci_banned; i++)
691 if (coreid == pci_ban[i])
692 break;
693 if (i < pci_banned)
694 continue;
695
696 for (func = 0; func < MAXFUNCS; ++func) {
697 /* Make sure we won't go beyond the limit */
698 if (cfg >= &sb_config_regs[SB_MAXCORES]) {
699 printk("PCI: too many emulated devices\n");
700 goto done;
701 }
702
703 /* Convert core id to pci id */
704 if (sb_corepciid(sbh, func, &vendor, &device, &class, &subclass,
705 &progif, &header))
706 continue;
707
708 /*
709 * Differentiate real PCI config from emulated.
710 * non zero 'pci' indicate there is a real PCI config space
711 * for this device.
712 */
713 switch (device) {
714 case BCM47XX_GIGETH_ID:
715 pci = (pci_config_regs *)((uint32)regs + 0x800);
716 break;
717 case BCM47XX_SATAXOR_ID:
718 pci = (pci_config_regs *)((uint32)regs + 0x400);
719 break;
720 case BCM47XX_ATA100_ID:
721 pci = (pci_config_regs *)((uint32)regs + 0x800);
722 break;
723 default:
724 pci = NULL;
725 break;
726 }
727 /* Supported translations */
728 cfg->vendor = htol16(vendor);
729 cfg->device = htol16(device);
730 cfg->rev_id = chiprev;
731 cfg->prog_if = progif;
732 cfg->sub_class = subclass;
733 cfg->base_class = class;
734 cfg->header_type = header;
735 sbpci_init_regions(sbh, func, cfg, bar);
736 /* Save core interrupt flag */
737 cfg->int_pin = R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
738 /* Save core interrupt assignment */
739 cfg->int_line = sb_irq(sbh);
740 /* Indicate there is no SROM */
741 *((uint32 *) &cfg->sprom_control) = 0xffffffff;
742
743 /* Point to the PCI config spaces */
744 sb_pci_cfg[dev][func].emu = cfg;
745 sb_pci_cfg[dev][func].pci = pci;
746 sb_pci_cfg[dev][func].bar = bar;
747 cfg ++;
748 bar ++;
749 }
750 }
751
752 done:
753 sb_setcoreidx(sbh, coreidx);
754 }
755
756 /*
757 * Initialize PCI core and construct PCI config spaces for SB cores.
758 * Must propagate sbpci_init_pci() return value to the caller to let
759 * them know the PCI core initialization status.
760 */
761 int __init
762 sbpci_init(sb_t *sbh)
763 {
764 int status = sbpci_init_pci(sbh);
765 sbpci_init_cores(sbh);
766 return status;
767 }
768
This page took 0.08705 seconds and 5 git commands to generate.