1 /* $NetBSD: pci_machdep.c,v 1.46 2009/03/14 21:04:06 dsl Exp $ */
4 * Copyright (c) 1996 Leo Weppelman. All rights reserved.
5 * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
6 * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Charles M. Hannum.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.46 2009/03/14 21:04:06 dsl Exp $");
37 #include "opt_mbtype.h"
39 #include <sys/types.h>
40 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/errno.h>
44 #include <sys/device.h>
45 #include <sys/malloc.h>
47 #define _ATARI_BUS_DMA_PRIVATE
48 #include <machine/bus.h>
50 #include <dev/pci/pcivar.h>
51 #include <dev/pci/pcireg.h>
53 #include <uvm/uvm_extern.h>
55 #include <machine/cpu.h>
56 #include <machine/iomap.h>
57 #include <machine/mfp.h>
59 #include <atari/atari/device.h>
60 #include <atari/pci/pci_vga.h>
63 * Sizes of pci memory and I/O area.
65 #define PCI_MEM_END 0x10000000 /* 256 MByte */
66 #define PCI_IO_END 0x10000000 /* 256 MByte */
69 * We preserve some space at the begin of the pci area for 32BIT_1M
70 * devices and standard vga.
72 #define PCI_MEM_START 0x00100000 /* 1 MByte */
73 #define PCI_IO_START 0x00004000 /* 16 kByte (some PCI cards allow only
74 I/O addresses up to 0xffff) */
77 * PCI memory and IO should be aligned acording to this masks
79 #define PCI_MACHDEP_IO_ALIGN_MASK 0xffffff00
80 #define PCI_MACHDEP_MEM_ALIGN_MASK 0xfffff000
83 * Convert a PCI 'device' number to a slot number.
85 #define DEV2SLOT(dev) (3 - dev)
88 * Struct to hold the memory and I/O datas of the pci devices
91 LIST_ENTRY(pci_memreg
) link
;
94 pcireg_t reg
, address
, mask
;
99 typedef LIST_HEAD(pci_memreg_head
, pci_memreg
) PCI_MEMREG
;
102 * Entry points for PCI DMA. Use only the 'standard' functions.
104 int _bus_dmamap_create(bus_dma_tag_t
, bus_size_t
, int, bus_size_t
,
105 bus_size_t
, int, bus_dmamap_t
*);
106 struct atari_bus_dma_tag pci_bus_dma_tag
= {
108 #if defined(_ATARIHW_)
109 0x80000000, /* On the Hades, CPU memory starts here PCI-wise */
116 _bus_dmamap_load_mbuf
,
117 _bus_dmamap_load_uio
,
118 _bus_dmamap_load_raw
,
123 int ataripcibusprint(void *auxp
, const char *);
124 int pcibusmatch(struct device
*, struct cfdata
*, void *);
125 void pcibusattach(struct device
*, struct device
*, void *);
127 static void enable_pci_devices(void);
128 static void insert_into_list(PCI_MEMREG
*head
, struct pci_memreg
*elem
);
129 static int overlap_pci_areas(struct pci_memreg
*p
,
130 struct pci_memreg
*self
, u_int addr
, u_int size
, u_int what
);
132 CFATTACH_DECL(pcib
, sizeof(struct device
),
133 pcibusmatch
, pcibusattach
, NULL
, NULL
);
136 * We need some static storage to probe pci-busses for VGA cards during
137 * early console init.
139 static struct atari_bus_space bs_storage
[2]; /* 1 iot, 1 memt */
142 pcibusmatch(struct device
*pdp
, struct cfdata
*cfp
, void *auxp
)
144 static int nmatched
= 0;
146 if (strcmp((char *)auxp
, "pcib"))
147 return (0); /* Wrong number... */
149 if(atari_realconfig
== 0)
152 if (machineid
& (ATARI_HADES
|ATARI_MILAN
)) {
154 * Both Hades and Milan have only one pci bus
165 pcibusattach(struct device
*pdp
, struct device
*dp
, void *auxp
)
167 struct pcibus_attach_args pba
;
171 pba
.pba_bridgetag
= NULL
;
172 pba
.pba_flags
= PCI_FLAGS_IO_ENABLED
| PCI_FLAGS_MEM_ENABLED
;
173 pba
.pba_dmat
= &pci_bus_dma_tag
;
174 pba
.pba_iot
= leb_alloc_bus_space_tag(&bs_storage
[0]);
175 pba
.pba_memt
= leb_alloc_bus_space_tag(&bs_storage
[1]);
176 if ((pba
.pba_iot
== NULL
) || (pba
.pba_memt
== NULL
)) {
177 printf("leb_alloc_bus_space_tag failed!\n");
180 pba
.pba_iot
->base
= PCI_IO_PHYS
;
181 pba
.pba_memt
->base
= PCI_MEM_PHYS
;
185 * Scan the bus for a VGA-card that we support. If we
186 * find one, try to initialize it to a 'standard' text
189 check_for_vga(pba
.pba_iot
, pba
.pba_memt
);
193 enable_pci_devices();
195 #if defined(_ATARIHW_)
196 MFP2
->mf_aer
&= ~(0x27); /* PCI interrupts: HIGH -> LOW */
201 config_found_ia(dp
, "pcibus", &pba
, ataripcibusprint
);
205 ataripcibusprint(void *auxp
, const char *name
)
213 pci_attach_hook(struct device
*parent
, struct device
*self
, struct pcibus_attach_args
*pba
)
218 * Initialize the PCI-bus. The Atari-BIOS does not do this, so....
219 * We only disable all devices here. Memory and I/O enabling is done
220 * later at pcibusattach.
225 pci_chipset_tag_t pc
= NULL
; /* XXX */
228 int device
, id
, maxndevs
;
233 maxndevs
= pci_bus_maxdevs(pc
, 0);
235 for (device
= 0; device
< maxndevs
; device
++) {
237 tag
= pci_make_tag(pc
, 0, device
, 0);
238 id
= pci_conf_read(pc
, tag
, PCI_ID_REG
);
239 if (id
== 0 || id
== 0xffffffff)
242 csr
= pci_conf_read(pc
, tag
, PCI_COMMAND_STATUS_REG
);
243 csr
&= ~(PCI_COMMAND_MEM_ENABLE
|PCI_COMMAND_IO_ENABLE
);
244 csr
&= ~PCI_COMMAND_MASTER_ENABLE
;
245 pci_conf_write(pc
, tag
, PCI_COMMAND_STATUS_REG
, csr
);
250 * insert a new element in an existing list that the ID's (size in struct
251 * pci_memreg) are sorted.
254 insert_into_list(PCI_MEMREG
*head
, struct pci_memreg
*elem
)
256 struct pci_memreg
*p
, *q
;
258 p
= LIST_FIRST(head
);
261 for (; p
!= NULL
&& p
->size
< elem
->size
; q
= p
, p
= LIST_NEXT(p
, link
));
264 LIST_INSERT_HEAD(head
, elem
, link
);
266 LIST_INSERT_AFTER(q
, elem
, link
);
271 * Test if a new selected area overlaps with an already (probably preselected)
275 overlap_pci_areas(struct pci_memreg
*p
, struct pci_memreg
*self
, u_int addr
, u_int size
, u_int what
)
277 struct pci_memreg
*q
;
284 if ((q
!= self
) && (q
->csr
& what
)) {
285 if ((addr
>= q
->address
) && (addr
< (q
->address
+ q
->size
))) {
286 #ifdef DEBUG_PCI_MACHDEP
287 printf("\noverlap area dev %d reg 0x%02x with dev %d reg 0x%02x",
288 self
->dev
, self
->reg
, q
->dev
, q
->reg
);
292 if ((q
->address
>= addr
) && (q
->address
< (addr
+ size
))) {
293 #ifdef DEBUG_PCI_MACHDEP
294 printf("\noverlap area dev %d reg 0x%02x with dev %d reg 0x%02x",
295 self
->dev
, self
->reg
, q
->dev
, q
->reg
);
300 q
= LIST_NEXT(q
, link
);
306 * Enable memory and I/O on pci devices. Care about already enabled devices
307 * (probabaly by the console driver).
309 * The idea behind the following code is:
310 * We build a by sizes sorted list of the requirements of the different
311 * pci devices. After that we choose the start addresses of that areas
312 * in such a way that they are placed as closed as possible together.
315 enable_pci_devices(void)
319 struct pci_memreg
*p
, *q
;
320 int dev
, reg
, id
, class;
322 pcireg_t csr
, address
, mask
;
323 pci_chipset_tag_t pc
;
324 int sizecnt
, membase_1m
;
334 * first step: go through all devices and gather memory and I/O
337 for (dev
= 0; dev
< pci_bus_maxdevs(pc
,0); dev
++) {
339 tag
= pci_make_tag(pc
, 0, dev
, 0);
340 id
= pci_conf_read(pc
, tag
, PCI_ID_REG
);
341 if (id
== 0 || id
== 0xffffffff)
344 csr
= pci_conf_read(pc
, tag
, PCI_COMMAND_STATUS_REG
);
347 * special case: if a display card is found and memory is enabled
348 * preserve 128k at 0xa0000 as vga memory.
349 * XXX: if a display card is found without being enabled, leave
350 * it alone! You will usually only create conflicts by enabeling
353 class = pci_conf_read(pc
, tag
, PCI_CLASS_REG
);
354 switch (PCI_CLASS(class)) {
355 case PCI_CLASS_PREHISTORIC
:
356 case PCI_CLASS_DISPLAY
:
357 if (csr
& (PCI_COMMAND_MEM_ENABLE
| PCI_COMMAND_MASTER_ENABLE
)) {
358 p
= (struct pci_memreg
*)malloc(sizeof(struct pci_memreg
),
360 memset(p
, '\0', sizeof(struct pci_memreg
));
364 p
->reg
= 0; /* there is no register about this */
365 p
->size
= 0x20000; /* 128kByte */
366 p
->mask
= 0xfffe0000;
367 p
->address
= 0xa0000;
369 insert_into_list(&memlist
, p
);
374 for (reg
= PCI_MAPREG_START
; reg
< PCI_MAPREG_END
; reg
+= 4) {
376 address
= pci_conf_read(pc
, tag
, reg
);
377 pci_conf_write(pc
, tag
, reg
, 0xffffffff);
378 mask
= pci_conf_read(pc
, tag
, reg
);
379 pci_conf_write(pc
, tag
, reg
, address
);
381 continue; /* Register unused */
383 p
= (struct pci_memreg
*)malloc(sizeof(struct pci_memreg
),
385 memset(p
, '\0', sizeof(struct pci_memreg
));
393 if (mask
& PCI_MAPREG_TYPE_IO
) {
394 p
->size
= PCI_MAPREG_IO_SIZE(mask
);
397 * Align IO if necessary
399 if (p
->size
< PCI_MAPREG_IO_SIZE(PCI_MACHDEP_IO_ALIGN_MASK
)) {
400 p
->mask
= PCI_MACHDEP_IO_ALIGN_MASK
;
401 p
->size
= PCI_MAPREG_IO_SIZE(p
->mask
);
405 * if I/O is already enabled (probably by the console driver)
406 * save the address in order to take care about it later.
408 if (csr
& PCI_COMMAND_IO_ENABLE
)
409 p
->address
= address
;
411 insert_into_list(&iolist
, p
);
413 p
->size
= PCI_MAPREG_MEM_SIZE(mask
);
416 * Align memory if necessary
418 if (p
->size
< PCI_MAPREG_IO_SIZE(PCI_MACHDEP_MEM_ALIGN_MASK
)) {
419 p
->mask
= PCI_MACHDEP_MEM_ALIGN_MASK
;
420 p
->size
= PCI_MAPREG_MEM_SIZE(p
->mask
);
424 * if memory is already enabled (probably by the console driver)
425 * save the address in order to take care about it later.
427 if (csr
& PCI_COMMAND_MEM_ENABLE
)
428 p
->address
= address
;
430 insert_into_list(&memlist
, p
);
432 if (PCI_MAPREG_MEM_TYPE(mask
) == PCI_MAPREG_MEM_TYPE_64BIT
)
438 #if defined(_ATARIHW_)
440 * Both interrupt pin & line are set to the device (== slot)
441 * number. This makes sense on the atari Hades because the
442 * individual slots are hard-wired to a specific MFP-pin.
444 csr
= (DEV2SLOT(dev
) << PCI_INTERRUPT_PIN_SHIFT
);
445 csr
|= (DEV2SLOT(dev
) << PCI_INTERRUPT_LINE_SHIFT
);
446 pci_conf_write(pc
, tag
, PCI_INTERRUPT_REG
, csr
);
449 * On the Milan, we accept the BIOS's choice.
455 * second step: calculate the memory and I/O addresses beginning from
456 * PCI_MEM_START and PCI_IO_START. Care about already mapped areas.
458 * begin with memory list
461 address
= PCI_MEM_START
;
464 p
= LIST_FIRST(&memlist
);
466 if (!(p
->csr
& PCI_COMMAND_MEM_ENABLE
)) {
467 if (PCI_MAPREG_MEM_TYPE(p
->mask
) == PCI_MAPREG_MEM_TYPE_32BIT_1M
) {
468 if (p
->size
> membase_1m
)
469 membase_1m
= p
->size
;
471 p
->address
= membase_1m
;
472 membase_1m
+= p
->size
;
473 } while (overlap_pci_areas(LIST_FIRST(&memlist
), p
, p
->address
,
474 p
->size
, PCI_COMMAND_MEM_ENABLE
));
475 if (membase_1m
> 0x00100000) {
477 * Should we panic here?
479 printf("\npcibus0: dev %d reg %d: memory not configured",
485 if (sizecnt
&& (p
->size
> sizecnt
))
486 sizecnt
= ((p
->size
+ sizecnt
) & p
->mask
) &
487 PCI_MAPREG_MEM_ADDR_MASK
;
488 if (sizecnt
> address
) {
494 p
->address
= address
+ sizecnt
;
496 } while (overlap_pci_areas(LIST_FIRST(&memlist
), p
, p
->address
,
497 p
->size
, PCI_COMMAND_MEM_ENABLE
));
499 if ((address
+ sizecnt
) > PCI_MEM_END
) {
501 * Should we panic here?
503 printf("\npcibus0: dev %d reg %d: memory not configured",
509 pci_conf_write(pc
, p
->tag
, p
->reg
, p
->address
);
510 csr
= pci_conf_read(pc
, p
->tag
, PCI_COMMAND_STATUS_REG
);
511 csr
|= PCI_COMMAND_MEM_ENABLE
| PCI_COMMAND_MASTER_ENABLE
;
512 pci_conf_write(pc
, p
->tag
, PCI_COMMAND_STATUS_REG
, csr
);
516 p
= LIST_NEXT(p
, link
);
523 address
= PCI_IO_START
;
525 p
= LIST_FIRST(&iolist
);
527 if (!(p
->csr
& PCI_COMMAND_IO_ENABLE
)) {
529 if (sizecnt
&& (p
->size
> sizecnt
))
530 sizecnt
= ((p
->size
+ sizecnt
) & p
->mask
) &
531 PCI_MAPREG_IO_ADDR_MASK
;
532 if (sizecnt
> address
) {
538 p
->address
= address
+ sizecnt
;
540 } while (overlap_pci_areas(LIST_FIRST(&iolist
), p
, p
->address
,
541 p
->size
, PCI_COMMAND_IO_ENABLE
));
543 if ((address
+ sizecnt
) > PCI_IO_END
) {
545 * Should we panic here?
547 printf("\npcibus0: dev %d reg %d: io not configured",
550 pci_conf_write(pc
, p
->tag
, p
->reg
, p
->address
);
551 csr
= pci_conf_read(pc
, p
->tag
, PCI_COMMAND_STATUS_REG
);
552 csr
|= PCI_COMMAND_IO_ENABLE
| PCI_COMMAND_MASTER_ENABLE
;
553 pci_conf_write(pc
, p
->tag
, PCI_COMMAND_STATUS_REG
, csr
);
557 p
= LIST_NEXT(p
, link
);
560 #ifdef DEBUG_PCI_MACHDEP
561 printf("\nI/O List:\n");
562 p
= LIST_FIRST(&iolist
);
565 printf("\ndev: %d, reg: 0x%02x, size: 0x%08x, addr: 0x%08x", p
->dev
,
566 p
->reg
, p
->size
, p
->address
);
567 p
= LIST_NEXT(p
, link
);
569 printf("\nMemlist:");
570 p
= LIST_FIRST(&memlist
);
573 printf("\ndev: %d, reg: 0x%02x, size: 0x%08x, addr: 0x%08x", p
->dev
,
574 p
->reg
, p
->size
, p
->address
);
575 p
= LIST_NEXT(p
, link
);
582 p
= LIST_FIRST(&iolist
);
585 LIST_REMOVE(q
, link
);
587 p
= LIST_FIRST(&iolist
);
589 p
= LIST_FIRST(&memlist
);
592 LIST_REMOVE(q
, link
);
594 p
= LIST_FIRST(&memlist
);
599 pci_make_tag(pci_chipset_tag_t pc
, int bus
, int device
, int function
)
601 return ((bus
<< 16) | (device
<< 11) | (function
<< 8));
605 pci_decompose_tag(pci_chipset_tag_t pc
, pcitag_t tag
, int *bp
, int *dp
, int *fp
)
609 *bp
= (tag
>> 16) & 0xff;
611 *dp
= (tag
>> 11) & 0x1f;
613 *fp
= (tag
>> 8) & 0x7;
617 pci_intr_map(struct pci_attach_args
*pa
, pci_intr_handle_t
*ihp
)
619 int line
= pa
->pa_intrline
;
621 #if defined(_MILANHW_)
623 * On the Hades, the 'pin' info is useless.
626 int pin
= pa
->pa_intrpin
;
632 if (pin
> PCI_INTERRUPT_PIN_MAX
) {
633 printf("pci_intr_map: bad interrupt pin %d\n", pin
);
637 #endif /* _MILANHW_ */
640 * According to the PCI-spec, 255 means `unknown' or `no connection'.
641 * Interpret this as 'no interrupt assigned'.
647 * Values are pretty useless on the Hades since all interrupt
648 * lines for a card are tied together and hardwired to a
649 * specific TT-MFP I/O port.
650 * On the Milan, they are tied to the ICU.
652 #if defined(_MILANHW_)
654 printf("pci_intr_map: bad interrupt line %d\n", line
);
658 printf("pci_intr_map: changed line 2 to line 9\n");
661 /* Assume line == 0 means unassigned */
674 pci_intr_string(pci_chipset_tag_t pc
, pci_intr_handle_t ih
)
676 static char irqstr
[8]; /* 4 + 2 + NULL + sanity */
679 panic("pci_intr_string: bogus handle 0x%x", ih
);
681 sprintf(irqstr
, "irq %d", ih
);
687 pci_intr_evcnt(pci_chipset_tag_t pc
, pci_intr_handle_t ih
)
690 /* XXX for now, no evcnt parent reported */