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