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