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