pci_tseng.c revision 1.8 1 1.8 christos /* $NetBSD: pci_tseng.c,v 1.8 2005/12/11 12:17:00 christos 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.7 lukem
32 1.7 lukem #include <sys/cdefs.h>
33 1.8 christos __KERNEL_RCSID(0, "$NetBSD: pci_tseng.c,v 1.8 2005/12/11 12:17:00 christos Exp $");
34 1.7 lukem
35 1.1 leo #include <sys/param.h>
36 1.1 leo #include <sys/queue.h>
37 1.1 leo #include <sys/systm.h>
38 1.1 leo #include <dev/pci/pcireg.h>
39 1.1 leo #include <dev/pci/pcivar.h>
40 1.1 leo #include <dev/pci/pcidevs.h>
41 1.1 leo #include <atari/pci/pci_vga.h>
42 1.1 leo #include <atari/dev/grf_etreg.h>
43 1.1 leo
44 1.1 leo #define PCI_LINMEMBASE 0x0e000000
45 1.1 leo #define PCI_IOBASE 0x800
46 1.1 leo
47 1.2 leo static void et6000_init(volatile u_char *, u_char *, int);
48 1.1 leo
49 1.1 leo /*
50 1.1 leo * Use tables for the card init...
51 1.1 leo */
52 1.1 leo static u_char seq_tab[] = {
53 1.5 leo 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x00, 0xb4 };
54 1.1 leo
55 1.1 leo static u_char gfx_tab[] = {
56 1.4 leo 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff };
57 1.1 leo
58 1.1 leo static u_char attr_tab[] = {
59 1.1 leo 0x0a, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00 };
60 1.1 leo
61 1.1 leo static u_char crt_tab[] = {
62 1.1 leo 0x60, 0x53, 0x4f, 0x94, 0x56, 0x05, 0xc1, 0x1f,
63 1.1 leo 0x00, 0x4f, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x80,
64 1.1 leo 0x98, 0x3d, 0x8f, 0x28, 0x0f, 0x8f, 0xc2, 0xa3,
65 1.6 thomas 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 1.6 thomas 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
67 1.6 thomas 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 1.6 thomas #ifdef ET4000_HAS_2MB_MEM
69 1.6 thomas 0x00, 0x80, 0xa0, 0x00, 0x00, 0x10, 0x03, 0x89, /* 2 MB video memory */
70 1.6 thomas #else
71 1.6 thomas 0x00, 0x80, 0x28, 0x00, 0x00, 0x10, 0x43, 0x09, /* 1 MB video memory */
72 1.6 thomas #endif
73 1.6 thomas 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
74 1.1 leo
75 1.2 leo static u_char ras_cas_tab[] = {
76 1.2 leo 0x11, 0x14, 0x15 };
77 1.2 leo
78 1.1 leo void
79 1.1 leo tseng_init(pc, tag, id, ba, fb)
80 1.1 leo pci_chipset_tag_t pc;
81 1.1 leo pcitag_t tag;
82 1.1 leo int id;
83 1.1 leo volatile u_char *ba;
84 1.1 leo u_char *fb;
85 1.1 leo {
86 1.2 leo int i, j, csr;
87 1.1 leo int is_et6000 = 0;
88 1.1 leo
89 1.1 leo is_et6000 = (id == PCI_PRODUCT_TSENG_ET6000) ? 1 : 0;
90 1.1 leo
91 1.1 leo /* Turn on the card */
92 1.1 leo pci_conf_write(pc, tag, PCI_MAPREG_START, PCI_LINMEMBASE);
93 1.1 leo if (is_et6000)
94 1.1 leo pci_conf_write(pc, tag, PCI_MAPREG_START+4,
95 1.1 leo PCI_IOBASE | PCI_MAPREG_TYPE_IO);
96 1.1 leo csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
97 1.1 leo csr |= (PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_IO_ENABLE);
98 1.1 leo csr |= PCI_COMMAND_MASTER_ENABLE;
99 1.1 leo pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
100 1.1 leo
101 1.2 leo if (is_et6000) {
102 1.2 leo /*
103 1.2 leo * The et6[01]000 cards have MDRAM chips. The
104 1.2 leo * timeing to those chips is not properly initialized
105 1.2 leo * by the card on init. The way to determine the
106 1.2 leo * values is not documented either :-( So that's why
107 1.2 leo * all this mess below (and in et6000_init()....
108 1.2 leo */
109 1.2 leo for (i = 0; i < sizeof(ras_cas_tab); i++) {
110 1.2 leo et6000_init(ba, fb, i);
111 1.2 leo for (j = 0; j < 32; j++)
112 1.2 leo fb[j] = j;
113 1.2 leo for (j = 0; j < 32; j++)
114 1.2 leo if (fb[j] != j)
115 1.2 leo break;
116 1.2 leo if (j == 32)
117 1.2 leo break;
118 1.2 leo }
119 1.2 leo }
120 1.2 leo
121 1.1 leo vgaw(ba, GREG_MISC_OUTPUT_W, 0x63);
122 1.1 leo vgaw(ba, GREG_VIDEOSYSENABLE, 0x01);
123 1.1 leo WCrt(ba, 0x17 , 0x00); /* color */
124 1.1 leo WCrt(ba, 0x11 , 0x00); /* color */
125 1.1 leo vgaw(ba, VDAC_MASK , 0xff);
126 1.1 leo WSeq(ba, SEQ_ID_RESET , 0x00);
127 1.1 leo vgaw(ba, GREG_HERCULESCOMPAT, 0x03);
128 1.1 leo vgaw(ba, GREG_DISPMODECONTROL, 0xa0);
129 1.1 leo
130 1.1 leo /* Load sequencer */
131 1.1 leo for (i = 1; i < 8; i++)
132 1.1 leo WSeq(ba, i, seq_tab[i]);
133 1.1 leo WSeq(ba, SEQ_ID_RESET , 0x03);
134 1.1 leo
135 1.1 leo vgar(ba, VDAC_ADDRESS); /* clear old state */
136 1.1 leo vgar(ba, VDAC_MASK);
137 1.1 leo vgar(ba, VDAC_MASK);
138 1.1 leo vgar(ba, VDAC_MASK);
139 1.1 leo vgar(ba, VDAC_MASK);
140 1.1 leo vgaw(ba, VDAC_MASK, 0); /* set to palette */
141 1.1 leo vgar(ba, VDAC_ADDRESS); /* clear state */
142 1.1 leo vgaw(ba, VDAC_MASK, 0xff);
143 1.1 leo
144 1.1 leo /*
145 1.1 leo * Make sure we're allowed to write all crt-registers
146 1.1 leo */
147 1.1 leo WCrt(ba, CRT_ID_END_VER_RETR, (RCrt(ba, CRT_ID_END_VER_RETR) & 0x7f));
148 1.1 leo
149 1.1 leo /* CRT registers */
150 1.1 leo for (i = 0; i < 0x3e; i++)
151 1.1 leo WCrt(ba, i, crt_tab[i]);
152 1.3 leo
153 1.1 leo /* GCT registers */
154 1.1 leo for (i = 0; i < 0x09; i++)
155 1.1 leo WGfx(ba, i, gfx_tab[i]);
156 1.1 leo
157 1.1 leo for (i = 0; i < 0x10; i++)
158 1.1 leo WAttr(ba, i, i);
159 1.1 leo for (; i < 0x18; i++)
160 1.1 leo WAttr(ba, i, attr_tab[i - 0x10]);
161 1.1 leo WAttr(ba, 0x20, 0);
162 1.1 leo }
163 1.1 leo
164 1.1 leo /*
165 1.1 leo * Initialize the et6000 specific (PCI) registers. Try to do it like the
166 1.1 leo * video-bios would have done it, so things like Xservers get what they
167 1.1 leo * expect. Most info was kindly provided by Koen Gadeyne.
168 1.1 leo */
169 1.1 leo
170 1.1 leo static void
171 1.2 leo et6000_init(ba, fb, iter)
172 1.1 leo volatile u_char *ba;
173 1.1 leo u_char *fb;
174 1.2 leo int iter;
175 1.1 leo {
176 1.1 leo
177 1.1 leo int i;
178 1.1 leo u_char dac_tab[] = { 0x7d,0x67, 0x5d,0x64, 0x56,0x63,
179 1.1 leo 0x28,0x22, 0x79,0x49, 0x6f,0x47,
180 1.1 leo 0x28,0x41, 0x6b,0x44, 0x00,0x00,
181 1.1 leo 0x00,0x00, 0x5d,0x25, 0x00,0x00,
182 1.1 leo 0x00,0x00, 0x00,0x96 };
183 1.1 leo
184 1.1 leo ba += 0x800;
185 1.1 leo
186 1.1 leo
187 1.1 leo ba[0x40] = 0x06; /* Use standard vga addressing */
188 1.1 leo ba[0x41] = 0x2a; /* Performance control */
189 1.1 leo ba[0x43] = 0x02; /* XCLK/SCLK config */
190 1.2 leo ba[0x44] = ras_cas_tab[iter]; /* RAS/CAS config */
191 1.1 leo ba[0x46] = 0x00; /* CRT display feature */
192 1.1 leo ba[0x47] = 0x10;
193 1.1 leo ba[0x58] = 0x00; /* Video Control 1 */
194 1.1 leo ba[0x59] = 0x04; /* Video Control 2 */
195 1.1 leo
196 1.1 leo /*
197 1.1 leo * Setup a 'standard' CLKDAC
198 1.1 leo */
199 1.1 leo ba[0x42] = 0x00; /* MCLK == CLK0 */
200 1.1 leo ba[0x67] = 0x00; /* Start filling from dac-reg 0 and up... */
201 1.1 leo for (i = 0; i < 0x16; i++)
202 1.1 leo ba[0x69] = dac_tab[i];
203 1.1 leo
204 1.1 leo if (ba[8] == 0x70) { /* et6100, right? */
205 1.1 leo volatile u_char *ma = (volatile u_char *)fb;
206 1.1 leo u_char bv;
207 1.1 leo
208 1.1 leo /*
209 1.1 leo * XXX Black magic to get the bloody MDRAM's to function...
210 1.1 leo * XXX _Only_ tested on my card! [leo]
211 1.1 leo */
212 1.1 leo bv = ba[45];
213 1.1 leo ba[0x45] = bv | 0x40; /* Reset MDRAM's */
214 1.1 leo ba[0x45] = bv | 0x70; /* Program latency value */
215 1.1 leo ma[0x0] = 0; /* Yeah, right :-( */
216 1.1 leo ba[0x45] = bv; /* Back to normal */
217 1.1 leo }
218 1.1 leo }
219