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