BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / cfe / cfe / arch / mips / board / p5064 / src / pci_machdep_p5064.c
blob31c930420e914db84d2b1b9a0625713cecf12596
1 /* Very loosely based on: */
2 /* $NetBSD: pci_machdep.c,v 1.17 1995/07/27 21:39:59 cgd Exp $ */
4 /*
5 * Copyright (c) 1994 Charles Hannum. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Charles Hannum.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Algorithmics P5064 machine-specific functions for PCI autoconfiguration.
37 #ifdef _CFE_
38 #include "sbmips.h"
39 #include "cfe_pci.h"
40 #else
41 #include <ametypes.h>
42 #include "mips.h"
43 #endif
45 #include "sbd.h" /* from Algorithmics */
46 #include "v96xpbc.h" /* from Algorithmics */
48 #include "pcivar.h"
49 #include "pcireg.h"
52 typedef long hsaddr_t;
54 #define hs_write8(a,b) *((volatile uint8_t *) (a)) = (b)
55 #define hs_write16(a,b) *((volatile uint16_t *) (a)) = (b)
56 #define hs_write32(a,b) *((volatile uint32_t *) (a)) = (b)
57 #define hs_write64(a,b) *((volatile uint32_t *) (a)) = (b)
58 #define hs_read8(a) *((volatile uint8_t *) (a))
59 #define hs_read16(a) *((volatile uint16_t *) (a))
60 #define hs_read32(a) *((volatile uint32_t *) (a))
61 #define hs_read64(a) *((volatile uint64_t *) (a))
64 #if defined(__MIPSEL)
65 #define V96X_SWAP_MEM V96X_SWAP_NONE
66 #define V96X_SWAP_IO V96X_SWAP_NONE
67 #elif defined(__MIPSEB)
68 #define V96X_SWAP_MEM V96X_SWAP_8BIT
69 #define V96X_SWAP_IO V96X_SWAP_AUTO
70 #else
71 #error "Must specifiy either MIPSEL or MIPSEB"
72 #endif
74 /* PCI i/o regions in PCI space */
75 #define PCI_IO_SPACE_PCI_BASE 0x00000000
77 /* PCI mem regions in PCI space */
78 #define PCI_MEM_SPACE_PCI_BASE 0x00000000
79 #define PCI_LOCAL_MEM_PCI_BASE 0x80000000
80 #define PCI_LOCAL_MEM_ISA_BASE 0x00800000
82 /* soft versions of above */
83 static pcireg_t pci_mem_space_pci_base = PCI_MEM_SPACE_PCI_BASE;
84 static pcireg_t pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;
85 static pcireg_t pci_local_mem_isa_base = PCI_LOCAL_MEM_ISA_BASE;
87 /* PCI mem space allocation (note - skip the 16MB ISA mem space) */
88 pcireg_t minpcimemaddr = PCI_MEM_SPACE_PCI_BASE + 0x1000000;
89 pcireg_t maxpcimemaddr = PCI_MEM_SPACE_PCI_BASE + PCI_MEM_SPACE_SIZE;
91 /* PCI i/o space allocation (note - bottom 512KB reserved for ISA i/o space) */
92 /* leave 512K at beginning of PCI i/o space for ISA bridge (it
93 actually uses only 64K, but this is needed for a ISA DMA
94 h/w fix which needs a higher address bit to spot ISA cycles). */
95 //const pcireg_t minpciioaddr = PCI_IO_SPACE_PCI_BASE + 0x80000;
96 //const pcireg_t maxpciioaddr = PCI_IO_SPACE_PCI_BASE + PCI_IO_SPACE_SIZE;
97 pcireg_t minpciioaddr = PCI_IO_SPACE_PCI_BASE + 0x1000;
98 pcireg_t maxpciioaddr = PCI_IO_SPACE_PCI_BASE + 0xF000;
100 static const struct pci_bus v96x_pci_bus = {
101 0, /* minimum grant */
102 255, /* maximum latency */
103 0, /* devsel time = fast */
104 1, /* we support fast back-to-back */
105 1, /* we support prefetch */
106 0, /* we don't support 66 MHz */
107 0, /* we don't support 64 bits */
108 4000000, /* bandwidth: in 0.25us cycles / sec */
109 1 /* initially one device on bus (i.e. us) */
112 static const struct pci_bus secondary_pci_bus = {
113 0, /* minimum grant */
114 255, /* maximum latency */
115 0, /* devsel time = fast */
116 0, /* we don't fast back-to-back */
117 0, /* we don't prefetch */
118 0, /* we don't support 66 MHz */
119 0, /* we don't support 64 bits */
120 4000000, /* bandwidth: in 0.25us cycles / sec */
121 0 /* initially no devices on bus */
124 #ifdef _CFE_
125 const cons_t pci_optnames[] = {
126 {"verbose",PCI_FLG_VERBOSE},
127 {NULL,0}};
128 #endif
130 extern int _pciverbose;
133 #define MAXBUS 3
134 const int _pci_maxbus = MAXBUS;
135 static int _pci_nbus = 0;
136 struct pci_bus _pci_bus[MAXBUS];
138 /* Access functions */
140 /* The following must either fail or return the next sequential bus
141 number to make secondary/subordinate numbering work correctly. */
143 pci_nextbus (int port)
145 int bus = _pci_nbus;
147 if (bus >= MAXBUS)
148 return -1;
149 _pci_nbus++;
150 return bus;
154 pci_maxbus (int port)
156 return _pci_nbus - 1;
159 struct pci_bus *
160 pci_businfo (int port, int bus)
162 return (bus < _pci_nbus ? &_pci_bus[bus] : NULL);
166 * PCI address resources.
167 * NB: initial limits for address allocation are assumed to be aligned
168 * appropriately for PCI bridges (4K boundaries for I/O, 1M for memory).
171 pcireg_t
172 pci_minmemaddr (int port)
174 /* skip the 16MB reserved for ISA mem space */
175 return PCI_MEM_SPACE_PCI_BASE + 0x1000000;
178 pcireg_t
179 pci_maxmemaddr (int port)
181 return PCI_MEM_SPACE_PCI_BASE + PCI_MEM_SPACE_SIZE;
184 pcireg_t
185 pci_minioaddr (int port)
187 /* Skip the 32KB reserved for ISA i/o space. */
188 return PCI_IO_SPACE_PCI_BASE + 0x1000;
191 pcireg_t
192 pci_maxioaddr (int port)
194 return PCI_IO_SPACE_PCI_BASE + 0xF000;
198 static unsigned char v96x_vrev;
200 #define sbddelay(n) ((void)(0))
203 * Called to initialise the host bridge at the beginning of time
206 pci_hwinit (int port, pci_flags_t flags)
208 int initialise = 1;
209 unsigned char * const _v96xp = (unsigned char *) PHYS_TO_K1(V96XPBC_BASE);
210 unsigned int pci_rd0, pci_rd1;
211 int i;
213 /* initialise global data */
214 v96x_vrev = V96X_PCI_CC_REV & V96X_PCI_CC_REV_VREV;
215 if (v96x_vrev < V96X_VREV_B2) {
216 printf ("V96 revisions < B.2 not supported\n");
217 return -1;
220 _pci_bus[0] = v96x_pci_bus;
221 _pci_nbus = 1;
222 for (i = _pci_nbus; i < MAXBUS; i++)
223 _pci_bus[i] = secondary_pci_bus;
225 pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;
226 pci_local_mem_isa_base = PCI_LOCAL_MEM_ISA_BASE;
227 pci_mem_space_pci_base = PCI_MEM_SPACE_PCI_BASE;
229 if (!initialise)
230 return 0;
232 /* stop the V3 chip from servicing any further PCI requests */
233 V96X_PCI_CMD = 0;
234 mips_wbflush ();
236 /* reset the PCI bus */
237 V96X_SYSTEM &= ~V96X_SYSTEM_RST_OUT;
239 /* enable bridge to PCI and PCI memory accesses, plus error handling */
240 V96X_PCI_CMD = V96X_PCI_CMD_MASTER_EN
241 | V96X_PCI_CMD_MEM_EN
242 | V96X_PCI_CMD_SERR_EN
243 | V96X_PCI_CMD_PAR_EN;
245 /* clear errors and say we do fast back-to-back transfers */
246 V96X_PCI_STAT = V96X_PCI_STAT_PAR_ERR
247 | V96X_PCI_STAT_SYS_ERR
248 | V96X_PCI_STAT_M_ABORT
249 | V96X_PCI_STAT_T_ABORT
250 | V96X_PCI_STAT_PAR_REP
251 | V96X_PCI_STAT_FAST_BACK;
253 /* Local to PCI aptr 0 - LOCAL:PCI_CONF_SPACE -> PCI:config (1MB) */
254 V96X_LB_BASE0 = PCI_CONF_SPACE | V96X_SWAP_IO | V96X_ADR_SIZE_1MB
255 | V96X_LB_BASEx_ENABLE;
257 V96X_LB_BASE1 = PCI_MEM_SPACE | V96X_SWAP_MEM | V96X_ADR_SIZE_128MB
258 | V96X_LB_BASEx_ENABLE;
259 V96X_LB_MAP1 = (pci_mem_space_pci_base >> 16) | V96X_LB_TYPE_MEM;
261 V96X_LB_BASE2 = (PCI_IO_SPACE >> 16) | (V96X_SWAP_IO >> 2)
262 | V96X_LB_BASEx_ENABLE;
263 V96X_LB_MAP2 = (PCI_IO_SPACE_PCI_BASE >> 16);
265 /* PCI to local aptr 1 - PCI:80000000-90000000 -> LOCAL:00000000 */
266 /* 256MB window for PCI bus masters to get at our local memory */
267 V96X_PCI_BASE1 = pci_local_mem_pci_base | V96X_PCI_BASEx_MEM
268 | V96X_PCI_BASEx_PREFETCH;
269 V96X_PCI_MAP1 = 0x00000000 | V96X_ADR_SIZE_256MB
270 | V96X_SWAP_MEM /*| V96X_PCI_MAPx_RD_POST_INH*/
271 | V96X_PCI_MAPx_REG_EN | V96X_PCI_MAPx_ENABLE;
272 pci_rd1 = (v96x_vrev >= V96X_VREV_C0)
273 ? V96X_FIFO_PRI_FLUSHBURST : V96X_FIFO_PRI_FLUSHALL;
275 /* PCI to local aptr 0 - PCI:00800000-01000000 -> LOCAL:00000000 */
276 /* 8MB window for ISA bus masters to get at our local memory */
277 V96X_PCI_BASE0 = pci_local_mem_isa_base | V96X_PCI_BASEx_MEM
278 | V96X_PCI_BASEx_PREFETCH;
279 V96X_PCI_MAP0 = 0x00000000 | V96X_ADR_SIZE_8MB
280 | V96X_SWAP_MEM /*| V96X_PCI_MAPx_RD_POST_INH*/
281 | V96X_PCI_MAPx_REG_EN | V96X_PCI_MAPx_ENABLE;
282 pci_rd0 = (v96x_vrev >= V96X_VREV_C0)
283 ? V96X_FIFO_PRI_FLUSHBURST : V96X_FIFO_PRI_FLUSHALL;
285 /* PCI to internal registers - disabled (but avoid address overlap) */
286 V96X_PCI_IO_BASE = 0xffffff00 | V96X_PCI_IO_BASE_IO;
288 /* Disable PCI_IO_BASE and set optional AD(1:0) to 01b for type1 config */
289 V96X_PCI_CFG = V96X_PCI_CFG_IO_DIS | (0x1 << V96X_PCI_CFG_AD_LOW_SHIFT);
291 V96X_FIFO_CFG =
292 (V96X_FIFO_CFG_BRST_256 << V96X_FIFO_CFG_PBRST_MAX_SHIFT)
293 | (V96X_FIFO_CFG_WR_ENDBRST << V96X_FIFO_CFG_WR_LB_SHIFT)
294 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_LB1_SHIFT)
295 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_LB0_SHIFT)
296 | (V96X_FIFO_CFG_BRST_16 << V96X_FIFO_CFG_LBRST_MAX_SHIFT)
297 | (V96X_FIFO_CFG_WR_ENDBRST << V96X_FIFO_CFG_WR_PCI_SHIFT)
298 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_PCI1_SHIFT)
299 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_PCI0_SHIFT);
301 /* Set fifo priorities: note that on Rev C.0 and above we set the
302 read prefetch fifos to flush at the end of a burst, and not to
303 retain data like a cache (which causes coherency problems). For
304 Rev B.2 and below we can't do this, so we set them to be
305 flushed by any write cycle (inefficient but safer), and we also
306 require explicit software flushing of the fifos to maintain
307 full coherency (i.e. call pci_flush() from the cache flush
308 routines or after modifying uncached descriptors). */
310 /* initial setting, may be updated in pci_hwreinit(), below */
311 V96X_FIFO_PRIORITY =
312 V96X_FIFO_PRIORITY_LOCAL_WR /* local->pci write priority (safe) */
313 | V96X_FIFO_PRIORITY_PCI_WR /* pci->local write priority (safe) */
314 | (V96X_FIFO_PRI_NOFLUSH << V96X_FIFO_PRIORITY_LB_RD0_SHIFT)
315 | (V96X_FIFO_PRI_NOFLUSH << V96X_FIFO_PRIORITY_LB_RD1_SHIFT)
316 | (pci_rd0 << V96X_FIFO_PRIORITY_PCI_RD0_SHIFT)
317 | (pci_rd1 << V96X_FIFO_PRIORITY_PCI_RD1_SHIFT);
320 /* clear latched PCI interrupts */
321 V96X_LB_ISTAT = 0;
323 /* enable V3 general interrupts */
324 V96X_LB_IMASK = V96X_LB_INTR_PCI_RD|V96X_LB_INTR_PCI_WR;
326 /* finally unreset the PCI bus */
327 V96X_SYSTEM |= V96X_SYSTEM_RST_OUT;
329 /* ... and the onboard PCI devices */
331 volatile p5064bcr1 * const bcr1 = (p5064bcr1 *) PHYS_TO_K1(BCR1_BASE);
332 bcr1->eth = BCR1_ENABLE;
333 bcr1->scsi = BCR1_ENABLE;
334 bcr1->isa = BCR1_ENABLE;
335 bcr1->pcmcia = BCR1_ENABLE;
336 sbddelay (1);
339 return 1;
344 * Called to reinitialise the bridge after we've scanned each PCI device
345 * and know what is possible.
347 void
348 pci_hwreinit (int port, pci_flags_t flags)
350 char * const _v96xp = (char *) PHYS_TO_K1(V96XPBC_BASE);
352 if (_pci_bus[0].fast_b2b)
353 /* fast back-to-back is supported by all devices */
354 V96X_PCI_CMD |= V96X_PCI_CMD_FBB_EN;
356 /* Rev B.1+: can now use variable latency timer */
357 V96X_PCI_HDR_CFG = _pci_bus[0].def_ltim << V96X_PCI_HDR_CFG_LT_SHIFT;
359 if (_pci_bus[0].prefetch && v96x_vrev >= V96X_VREV_C0) {
360 /* Rev C.0+: we can safely prefetch from all pci mem devices */
361 V96X_LB_BASE1 |= V96X_LB_BASEx_PREFETCH;
362 V96X_FIFO_PRIORITY = (V96X_FIFO_PRIORITY & ~V96X_FIFO_PRIORITY_LB_RD1)
363 | (V96X_FIFO_PRI_FLUSHBURST << V96X_FIFO_PRIORITY_LB_RD1_SHIFT);
366 /* clear latched PCI interrupts */
367 V96X_LB_ISTAT = 0;
369 /* enable PCI read/write error interrupts */
370 V96X_LB_IMASK = V96X_LB_INTR_PCI_RD | V96X_LB_INTR_PCI_WR;
374 /* Called for each bridge after configuring the secondary bus, to allow
375 device-specific initialization. */
376 void
377 pci_bridge_setup (pcitag_t tag, pci_flags_t flags)
379 /* nothing to do */
382 void
383 pci_flush (void)
385 /* flush read-ahead fifos (not necessary on Rev C.0 and above) */
386 if (v96x_vrev < V96X_VREV_C0) {
387 char * const _v96xp = (char *) PHYS_TO_K1(V96XPBC_BASE);
388 V96X_SYSTEM |=
389 V96X_SYSTEM_LB_RD_PCI1 | V96X_SYSTEM_LB_RD_PCI0 |
390 V96X_SYSTEM_PCI_RD_LB1 | V96X_SYSTEM_PCI_RD_LB0;
397 pcitag_t
398 pci_make_tag(int port, int bus, int device, int function)
400 pcitag_t tag;
401 tag = (bus << 16) | (device << 11) | (function << 8);
402 return tag;
405 void
406 pci_break_tag(pcitag_t tag,
407 int *portp, int *busp, int *devicep, int *functionp)
409 if (portp) *portp = 0;
410 if (busp) *busp = (tag >> 16) & PCI_BUSMAX;
411 if (devicep) *devicep = (tag >> 11) & PCI_DEVMAX;
412 if (functionp) *functionp = (tag >> 8) & PCI_FUNCMAX;
416 pci_canscan (pcitag_t tag)
418 return 1;
422 pci_probe_tag(pcitag_t tag)
424 pcireg_t data;
426 if (!pci_canscan(tag))
427 return 0;
429 data = pci_conf_read(tag,PCI_ID_REG);
431 mips_wbflush ();
433 if ((data == 0) || (data == 0xffffffff)) return 0;
435 return 1;
439 pci_device_preset (pcitag_t tag)
441 /* Nothing to do for now. */
442 return 0;
444 void
445 pci_device_setup (pcitag_t tag)
447 /* Nothing to do for now. */
451 /* Read/write access to PCI configuration registers. For most
452 applications, pci_conf_read<N> and pci_conf_write<N> are deprecated
453 unless N = 32. */
455 static pcireg_t
456 pci_conf_readn(pcitag_t tag, int reg, int width)
458 char * const _v96xp = (char *) PHYS_TO_K1(V96XPBC_BASE);
459 uint32_t addr, ad_low;
460 hsaddr_t addrp;
462 pcireg_t data;
463 int bus, device, function;
465 if (reg & (width-1) || reg < 0 || reg >= PCI_REGMAX) {
466 if (_pciverbose >= 1)
467 pci_tagprintf (tag, "pci_conf_readn: bad reg 0x%x\r\n", reg);
468 return ~0;
471 pci_break_tag (tag, NULL, &bus, &device, &function);
472 if (bus == 0) {
473 /* Type 0 configuration on onboard PCI bus */
474 if (device > 5 || function > 7)
475 return ~0; /* device out of range */
476 addr = (1 << (device+24)) | (function << 8) | reg;
477 ad_low = 0;
478 } else if (v96x_vrev >= V96X_VREV_C0) {
479 /* Type 1 configuration on offboard PCI bus */
480 if (bus > PCI_BUSMAX || device > PCI_DEVMAX || function > PCI_FUNCMAX)
481 return ~0; /* device out of range */
482 addr = (bus << 16) | (device << 11) | (function << 8) | reg;
483 ad_low = V96X_LB_MAPx_AD_LOW_EN;
484 } else {
485 return ~0; /* bus out of range */
488 /* high 12 bits of address go in map register; set conf space */
489 V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR)
490 | ad_low | V96X_LB_TYPE_CONF;
492 /* clear aborts */
493 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT | V96X_PCI_STAT_T_ABORT;
495 mips_wbflush ();
497 /* low 20 bits of address are in the actual address */
498 addrp = PHYS_TO_K1(PCI_CONF_SPACE + (addr & 0xfffff));
499 switch (width) {
500 case 1:
501 data = (pcireg_t)hs_read8(addrp);
502 break;
503 case 2:
504 data = (pcireg_t)hs_read16(addrp);
505 break;
506 default:
507 case 4:
508 data = (pcireg_t)hs_read32(addrp);
509 break;
512 if (V96X_PCI_STAT & V96X_PCI_STAT_M_ABORT) {
513 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT;
514 return ~0;
517 if (V96X_PCI_STAT & V96X_PCI_STAT_T_ABORT) {
518 V96X_PCI_STAT |= V96X_PCI_STAT_T_ABORT;
519 if (_pciverbose >= 1)
520 pci_tagprintf (tag, "pci_conf_read: target abort\r\n");
521 return ~0;
524 return data;
527 pcireg_t
528 pci_conf_read8(pcitag_t tag, int reg)
530 return pci_conf_readn (tag, reg, 1);
533 pcireg_t
534 pci_conf_read16(pcitag_t tag, int reg)
536 return pci_conf_readn (tag, reg, 2);
539 #ifndef pci_conf_read32
540 pcireg_t
541 pci_conf_read32(pcitag_t tag, int reg)
543 return pci_conf_readn (tag, reg, 4);
545 #endif
547 pcireg_t
548 pci_conf_read(pcitag_t tag, int reg)
550 return pci_conf_readn (tag, reg, 4);
553 static void
554 pci_conf_writen(pcitag_t tag, int reg, pcireg_t data, int width)
556 char * const _v96xp = (char *) PHYS_TO_K1(V96XPBC_BASE);
557 uint32_t addr, ad_low;
558 hsaddr_t addrp;
559 int bus, device, function;
561 if (reg & (width-1) || reg < 0 || reg > PCI_REGMAX) {
562 if (_pciverbose >= 1)
563 pci_tagprintf (tag, "pci_conf_read: bad reg %x\r\n", reg);
564 return;
567 pci_break_tag (tag, NULL, &bus, &device, &function);
569 if (bus == 0) {
570 /* Type 0 configuration on onboard PCI bus */
571 if (device > 5 || function > 7)
572 return; /* device out of range */
573 addr = (1 << (device+24)) | (function << 8) | reg;
574 ad_low = 0;
576 else if (v96x_vrev >= V96X_VREV_C0) {
577 /* Type 1 configuration on offboard PCI bus */
578 if (bus > PCI_BUSMAX || device > PCI_DEVMAX || function > PCI_FUNCMAX)
579 return; /* device out of range */
580 addr = (bus << 16) | (device << 11) | (function << 8) | reg;
581 ad_low = V96X_LB_MAPx_AD_LOW_EN;
583 else
584 return; /* bus out of range */
586 /* high 12 bits of address go in map register; set conf space */
587 V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR)
588 | ad_low | V96X_LB_TYPE_CONF;
590 /* clear aborts */
591 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT | V96X_PCI_STAT_T_ABORT;
593 mips_wbflush ();
595 /* low 20 bits of address are in the actual address */
596 addrp = PHYS_TO_K1(PCI_CONF_SPACE + (addr & 0xfffff));
597 switch (width) {
598 case 1:
599 hs_write8(addrp,data);
600 break;
601 case 2:
602 hs_write16(addrp,data);
603 break;
604 default:
605 case 4:
606 hs_write32(addrp,data);
607 break;
610 mips_wbflush ();
612 /* wait for write FIFO to empty */
613 while (V96X_FIFO_STAT & V96X_FIFO_STAT_L2P_WR)
614 continue;
616 if (V96X_PCI_STAT & V96X_PCI_STAT_M_ABORT) {
617 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT;
618 if (_pciverbose >= 1)
619 pci_tagprintf (tag, "pci_conf_write: master abort\r\n");
622 if (V96X_PCI_STAT & V96X_PCI_STAT_T_ABORT) {
623 V96X_PCI_STAT |= V96X_PCI_STAT_T_ABORT;
624 if (_pciverbose >= 1)
625 pci_tagprintf (tag, "pci_conf_write: target abort\r\n");
629 void
630 pci_conf_write8(pcitag_t tag, int reg, pcireg_t data)
632 pci_conf_writen (tag, reg, data, 1);
635 void
636 pci_conf_write16(pcitag_t tag, int reg, pcireg_t data)
638 pci_conf_writen (tag, reg, data, 2);
641 #ifndef pci_conf_write32
642 void
643 pci_conf_write32(pcitag_t tag, int reg, pcireg_t data)
645 pci_conf_writen (tag, reg, data, 4);
647 #endif
649 void
650 pci_conf_write(pcitag_t tag, int reg, pcireg_t data)
652 pci_conf_writen (tag, reg, data, 4);
656 pci_conf_write_acked(pcitag_t tag, int reg, pcireg_t data)
658 pci_conf_write(tag,reg,data);
659 return 1;
666 pci_map_io(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap)
668 pcireg_t address;
669 phys_addr_t pa;
671 if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {
672 if (_pciverbose >= 1)
673 pci_tagprintf(tag, "pci_map_io: bad request\r\n");
674 return -1;
677 address = pci_conf_read(tag, reg);
679 if ((address & PCI_MAPREG_TYPE_IO) == 0) {
680 if (_pciverbose >= 1)
681 pci_tagprintf (tag, "pci_map_io: attempt to i/o map a memory region\r\n");
682 return -1;
685 pa = (address & PCI_MAPREG_IO_ADDR_MASK) - PCI_IO_SPACE_PCI_BASE;
686 pa += PCI_IO_SPACE;
687 *pap = pa;
689 if (_pciverbose >= 3)
690 pci_tagprintf(tag, "pci_map_io: mapping i/o at physical %016llx\n",
691 *pap);
693 return 0;
698 pci_map_mem(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap)
700 pcireg_t address;
701 phys_addr_t pa;
703 if (reg == PCI_MAPREG_ROM) {
704 /* expansion ROM */
705 address = pci_conf_read(tag, reg);
706 if (!(address & PCI_MAPREG_ROM_ENABLE)) {
707 pci_tagprintf (tag, "pci_map_mem: attempt to map missing rom\r\n");
708 return -1;
710 pa = address & PCI_MAPREG_ROM_ADDR_MASK;
711 } else {
712 if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {
713 if (_pciverbose >= 1)
714 pci_tagprintf(tag, "pci_map_mem: bad request\r\n");
715 return -1;
718 address = pci_conf_read(tag, reg);
720 if ((address & PCI_MAPREG_TYPE_IO) != 0) {
721 if (_pciverbose >= 1)
722 pci_tagprintf(tag, "pci_map_mem: attempt to memory map an I/O region\r\n");
723 return -1;
726 switch (address & PCI_MAPREG_MEM_TYPE_MASK) {
727 case PCI_MAPREG_MEM_TYPE_32BIT:
728 case PCI_MAPREG_MEM_TYPE_32BIT_1M:
729 break;
730 case PCI_MAPREG_MEM_TYPE_64BIT:
731 if (_pciverbose >= 1)
732 pci_tagprintf (tag, "pci_map_mem: attempt to map 64-bit region\r\n");
733 return -1;
734 default:
735 if (_pciverbose >= 1)
736 pci_tagprintf (tag, "pci_map_mem: reserved mapping type\r\n");
737 return -1;
739 pa = address & PCI_MAPREG_MEM_ADDR_MASK;
742 pa -= pci_mem_space_pci_base;
743 pa += PCI_MEM_SPACE;
744 *pap = pa;
746 if (_pciverbose >= 3)
747 pci_tagprintf (tag, "pci_map_mem: mapping memory at physical 0x%016llx\r\n",
748 *pap);
749 return 0;
753 /* Algorthmics P5064 PCI mappings.
755 IDSEL (Table 5.8):
756 device IDSEL DevID INT{A,B,C,D}
757 PCI slot 1 29 5 PCIIRQ{2,3,0,1}
758 PCI slot 2 28 4 PCIIRQ{3,0,1,2}
759 PCI slot 3 27 3 PCIIRQ{0,1,2,3}
760 ISA bridge 26 2
761 SCSI ctrl 25 1
762 Enet ctrl 24 0
763 The IDSEL bit to DevID mapping is nonstandard; see pci_conf_readn
764 and pci_conf_writen above.
766 Interrupt Request/Enable (PCIINT at 0x8)
767 7 6 5 4 3 2 1 0
768 pci3 pci2 pci1 pci0 usb scsi eth e_mdint
771 /* The base shift of a slot or device on the motherboard. Only device
772 ids 3, 4 and 5 are implemented as PCI connectors. */
773 uint8_t
774 pci_int_shift_0(pcitag_t tag)
776 int bus, device;
778 pci_break_tag (tag, NULL, &bus, &device, NULL);
780 if (bus != 0)
781 return 0;
783 switch (device) {
784 case 0: case 1: case 2: /* dedicated on-board devices */
785 return 0;
786 case 3: case 4: case 5: /* PCI slots */
787 return ((device - 3) % 4);
788 default:
789 return 0;
793 #define PCI_INTERRUPT_ENET 5
794 #define PCI_INTERRUPT_SCSI 6
795 #define PCI_INTERRUPT_USB 8
797 /* Return the mapping of a P5064 device/function interrupt to an
798 interrupt line. Values 1-4 indicate the PCIIRQ0-3 inputs to the
799 interrupt mapper, respectively, dedicated values as above, or 0 if
800 there is no mapping. This is board specific. */
801 uint8_t
802 pci_int_map_0(pcitag_t tag)
804 pcireg_t data;
805 int pin, bus, device;
807 data = pci_conf_read(tag, PCI_BPARAM_INTERRUPT_REG);
808 pin = PCI_INTERRUPT_PIN(data);
809 if (pin == 0) {
810 /* No IRQ used. */
811 return 0;
813 if (pin > 4) {
814 if (_pciverbose >= 1)
815 pci_tagprintf (tag, "pci_map_int: bad interrupt pin %d\n", pin);
816 return 0;
819 pci_break_tag (tag, NULL, &bus, &device, NULL);
821 if (bus != 0)
822 return 0;
824 switch (device) {
825 case 0:
826 return PCI_INTERRUPT_ENET;
827 case 1:
828 return PCI_INTERRUPT_SCSI;
829 case 2:
830 return PCI_INTERRUPT_USB;
831 case 3: case 4: case 5:
832 return (((pin - 1) + pci_int_shift_0(tag)) % 4) + 1;
833 default:
834 return 0;
838 /* Map PCI interrupts A, B, C, D into a value for the IntLine
839 register. For SB1250, return the source number used by the
840 interrupt mapper, or 0xff if none. */
841 uint8_t
842 pci_int_line(uint8_t pci_int)
844 switch (pci_int) {
845 case PCI_INTERRUPT_ENET:
846 return 0x02;
847 case PCI_INTERRUPT_SCSI:
848 return 0x04;
849 case PCI_INTERRUPT_USB:
850 return 0x08;
851 case 1: case 2: case 3: case 4: /* PCI_INT_A .. PCI_INT_D */
852 return 0x10 << (pci_int - 1);
853 default:
854 return 0;
859 #define ISAPORT_ADDR(port) (PHYS_TO_K1 (ISAPORT_BASE(port)))
862 uint8_t
863 inb (unsigned int port)
865 return hs_read8(ISAPORT_ADDR(port));
868 uint16_t
869 inw (unsigned int port)
871 return hs_read16(ISAPORT_ADDR(port));
874 uint32_t
875 inl (unsigned int port)
877 return hs_read32(ISAPORT_ADDR(port));
880 void
881 outb (unsigned int port, uint8_t val)
883 hs_write8(ISAPORT_ADDR(port),val);
884 mips_wbflush ();
887 void
888 outw (unsigned int port, uint16_t val)
890 hs_write16(ISAPORT_ADDR(port),val);
891 mips_wbflush ();
894 void
895 outl (unsigned int port, uint32_t val)
897 hs_write32(ISAPORT_ADDR(port),val);
898 mips_wbflush ();
903 pci_map_window(phys_addr_t va,
904 unsigned int offset, unsigned int len,
905 int l2ca, int endian)
907 return -1;
911 pci_unmap_window(unsigned int offset, unsigned int len)
913 return -1;