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