Home | History | Annotate | Line # | Download | only in pci
pci_tseng.c revision 1.4.8.2
      1  1.4.8.2  nathanw /*	$NetBSD: pci_tseng.c,v 1.4.8.2 2002/09/17 21:13:50 nathanw Exp $	*/
      2  1.4.8.2  nathanw 
      3  1.4.8.2  nathanw /*
      4  1.4.8.2  nathanw  * Copyright (c) 1999 Leo Weppelman.  All rights reserved.
      5  1.4.8.2  nathanw  *
      6  1.4.8.2  nathanw  * Redistribution and use in source and binary forms, with or without
      7  1.4.8.2  nathanw  * modification, are permitted provided that the following conditions
      8  1.4.8.2  nathanw  * are met:
      9  1.4.8.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     10  1.4.8.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     11  1.4.8.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.4.8.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     13  1.4.8.2  nathanw  *    documentation and/or other materials provided with the distribution.
     14  1.4.8.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     15  1.4.8.2  nathanw  *    must display the following acknowledgement:
     16  1.4.8.2  nathanw  *	This product includes software developed by Leo Weppelman.
     17  1.4.8.2  nathanw  * 4. The name of the author may not be used to endorse or promote products
     18  1.4.8.2  nathanw  *    derived from this software without specific prior written permission.
     19  1.4.8.2  nathanw  *
     20  1.4.8.2  nathanw  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  1.4.8.2  nathanw  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  1.4.8.2  nathanw  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  1.4.8.2  nathanw  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  1.4.8.2  nathanw  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  1.4.8.2  nathanw  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  1.4.8.2  nathanw  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  1.4.8.2  nathanw  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  1.4.8.2  nathanw  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  1.4.8.2  nathanw  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  1.4.8.2  nathanw  */
     31  1.4.8.2  nathanw #include <sys/param.h>
     32  1.4.8.2  nathanw #include <sys/queue.h>
     33  1.4.8.2  nathanw #include <sys/systm.h>
     34  1.4.8.2  nathanw #include <dev/pci/pcireg.h>
     35  1.4.8.2  nathanw #include <dev/pci/pcivar.h>
     36  1.4.8.2  nathanw #include <dev/pci/pcidevs.h>
     37  1.4.8.2  nathanw #include <atari/pci/pci_vga.h>
     38  1.4.8.2  nathanw #include <atari/dev/grf_etreg.h>
     39  1.4.8.2  nathanw 
     40  1.4.8.2  nathanw #define PCI_LINMEMBASE	0x0e000000
     41  1.4.8.2  nathanw #define PCI_IOBASE	0x800
     42  1.4.8.2  nathanw 
     43  1.4.8.2  nathanw static void et6000_init(volatile u_char *, u_char *, int);
     44  1.4.8.2  nathanw 
     45  1.4.8.2  nathanw /*
     46  1.4.8.2  nathanw  * Use tables for the card init...
     47  1.4.8.2  nathanw  */
     48  1.4.8.2  nathanw static u_char seq_tab[] = {
     49  1.4.8.2  nathanw  	0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x00, 0xb4 };
     50  1.4.8.2  nathanw 
     51  1.4.8.2  nathanw static u_char gfx_tab[] = {
     52  1.4.8.2  nathanw 	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
     53  1.4.8.2  nathanw 
     54  1.4.8.2  nathanw static u_char attr_tab[] = {
     55  1.4.8.2  nathanw 	0x0a, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 };
     56  1.4.8.2  nathanw 
     57  1.4.8.2  nathanw static u_char crt_tab[] = {
     58  1.4.8.2  nathanw 	0x60, 0x53, 0x4f, 0x94, 0x56, 0x05, 0xc1, 0x1f,
     59  1.4.8.2  nathanw 	0x00, 0x4f, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x80,
     60  1.4.8.2  nathanw 	0x98, 0x3d, 0x8f, 0x28, 0x0f, 0x8f, 0xc2, 0xa3,
     61  1.4.8.2  nathanw 	0xff, 0x3d, 0x8f, 0x28, 0x0f, 0x8f, 0xc2, 0xa3,
     62  1.4.8.2  nathanw 	0x60, 0x08, 0x00, 0x00, 0x56, 0x05, 0xc1, 0x1f,
     63  1.4.8.2  nathanw 	0x00, 0x4f, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x80,
     64  1.4.8.2  nathanw 	0x00, 0x80, 0x28, 0x00, 0x00, 0x10, 0x43, 0x09,
     65  1.4.8.2  nathanw 	0x05, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 };
     66  1.4.8.2  nathanw 
     67  1.4.8.2  nathanw static u_char ras_cas_tab[] = {
     68  1.4.8.2  nathanw 	0x11, 0x14, 0x15 };
     69  1.4.8.2  nathanw 
     70  1.4.8.2  nathanw void
     71  1.4.8.2  nathanw tseng_init(pc, tag, id, ba, fb)
     72  1.4.8.2  nathanw 	pci_chipset_tag_t	pc;
     73  1.4.8.2  nathanw 	pcitag_t		tag;
     74  1.4.8.2  nathanw 	int			id;
     75  1.4.8.2  nathanw 	volatile u_char		*ba;
     76  1.4.8.2  nathanw 	u_char			*fb;
     77  1.4.8.2  nathanw {
     78  1.4.8.2  nathanw 	int			i, j, csr;
     79  1.4.8.2  nathanw 	int			is_et6000 = 0;
     80  1.4.8.2  nathanw 
     81  1.4.8.2  nathanw 	is_et6000 = (id ==  PCI_PRODUCT_TSENG_ET6000) ? 1 : 0;
     82  1.4.8.2  nathanw 
     83  1.4.8.2  nathanw 	/* Turn on the card */
     84  1.4.8.2  nathanw 	pci_conf_write(pc, tag, PCI_MAPREG_START, PCI_LINMEMBASE);
     85  1.4.8.2  nathanw 	if (is_et6000)
     86  1.4.8.2  nathanw 		pci_conf_write(pc, tag, PCI_MAPREG_START+4,
     87  1.4.8.2  nathanw 					PCI_IOBASE | PCI_MAPREG_TYPE_IO);
     88  1.4.8.2  nathanw 	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
     89  1.4.8.2  nathanw 	csr |= (PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_IO_ENABLE);
     90  1.4.8.2  nathanw 	csr |= PCI_COMMAND_MASTER_ENABLE;
     91  1.4.8.2  nathanw 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
     92  1.4.8.2  nathanw 
     93  1.4.8.2  nathanw 	if (is_et6000) {
     94  1.4.8.2  nathanw 		/*
     95  1.4.8.2  nathanw 		 * The et6[01]000 cards have MDRAM chips. The
     96  1.4.8.2  nathanw 		 * timeing to those chips is not properly initialized
     97  1.4.8.2  nathanw 		 * by the card on init. The way to determine the
     98  1.4.8.2  nathanw 		 * values is not documented either :-( So that's why
     99  1.4.8.2  nathanw 		 * all this mess below (and in et6000_init()....
    100  1.4.8.2  nathanw 		 */
    101  1.4.8.2  nathanw 		for (i = 0; i < sizeof(ras_cas_tab); i++) {
    102  1.4.8.2  nathanw 			et6000_init(ba, fb, i);
    103  1.4.8.2  nathanw 			for (j = 0; j < 32; j++)
    104  1.4.8.2  nathanw 				fb[j] = j;
    105  1.4.8.2  nathanw 			for (j = 0; j < 32; j++)
    106  1.4.8.2  nathanw 				if (fb[j] != j)
    107  1.4.8.2  nathanw 					break;
    108  1.4.8.2  nathanw 			if (j == 32)
    109  1.4.8.2  nathanw 				break;
    110  1.4.8.2  nathanw 		}
    111  1.4.8.2  nathanw 	}
    112  1.4.8.2  nathanw 
    113  1.4.8.2  nathanw 	vgaw(ba, GREG_MISC_OUTPUT_W,      0x63);
    114  1.4.8.2  nathanw 	vgaw(ba, GREG_VIDEOSYSENABLE,     0x01);
    115  1.4.8.2  nathanw 	WCrt(ba, 0x17               ,     0x00); /* color */
    116  1.4.8.2  nathanw 	WCrt(ba, 0x11               ,     0x00); /* color */
    117  1.4.8.2  nathanw 	vgaw(ba, VDAC_MASK          ,     0xff);
    118  1.4.8.2  nathanw 	WSeq(ba, SEQ_ID_RESET       ,     0x00);
    119  1.4.8.2  nathanw 	vgaw(ba, GREG_HERCULESCOMPAT,     0x03);
    120  1.4.8.2  nathanw 	vgaw(ba, GREG_DISPMODECONTROL,    0xa0);
    121  1.4.8.2  nathanw 
    122  1.4.8.2  nathanw 	/* Load sequencer */
    123  1.4.8.2  nathanw 	for (i = 1; i < 8; i++)
    124  1.4.8.2  nathanw 		WSeq(ba, i, seq_tab[i]);
    125  1.4.8.2  nathanw 	WSeq(ba, SEQ_ID_RESET       ,     0x03);
    126  1.4.8.2  nathanw 
    127  1.4.8.2  nathanw 	vgar(ba, VDAC_ADDRESS);	/* clear old state */
    128  1.4.8.2  nathanw         vgar(ba, VDAC_MASK);
    129  1.4.8.2  nathanw         vgar(ba, VDAC_MASK);
    130  1.4.8.2  nathanw         vgar(ba, VDAC_MASK);
    131  1.4.8.2  nathanw         vgar(ba, VDAC_MASK);
    132  1.4.8.2  nathanw 	vgaw(ba, VDAC_MASK, 0);		/* set to palette */
    133  1.4.8.2  nathanw 	vgar(ba, VDAC_ADDRESS);		/* clear state */
    134  1.4.8.2  nathanw 	vgaw(ba, VDAC_MASK, 0xff);
    135  1.4.8.2  nathanw 
    136  1.4.8.2  nathanw 	/*
    137  1.4.8.2  nathanw 	 * Make sure we're allowed to write all crt-registers
    138  1.4.8.2  nathanw 	 */
    139  1.4.8.2  nathanw 	WCrt(ba, CRT_ID_END_VER_RETR, (RCrt(ba, CRT_ID_END_VER_RETR) & 0x7f));
    140  1.4.8.2  nathanw 
    141  1.4.8.2  nathanw 	/* CRT registers */
    142  1.4.8.2  nathanw 	for (i = 0; i < 0x3e; i++)
    143  1.4.8.2  nathanw 		WCrt(ba, i, crt_tab[i]);
    144  1.4.8.2  nathanw 
    145  1.4.8.2  nathanw 	/* GCT registers */
    146  1.4.8.2  nathanw 	for (i = 0; i < 0x09; i++)
    147  1.4.8.2  nathanw 		WGfx(ba, i, gfx_tab[i]);
    148  1.4.8.2  nathanw 
    149  1.4.8.2  nathanw 	for (i = 0; i < 0x10; i++)
    150  1.4.8.2  nathanw 		WAttr(ba, i, i);
    151  1.4.8.2  nathanw 	for (; i < 0x18; i++)
    152  1.4.8.2  nathanw 		WAttr(ba, i, attr_tab[i - 0x10]);
    153  1.4.8.2  nathanw 	WAttr(ba, 0x20, 0);
    154  1.4.8.2  nathanw }
    155  1.4.8.2  nathanw 
    156  1.4.8.2  nathanw /*
    157  1.4.8.2  nathanw  * Initialize the et6000 specific (PCI) registers. Try to do it like the
    158  1.4.8.2  nathanw  * video-bios would have done it, so things like Xservers get what they
    159  1.4.8.2  nathanw  * expect. Most info was kindly provided by Koen Gadeyne.
    160  1.4.8.2  nathanw  */
    161  1.4.8.2  nathanw 
    162  1.4.8.2  nathanw static void
    163  1.4.8.2  nathanw et6000_init(ba, fb, iter)
    164  1.4.8.2  nathanw volatile u_char *ba;
    165  1.4.8.2  nathanw u_char		*fb;
    166  1.4.8.2  nathanw int		iter;
    167  1.4.8.2  nathanw {
    168  1.4.8.2  nathanw 
    169  1.4.8.2  nathanw 	int		i;
    170  1.4.8.2  nathanw 	u_char		dac_tab[] = { 0x7d,0x67, 0x5d,0x64, 0x56,0x63,
    171  1.4.8.2  nathanw 				      0x28,0x22, 0x79,0x49, 0x6f,0x47,
    172  1.4.8.2  nathanw 				      0x28,0x41, 0x6b,0x44, 0x00,0x00,
    173  1.4.8.2  nathanw 				      0x00,0x00, 0x5d,0x25, 0x00,0x00,
    174  1.4.8.2  nathanw 				      0x00,0x00, 0x00,0x96 };
    175  1.4.8.2  nathanw 
    176  1.4.8.2  nathanw 	ba += 0x800;
    177  1.4.8.2  nathanw 
    178  1.4.8.2  nathanw 
    179  1.4.8.2  nathanw 	ba[0x40] = 0x06;	/* Use standard vga addressing		*/
    180  1.4.8.2  nathanw 	ba[0x41] = 0x2a;	/* Performance control			*/
    181  1.4.8.2  nathanw 	ba[0x43] = 0x02;	/* XCLK/SCLK config			*/
    182  1.4.8.2  nathanw 	ba[0x44] = ras_cas_tab[iter];	/* RAS/CAS config		*/
    183  1.4.8.2  nathanw 	ba[0x46] = 0x00;	/* CRT display feature			*/
    184  1.4.8.2  nathanw 	ba[0x47] = 0x10;
    185  1.4.8.2  nathanw 	ba[0x58] = 0x00;	/* Video Control 1			*/
    186  1.4.8.2  nathanw 	ba[0x59] = 0x04;	/* Video Control 2			*/
    187  1.4.8.2  nathanw 
    188  1.4.8.2  nathanw 	/*
    189  1.4.8.2  nathanw 	 * Setup a 'standard' CLKDAC
    190  1.4.8.2  nathanw 	 */
    191  1.4.8.2  nathanw 	ba[0x42] = 0x00;	/* MCLK == CLK0 */
    192  1.4.8.2  nathanw 	ba[0x67] = 0x00;	/* Start filling from dac-reg 0 and up... */
    193  1.4.8.2  nathanw 	for (i = 0; i < 0x16; i++)
    194  1.4.8.2  nathanw 		ba[0x69] = dac_tab[i];
    195  1.4.8.2  nathanw 
    196  1.4.8.2  nathanw 	if (ba[8] == 0x70) { /* et6100, right? */
    197  1.4.8.2  nathanw 		volatile u_char *ma = (volatile u_char *)fb;
    198  1.4.8.2  nathanw 		u_char		bv;
    199  1.4.8.2  nathanw 
    200  1.4.8.2  nathanw 		/*
    201  1.4.8.2  nathanw 		 * XXX Black magic to get the bloody MDRAM's to function...
    202  1.4.8.2  nathanw                  * XXX _Only_ tested on my card! [leo]
    203  1.4.8.2  nathanw 		 */
    204  1.4.8.2  nathanw 		bv = ba[45];
    205  1.4.8.2  nathanw 		ba[0x45] = bv | 0x40;	/* Reset MDRAM's		*/
    206  1.4.8.2  nathanw 		ba[0x45] = bv | 0x70;	/* Program latency value	*/
    207  1.4.8.2  nathanw 		ma[0x0] = 0;		/* Yeah, right :-(		*/
    208  1.4.8.2  nathanw 		ba[0x45] = bv;		/* Back to normal		*/
    209  1.4.8.2  nathanw 	}
    210  1.4.8.2  nathanw }
    211