Home | History | Annotate | Line # | Download | only in pci
pci_hades.c revision 1.1.10.3
      1  1.1.10.3  nathanw /*	$NetBSD: pci_hades.c,v 1.1.10.3 2002/02/28 04:08:27 nathanw Exp $	*/
      2  1.1.10.2  nathanw 
      3  1.1.10.2  nathanw /*
      4  1.1.10.2  nathanw  * Copyright (c) 1996 Leo Weppelman.  All rights reserved.
      5  1.1.10.2  nathanw  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
      6  1.1.10.2  nathanw  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
      7  1.1.10.2  nathanw  *
      8  1.1.10.2  nathanw  * Redistribution and use in source and binary forms, with or without
      9  1.1.10.2  nathanw  * modification, are permitted provided that the following conditions
     10  1.1.10.2  nathanw  * are met:
     11  1.1.10.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     12  1.1.10.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     13  1.1.10.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1.10.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     15  1.1.10.2  nathanw  *    documentation and/or other materials provided with the distribution.
     16  1.1.10.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     17  1.1.10.2  nathanw  *    must display the following acknowledgement:
     18  1.1.10.2  nathanw  *	This product includes software developed by Charles M. Hannum.
     19  1.1.10.2  nathanw  * 4. The name of the author may not be used to endorse or promote products
     20  1.1.10.2  nathanw  *    derived from this software without specific prior written permission.
     21  1.1.10.2  nathanw  *
     22  1.1.10.2  nathanw  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  1.1.10.2  nathanw  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  1.1.10.2  nathanw  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  1.1.10.2  nathanw  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  1.1.10.2  nathanw  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  1.1.10.2  nathanw  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  1.1.10.2  nathanw  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  1.1.10.2  nathanw  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  1.1.10.2  nathanw  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  1.1.10.2  nathanw  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  1.1.10.2  nathanw  */
     33  1.1.10.2  nathanw 
     34  1.1.10.2  nathanw #include <sys/types.h>
     35  1.1.10.2  nathanw #include <sys/param.h>
     36  1.1.10.2  nathanw #include <sys/systm.h>
     37  1.1.10.2  nathanw #include <sys/device.h>
     38  1.1.10.2  nathanw 
     39  1.1.10.2  nathanw #include <machine/bus.h>
     40  1.1.10.2  nathanw 
     41  1.1.10.2  nathanw #include <dev/pci/pcivar.h>
     42  1.1.10.2  nathanw #include <dev/pci/pcireg.h>
     43  1.1.10.2  nathanw 
     44  1.1.10.2  nathanw #include <machine/cpu.h>
     45  1.1.10.2  nathanw #include <machine/iomap.h>
     46  1.1.10.2  nathanw #include <machine/mfp.h>
     47  1.1.10.2  nathanw #include <machine/bswap.h>
     48  1.1.10.2  nathanw 
     49  1.1.10.2  nathanw #include <atari/atari/device.h>
     50  1.1.10.2  nathanw #include <atari/pci/pci_vga.h>
     51  1.1.10.2  nathanw #include <atari/dev/grf_etreg.h>
     52  1.1.10.2  nathanw 
     53  1.1.10.2  nathanw int
     54  1.1.10.2  nathanw pci_bus_maxdevs(pc, busno)
     55  1.1.10.2  nathanw 	pci_chipset_tag_t pc;
     56  1.1.10.2  nathanw 	int busno;
     57  1.1.10.2  nathanw {
     58  1.1.10.2  nathanw 	return (4);
     59  1.1.10.2  nathanw }
     60  1.1.10.2  nathanw 
     61  1.1.10.2  nathanw static int pci_config_offset __P((pcitag_t));
     62  1.1.10.2  nathanw 
     63  1.1.10.2  nathanw /*
     64  1.1.10.2  nathanw  * Atari_init.c maps the config areas NBPG bytes apart....
     65  1.1.10.2  nathanw  */
     66  1.1.10.2  nathanw static int pci_config_offset(tag)
     67  1.1.10.2  nathanw pcitag_t	tag;
     68  1.1.10.2  nathanw {
     69  1.1.10.2  nathanw 	int	device;
     70  1.1.10.2  nathanw 
     71  1.1.10.2  nathanw 	device = (tag >> 11) & 0x1f;
     72  1.1.10.2  nathanw 	return(device * NBPG);
     73  1.1.10.2  nathanw }
     74  1.1.10.2  nathanw 
     75  1.1.10.2  nathanw pcireg_t
     76  1.1.10.2  nathanw pci_conf_read(pc, tag, reg)
     77  1.1.10.2  nathanw 	pci_chipset_tag_t pc;
     78  1.1.10.2  nathanw 	pcitag_t tag;
     79  1.1.10.2  nathanw 	int reg;
     80  1.1.10.2  nathanw {
     81  1.1.10.2  nathanw 	u_long	data;
     82  1.1.10.2  nathanw 
     83  1.1.10.2  nathanw 	data = *(u_long *)(pci_conf_addr + pci_config_offset(tag) + reg);
     84  1.1.10.2  nathanw 	return (bswap32(data));
     85  1.1.10.2  nathanw }
     86  1.1.10.2  nathanw 
     87  1.1.10.2  nathanw void
     88  1.1.10.2  nathanw pci_conf_write(pc, tag, reg, data)
     89  1.1.10.2  nathanw 	pci_chipset_tag_t pc;
     90  1.1.10.2  nathanw 	pcitag_t tag;
     91  1.1.10.2  nathanw 	int reg;
     92  1.1.10.2  nathanw 	pcireg_t data;
     93  1.1.10.2  nathanw {
     94  1.1.10.2  nathanw 	*((u_long *)(pci_conf_addr + pci_config_offset(tag) + reg))
     95  1.1.10.2  nathanw 		= bswap32(data);
     96  1.1.10.2  nathanw }
     97  1.1.10.2  nathanw 
     98  1.1.10.2  nathanw /*
     99  1.1.10.2  nathanw  * The interrupt stuff is rather ugly. On the Hades, all interrupt lines
    100  1.1.10.2  nathanw  * for a slot are wired together and connected to IO 0,1,2 or 5 (slots:
    101  1.1.10.2  nathanw  * (0-3) on the TT-MFP. The Pci-config code initializes the irq. number
    102  1.1.10.2  nathanw  * to the slot position.
    103  1.1.10.2  nathanw  */
    104  1.1.10.2  nathanw static pci_intr_info_t iinfo[4] = { { -1 }, { -1 }, { -1 }, { -1 } };
    105  1.1.10.2  nathanw 
    106  1.1.10.2  nathanw static int	iifun __P((int, int));
    107  1.1.10.2  nathanw 
    108  1.1.10.2  nathanw static int
    109  1.1.10.2  nathanw iifun(slot, sr)
    110  1.1.10.2  nathanw int	slot;
    111  1.1.10.2  nathanw int	sr;
    112  1.1.10.2  nathanw {
    113  1.1.10.2  nathanw 	pci_intr_info_t *iinfo_p;
    114  1.1.10.2  nathanw 	int		s;
    115  1.1.10.2  nathanw 
    116  1.1.10.2  nathanw 	iinfo_p = &iinfo[slot];
    117  1.1.10.2  nathanw 
    118  1.1.10.2  nathanw 	/*
    119  1.1.10.2  nathanw 	 * Disable the interrupts
    120  1.1.10.2  nathanw 	 */
    121  1.1.10.2  nathanw 	MFP2->mf_imrb  &= ~iinfo_p->imask;
    122  1.1.10.2  nathanw 
    123  1.1.10.2  nathanw 	if ((sr & PSL_IPL) >= (iinfo_p->ipl & PSL_IPL)) {
    124  1.1.10.2  nathanw 		/*
    125  1.1.10.2  nathanw 		 * We're running at a too high priority now.
    126  1.1.10.2  nathanw 		 */
    127  1.1.10.2  nathanw 		add_sicallback((si_farg)iifun, (void*)slot, 0);
    128  1.1.10.2  nathanw 	}
    129  1.1.10.2  nathanw 	else {
    130  1.1.10.2  nathanw 		s = splx(iinfo_p->ipl);
    131  1.1.10.2  nathanw 		(void) (iinfo_p->ifunc)(iinfo_p->iarg);
    132  1.1.10.2  nathanw 		splx(s);
    133  1.1.10.2  nathanw 
    134  1.1.10.2  nathanw 		/*
    135  1.1.10.2  nathanw 		 * Re-enable interrupts after handling
    136  1.1.10.2  nathanw 		 */
    137  1.1.10.2  nathanw 		MFP2->mf_imrb |= iinfo_p->imask;
    138  1.1.10.2  nathanw 	}
    139  1.1.10.2  nathanw 	return 1;
    140  1.1.10.2  nathanw }
    141  1.1.10.2  nathanw 
    142  1.1.10.2  nathanw void *
    143  1.1.10.2  nathanw pci_intr_establish(pc, ih, level, ih_fun, ih_arg)
    144  1.1.10.2  nathanw 	pci_chipset_tag_t	pc;
    145  1.1.10.2  nathanw 	pci_intr_handle_t	ih;
    146  1.1.10.2  nathanw 	int			level;
    147  1.1.10.2  nathanw 	int			(*ih_fun) __P((void *));
    148  1.1.10.2  nathanw 	void			*ih_arg;
    149  1.1.10.2  nathanw {
    150  1.1.10.2  nathanw 	pci_intr_info_t *iinfo_p;
    151  1.1.10.2  nathanw 	struct intrhand	*ihand;
    152  1.1.10.2  nathanw 	int		slot;
    153  1.1.10.2  nathanw 
    154  1.1.10.2  nathanw 	slot    = ih;
    155  1.1.10.2  nathanw 	iinfo_p = &iinfo[slot];
    156  1.1.10.2  nathanw 
    157  1.1.10.2  nathanw 	if (iinfo_p->ipl > 0)
    158  1.1.10.2  nathanw 	    panic("pci_intr_establish: interrupt was already established\n");
    159  1.1.10.2  nathanw 
    160  1.1.10.2  nathanw 	ihand = intr_establish((slot == 3) ? 23 : 16 + slot, USER_VEC, 0,
    161  1.1.10.2  nathanw 				(hw_ifun_t)iifun, (void *)slot);
    162  1.1.10.2  nathanw 	if (ihand != NULL) {
    163  1.1.10.2  nathanw 		iinfo_p->ipl   = level;
    164  1.1.10.2  nathanw 		iinfo_p->imask = (slot == 3) ? 0x80 : (0x01 << slot);
    165  1.1.10.2  nathanw 		iinfo_p->ifunc = ih_fun;
    166  1.1.10.2  nathanw 		iinfo_p->iarg  = ih_arg;
    167  1.1.10.2  nathanw 		iinfo_p->ihand = ihand;
    168  1.1.10.2  nathanw 
    169  1.1.10.2  nathanw 		/*
    170  1.1.10.2  nathanw 		 * Enable (unmask) the interrupt
    171  1.1.10.2  nathanw 		 */
    172  1.1.10.2  nathanw 		MFP2->mf_imrb |= iinfo_p->imask;
    173  1.1.10.2  nathanw 		MFP2->mf_ierb |= iinfo_p->imask;
    174  1.1.10.2  nathanw 		return(iinfo_p);
    175  1.1.10.2  nathanw 	}
    176  1.1.10.2  nathanw 	return NULL;
    177  1.1.10.2  nathanw }
    178  1.1.10.2  nathanw 
    179  1.1.10.2  nathanw void
    180  1.1.10.2  nathanw pci_intr_disestablish(pc, cookie)
    181  1.1.10.2  nathanw 	pci_chipset_tag_t pc;
    182  1.1.10.2  nathanw 	void *cookie;
    183  1.1.10.2  nathanw {
    184  1.1.10.2  nathanw 	pci_intr_info_t *iinfo_p = (pci_intr_info_t *)cookie;
    185  1.1.10.2  nathanw 
    186  1.1.10.2  nathanw 	if (iinfo->ipl < 0)
    187  1.1.10.2  nathanw 	    panic("pci_intr_disestablish: interrupt was not established\n");
    188  1.1.10.2  nathanw 
    189  1.1.10.2  nathanw 	MFP2->mf_imrb &= ~iinfo->imask;
    190  1.1.10.2  nathanw 	MFP2->mf_ierb &= ~iinfo->imask;
    191  1.1.10.2  nathanw 	(void) intr_disestablish(iinfo_p->ihand);
    192  1.1.10.2  nathanw 	iinfo_p->ipl = -1;
    193  1.1.10.2  nathanw }
    194  1.1.10.2  nathanw 
    195  1.1.10.2  nathanw /*
    196  1.1.10.2  nathanw  * XXX: Why are we repeating this everywhere! (Leo)
    197  1.1.10.2  nathanw  */
    198  1.1.10.2  nathanw #define PCI_LINMEMBASE  0x0e000000
    199  1.1.10.2  nathanw 
    200  1.1.10.2  nathanw static u_char crt_tab[] = {
    201  1.1.10.2  nathanw 	0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
    202  1.1.10.2  nathanw 	0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
    203  1.1.10.2  nathanw 	0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
    204  1.1.10.2  nathanw 	0xff };
    205  1.1.10.2  nathanw 
    206  1.1.10.2  nathanw static u_char seq_tab[] = {
    207  1.1.10.2  nathanw 	0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00 };
    208  1.1.10.2  nathanw 
    209  1.1.10.2  nathanw static u_char attr_tab[] = {
    210  1.1.10.2  nathanw 	0x0c, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00 };
    211  1.1.10.2  nathanw 
    212  1.1.10.2  nathanw static u_char gdc_tab[] = {
    213  1.1.10.2  nathanw 	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff };
    214  1.1.10.2  nathanw 
    215  1.1.10.2  nathanw void
    216  1.1.10.2  nathanw ati_vga_init(pc, tag, id, ba, fb)
    217  1.1.10.2  nathanw 	pci_chipset_tag_t	pc;
    218  1.1.10.2  nathanw 	pcitag_t		tag;
    219  1.1.10.2  nathanw 	int			id;
    220  1.1.10.2  nathanw 	volatile u_char		*ba;
    221  1.1.10.2  nathanw 	u_char			*fb;
    222  1.1.10.2  nathanw {
    223  1.1.10.2  nathanw 	int			i, csr;
    224  1.1.10.2  nathanw 
    225  1.1.10.2  nathanw 	/* Turn on the card */
    226  1.1.10.2  nathanw 	pci_conf_write(pc, tag, PCI_MAPREG_START, PCI_LINMEMBASE);
    227  1.1.10.2  nathanw 	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
    228  1.1.10.2  nathanw 	csr |= (PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_IO_ENABLE);
    229  1.1.10.2  nathanw 	csr |= PCI_COMMAND_MASTER_ENABLE;
    230  1.1.10.2  nathanw 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
    231  1.1.10.2  nathanw 
    232  1.1.10.2  nathanw 	/*
    233  1.1.10.2  nathanw 	 * Make sure we're allowed to write all crt-registers and reload them.
    234  1.1.10.2  nathanw 	 */
    235  1.1.10.2  nathanw 	WCrt(ba, CRT_ID_END_VER_RETR, (RCrt(ba, CRT_ID_END_VER_RETR) & 0x7f));
    236  1.1.10.2  nathanw 
    237  1.1.10.2  nathanw 	for (i = 0; i < 0x18; i++)
    238  1.1.10.2  nathanw 		WCrt(ba, i, crt_tab[i]);
    239  1.1.10.2  nathanw 	for (i = 0; i < 8; i++)
    240  1.1.10.2  nathanw 		WSeq(ba, i, seq_tab[i]);
    241  1.1.10.2  nathanw 	for (i = 0; i < 9; i++)
    242  1.1.10.2  nathanw 		WGfx(ba, i, gdc_tab[i]);
    243  1.1.10.2  nathanw 	for (i = 0x10; i < 0x18; i++)
    244  1.1.10.2  nathanw 		WAttr(ba, i, attr_tab[i - 0x10]);
    245  1.1.10.2  nathanw 	WAttr(ba, 0x20, 0);
    246  1.1.10.2  nathanw }
    247