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