RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / board / p6064 / src / pci_machdep_p6064.c
bloba5e4c7382e35ee5c23b51166b51498e8a9811f6f
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 "cfe_pci.h"
39 #else
40 #include <ametypes.h>
41 #include "mips.h"
42 #endif
44 #include "sbd.h" /* from Algorithmics */
45 #include "v96xpbc.h" /* from Algorithmics */
47 #include "pcivar.h"
48 #include "pcireg.h"
51 typedef long hsaddr_t;
53 #define hs_write8(a,b) *((volatile uint8_t *) (a)) = (b)
54 #define hs_write16(a,b) *((volatile uint16_t *) (a)) = (b)
55 #define hs_write32(a,b) *((volatile uint32_t *) (a)) = (b)
56 #define hs_write64(a,b) *((volatile uint32_t *) (a)) = (b)
57 #define hs_read8(a) *((volatile uint8_t *) (a))
58 #define hs_read16(a) *((volatile uint16_t *) (a))
59 #define hs_read32(a) *((volatile uint32_t *) (a))
60 #define hs_read64(a) *((volatile uint64_t *) (a))
63 #if defined(__MIPSEL)
64 #define V96X_SWAP_MEM V96X_SWAP_NONE
65 #define V96X_SWAP_IO V96X_SWAP_NONE
66 #elif defined(__MIPSEB)
67 #define V96X_SWAP_MEM V96X_SWAP_8BIT
68 #define V96X_SWAP_IO V96X_SWAP_AUTO
69 #else
70 #error "Must specifiy either MIPSEL or MIPSEB"
71 #endif
73 /* PCI i/o regions in PCI space */
74 #define PCI_IO_SPACE_PCI_BASE 0x00000000
76 /* PCI mem regions in PCI space */
77 #define PCI_MEM_SPACE_PCI_BASE 0x00000000
78 #define PCI_LOCAL_MEM_PCI_BASE 0x80000000
79 #define PCI_LOCAL_MEM_ISA_BASE 0x00800000
81 /* soft versions of above */
82 static pcireg_t pci_mem_space_pci_base = PCI_MEM_SPACE_PCI_BASE;
83 static pcireg_t pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;
84 static pcireg_t pci_local_mem_isa_base = PCI_LOCAL_MEM_ISA_BASE;
86 /* PCI mem space allocation (note - skip the 16MB ISA mem space) */
87 const pcireg_t minpcimemaddr = PCI_MEM_SPACE_PCI_BASE + 0x1000000;
88 const pcireg_t maxpcimemaddr = PCI_MEM_SPACE_PCI_BASE + PCI_MEM_SPACE_SIZE;
90 /* PCI i/o space allocation (note - bottom 512KB reserved for ISA i/o space) */
91 /* leave 512K at beginning of PCI i/o space for ISA bridge (it
92 actually uses only 64K, but this is needed for a ISA DMA
93 h/w fix which needs a higher address bit to spot ISA cycles). */
94 //const pcireg_t minpciioaddr = PCI_IO_SPACE_PCI_BASE + 0x80000;
95 //const pcireg_t maxpciioaddr = PCI_IO_SPACE_PCI_BASE + PCI_IO_SPACE_SIZE;
96 const pcireg_t minpciioaddr = PCI_IO_SPACE_PCI_BASE + 0x1000;
97 const pcireg_t maxpciioaddr = PCI_IO_SPACE_PCI_BASE + 0xF000;
99 static const struct pci_bus v96x_pci_bus = {
100 0, /* minimum grant */
101 255, /* maximum latency */
102 0, /* devsel time = fast */
103 1, /* we support fast back-to-back */
104 1, /* we support prefetch */
105 0, /* we don't support 66 MHz */
106 0, /* we don't support 64 bits */
107 4000000, /* bandwidth: in 0.25us cycles / sec */
108 1 /* initially one device on bus (i.e. us) */
111 static const struct pci_bus secondary_pci_bus = {
112 0, /* minimum grant */
113 255, /* maximum latency */
114 0, /* devsel time = fast */
115 0, /* we don't fast back-to-back */
116 0, /* we don't prefetch */
117 0, /* we don't support 66 MHz */
118 0, /* we don't support 64 bits */
119 4000000, /* bandwidth: in 0.25us cycles / sec */
120 0 /* initially no devices on bus */
123 #ifdef _CFE_
124 const cons_t pci_optnames[] = {
125 {"verbose",PCI_FLG_VERBOSE},
126 {NULL,0}};
127 #endif
129 extern int _pciverbose;
132 #define MAXBUS 3
133 const int _pci_maxbus = MAXBUS;
134 struct pci_bus _pci_bus[MAXBUS];
136 static unsigned char v96x_vrev;
138 #define sbddelay(n) ((void)(0))
141 * Called to initialise the host bridge at the beginning of time
144 pci_hwinit (pci_flags_t flags)
146 int initialise = 1;
147 unsigned char * const _v96xp = (unsigned char *) MIPS_PHYS_TO_K1(V96XPBC_BASE);
148 unsigned int pci_rd0, pci_rd1;
149 int i;
151 /* initialise global data */
152 v96x_vrev = V96X_PCI_CC_REV & V96X_PCI_CC_REV_VREV;
153 if (v96x_vrev < V96X_VREV_B2) {
154 printf ("V96 revisions < B.2 not supported\n");
155 return -1;
158 _pci_bus[0] = v96x_pci_bus;
159 _pci_nbus = 1;
160 for (i = _pci_nbus; i < MAXBUS; i++)
161 _pci_bus[i] = secondary_pci_bus;
163 pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;
164 pci_local_mem_isa_base = PCI_LOCAL_MEM_ISA_BASE;
165 pci_mem_space_pci_base = PCI_MEM_SPACE_PCI_BASE;
167 if (!initialise)
168 return 0;
170 /* stop the V3 chip from servicing any further PCI requests */
171 V96X_PCI_CMD = 0;
172 mips_wbflush ();
174 /* reset the PCI bus */
175 V96X_SYSTEM &= ~V96X_SYSTEM_RST_OUT;
177 /* enable bridge to PCI and PCI memory accesses, plus error handling */
178 V96X_PCI_CMD = V96X_PCI_CMD_MASTER_EN
179 | V96X_PCI_CMD_MEM_EN
180 | V96X_PCI_CMD_SERR_EN
181 | V96X_PCI_CMD_PAR_EN;
183 /* clear errors and say we do fast back-to-back transfers */
184 V96X_PCI_STAT = V96X_PCI_STAT_PAR_ERR
185 | V96X_PCI_STAT_SYS_ERR
186 | V96X_PCI_STAT_M_ABORT
187 | V96X_PCI_STAT_T_ABORT
188 | V96X_PCI_STAT_PAR_REP
189 | V96X_PCI_STAT_FAST_BACK;
191 /* Local to PCI aptr 0 - LOCAL:PCI_CONF_SPACE -> PCI:config (1MB) */
192 V96X_LB_BASE0 = PCI_CONF_SPACE | V96X_SWAP_IO | V96X_ADR_SIZE_1MB
193 | V96X_LB_BASEx_ENABLE;
195 V96X_LB_BASE1 = PCI_MEM_SPACE | V96X_SWAP_MEM | V96X_ADR_SIZE_128MB
196 | V96X_LB_BASEx_ENABLE;
197 V96X_LB_MAP1 = (pci_mem_space_pci_base >> 16) | V96X_LB_TYPE_MEM;
199 V96X_LB_BASE2 = (PCI_IO_SPACE >> 16) | (V96X_SWAP_IO >> 2)
200 | V96X_LB_BASEx_ENABLE;
201 V96X_LB_MAP2 = (PCI_IO_SPACE_PCI_BASE >> 16);
203 /* PCI to local aptr 1 - PCI:80000000-90000000 -> LOCAL:00000000 */
204 /* 256MB window for PCI bus masters to get at our local memory */
205 V96X_PCI_BASE1 = pci_local_mem_pci_base | V96X_PCI_BASEx_MEM
206 | V96X_PCI_BASEx_PREFETCH;
207 V96X_PCI_MAP1 = 0x00000000 | V96X_ADR_SIZE_256MB
208 | V96X_SWAP_MEM /*| V96X_PCI_MAPx_RD_POST_INH*/
209 | V96X_PCI_MAPx_REG_EN | V96X_PCI_MAPx_ENABLE;
210 pci_rd1 = (v96x_vrev >= V96X_VREV_C0)
211 ? V96X_FIFO_PRI_FLUSHBURST : V96X_FIFO_PRI_FLUSHALL;
213 /* PCI to local aptr 0 - PCI:00800000-01000000 -> LOCAL:00000000 */
214 /* 8MB window for ISA bus masters to get at our local memory */
215 V96X_PCI_BASE0 = pci_local_mem_isa_base | V96X_PCI_BASEx_MEM
216 | V96X_PCI_BASEx_PREFETCH;
217 V96X_PCI_MAP0 = 0x00000000 | V96X_ADR_SIZE_8MB
218 | V96X_SWAP_MEM /*| V96X_PCI_MAPx_RD_POST_INH*/
219 | V96X_PCI_MAPx_REG_EN | V96X_PCI_MAPx_ENABLE;
220 pci_rd0 = (v96x_vrev >= V96X_VREV_C0)
221 ? V96X_FIFO_PRI_FLUSHBURST : V96X_FIFO_PRI_FLUSHALL;
223 /* PCI to internal registers - disabled (but avoid address overlap) */
224 V96X_PCI_IO_BASE = 0xffffff00 | V96X_PCI_IO_BASE_IO;
226 /* Disable PCI_IO_BASE and set optional AD(1:0) to 01b for type1 config */
227 V96X_PCI_CFG = V96X_PCI_CFG_IO_DIS | (0x1 << V96X_PCI_CFG_AD_LOW_SHIFT);
229 V96X_FIFO_CFG =
230 (V96X_FIFO_CFG_BRST_256 << V96X_FIFO_CFG_PBRST_MAX_SHIFT)
231 | (V96X_FIFO_CFG_WR_ENDBRST << V96X_FIFO_CFG_WR_LB_SHIFT)
232 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_LB1_SHIFT)
233 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_LB0_SHIFT)
234 | (V96X_FIFO_CFG_BRST_16 << V96X_FIFO_CFG_LBRST_MAX_SHIFT)
235 | (V96X_FIFO_CFG_WR_ENDBRST << V96X_FIFO_CFG_WR_PCI_SHIFT)
236 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_PCI1_SHIFT)
237 | (V96X_FIFO_CFG_RD_NOTFULL << V96X_FIFO_CFG_RD_PCI0_SHIFT);
239 /* Set fifo priorities: note that on Rev C.0 and above we set the
240 read prefetch fifos to flush at the end of a burst, and not to
241 retain data like a cache (which causes coherency problems). For
242 Rev B.2 and below we can't do this, so we set them to be
243 flushed by any write cycle (inefficient but safer), and we also
244 require explicit software flushing of the fifos to maintain
245 full coherency (i.e. call pci_flush() from the cache flush
246 routines or after modifying uncached descriptors). */
248 /* initial setting, may be updated in pci_hwreinit(), below */
249 V96X_FIFO_PRIORITY =
250 V96X_FIFO_PRIORITY_LOCAL_WR /* local->pci write priority (safe) */
251 | V96X_FIFO_PRIORITY_PCI_WR /* pci->local write priority (safe) */
252 | (V96X_FIFO_PRI_NOFLUSH << V96X_FIFO_PRIORITY_LB_RD0_SHIFT)
253 | (V96X_FIFO_PRI_NOFLUSH << V96X_FIFO_PRIORITY_LB_RD1_SHIFT)
254 | (pci_rd0 << V96X_FIFO_PRIORITY_PCI_RD0_SHIFT)
255 | (pci_rd1 << V96X_FIFO_PRIORITY_PCI_RD1_SHIFT);
258 /* clear latched PCI interrupts */
259 V96X_LB_ISTAT = 0;
261 /* enable V3 general interrupts */
262 V96X_LB_IMASK = V96X_LB_INTR_PCI_RD|V96X_LB_INTR_PCI_WR;
264 /* finally unreset the PCI bus */
265 V96X_SYSTEM |= V96X_SYSTEM_RST_OUT;
267 /* ... and the onboard PCI devices */
269 volatile p5064bcr1 * const bcr1 = (p5064bcr1 *) MIPS_PHYS_TO_K1(BCR1_BASE);
270 bcr1->eth = BCR1_ENABLE;
271 bcr1->scsi = BCR1_ENABLE;
272 bcr1->isa = BCR1_ENABLE;
273 bcr1->pcmcia = BCR1_ENABLE;
274 sbddelay (1);
277 return 1;
282 * Called to reinitialise the bridge after we've scanned each PCI device
283 * and know what is possible.
285 void
286 pci_hwreinit (pci_flags_t flags)
288 char * const _v96xp = (char *) MIPS_PHYS_TO_K1(V96XPBC_BASE);
290 if (_pci_bus[0].fast_b2b)
291 /* fast back-to-back is supported by all devices */
292 V96X_PCI_CMD |= V96X_PCI_CMD_FBB_EN;
294 /* Rev B.1+: can now use variable latency timer */
295 V96X_PCI_HDR_CFG = _pci_bus[0].def_ltim << V96X_PCI_HDR_CFG_LT_SHIFT;
297 if (_pci_bus[0].prefetch && v96x_vrev >= V96X_VREV_C0) {
298 /* Rev C.0+: we can safely prefetch from all pci mem devices */
299 V96X_LB_BASE1 |= V96X_LB_BASEx_PREFETCH;
300 V96X_FIFO_PRIORITY = (V96X_FIFO_PRIORITY & ~V96X_FIFO_PRIORITY_LB_RD1)
301 | (V96X_FIFO_PRI_FLUSHBURST << V96X_FIFO_PRIORITY_LB_RD1_SHIFT);
304 /* clear latched PCI interrupts */
305 V96X_LB_ISTAT = 0;
307 /* enable PCI read/write error interrupts */
308 V96X_LB_IMASK = V96X_LB_INTR_PCI_RD | V96X_LB_INTR_PCI_WR;
312 /* Called for each bridge after configuring the secondary bus, to allow
313 device-specific initialization. */
314 void
315 pci_bridge_setup (pcitag_t tag, pci_flags_t flags)
317 /* nothing to do */
320 void
321 pci_flush (void)
323 /* flush read-ahead fifos (not necessary on Rev C.0 and above) */
324 if (v96x_vrev < V96X_VREV_C0) {
325 char * const _v96xp = (char *) MIPS_PHYS_TO_K1(V96XPBC_BASE);
326 V96X_SYSTEM |=
327 V96X_SYSTEM_LB_RD_PCI1 | V96X_SYSTEM_LB_RD_PCI0 |
328 V96X_SYSTEM_PCI_RD_LB1 | V96X_SYSTEM_PCI_RD_LB0;
333 /* Map the CPU virtual address of an area of local memory to a PCI
334 address that can be used by a PCI bus master to access it. */
335 pci_addr_t
336 pci_dmamap (v_addr_t va, unsigned int len)
338 return pci_local_mem_pci_base + MIPS_K1_TO_PHYS(va);
341 /* Map the PCI address of an area of local memory to a CPU physical
342 address. */
343 phys_addr_t
344 pci_cpumap (pci_addr_t pcia, unsigned int len)
346 return pcia - pci_local_mem_pci_base;
350 /* Map an ISA address to the corresponding CPU physical address */
351 phys_addr_t
352 cpu_isamap(pci_addr_t isaaddr,unsigned int len)
354 return PCI_MEM_SPACE + isaaddr;
357 /* Map the CPU virtual address of an area of local memory to an ISA
358 address that can be used by a ISA bus master to access it. */
359 pci_addr_t
360 isa_dmamap (v_addr_t va, unsigned int len)
362 unsigned long pa = MIPS_K1_TO_PHYS (va);
364 /* restrict ISA DMA access to bottom 8/16MB of local memory */
365 if (pa + len > 0x1000000 - pci_local_mem_isa_base)
366 return (phys_addr_t)0xffffffff;
367 return pci_local_mem_isa_base + pa;
370 /* Map the ISA address of an area of local memory to a CPU physical
371 address. */
372 phys_addr_t
373 isa_cpumap (pci_addr_t pcia, unsigned int len)
375 return pcia - pci_local_mem_isa_base;
379 pcitag_t
380 pci_make_tag(int bus, int device, int function)
382 pcitag_t tag;
383 tag = (bus << 16) | (device << 11) | (function << 8);
384 return tag;
387 void
388 pci_break_tag(pcitag_t tag, int *busp, int *devicep, int *functionp)
390 if (busp) *busp = (tag >> 16) & PCI_BUSMAX;
391 if (devicep) *devicep = (tag >> 11) & PCI_DEVMAX;
392 if (functionp) *functionp = (tag >> 8) & PCI_FUNCMAX;
396 pci_canscan (pcitag_t tag)
398 return 1;
402 pci_probe_tag(pcitag_t tag)
404 pcireg_t data;
406 if (!pci_canscan(tag))
407 return 0;
409 data = pci_conf_read(tag,PCI_ID_REG);
411 mips_wbflush ();
413 if ((data == 0) || (data == 0xffffffff)) return 0;
415 return 1;
418 void
419 pci_device_preset (pcitag_t tag)
421 /* Nothing to do for now. */
423 void
424 pci_device_setup (pcitag_t tag)
426 /* Nothing to do for now. */
430 /* Read/write access to PCI configuration registers. For most
431 applications, pci_conf_read<N> and pci_conf_write<N> are deprecated
432 unless N = 32. */
434 static pcireg_t
435 pci_conf_readn(pcitag_t tag, int reg, int width)
437 char * const _v96xp = (char *) MIPS_PHYS_TO_K1(V96XPBC_BASE);
438 uint32_t addr, ad_low;
439 hsaddr_t addrp;
441 pcireg_t data;
442 int bus, device, function;
444 if (reg & (width-1) || reg < 0 || reg >= PCI_REGMAX) {
445 if (_pciverbose >= 1)
446 pci_tagprintf (tag, "pci_conf_readn: bad reg 0x%x\r\n", reg);
447 return ~0;
450 pci_break_tag (tag, &bus, &device, &function);
451 if (bus == 0) {
452 /* Type 0 configuration on onboard PCI bus */
453 if (device > 5 || function > 7)
454 return ~0; /* device out of range */
455 addr = (1 << (device+24)) | (function << 8) | reg;
456 ad_low = 0;
457 } else if (v96x_vrev >= V96X_VREV_C0) {
458 /* Type 1 configuration on offboard PCI bus */
459 if (bus > PCI_BUSMAX || device > PCI_DEVMAX || function > PCI_FUNCMAX)
460 return ~0; /* device out of range */
461 addr = (bus << 16) | (device << 11) | (function << 8) | reg;
462 ad_low = V96X_LB_MAPx_AD_LOW_EN;
463 } else {
464 return ~0; /* bus out of range */
467 /* high 12 bits of address go in map register; set conf space */
468 V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR)
469 | ad_low | V96X_LB_TYPE_CONF;
471 /* clear aborts */
472 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT | V96X_PCI_STAT_T_ABORT;
474 mips_wbflush ();
476 /* low 20 bits of address are in the actual address */
477 addrp = MIPS_PHYS_TO_K1(PCI_CONF_SPACE + (addr & 0xfffff));
478 switch (width) {
479 case 1:
480 data = (pcireg_t)hs_read8(addrp);
481 break;
482 case 2:
483 data = (pcireg_t)hs_read16(addrp);
484 break;
485 default:
486 case 4:
487 data = (pcireg_t)hs_read32(addrp);
488 break;
491 if (V96X_PCI_STAT & V96X_PCI_STAT_M_ABORT) {
492 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT;
493 return ~0;
496 if (V96X_PCI_STAT & V96X_PCI_STAT_T_ABORT) {
497 V96X_PCI_STAT |= V96X_PCI_STAT_T_ABORT;
498 if (_pciverbose >= 1)
499 pci_tagprintf (tag, "pci_conf_read: target abort\r\n");
500 return ~0;
503 return data;
506 pcireg_t
507 pci_conf_read8(pcitag_t tag, int reg)
509 return pci_conf_readn (tag, reg, 1);
512 pcireg_t
513 pci_conf_read16(pcitag_t tag, int reg)
515 return pci_conf_readn (tag, reg, 2);
518 #ifndef pci_conf_read32
519 pcireg_t
520 pci_conf_read32(pcitag_t tag, int reg)
522 return pci_conf_readn (tag, reg, 4);
524 #endif
526 pcireg_t
527 pci_conf_read(pcitag_t tag, int reg)
529 return pci_conf_readn (tag, reg, 4);
532 static void
533 pci_conf_writen(pcitag_t tag, int reg, pcireg_t data, int width)
535 char * const _v96xp = (char *) MIPS_PHYS_TO_K1(V96XPBC_BASE);
536 uint32_t addr, ad_low;
537 hsaddr_t addrp;
538 int bus, device, function;
540 if (reg & (width-1) || reg < 0 || reg > PCI_REGMAX) {
541 if (_pciverbose >= 1)
542 pci_tagprintf (tag, "pci_conf_read: bad reg %x\r\n", reg);
543 return;
546 pci_break_tag (tag, &bus, &device, &function);
548 if (bus == 0) {
549 /* Type 0 configuration on onboard PCI bus */
550 if (device > 5 || function > 7)
551 return; /* device out of range */
552 addr = (1 << (device+24)) | (function << 8) | reg;
553 ad_low = 0;
555 else if (v96x_vrev >= V96X_VREV_C0) {
556 /* Type 1 configuration on offboard PCI bus */
557 if (bus > PCI_BUSMAX || device > PCI_DEVMAX || function > PCI_FUNCMAX)
558 return; /* device out of range */
559 addr = (bus << 16) | (device << 11) | (function << 8) | reg;
560 ad_low = V96X_LB_MAPx_AD_LOW_EN;
562 else
563 return; /* bus out of range */
565 /* high 12 bits of address go in map register; set conf space */
566 V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR)
567 | ad_low | V96X_LB_TYPE_CONF;
569 /* clear aborts */
570 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT | V96X_PCI_STAT_T_ABORT;
572 mips_wbflush ();
574 /* low 20 bits of address are in the actual address */
575 addrp = MIPS_PHYS_TO_K1(PCI_CONF_SPACE + (addr & 0xfffff));
576 switch (width) {
577 case 1:
578 hs_write8(addrp,data);
579 break;
580 case 2:
581 hs_write16(addrp,data);
582 break;
583 default:
584 case 4:
585 hs_write32(addrp,data);
586 break;
589 mips_wbflush ();
591 /* wait for write FIFO to empty */
592 while (V96X_FIFO_STAT & V96X_FIFO_STAT_L2P_WR)
593 continue;
595 if (V96X_PCI_STAT & V96X_PCI_STAT_M_ABORT) {
596 V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT;
597 if (_pciverbose >= 1)
598 pci_tagprintf (tag, "pci_conf_write: master abort\r\n");
601 if (V96X_PCI_STAT & V96X_PCI_STAT_T_ABORT) {
602 V96X_PCI_STAT |= V96X_PCI_STAT_T_ABORT;
603 if (_pciverbose >= 1)
604 pci_tagprintf (tag, "pci_conf_write: target abort\r\n");
608 void
609 pci_conf_write8(pcitag_t tag, int reg, pcireg_t data)
611 pci_conf_writen (tag, reg, data, 1);
614 void
615 pci_conf_write16(pcitag_t tag, int reg, pcireg_t data)
617 pci_conf_writen (tag, reg, data, 2);
620 #ifndef pci_conf_write32
621 void
622 pci_conf_write32(pcitag_t tag, int reg, pcireg_t data)
624 pci_conf_writen (tag, reg, data, 4);
626 #endif
628 void
629 pci_conf_write(pcitag_t tag, int reg, pcireg_t data)
631 pci_conf_writen (tag, reg, data, 4);
639 pci_map_io(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap)
641 pcireg_t address;
642 phys_addr_t pa;
644 if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {
645 if (_pciverbose >= 1)
646 pci_tagprintf(tag, "pci_map_io: bad request\r\n");
647 return -1;
650 address = pci_conf_read(tag, reg);
652 if ((address & PCI_MAPREG_TYPE_IO) == 0) {
653 if (_pciverbose >= 1)
654 pci_tagprintf (tag, "pci_map_io: attempt to i/o map a memory region\r\n");
655 return -1;
658 pa = (address & PCI_MAPREG_IO_ADDR_MASK) - PCI_IO_SPACE_PCI_BASE;
659 pa += PCI_IO_SPACE;
660 *pap = pa;
662 if (_pciverbose >= 3)
663 pci_tagprintf(tag, "pci_map_io: mapping i/o at physical %016llx\n",
664 *pap);
666 return 0;
671 pci_map_mem(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap)
673 pcireg_t address;
674 phys_addr_t pa;
676 if (reg == PCI_MAPREG_ROM) {
677 /* expansion ROM */
678 address = pci_conf_read(tag, reg);
679 if (!(address & PCI_MAPREG_ROM_ENABLE)) {
680 pci_tagprintf (tag, "pci_map_mem: attempt to map missing rom\r\n");
681 return -1;
683 pa = address & PCI_MAPREG_ROM_ADDR_MASK;
684 } else {
685 if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {
686 if (_pciverbose >= 1)
687 pci_tagprintf(tag, "pci_map_mem: bad request\r\n");
688 return -1;
691 address = pci_conf_read(tag, reg);
693 if ((address & PCI_MAPREG_TYPE_IO) != 0) {
694 if (_pciverbose >= 1)
695 pci_tagprintf(tag, "pci_map_mem: attempt to memory map an I/O region\r\n");
696 return -1;
699 switch (address & PCI_MAPREG_MEM_TYPE_MASK) {
700 case PCI_MAPREG_MEM_TYPE_32BIT:
701 case PCI_MAPREG_MEM_TYPE_32BIT_1M:
702 break;
703 case PCI_MAPREG_MEM_TYPE_64BIT:
704 if (_pciverbose >= 1)
705 pci_tagprintf (tag, "pci_map_mem: attempt to map 64-bit region\r\n");
706 return -1;
707 default:
708 if (_pciverbose >= 1)
709 pci_tagprintf (tag, "pci_map_mem: reserved mapping type\r\n");
710 return -1;
712 pa = address & PCI_MAPREG_MEM_ADDR_MASK;
715 pa -= pci_mem_space_pci_base;
716 pa += PCI_MEM_SPACE;
717 *pap = pa;
719 if (_pciverbose >= 3)
720 pci_tagprintf (tag, "pci_map_mem: mapping memory at physical 0x%016llx\r\n",
721 *pap);
722 return 0;
726 /* Algorthmics P5064 PCI mappings.
728 IDSEL (Table 5.8):
729 device IDSEL DevID INT{A,B,C,D}
730 PCI slot 1 29 5 PCIIRQ{2,3,0,1}
731 PCI slot 2 28 4 PCIIRQ{3,0,1,2}
732 PCI slot 3 27 3 PCIIRQ{0,1,2,3}
733 ISA bridge 26 2
734 SCSI ctrl 25 1
735 Enet ctrl 24 0
736 The IDSEL bit to DevID mapping is nonstandard; see pci_conf_readn
737 and pci_conf_writen above.
739 Interrupt Request/Enable (PCIINT at 0x8)
740 7 6 5 4 3 2 1 0
741 pci3 pci2 pci1 pci0 usb scsi eth e_mdint
744 /* The base shift of a slot or device on the motherboard. Only device
745 ids 3, 4 and 5 are implemented as PCI connectors. */
746 uint8_t
747 pci_int_shift_0(pcitag_t tag)
749 int bus, device;
751 pci_break_tag (tag, &bus, &device, NULL);
753 if (bus != 0)
754 return 0;
756 switch (device) {
757 case 0: case 1: case 2: /* dedicated on-board devices */
758 return 0;
759 case 3: case 4: case 5: /* PCI slots */
760 return ((device - 3) % 4);
761 default:
762 return 0;
766 #define PCI_INTERRUPT_ENET 5
767 #define PCI_INTERRUPT_SCSI 6
768 #define PCI_INTERRUPT_USB 8
770 /* Return the mapping of a P5064 device/function interrupt to an
771 interrupt line. Values 1-4 indicate the PCIIRQ0-3 inputs to the
772 interrupt mapper, respectively, dedicated values as above, or 0 if
773 there is no mapping. This is board specific. */
774 uint8_t
775 pci_int_map_0(pcitag_t tag)
777 pcireg_t data;
778 int pin, bus, device;
780 data = pci_conf_read(tag, PCI_BPARAM_INTERRUPT_REG);
781 pin = PCI_INTERRUPT_PIN(data);
782 if (pin == 0) {
783 /* No IRQ used. */
784 return 0;
786 if (pin > 4) {
787 if (_pciverbose >= 1)
788 pci_tagprintf (tag, "pci_map_int: bad interrupt pin %d\n", pin);
789 return 0;
792 pci_break_tag (tag, &bus, &device, NULL);
794 if (bus != 0)
795 return 0;
797 switch (device) {
798 case 0:
799 return PCI_INTERRUPT_ENET;
800 case 1:
801 return PCI_INTERRUPT_SCSI;
802 case 2:
803 return PCI_INTERRUPT_USB;
804 case 3: case 4: case 5:
805 return (((pin - 1) + pci_int_shift_0(tag)) % 4) + 1;
806 default:
807 return 0;
811 /* Map PCI interrupts A, B, C, D into a value for the IntLine
812 register. For SB1250, return the source number used by the
813 interrupt mapper, or 0xff if none. */
814 uint8_t
815 pci_int_line(uint8_t pci_int)
817 switch (pci_int) {
818 case PCI_INTERRUPT_ENET:
819 return 0x02;
820 case PCI_INTERRUPT_SCSI:
821 return 0x04;
822 case PCI_INTERRUPT_USB:
823 return 0x08;
824 case 1: case 2: case 3: case 4: /* PCI_INT_A .. PCI_INT_D */
825 return 0x10 << (pci_int - 1);
826 default:
827 return 0;
832 #define ISAPORT_ADDR(port) (MIPS_PHYS_TO_K1 (ISAPORT_BASE(port)))
834 uint64_t
835 iodev_map (unsigned int port)
837 return ISAPORT_ADDR(port);
840 uint8_t
841 inb (unsigned int port)
843 return hs_read8(ISAPORT_ADDR(port));
846 uint16_t
847 inw (unsigned int port)
849 return hs_read16(ISAPORT_ADDR(port));
852 uint32_t
853 inl (unsigned int port)
855 return hs_read32(ISAPORT_ADDR(port));
858 void
859 outb (unsigned int port, uint8_t val)
861 hs_write8(ISAPORT_ADDR(port),val);
862 mips_wbflush ();
865 void
866 outw (unsigned int port, uint16_t val)
868 hs_write16(ISAPORT_ADDR(port),val);
869 mips_wbflush ();
872 void
873 outl (unsigned int port, uint32_t val)
875 hs_write32(ISAPORT_ADDR(port),val);
876 mips_wbflush ();
881 pci_map_window(phys_addr_t va,
882 unsigned int offset, unsigned int len,
883 int l2ca, int endian)
885 return -1;
889 pci_unmap_window(unsigned int offset, unsigned int len)
891 return -1;