1 /* Very loosely based on: */
2 /* $NetBSD: pci_machdep.c,v 1.17 1995/07/27 21:39:59 cgd Exp $ */
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
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.
44 #include "sbd.h" /* from Algorithmics */
45 #include "v96xpbc.h" /* from Algorithmics */
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))
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
70 #error "Must specifiy either MIPSEL or MIPSEB"
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 */
124 const cons_t pci_optnames
[] = {
125 {"verbose",PCI_FLG_VERBOSE
},
129 extern int _pciverbose
;
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
)
147 unsigned char * const _v96xp
= (unsigned char *) MIPS_PHYS_TO_K1(V96XPBC_BASE
);
148 unsigned int pci_rd0
, pci_rd1
;
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");
158 _pci_bus
[0] = v96x_pci_bus
;
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
;
170 /* stop the V3 chip from servicing any further PCI requests */
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
);
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 */
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 */
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
;
282 * Called to reinitialise the bridge after we've scanned each PCI device
283 * and know what is possible.
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 */
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. */
315 pci_bridge_setup (pcitag_t tag
, pci_flags_t flags
)
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
);
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. */
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
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 */
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. */
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
373 isa_cpumap (pci_addr_t pcia
, unsigned int len
)
375 return pcia
- pci_local_mem_isa_base
;
380 pci_make_tag(int bus
, int device
, int function
)
383 tag
= (bus
<< 16) | (device
<< 11) | (function
<< 8);
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
)
402 pci_probe_tag(pcitag_t tag
)
406 if (!pci_canscan(tag
))
409 data
= pci_conf_read(tag
,PCI_ID_REG
);
413 if ((data
== 0) || (data
== 0xffffffff)) return 0;
419 pci_device_preset (pcitag_t tag
)
421 /* Nothing to do for now. */
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
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
;
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
);
450 pci_break_tag (tag
, &bus
, &device
, &function
);
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
;
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
;
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
;
472 V96X_PCI_STAT
|= V96X_PCI_STAT_M_ABORT
| V96X_PCI_STAT_T_ABORT
;
476 /* low 20 bits of address are in the actual address */
477 addrp
= MIPS_PHYS_TO_K1(PCI_CONF_SPACE
+ (addr
& 0xfffff));
480 data
= (pcireg_t
)hs_read8(addrp
);
483 data
= (pcireg_t
)hs_read16(addrp
);
487 data
= (pcireg_t
)hs_read32(addrp
);
491 if (V96X_PCI_STAT
& V96X_PCI_STAT_M_ABORT
) {
492 V96X_PCI_STAT
|= V96X_PCI_STAT_M_ABORT
;
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");
507 pci_conf_read8(pcitag_t tag
, int reg
)
509 return pci_conf_readn (tag
, reg
, 1);
513 pci_conf_read16(pcitag_t tag
, int reg
)
515 return pci_conf_readn (tag
, reg
, 2);
518 #ifndef pci_conf_read32
520 pci_conf_read32(pcitag_t tag
, int reg
)
522 return pci_conf_readn (tag
, reg
, 4);
527 pci_conf_read(pcitag_t tag
, int reg
)
529 return pci_conf_readn (tag
, reg
, 4);
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
;
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
);
546 pci_break_tag (tag
, &bus
, &device
, &function
);
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
;
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
;
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
;
570 V96X_PCI_STAT
|= V96X_PCI_STAT_M_ABORT
| V96X_PCI_STAT_T_ABORT
;
574 /* low 20 bits of address are in the actual address */
575 addrp
= MIPS_PHYS_TO_K1(PCI_CONF_SPACE
+ (addr
& 0xfffff));
578 hs_write8(addrp
,data
);
581 hs_write16(addrp
,data
);
585 hs_write32(addrp
,data
);
591 /* wait for write FIFO to empty */
592 while (V96X_FIFO_STAT
& V96X_FIFO_STAT_L2P_WR
)
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");
609 pci_conf_write8(pcitag_t tag
, int reg
, pcireg_t data
)
611 pci_conf_writen (tag
, reg
, data
, 1);
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
622 pci_conf_write32(pcitag_t tag
, int reg
, pcireg_t data
)
624 pci_conf_writen (tag
, reg
, data
, 4);
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
)
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");
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");
658 pa
= (address
& PCI_MAPREG_IO_ADDR_MASK
) - PCI_IO_SPACE_PCI_BASE
;
662 if (_pciverbose
>= 3)
663 pci_tagprintf(tag
, "pci_map_io: mapping i/o at physical %016llx\n",
671 pci_map_mem(pcitag_t tag
, int reg
, pci_endian_t endian
, phys_addr_t
*pap
)
676 if (reg
== PCI_MAPREG_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");
683 pa
= address
& PCI_MAPREG_ROM_ADDR_MASK
;
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");
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");
699 switch (address
& PCI_MAPREG_MEM_TYPE_MASK
) {
700 case PCI_MAPREG_MEM_TYPE_32BIT
:
701 case PCI_MAPREG_MEM_TYPE_32BIT_1M
:
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");
708 if (_pciverbose
>= 1)
709 pci_tagprintf (tag
, "pci_map_mem: reserved mapping type\r\n");
712 pa
= address
& PCI_MAPREG_MEM_ADDR_MASK
;
715 pa
-= pci_mem_space_pci_base
;
719 if (_pciverbose
>= 3)
720 pci_tagprintf (tag
, "pci_map_mem: mapping memory at physical 0x%016llx\r\n",
726 /* Algorthmics P5064 PCI mappings.
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}
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)
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. */
747 pci_int_shift_0(pcitag_t tag
)
751 pci_break_tag (tag
, &bus
, &device
, NULL
);
757 case 0: case 1: case 2: /* dedicated on-board devices */
759 case 3: case 4: case 5: /* PCI slots */
760 return ((device
- 3) % 4);
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. */
775 pci_int_map_0(pcitag_t tag
)
778 int pin
, bus
, device
;
780 data
= pci_conf_read(tag
, PCI_BPARAM_INTERRUPT_REG
);
781 pin
= PCI_INTERRUPT_PIN(data
);
787 if (_pciverbose
>= 1)
788 pci_tagprintf (tag
, "pci_map_int: bad interrupt pin %d\n", pin
);
792 pci_break_tag (tag
, &bus
, &device
, NULL
);
799 return PCI_INTERRUPT_ENET
;
801 return PCI_INTERRUPT_SCSI
;
803 return PCI_INTERRUPT_USB
;
804 case 3: case 4: case 5:
805 return (((pin
- 1) + pci_int_shift_0(tag
)) % 4) + 1;
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. */
815 pci_int_line(uint8_t pci_int
)
818 case PCI_INTERRUPT_ENET
:
820 case PCI_INTERRUPT_SCSI
:
822 case PCI_INTERRUPT_USB
:
824 case 1: case 2: case 3: case 4: /* PCI_INT_A .. PCI_INT_D */
825 return 0x10 << (pci_int
- 1);
832 #define ISAPORT_ADDR(port) (MIPS_PHYS_TO_K1 (ISAPORT_BASE(port)))
835 iodev_map (unsigned int port
)
837 return ISAPORT_ADDR(port
);
841 inb (unsigned int port
)
843 return hs_read8(ISAPORT_ADDR(port
));
847 inw (unsigned int port
)
849 return hs_read16(ISAPORT_ADDR(port
));
853 inl (unsigned int port
)
855 return hs_read32(ISAPORT_ADDR(port
));
859 outb (unsigned int port
, uint8_t val
)
861 hs_write8(ISAPORT_ADDR(port
),val
);
866 outw (unsigned int port
, uint16_t val
)
868 hs_write16(ISAPORT_ADDR(port
),val
);
873 outl (unsigned int port
, uint32_t val
)
875 hs_write32(ISAPORT_ADDR(port
),val
);
881 pci_map_window(phys_addr_t va
,
882 unsigned int offset
, unsigned int len
,
883 int l2ca
, int endian
)
889 pci_unmap_window(unsigned int offset
, unsigned int len
)