grf_cv.c revision 1.6 1 1.6 chopps /* $NetBSD: grf_cv.c,v 1.6 1996/02/24 20:13:01 chopps Exp $ */
2 1.4 jtc
3 1.1 chopps /*
4 1.1 chopps * Copyright (c) 1995 Michael Teske
5 1.1 chopps * All rights reserved.
6 1.1 chopps *
7 1.1 chopps * Redistribution and use in source and binary forms, with or without
8 1.1 chopps * modification, are permitted provided that the following conditions
9 1.1 chopps * are met:
10 1.1 chopps * 1. Redistributions of source code must retain the above copyright
11 1.1 chopps * notice, this list of conditions and the following disclaimer.
12 1.1 chopps * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 chopps * notice, this list of conditions and the following disclaimer in the
14 1.1 chopps * documentation and/or other materials provided with the distribution.
15 1.1 chopps * 3. All advertising materials mentioning features or use of this software
16 1.1 chopps * must display the following acknowledgement:
17 1.1 chopps * This product includes software developed by Ezra Story, by Kari
18 1.1 chopps * Mettinen and by Bernd Ernesti.
19 1.1 chopps * 4. The name of the author may not be used to endorse or promote products
20 1.1 chopps * derived from this software without specific prior written permission
21 1.1 chopps *
22 1.1 chopps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 1.1 chopps * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1 chopps * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1 chopps * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 1.1 chopps * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 1.1 chopps * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 1.1 chopps * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 1.1 chopps * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 1.1 chopps * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 1.1 chopps * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 chopps */
33 1.1 chopps #include "grfcv.h"
34 1.1 chopps #if NGRFCV > 0
35 1.1 chopps
36 1.3 chopps #undef CV64CONSOLE /* DO NOT REMOVE THIS till ite5 is ready */
37 1.3 chopps
38 1.1 chopps /*
39 1.1 chopps * Graphics routines for the CyberVision 64 board, using the S3 Trio64.
40 1.1 chopps *
41 1.1 chopps * Modified for CV64 from
42 1.1 chopps * Kari Mettinen's Cirrus driver by Michael Teske 10/95
43 1.1 chopps * For questions mail me at teske (at) dice2.desy.de
44 1.1 chopps *
45 1.1 chopps * Thanks to Tekelec Airtronic for providing me with a S3 Trio64 documentation.
46 1.1 chopps * Thanks to Bernd 'the fabulous bug-finder' Ernesti for bringing my messy
47 1.1 chopps * source to NetBSD style :)
48 1.1 chopps *
49 1.1 chopps * TODO:
50 1.1 chopps * Hardware Cursor support
51 1.1 chopps * Blitter support
52 1.1 chopps *
53 1.1 chopps * BUGS:
54 1.4 jtc * Xamiag24 and grf_cv can crash when you use fvwm with xterm's, you can
55 1.4 jtc * avoid this by starting the xterm with '-ah', see the manpage of xterm
56 1.4 jtc * for more informations about this switch.
57 1.4 jtc * There is a bug in the Trio64 which produce a small (1 or 2 pixel) white
58 1.4 jtc * vertical bar on the right side of an 8bit-Screen (only when you use more
59 1.4 jtc * then 80MHz pixelclock). This has to be fixed in the Xserver.
60 1.1 chopps *
61 1.1 chopps */
62 1.1 chopps
63 1.1 chopps #include <sys/param.h>
64 1.1 chopps #include <sys/errno.h>
65 1.1 chopps #include <sys/ioctl.h>
66 1.1 chopps #include <sys/device.h>
67 1.1 chopps #include <sys/malloc.h>
68 1.1 chopps #include <sys/systm.h>
69 1.1 chopps #include <machine/cpu.h>
70 1.1 chopps #include <dev/cons.h>
71 1.1 chopps #include <amiga/amiga/device.h>
72 1.1 chopps #include <amiga/dev/grfioctl.h>
73 1.1 chopps #include <amiga/dev/grfvar.h>
74 1.1 chopps #include <amiga/dev/grf_cvreg.h>
75 1.1 chopps #include <amiga/dev/zbusvar.h>
76 1.1 chopps
77 1.4 jtc int grfcvmatch __P((struct device *, struct cfdata *, void *));
78 1.4 jtc void grfcvattach __P((struct device *, struct device *, void *));
79 1.4 jtc int grfcvprint __P((void *, char *));
80 1.4 jtc
81 1.4 jtc static int cv_has_4mb __P((volatile char *));
82 1.1 chopps static unsigned short compute_clock __P((unsigned long));
83 1.4 jtc void cv_boardinit __P((struct grf_softc *));
84 1.4 jtc int cv_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
85 1.4 jtc int cv_setvmode __P((struct grf_softc *, unsigned int));
86 1.4 jtc int cv_blank __P((struct grf_softc *, int *));
87 1.4 jtc int cv_mode __P((register struct grf_softc *, int, void *, int, int));
88 1.4 jtc int cv_ioctl __P((register struct grf_softc *gp, int cmd, void *data));
89 1.4 jtc int cv_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
90 1.4 jtc int cv_getcmap __P((struct grf_softc *, struct grf_colormap *));
91 1.4 jtc int cv_putcmap __P((struct grf_softc *, struct grf_colormap *));
92 1.4 jtc int cv_toggle __P((struct grf_softc *));
93 1.4 jtc int cv_mondefok __P((struct grfvideo_mode *));
94 1.4 jtc int cv_load_mon __P((struct grf_softc *, struct grfcvtext_mode *));
95 1.4 jtc void cv_inittextmode __P((struct grf_softc *));
96 1.4 jtc void cv_memset __P((unsigned char *, unsigned char, int));
97 1.1 chopps
98 1.3 chopps #ifdef CV64CONSOLE
99 1.3 chopps extern void grfcv_iteinit __P((struct grf_softc *));
100 1.3 chopps #endif
101 1.3 chopps
102 1.1 chopps /* Graphics display definitions.
103 1.1 chopps * These are filled by 'grfconfig' using GRFIOCSETMON.
104 1.1 chopps */
105 1.1 chopps #define monitor_def_max 8
106 1.1 chopps static struct grfvideo_mode monitor_def[8] = {
107 1.1 chopps {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
108 1.1 chopps };
109 1.1 chopps static struct grfvideo_mode *monitor_current = &monitor_def[0];
110 1.1 chopps #define MAXPIXELCLOCK 135000000 /* safety */
111 1.1 chopps
112 1.6 chopps /* generated by gen_cvtab.c */
113 1.6 chopps static int cv_convtab[31] = {
114 1.6 chopps 163, 148, 135, 124, 114,
115 1.6 chopps 106, 98, 91, 85, 79,
116 1.6 chopps 74, 69, 65, 61, 57,
117 1.6 chopps 53, 50, 47, 44, 42,
118 1.6 chopps 39, 37, 35, 33, 31,
119 1.6 chopps 29, 27, 26, 24, 22,
120 1.6 chopps 21,
121 1.6 chopps };
122 1.1 chopps
123 1.1 chopps /* Console display definition.
124 1.1 chopps * Default hardcoded text mode. This grf_cv is set up to
125 1.1 chopps * use one text mode only, and this is it. You may use
126 1.1 chopps * grfconfig to change the mode after boot.
127 1.1 chopps */
128 1.1 chopps
129 1.1 chopps /* Console font */
130 1.1 chopps #define S3FONT kernel_font_8x8
131 1.1 chopps #define S3FONTX 8
132 1.1 chopps #define S3FONTY 8
133 1.1 chopps extern unsigned char S3FONT[];
134 1.1 chopps
135 1.1 chopps struct grfcvtext_mode cvconsole_mode = {
136 1.3 chopps {255, "", 25000000, 640, 400, 4, 640, 656, 672, 720, 760, 406,
137 1.1 chopps 441, 412, 426, 447},
138 1.1 chopps S3FONTX, S3FONTY, 80, 506/S3FONTY, S3FONT, 32, 255
139 1.1 chopps };
140 1.1 chopps
141 1.1 chopps /* Console colors */
142 1.1 chopps unsigned char cvconscolors[3][3] = { /* background, foreground, hilite */
143 1.1 chopps {0,0x40,0x50}, {152,152,152}, {255,255,255}
144 1.1 chopps };
145 1.1 chopps
146 1.1 chopps
147 1.1 chopps /* Board Address of CV64 */
148 1.1 chopps
149 1.4 jtc static volatile caddr_t cv_boardaddr;
150 1.1 chopps static int cv_fbsize;
151 1.1 chopps
152 1.1 chopps int
153 1.1 chopps grfcv_cnprobe()
154 1.1 chopps {
155 1.1 chopps int rv;
156 1.1 chopps rv = CN_DEAD;
157 1.2 chopps return (rv);
158 1.1 chopps }
159 1.1 chopps
160 1.1 chopps /* standard driver stuff */
161 1.1 chopps struct cfdriver grfcvcd = {
162 1.1 chopps NULL, "grfcv", (cfmatch_t)grfcvmatch, grfcvattach,
163 1.1 chopps DV_DULL, sizeof(struct grf_softc), NULL, 0
164 1.1 chopps };
165 1.1 chopps static struct cfdata *cfdata;
166 1.1 chopps
167 1.1 chopps
168 1.1 chopps /* Reads from the fb must be done at addr + 0x02000000 */
169 1.1 chopps #define READ_OFFSET 0x02000000
170 1.1 chopps
171 1.1 chopps /*
172 1.1 chopps * Get frambuffer memory size.
173 1.1 chopps * phase5 didn't provide the bit in CR36,
174 1.1 chopps * so we have to do it this way.
175 1.1 chopps * Return 0 for 2MB, 1 for 4MB
176 1.1 chopps */
177 1.1 chopps
178 1.1 chopps static int
179 1.1 chopps cv_has_4mb (volatile char *fb)
180 1.1 chopps {
181 1.1 chopps volatile unsigned long *testfbw, *testfbr;
182 1.1 chopps
183 1.1 chopps /* write patterns in memory and test if they can be read */
184 1.1 chopps testfbw = (volatile unsigned long *) fb;
185 1.1 chopps *testfbw = 0x87654321;
186 1.1 chopps testfbr = (volatile unsigned long *)(fb + READ_OFFSET);
187 1.1 chopps if (*testfbr != 0x87654321)
188 1.2 chopps return (0);
189 1.1 chopps /* upper memory region */
190 1.1 chopps testfbw = (volatile unsigned long *)(fb + 0x00200000);
191 1.1 chopps testfbr = (volatile unsigned long *)(fb + 0x00200000 + READ_OFFSET);
192 1.1 chopps *testfbw = 0x87654321;
193 1.1 chopps if (*testfbr != 0x87654321)
194 1.2 chopps return (0);
195 1.1 chopps *testfbw = 0xAAAAAAAA;
196 1.1 chopps if (*testfbr != 0xAAAAAAAA)
197 1.2 chopps return (0);
198 1.1 chopps *testfbw = 0x55555555;
199 1.1 chopps if (*testfbr != 0x55555555)
200 1.2 chopps return (0);
201 1.2 chopps return (1);
202 1.1 chopps }
203 1.1 chopps
204 1.1 chopps int
205 1.1 chopps grfcvmatch(pdp, cfp, auxp)
206 1.1 chopps struct device *pdp;
207 1.1 chopps struct cfdata *cfp;
208 1.1 chopps void *auxp;
209 1.1 chopps {
210 1.1 chopps struct zbus_args *zap;
211 1.1 chopps
212 1.1 chopps zap = auxp;
213 1.1 chopps
214 1.1 chopps #ifndef CV64CONSOLE
215 1.1 chopps if (amiga_realconfig == 0)
216 1.2 chopps return (0);
217 1.1 chopps #endif
218 1.1 chopps
219 1.1 chopps /* Lets be Paranoid: Test man and prod id */
220 1.1 chopps if (zap->manid != 8512 || zap->prodid != 34)
221 1.2 chopps return (0);
222 1.1 chopps
223 1.1 chopps cv_boardaddr = zap->va;
224 1.1 chopps
225 1.1 chopps #ifdef CV64CONSOLE
226 1.1 chopps if (amiga_realconfig == 0) {
227 1.1 chopps cfdata = cfp;
228 1.1 chopps }
229 1.1 chopps #endif
230 1.1 chopps
231 1.2 chopps return (1);
232 1.1 chopps }
233 1.1 chopps
234 1.1 chopps void
235 1.1 chopps grfcvattach(pdp, dp, auxp)
236 1.1 chopps struct device *pdp, *dp;
237 1.1 chopps void *auxp;
238 1.1 chopps {
239 1.1 chopps struct zbus_args *zap;
240 1.1 chopps struct grf_softc *gp;
241 1.1 chopps
242 1.1 chopps zap = auxp;
243 1.1 chopps
244 1.1 chopps printf("\n");
245 1.1 chopps
246 1.4 jtc gp = (struct grf_softc *)dp;
247 1.1 chopps
248 1.4 jtc gp->g_regkva = (volatile caddr_t)cv_boardaddr + READ_OFFSET;
249 1.4 jtc gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
250 1.1 chopps
251 1.4 jtc gp->g_unit = GRF_CV64_UNIT;
252 1.4 jtc gp->g_mode = cv_mode;
253 1.4 jtc gp->g_conpri = grfcv_cnprobe();
254 1.4 jtc gp->g_flags = GF_ALIVE;
255 1.1 chopps
256 1.4 jtc /* wakeup the board */
257 1.4 jtc cv_boardinit(gp);
258 1.1 chopps
259 1.1 chopps #ifdef CV64CONSOLE
260 1.4 jtc grfcv_iteinit(gp);
261 1.4 jtc (void)cv_load_mon(gp, &cvconsole_mode);
262 1.1 chopps #endif
263 1.1 chopps
264 1.1 chopps /*
265 1.4 jtc * attach grf
266 1.1 chopps */
267 1.4 jtc if (amiga_config_found(cfdata, &gp->g_device, gp, grfcvprint))
268 1.1 chopps printf("grfcv: CyberVision64 with %dMB being used\n", cv_fbsize/0x100000);
269 1.1 chopps }
270 1.1 chopps
271 1.1 chopps int
272 1.1 chopps grfcvprint(auxp, pnp)
273 1.1 chopps void *auxp;
274 1.1 chopps char *pnp;
275 1.1 chopps {
276 1.1 chopps if (pnp)
277 1.1 chopps printf("ite at %s: ", pnp);
278 1.2 chopps return (UNCONF);
279 1.1 chopps }
280 1.1 chopps
281 1.1 chopps
282 1.1 chopps /*
283 1.1 chopps * Computes M, N, and R values from
284 1.1 chopps * given input frequency. It uses a table of
285 1.1 chopps * precomputed values, to keep CPU time low.
286 1.1 chopps *
287 1.1 chopps * The return value consist of:
288 1.1 chopps * lower byte: Bits 4-0: N Divider Value
289 1.1 chopps * Bits 5-6: R Value for e.g. SR10 or SR12
290 1.1 chopps * higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
291 1.1 chopps */
292 1.1 chopps
293 1.1 chopps static unsigned short
294 1.1 chopps compute_clock(freq)
295 1.1 chopps unsigned long freq;
296 1.1 chopps {
297 1.1 chopps
298 1.1 chopps static unsigned char *mnr, *save; /* M, N + R vals */
299 1.1 chopps unsigned long work_freq, r;
300 1.1 chopps unsigned short erg;
301 1.1 chopps long diff, d2;
302 1.1 chopps
303 1.1 chopps /* 0xBEBC20 = 12.5M */
304 1.1 chopps /* 0x080BEFC0 = 135M */
305 1.1 chopps if (freq < 0x00BEBC20 || freq > 0x080BEFC0) {
306 1.1 chopps printf("grfcv: Wrong clock frequency: %dMHz", freq/1000000);
307 1.1 chopps printf("grfcv: Using default frequency: 25MHz");
308 1.1 chopps freq = 0x017D7840;
309 1.1 chopps }
310 1.1 chopps
311 1.1 chopps mnr = clocks; /* there the vals are stored */
312 1.1 chopps d2 = 0x7fffffff;
313 1.1 chopps
314 1.1 chopps while (*mnr) { /* mnr vals are 0-terminated */
315 1.1 chopps work_freq = (0x37EE * (mnr[0] + 2)) / ((mnr[1] & 0x1F) + 2);
316 1.1 chopps
317 1.1 chopps r = (mnr[1] >> 5) & 0x03;
318 1.1 chopps if (r != 0)
319 1.1 chopps work_freq=work_freq >> r; /* r is the freq divider */
320 1.1 chopps
321 1.1 chopps work_freq *= 0x3E8; /* 2nd part of OSC */
322 1.1 chopps
323 1.1 chopps diff = abs(freq - work_freq);
324 1.1 chopps
325 1.1 chopps if (d2 >= diff) {
326 1.1 chopps d2 = diff;
327 1.1 chopps /* In save are the vals for minimal diff */
328 1.1 chopps save = mnr;
329 1.1 chopps }
330 1.1 chopps mnr += 2;
331 1.1 chopps }
332 1.1 chopps erg = *((unsigned short *)save);
333 1.1 chopps
334 1.1 chopps return (erg);
335 1.1 chopps }
336 1.1 chopps
337 1.1 chopps
338 1.1 chopps void
339 1.1 chopps cv_boardinit(gp)
340 1.1 chopps struct grf_softc *gp;
341 1.1 chopps {
342 1.4 jtc volatile caddr_t ba = gp->g_regkva;
343 1.1 chopps unsigned char test;
344 1.1 chopps unsigned int clockpar;
345 1.1 chopps int i;
346 1.4 jtc struct grfinfo *gi;
347 1.1 chopps
348 1.1 chopps /* Reset board */
349 1.1 chopps for (i = 0; i < 6; i++)
350 1.1 chopps cv_write_port (0xff, ba - READ_OFFSET); /* Clear all bits */
351 1.1 chopps
352 1.1 chopps /* Return to operational Mode */
353 1.1 chopps cv_write_port(0x8004, ba - READ_OFFSET);
354 1.1 chopps
355 1.1 chopps /* Wakeup Chip */
356 1.1 chopps vgaw(ba, SREG_VIDEO_SUBS_ENABLE, 0x10);
357 1.1 chopps vgaw(ba, SREG_OPTION_SELECT, 0x1);
358 1.1 chopps vgaw(ba, SREG_VIDEO_SUBS_ENABLE, 0x8);
359 1.1 chopps
360 1.1 chopps vgaw(ba, GREG_MISC_OUTPUT_W, 0x23);
361 1.1 chopps
362 1.1 chopps WCrt(ba, CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock S3 VGA regs */
363 1.1 chopps WCrt(ba, CRT_ID_REGISTER_LOCK_2, 0xA5); /* unlock syscontrol */
364 1.1 chopps
365 1.1 chopps test = RCrt(ba, CRT_ID_SYSTEM_CONFIG);
366 1.1 chopps test = test | 0x01; /* enable enhaced register access */
367 1.1 chopps test = test & 0xEF; /* clear bit 4, 0 wait state */
368 1.1 chopps WCrt(ba, CRT_ID_SYSTEM_CONFIG, test);
369 1.1 chopps
370 1.1 chopps /*
371 1.1 chopps * bit 1=1: enable enhanced mode functions
372 1.1 chopps * bit 4=1: enable linear adressing
373 1.1 chopps */
374 1.1 chopps vgaw(ba, ECR_ADV_FUNC_CNTL, 0x11);
375 1.1 chopps
376 1.1 chopps /* enable cpu acess, color mode, high 64k page */
377 1.1 chopps vgaw(ba, GREG_MISC_OUTPUT_W, 0x23);
378 1.1 chopps
379 1.1 chopps /* Cpu base addr */
380 1.1 chopps WCrt(ba, CRT_ID_EXT_SYS_CNTL_4, 0x0);
381 1.1 chopps
382 1.1 chopps /* Reset. This does nothing, but everyone does it:) */
383 1.1 chopps WSeq(ba, SEQ_ID_RESET, 0x3);
384 1.1 chopps
385 1.1 chopps WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x1); /* 8 Dot Clock */
386 1.1 chopps WSeq(ba, SEQ_ID_MAP_MASK, 0xF); /* Enable write planes */
387 1.1 chopps WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x0); /* Character Font */
388 1.1 chopps
389 1.1 chopps WSeq(ba, SEQ_ID_MEMORY_MODE, 0x2); /* Complete mem access */
390 1.1 chopps
391 1.1 chopps WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x6); /* Unlock extensions */
392 1.1 chopps test = RSeq(ba, SEQ_ID_BUS_REQ_CNTL); /* Bus Request */
393 1.1 chopps
394 1.1 chopps /* enable 4MB fast Page Mode */
395 1.1 chopps test = test | 1 << 6;
396 1.1 chopps WSeq(ba, SEQ_ID_BUS_REQ_CNTL, test);
397 1.4 jtc /* faster LUT write */
398 1.4 jtc WSeq(ba, SEQ_ID_RAMDAC_CNTL, 0x40);
399 1.1 chopps
400 1.1 chopps test = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2); /* Clksyn2 read */
401 1.1 chopps
402 1.1 chopps /* immediately Clkload bit clear */
403 1.1 chopps test = test & 0xDF;
404 1.1 chopps WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, test);
405 1.1 chopps
406 1.1 chopps clockpar = compute_clock(0x3473BC0);
407 1.1 chopps test = (clockpar & 0xFF00) >> 8;
408 1.1 chopps
409 1.5 chopps if (RCrt(ba, CRT_ID_REVISION) == 0x10) {
410 1.5 chopps WSeq(ba, SEQ_ID_MCLK_HI, test); /* PLL N-Divider Value */
411 1.5 chopps
412 1.5 chopps test = clockpar & 0xFF;
413 1.5 chopps WSeq(ba, SEQ_ID_MCLK_LO, test); /* PLL M-Divider Value */
414 1.5 chopps
415 1.5 chopps test = (clockpar & 0xFF00) >> 8;
416 1.5 chopps WSeq(ba, SEQ_ID_MORE_MAGIC, test);
417 1.5 chopps } else {
418 1.5 chopps WSeq(ba, SEQ_ID_MCLK_HI, test); /* PLL N-Divider Value */
419 1.5 chopps
420 1.5 chopps test = clockpar & 0xFF;
421 1.5 chopps WSeq(ba, SEQ_ID_MCLK_LO, test); /* PLL M-Divider Value */
422 1.5 chopps }
423 1.1 chopps
424 1.1 chopps /* We now load an 25 MHz, 31 kHz, 640x480 standard VGA Mode. */
425 1.1 chopps /* DCLK */
426 1.1 chopps WSeq(ba, SEQ_ID_DCLK_HI, 0x13);
427 1.1 chopps WSeq(ba, SEQ_ID_DCLK_LO, 0x41);
428 1.1 chopps
429 1.1 chopps test = RSeq (ba, SEQ_ID_CLKSYN_CNTL_2);
430 1.1 chopps test = test | 0x22;
431 1.1 chopps
432 1.1 chopps /* DCLK + MCLK Clock immediate load! */
433 1.1 chopps WSeq(ba,SEQ_ID_CLKSYN_CNTL_2, test);
434 1.1 chopps
435 1.1 chopps /* DCLK load */
436 1.1 chopps test = vgar(ba, 0x3cc);
437 1.1 chopps test = test | 0x0c;
438 1.1 chopps vgaw(ba, 0x3c2, test);
439 1.1 chopps
440 1.1 chopps /* Clear bit 5 again, prevent further loading. */
441 1.1 chopps WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, 0x2);
442 1.1 chopps
443 1.1 chopps WCrt(ba, CRT_ID_HOR_TOTAL, 0x5F);
444 1.1 chopps WCrt(ba, CRT_ID_HOR_DISP_ENA_END, 0x4F);
445 1.1 chopps WCrt(ba, CRT_ID_START_HOR_BLANK, 0x50);
446 1.1 chopps WCrt(ba, CRT_ID_END_HOR_BLANK, 0x82);
447 1.1 chopps WCrt(ba, CRT_ID_START_HOR_RETR, 0x54);
448 1.1 chopps WCrt(ba, CRT_ID_END_HOR_RETR, 0x80);
449 1.1 chopps WCrt(ba, CRT_ID_VER_TOTAL, 0xBF);
450 1.1 chopps
451 1.1 chopps WCrt(ba, CRT_ID_OVERFLOW, 0x1F); /* overflow reg */
452 1.1 chopps
453 1.1 chopps WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x0); /* no panning */
454 1.1 chopps
455 1.1 chopps WCrt(ba, CRT_ID_MAX_SCAN_LINE, 0x40); /* vscan */
456 1.1 chopps
457 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, 0x00);
458 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, 0x00);
459 1.1 chopps
460 1.1 chopps /* Display start adress */
461 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
462 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
463 1.1 chopps
464 1.1 chopps /* Cursor location */
465 1.3 chopps WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
466 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
467 1.1 chopps
468 1.1 chopps /* Vertical retrace */
469 1.1 chopps WCrt(ba, CRT_ID_START_VER_RETR, 0x9C);
470 1.1 chopps WCrt(ba, CRT_ID_END_VER_RETR, 0x0E);
471 1.1 chopps
472 1.1 chopps WCrt(ba, CRT_ID_VER_DISP_ENA_END, 0x8F);
473 1.1 chopps WCrt(ba, CRT_ID_SCREEN_OFFSET, 0x50);
474 1.1 chopps
475 1.1 chopps WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x00);
476 1.1 chopps
477 1.1 chopps WCrt(ba, CRT_ID_START_VER_BLANK, 0x96);
478 1.1 chopps WCrt(ba, CRT_ID_END_VER_BLANK, 0xB9);
479 1.1 chopps
480 1.1 chopps WCrt(ba, CRT_ID_MODE_CONTROL, 0xE3);
481 1.1 chopps
482 1.1 chopps WCrt(ba, CRT_ID_LINE_COMPARE, 0xFF);
483 1.1 chopps
484 1.1 chopps WCrt(ba, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
485 1.1 chopps
486 1.1 chopps /* Refresh count 1, High speed text font, enhanced color mode */
487 1.1 chopps WCrt(ba, CRT_ID_MISC_1, 0x35);
488 1.1 chopps
489 1.1 chopps /* start fifo position */
490 1.1 chopps WCrt(ba, CRT_ID_DISPLAY_FIFO, 0x5a);
491 1.1 chopps
492 1.1 chopps WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, 0x70);
493 1.1 chopps
494 1.1 chopps /* address window position */
495 1.1 chopps WCrt(ba, CRT_ID_LAW_POS_LO, 0x40);
496 1.1 chopps
497 1.1 chopps /* N Parameter for Display FIFO */
498 1.1 chopps WCrt(ba, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
499 1.1 chopps
500 1.1 chopps WGfx(ba, GCT_ID_SET_RESET, 0x0);
501 1.1 chopps WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x0);
502 1.1 chopps WGfx(ba, GCT_ID_COLOR_COMPARE, 0x0);
503 1.1 chopps WGfx(ba, GCT_ID_DATA_ROTATE, 0x0);
504 1.1 chopps WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x0);
505 1.1 chopps WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
506 1.1 chopps WGfx(ba, GCT_ID_MISC, 0x01);
507 1.1 chopps WGfx(ba, GCT_ID_COLOR_XCARE, 0x0F);
508 1.1 chopps WGfx(ba, GCT_ID_BITMASK, 0xFF);
509 1.1 chopps
510 1.1 chopps /* colors for text mode */
511 1.1 chopps for (i = 0; i <= 0xf; i++)
512 1.1 chopps WAttr (ba, i, i);
513 1.1 chopps
514 1.4 jtc WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x41);
515 1.4 jtc WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x01);
516 1.4 jtc WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0F);
517 1.4 jtc WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x0);
518 1.4 jtc WAttr(ba, ACT_ID_COLOR_SELECT, 0x0);
519 1.1 chopps
520 1.1 chopps vgaw(ba, VDAC_MASK, 0xFF); /* DAC Mask */
521 1.1 chopps
522 1.1 chopps *((unsigned long *)(ba + ECR_FRGD_COLOR)) = 0xFF;
523 1.1 chopps *((unsigned long *)(ba + ECR_BKGD_COLOR)) = 0;
524 1.1 chopps
525 1.1 chopps /* colors initially set to greyscale */
526 1.1 chopps
527 1.1 chopps vgaw(ba, VDAC_ADDRESS_W, 0);
528 1.1 chopps for (i = 255; i >= 0 ; i--) {
529 1.1 chopps vgaw(ba, VDAC_DATA, i);
530 1.1 chopps vgaw(ba, VDAC_DATA, i);
531 1.1 chopps vgaw(ba, VDAC_DATA, i);
532 1.1 chopps }
533 1.1 chopps
534 1.1 chopps /* GFx hardware cursor off */
535 1.1 chopps WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
536 1.1 chopps
537 1.1 chopps /* Set first to 4 MB, so test will work */
538 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x13);
539 1.1 chopps
540 1.1 chopps /* find *correct* fbsize of z3 board */
541 1.1 chopps if (cv_has_4mb((volatile char *)cv_boardaddr + 0x01400000)) {
542 1.1 chopps cv_fbsize = 1024 * 1024 * 4;
543 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x13); /* 4 MB */
544 1.1 chopps } else {
545 1.1 chopps cv_fbsize = 1024 * 1024 * 2;
546 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x12); /* 2 MB */
547 1.1 chopps }
548 1.1 chopps
549 1.1 chopps /* If I knew what this really does... but it _is_ necessary
550 1.1 chopps to get any gfx on the screen!! Undocumented register? */
551 1.1 chopps WAttr(ba, 0x33, 0);
552 1.4 jtc
553 1.4 jtc gi = &gp->g_display;
554 1.4 jtc gi->gd_regaddr = (caddr_t) kvtop (ba);
555 1.4 jtc gi->gd_regsize = 64 * 1024;
556 1.4 jtc gi->gd_fbaddr = (caddr_t) kvtop (gp->g_fbkva);
557 1.4 jtc gi->gd_fbsize = cv_fbsize;
558 1.1 chopps }
559 1.1 chopps
560 1.1 chopps
561 1.1 chopps int
562 1.1 chopps cv_getvmode(gp, vm)
563 1.1 chopps struct grf_softc *gp;
564 1.1 chopps struct grfvideo_mode *vm;
565 1.1 chopps {
566 1.1 chopps struct grfvideo_mode *gv;
567 1.1 chopps
568 1.1 chopps #ifdef CV64CONSOLE
569 1.1 chopps /* Handle grabbing console mode */
570 1.1 chopps if (vm->mode_num == 255) {
571 1.1 chopps bcopy(&cvconsole_mode, vm, sizeof(struct grfvideo_mode));
572 1.2 chopps /* XXX so grfconfig can tell us the correct text dimensions. */
573 1.1 chopps vm->depth = cvconsole_mode.fy;
574 1.2 chopps } else
575 1.1 chopps #endif
576 1.2 chopps {
577 1.2 chopps if (vm->mode_num == 0)
578 1.2 chopps vm->mode_num = (monitor_current - monitor_def) + 1;
579 1.2 chopps if (vm->mode_num < 1 || vm->mode_num > monitor_def_max)
580 1.2 chopps return (EINVAL);
581 1.2 chopps gv = monitor_def + (vm->mode_num - 1);
582 1.2 chopps if (gv->mode_num == 0)
583 1.2 chopps return (EINVAL);
584 1.2 chopps
585 1.2 chopps bcopy(gv, vm, sizeof(struct grfvideo_mode));
586 1.2 chopps }
587 1.2 chopps
588 1.2 chopps /* adjust internal values to pixel values */
589 1.2 chopps
590 1.2 chopps vm->hblank_start *= 8;
591 1.2 chopps vm->hblank_stop *= 8;
592 1.2 chopps vm->hsync_start *= 8;
593 1.2 chopps vm->hsync_stop *= 8;
594 1.2 chopps vm->htotal *= 8;
595 1.1 chopps
596 1.2 chopps return (0);
597 1.1 chopps }
598 1.1 chopps
599 1.1 chopps
600 1.1 chopps int
601 1.1 chopps cv_setvmode(gp, mode)
602 1.1 chopps struct grf_softc *gp;
603 1.1 chopps unsigned mode;
604 1.1 chopps {
605 1.1 chopps if (!mode || (mode > monitor_def_max) ||
606 1.4 jtc monitor_def[mode - 1].mode_num == 0)
607 1.2 chopps return (EINVAL);
608 1.1 chopps
609 1.1 chopps monitor_current = monitor_def + (mode - 1);
610 1.1 chopps
611 1.2 chopps return (0);
612 1.1 chopps }
613 1.1 chopps
614 1.1 chopps
615 1.1 chopps int
616 1.1 chopps cv_blank(gp, on)
617 1.1 chopps struct grf_softc *gp;
618 1.1 chopps int *on;
619 1.1 chopps {
620 1.4 jtc volatile caddr_t ba = gp->g_regkva;
621 1.1 chopps
622 1.2 chopps gfx_on_off(*on ? 1 : 0, ba);
623 1.1 chopps return (0);
624 1.1 chopps }
625 1.1 chopps
626 1.1 chopps
627 1.1 chopps /*
628 1.1 chopps * Change the mode of the display.
629 1.1 chopps * Return a UNIX error number or 0 for success.
630 1.1 chopps */
631 1.1 chopps int
632 1.1 chopps cv_mode(gp, cmd, arg, a2, a3)
633 1.1 chopps register struct grf_softc *gp;
634 1.1 chopps int cmd;
635 1.1 chopps void *arg;
636 1.1 chopps int a2, a3;
637 1.1 chopps {
638 1.1 chopps int error;
639 1.1 chopps
640 1.1 chopps switch (cmd) {
641 1.1 chopps case GM_GRFON:
642 1.1 chopps error = cv_load_mon (gp,
643 1.1 chopps (struct grfcvtext_mode *) monitor_current) ? 0 : EINVAL;
644 1.2 chopps return (error);
645 1.1 chopps
646 1.1 chopps case GM_GRFOFF:
647 1.1 chopps #ifndef CV64CONSOLE
648 1.4 jtc (void)cv_toggle(gp);
649 1.1 chopps #else
650 1.1 chopps cv_load_mon(gp, &cvconsole_mode);
651 1.1 chopps #endif
652 1.2 chopps return (0);
653 1.1 chopps
654 1.1 chopps case GM_GRFCONFIG:
655 1.2 chopps return (0);
656 1.1 chopps
657 1.1 chopps case GM_GRFGETVMODE:
658 1.2 chopps return (cv_getvmode (gp, (struct grfvideo_mode *) arg));
659 1.1 chopps
660 1.1 chopps case GM_GRFSETVMODE:
661 1.1 chopps error = cv_setvmode (gp, *(unsigned *) arg);
662 1.1 chopps if (!error && (gp->g_flags & GF_GRFON))
663 1.1 chopps cv_load_mon(gp,
664 1.1 chopps (struct grfcvtext_mode *) monitor_current);
665 1.2 chopps return (error);
666 1.1 chopps
667 1.1 chopps case GM_GRFGETNUMVM:
668 1.1 chopps *(int *)arg = monitor_def_max;
669 1.2 chopps return (0);
670 1.1 chopps
671 1.1 chopps case GM_GRFIOCTL:
672 1.2 chopps return (cv_ioctl (gp, (int) arg, (caddr_t) a2));
673 1.1 chopps
674 1.1 chopps default:
675 1.1 chopps break;
676 1.1 chopps }
677 1.1 chopps
678 1.2 chopps return (EINVAL);
679 1.1 chopps }
680 1.1 chopps
681 1.1 chopps int
682 1.1 chopps cv_ioctl (gp, cmd, data)
683 1.1 chopps register struct grf_softc *gp;
684 1.1 chopps int cmd;
685 1.1 chopps void *data;
686 1.1 chopps {
687 1.1 chopps switch (cmd) {
688 1.1 chopps case GRFIOCGSPRITEPOS:
689 1.1 chopps case GRFIOCSSPRITEPOS:
690 1.1 chopps case GRFIOCSSPRITEINF:
691 1.1 chopps case GRFIOCGSPRITEINF:
692 1.1 chopps case GRFIOCGSPRITEMAX:
693 1.1 chopps break;
694 1.1 chopps
695 1.1 chopps case GRFIOCGETCMAP:
696 1.2 chopps return (cv_getcmap (gp, (struct grf_colormap *) data));
697 1.1 chopps
698 1.1 chopps case GRFIOCPUTCMAP:
699 1.2 chopps return (cv_putcmap (gp, (struct grf_colormap *) data));
700 1.1 chopps
701 1.1 chopps case GRFIOCBITBLT:
702 1.1 chopps break;
703 1.1 chopps
704 1.1 chopps case GRFTOGGLE:
705 1.4 jtc return (cv_toggle (gp));
706 1.1 chopps
707 1.1 chopps case GRFIOCSETMON:
708 1.2 chopps return (cv_setmonitor (gp, (struct grfvideo_mode *)data));
709 1.1 chopps
710 1.1 chopps case GRFIOCBLANK:
711 1.2 chopps return (cv_blank (gp, (int *)data));
712 1.1 chopps }
713 1.2 chopps return (EINVAL);
714 1.1 chopps }
715 1.1 chopps
716 1.1 chopps int
717 1.1 chopps cv_setmonitor(gp, gv)
718 1.1 chopps struct grf_softc *gp;
719 1.1 chopps struct grfvideo_mode *gv;
720 1.1 chopps {
721 1.1 chopps struct grfvideo_mode *md;
722 1.1 chopps
723 1.2 chopps if (!cv_mondefok(gv))
724 1.2 chopps return (EINVAL);
725 1.2 chopps
726 1.1 chopps #ifdef CV64CONSOLE
727 1.1 chopps /* handle interactive setting of console mode */
728 1.2 chopps if (gv->mode_num == 255) {
729 1.1 chopps bcopy(gv, &cvconsole_mode.gv, sizeof(struct grfvideo_mode));
730 1.2 chopps cvconsole_mode.gv.hblank_start /= 8;
731 1.2 chopps cvconsole_mode.gv.hblank_stop /= 8;
732 1.2 chopps cvconsole_mode.gv.hsync_start /= 8;
733 1.2 chopps cvconsole_mode.gv.hsync_stop /= 8;
734 1.2 chopps cvconsole_mode.gv.htotal /= 8;
735 1.1 chopps cvconsole_mode.rows = gv->disp_height / cvconsole_mode.fy;
736 1.1 chopps cvconsole_mode.cols = gv->disp_width / cvconsole_mode.fx;
737 1.1 chopps if (!(gp->g_flags & GF_GRFON))
738 1.1 chopps cv_load_mon(gp, &cvconsole_mode);
739 1.1 chopps ite_reinit(gp->g_itedev);
740 1.2 chopps return (0);
741 1.1 chopps }
742 1.1 chopps #endif
743 1.1 chopps
744 1.2 chopps md = monitor_def + (gv->mode_num - 1);
745 1.2 chopps bcopy(gv, md, sizeof(struct grfvideo_mode));
746 1.1 chopps
747 1.2 chopps /* adjust pixel oriented values to internal rep. */
748 1.1 chopps
749 1.2 chopps md->hblank_start /= 8;
750 1.2 chopps md->hblank_stop /= 8;
751 1.2 chopps md->hsync_start /= 8;
752 1.2 chopps md->hsync_stop /= 8;
753 1.2 chopps md->htotal /= 8;
754 1.1 chopps
755 1.2 chopps return (0);
756 1.1 chopps }
757 1.1 chopps
758 1.1 chopps int
759 1.1 chopps cv_getcmap(gfp, cmap)
760 1.1 chopps struct grf_softc *gfp;
761 1.1 chopps struct grf_colormap *cmap;
762 1.1 chopps {
763 1.4 jtc volatile caddr_t ba;
764 1.1 chopps u_char red[256], green[256], blue[256], *rp, *gp, *bp;
765 1.1 chopps short x;
766 1.1 chopps int error;
767 1.1 chopps
768 1.1 chopps if (cmap->count == 0 || cmap->index >= 256)
769 1.2 chopps return (0);
770 1.1 chopps
771 1.1 chopps if (cmap->index + cmap->count > 256)
772 1.1 chopps cmap->count = 256 - cmap->index;
773 1.1 chopps
774 1.1 chopps ba = gfp->g_regkva;
775 1.1 chopps /* first read colors out of the chip, then copyout to userspace */
776 1.1 chopps vgaw (ba, VDAC_ADDRESS_W, cmap->index);
777 1.1 chopps x = cmap->count - 1;
778 1.1 chopps
779 1.1 chopps rp = red + cmap->index;
780 1.1 chopps gp = green + cmap->index;
781 1.1 chopps bp = blue + cmap->index;
782 1.1 chopps
783 1.1 chopps do {
784 1.1 chopps *rp++ = vgar (ba, VDAC_DATA) << 2;
785 1.1 chopps *gp++ = vgar (ba, VDAC_DATA) << 2;
786 1.1 chopps *bp++ = vgar (ba, VDAC_DATA) << 2;
787 1.1 chopps } while (x-- > 0);
788 1.1 chopps
789 1.1 chopps if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
790 1.1 chopps && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
791 1.1 chopps && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
792 1.2 chopps return (0);
793 1.1 chopps
794 1.2 chopps return (error);
795 1.1 chopps }
796 1.1 chopps
797 1.1 chopps int
798 1.1 chopps cv_putcmap(gfp, cmap)
799 1.1 chopps struct grf_softc *gfp;
800 1.1 chopps struct grf_colormap *cmap;
801 1.1 chopps {
802 1.4 jtc volatile caddr_t ba;
803 1.1 chopps u_char red[256], green[256], blue[256], *rp, *gp, *bp;
804 1.1 chopps short x;
805 1.1 chopps int error;
806 1.1 chopps
807 1.1 chopps if (cmap->count == 0 || cmap->index >= 256)
808 1.2 chopps return (0);
809 1.1 chopps
810 1.1 chopps if (cmap->index + cmap->count > 256)
811 1.1 chopps cmap->count = 256 - cmap->index;
812 1.1 chopps
813 1.1 chopps /* first copy the colors into kernelspace */
814 1.1 chopps if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
815 1.1 chopps && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
816 1.1 chopps && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
817 1.1 chopps ba = gfp->g_regkva;
818 1.1 chopps vgaw (ba, VDAC_ADDRESS_W, cmap->index);
819 1.1 chopps x = cmap->count - 1;
820 1.1 chopps
821 1.1 chopps rp = red + cmap->index;
822 1.1 chopps gp = green + cmap->index;
823 1.1 chopps bp = blue + cmap->index;
824 1.1 chopps
825 1.1 chopps do {
826 1.1 chopps vgaw (ba, VDAC_DATA, *rp++ >> 2);
827 1.1 chopps vgaw (ba, VDAC_DATA, *gp++ >> 2);
828 1.1 chopps vgaw (ba, VDAC_DATA, *bp++ >> 2);
829 1.1 chopps } while (x-- > 0);
830 1.2 chopps return (0);
831 1.2 chopps } else
832 1.2 chopps return (error);
833 1.1 chopps }
834 1.1 chopps
835 1.1 chopps
836 1.1 chopps int
837 1.4 jtc cv_toggle(gp)
838 1.1 chopps struct grf_softc *gp;
839 1.1 chopps {
840 1.4 jtc volatile caddr_t ba;
841 1.1 chopps
842 1.4 jtc ba = gp->g_regkva;
843 1.4 jtc cvscreen(1, ba - READ_OFFSET);
844 1.1 chopps
845 1.2 chopps return (0);
846 1.1 chopps }
847 1.1 chopps
848 1.1 chopps
849 1.1 chopps int
850 1.2 chopps cv_mondefok(gv)
851 1.2 chopps struct grfvideo_mode *gv;
852 1.1 chopps {
853 1.2 chopps unsigned long maxpix;
854 1.2 chopps
855 1.2 chopps if (gv->mode_num < 1 || gv->mode_num > monitor_def_max)
856 1.2 chopps if (gv->mode_num != 255 || gv->depth != 4)
857 1.2 chopps return (0);
858 1.1 chopps
859 1.2 chopps switch(gv->depth) {
860 1.1 chopps case 1:
861 1.1 chopps case 4:
862 1.3 chopps /* Remove this comment when ite5 is ready */
863 1.2 chopps /* if (gv->mode_num != 255) */
864 1.2 chopps return (0);
865 1.1 chopps case 8:
866 1.2 chopps maxpix = MAXPIXELCLOCK;
867 1.2 chopps break;
868 1.1 chopps case 15:
869 1.1 chopps case 16:
870 1.2 chopps maxpix = MAXPIXELCLOCK - 55000000;
871 1.2 chopps break;
872 1.1 chopps case 24:
873 1.2 chopps maxpix = MAXPIXELCLOCK - 85000000;
874 1.2 chopps break;
875 1.1 chopps default:
876 1.2 chopps return (0);
877 1.1 chopps }
878 1.2 chopps
879 1.2 chopps if (gv->pixel_clock > maxpix)
880 1.2 chopps return (0);
881 1.2 chopps return (1);
882 1.1 chopps }
883 1.1 chopps
884 1.1 chopps int
885 1.1 chopps cv_load_mon(gp, md)
886 1.1 chopps struct grf_softc *gp;
887 1.1 chopps struct grfcvtext_mode *md;
888 1.1 chopps {
889 1.1 chopps struct grfvideo_mode *gv;
890 1.1 chopps struct grfinfo *gi;
891 1.4 jtc volatile caddr_t ba, fb;
892 1.1 chopps unsigned short mnr;
893 1.2 chopps unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
894 1.2 chopps VSE, VT;
895 1.1 chopps char LACE, DBLSCAN, TEXT;
896 1.1 chopps int uplim, lowlim;
897 1.4 jtc int cr33, sr15, sr18, clock_mode, test;
898 1.6 chopps int m, n, clock, i; /* For calc'ing display FIFO */
899 1.1 chopps
900 1.1 chopps /* identity */
901 1.1 chopps gv = &md->gv;
902 1.1 chopps TEXT = (gv->depth == 4);
903 1.1 chopps
904 1.1 chopps if (!cv_mondefok(gv)) {
905 1.1 chopps printf("mondef not ok\n");
906 1.2 chopps return (0);
907 1.1 chopps }
908 1.1 chopps ba = gp->g_regkva;
909 1.1 chopps fb = gp->g_fbkva;
910 1.1 chopps
911 1.3 chopps /* turn gfx off, don't mess up the display */
912 1.3 chopps gfx_on_off(1, ba);
913 1.3 chopps
914 1.2 chopps /* provide all needed information in grf device-independant locations */
915 1.1 chopps gp->g_data = (caddr_t) gv;
916 1.1 chopps gi = &gp->g_display;
917 1.1 chopps gi->gd_colors = 1 << gv->depth;
918 1.1 chopps gi->gd_planes = gv->depth;
919 1.1 chopps gi->gd_fbwidth = gv->disp_width;
920 1.1 chopps gi->gd_fbheight = gv->disp_height;
921 1.1 chopps gi->gd_fbx = 0;
922 1.1 chopps gi->gd_fby = 0;
923 1.1 chopps if (TEXT) {
924 1.1 chopps gi->gd_dwidth = md->fx * md->cols;
925 1.1 chopps gi->gd_dheight = md->fy * md->rows;
926 1.1 chopps } else {
927 1.1 chopps gi->gd_dwidth = gv->disp_width;
928 1.1 chopps gi->gd_dheight = gv->disp_height;
929 1.1 chopps }
930 1.1 chopps gi->gd_dx = 0;
931 1.1 chopps gi->gd_dy = 0;
932 1.1 chopps
933 1.1 chopps /* get display mode parameters */
934 1.1 chopps
935 1.1 chopps HBS = gv->hblank_start;
936 1.1 chopps HBE = gv->hblank_stop;
937 1.1 chopps HSS = gv->hsync_start;
938 1.1 chopps HSE = gv->hsync_stop;
939 1.4 jtc HT = gv->htotal - 5;
940 1.4 jtc VBS = gv->vblank_start - 1;
941 1.1 chopps VSS = gv->vsync_start;
942 1.1 chopps VSE = gv->vsync_stop;
943 1.1 chopps VBE = gv->vblank_stop;
944 1.4 jtc VT = gv->vtotal - 2;
945 1.1 chopps
946 1.1 chopps if (TEXT)
947 1.1 chopps HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
948 1.1 chopps else
949 1.1 chopps HDE = (gv->disp_width + 3) / 8 - 1; /*HBS;*/
950 1.1 chopps VDE = gv->disp_height - 1;
951 1.1 chopps
952 1.1 chopps /* figure out whether lace or dblscan is needed */
953 1.1 chopps
954 1.1 chopps uplim = gv->disp_height + (gv->disp_height / 4);
955 1.1 chopps lowlim = gv->disp_height - (gv->disp_height / 4);
956 1.1 chopps LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
957 1.1 chopps DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
958 1.1 chopps
959 1.1 chopps /* adjustments */
960 1.1 chopps
961 1.1 chopps if (LACE)
962 1.1 chopps VDE /= 2;
963 1.1 chopps
964 1.1 chopps WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
965 1.1 chopps WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
966 1.1 chopps WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff);
967 1.1 chopps WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
968 1.1 chopps
969 1.1 chopps /* Set clock */
970 1.1 chopps
971 1.1 chopps switch (gv->depth) {
972 1.1 chopps case 15:
973 1.1 chopps case 16:
974 1.1 chopps mnr = compute_clock(gv->pixel_clock * 2);
975 1.1 chopps break;
976 1.1 chopps case 24:
977 1.1 chopps mnr = compute_clock(gv->pixel_clock * 3);
978 1.1 chopps break;
979 1.1 chopps default:
980 1.1 chopps mnr = compute_clock(gv->pixel_clock);
981 1.1 chopps break;
982 1.1 chopps }
983 1.1 chopps
984 1.1 chopps WSeq(ba, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8) );
985 1.1 chopps WSeq(ba, SEQ_ID_DCLK_LO, (mnr & 0xFF));
986 1.1 chopps
987 1.1 chopps /* load display parameters into board */
988 1.1 chopps
989 1.1 chopps WCrt(ba, CRT_ID_EXT_HOR_OVF,
990 1.1 chopps ((HT & 0x100) ? 0x01 : 0x00) |
991 1.1 chopps ((HDE & 0x100) ? 0x02 : 0x00) |
992 1.1 chopps ((HBS & 0x100) ? 0x04 : 0x00) |
993 1.3 chopps /* ((HBE & 0x40) ? 0x08 : 0x00) | */ /* Later... */
994 1.1 chopps ((HSS & 0x100) ? 0x10 : 0x00) |
995 1.3 chopps /* ((HSE & 0x20) ? 0x20 : 0x00) | */
996 1.1 chopps (((HT-5) & 0x100) ? 0x40 : 0x00) );
997 1.1 chopps
998 1.1 chopps WCrt(ba, CRT_ID_EXT_VER_OVF,
999 1.1 chopps 0x40 | /* Line compare */
1000 1.1 chopps ((VT & 0x400) ? 0x01 : 0x00) |
1001 1.1 chopps ((VDE & 0x400) ? 0x02 : 0x00) |
1002 1.1 chopps ((VBS & 0x400) ? 0x04 : 0x00) |
1003 1.1 chopps ((VSS & 0x400) ? 0x10 : 0x00) );
1004 1.1 chopps
1005 1.1 chopps WCrt(ba, CRT_ID_HOR_TOTAL, HT);
1006 1.1 chopps WCrt(ba, CRT_ID_DISPLAY_FIFO, HT - 5);
1007 1.1 chopps
1008 1.1 chopps WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
1009 1.1 chopps WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
1010 1.1 chopps WCrt(ba, CRT_ID_END_HOR_BLANK, ((HBE & 0x1f) | 0x80));
1011 1.1 chopps WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
1012 1.1 chopps WCrt(ba, CRT_ID_END_HOR_RETR,
1013 1.1 chopps (HSE & 0x1f) |
1014 1.1 chopps ((HBE & 0x20) ? 0x80 : 0x00) );
1015 1.1 chopps WCrt(ba, CRT_ID_VER_TOTAL, VT);
1016 1.1 chopps WCrt(ba, CRT_ID_OVERFLOW,
1017 1.1 chopps 0x10 |
1018 1.1 chopps ((VT & 0x100) ? 0x01 : 0x00) |
1019 1.1 chopps ((VDE & 0x100) ? 0x02 : 0x00) |
1020 1.1 chopps ((VSS & 0x100) ? 0x04 : 0x00) |
1021 1.1 chopps ((VBS & 0x100) ? 0x08 : 0x00) |
1022 1.1 chopps ((VT & 0x200) ? 0x20 : 0x00) |
1023 1.1 chopps ((VDE & 0x200) ? 0x40 : 0x00) |
1024 1.1 chopps ((VSS & 0x200) ? 0x80 : 0x00) );
1025 1.1 chopps
1026 1.1 chopps WCrt(ba, CRT_ID_MAX_SCAN_LINE,
1027 1.1 chopps 0x40 | /* TEXT ? 0x00 ??? */
1028 1.1 chopps (DBLSCAN ? 0x80 : 0x00) |
1029 1.1 chopps ((VBS & 0x200) ? 0x20 : 0x00) |
1030 1.1 chopps (TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
1031 1.1 chopps
1032 1.1 chopps WCrt(ba, CRT_ID_MODE_CONTROL,
1033 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0xc3 : 0xe3));
1034 1.1 chopps
1035 1.1 chopps /* text cursor */
1036 1.1 chopps
1037 1.1 chopps if (TEXT) {
1038 1.1 chopps #if 1
1039 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
1040 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
1041 1.1 chopps #else
1042 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, 0x00);
1043 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
1044 1.1 chopps #endif
1045 1.1 chopps WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->fy - 1) & 0x1f);
1046 1.1 chopps
1047 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1048 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
1049 1.1 chopps }
1050 1.1 chopps
1051 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
1052 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
1053 1.1 chopps
1054 1.1 chopps WCrt(ba, CRT_ID_START_VER_RETR, VSS);
1055 1.1 chopps WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f));
1056 1.1 chopps WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE);
1057 1.1 chopps WCrt(ba, CRT_ID_START_VER_BLANK, VBS);
1058 1.1 chopps WCrt(ba, CRT_ID_END_VER_BLANK, VBE);
1059 1.1 chopps
1060 1.1 chopps WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
1061 1.1 chopps WCrt(ba, CRT_ID_LACE_RETR_START, HT / 2);
1062 1.1 chopps WCrt(ba, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
1063 1.1 chopps
1064 1.1 chopps WGfx(ba, GCT_ID_GRAPHICS_MODE,
1065 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
1066 1.1 chopps WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1067 1.1 chopps
1068 1.1 chopps WSeq (ba, SEQ_ID_MEMORY_MODE,
1069 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0x6 : 0x02));
1070 1.1 chopps
1071 1.1 chopps vgaw(ba, VDAC_MASK, 0xff);
1072 1.1 chopps
1073 1.4 jtc sr15 = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2);
1074 1.4 jtc sr15 &= 0xef;
1075 1.4 jtc sr18 = RSeq(ba, SEQ_ID_RAMDAC_CNTL);
1076 1.4 jtc sr18 &= 0x7f;
1077 1.4 jtc cr33 = RCrt(ba, CRT_ID_BACKWAD_COMP_2);
1078 1.4 jtc cr33 &= 0xdf;
1079 1.4 jtc clock_mode = 0x00;
1080 1.1 chopps
1081 1.1 chopps test = RCrt(ba, CRT_ID_EXT_MISC_CNTL_2);
1082 1.4 jtc test &= 0xd;
1083 1.1 chopps
1084 1.1 chopps switch (gv->depth) {
1085 1.1 chopps case 1:
1086 1.1 chopps case 4: /* text */
1087 1.1 chopps HDE = gv->disp_width / 16;
1088 1.1 chopps break;
1089 1.1 chopps case 8:
1090 1.4 jtc if (gv->pixel_clock > 80000000) {
1091 1.4 jtc clock_mode = 0x10 | 0x02;
1092 1.4 jtc sr15 |= 0x10;
1093 1.4 jtc sr18 |= 0x80;
1094 1.4 jtc cr33 |= 0x20;
1095 1.4 jtc }
1096 1.1 chopps HDE = gv->disp_width / 8;
1097 1.1 chopps break;
1098 1.1 chopps case 15:
1099 1.4 jtc clock_mode = 0x30;
1100 1.1 chopps HDE = gv->disp_width / 4;
1101 1.1 chopps break;
1102 1.1 chopps case 16:
1103 1.4 jtc clock_mode = 0x50;
1104 1.1 chopps HDE = gv->disp_width / 4;
1105 1.1 chopps break;
1106 1.1 chopps case 24:
1107 1.4 jtc clock_mode = 0xd0;
1108 1.1 chopps HDE = (gv->disp_width / 8) * 3;
1109 1.1 chopps break;
1110 1.1 chopps }
1111 1.1 chopps
1112 1.4 jtc WCrt(ba, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
1113 1.4 jtc WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, sr15);
1114 1.4 jtc WSeq(ba, SEQ_ID_RAMDAC_CNTL, sr18);
1115 1.4 jtc WCrt(ba, CRT_ID_BACKWAD_COMP_2, cr33);
1116 1.4 jtc WCrt(ba, CRT_ID_SCREEN_OFFSET, HDE);
1117 1.1 chopps
1118 1.1 chopps test = RCrt(ba, CRT_ID_EXT_SYS_CNTL_2);
1119 1.1 chopps /* HDE Overflow in bits 4-5 */
1120 1.1 chopps test |= (HDE >> 4) & 0x30;
1121 1.1 chopps WCrt(ba, CRT_ID_EXT_SYS_CNTL_2, test);
1122 1.1 chopps
1123 1.1 chopps delay(100000);
1124 1.1 chopps WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x41));
1125 1.1 chopps delay(100000);
1126 1.1 chopps WAttr(ba, ACT_ID_COLOR_PLANE_ENA,
1127 1.1 chopps (gv->depth == 1) ? 0x01 : 0x0f);
1128 1.1 chopps delay(100000);
1129 1.1 chopps
1130 1.4 jtc /*
1131 1.4 jtc * Calc. display fifo m and n parameters
1132 1.4 jtc * Dont't ask me what the hell these values mean.
1133 1.1 chopps */
1134 1.4 jtc
1135 1.4 jtc n = 0xff;
1136 1.4 jtc if (gv->depth < 9)
1137 1.6 chopps clock = gv->pixel_clock / 500000;
1138 1.4 jtc else if (gv->depth == 15)
1139 1.6 chopps clock = gv->pixel_clock / 250000;
1140 1.4 jtc else
1141 1.6 chopps clock = (gv->pixel_clock * (gv->depth / 8)) / 500000;
1142 1.6 chopps #if 0
1143 1.6 chopps /*
1144 1.6 chopps * Note: if you change this you should change it in
1145 1.6 chopps * gen_cvtab.c and regenerate the conversion table
1146 1.6 chopps * rerun gen_cvtab
1147 1.6 chopps */
1148 1.6 chopps m = (int)((55 * .72 + 16.867) * 89.736 / (clock + 39) - 21.1543)
1149 1.6 chopps m = (m / 2) - 1;
1150 1.4 jtc if (m > 31)
1151 1.4 jtc m = 31;
1152 1.4 jtc else if (m <= 0) {
1153 1.4 jtc m = 0;
1154 1.4 jtc n = 16;
1155 1.1 chopps }
1156 1.6 chopps #endif
1157 1.6 chopps for (m = 0; m < 31; ++m)
1158 1.6 chopps if (clock >= cv_convtab[m])
1159 1.6 chopps break;
1160 1.6 chopps if (m == 0)
1161 1.6 chopps n = 16;
1162 1.1 chopps
1163 1.4 jtc m = m << 3;
1164 1.4 jtc WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, m);
1165 1.4 jtc WCrt(ba, CRT_ID_EXT_MEM_CNTL_3, n);
1166 1.1 chopps delay(10000);
1167 1.1 chopps
1168 1.3 chopps /* text initialization */
1169 1.3 chopps
1170 1.3 chopps if (TEXT) {
1171 1.3 chopps cv_inittextmode(gp);
1172 1.3 chopps }
1173 1.3 chopps
1174 1.1 chopps /* Some kind of Magic */
1175 1.1 chopps WAttr(ba, 0x33, 0);
1176 1.1 chopps
1177 1.1 chopps /* turn gfx on again */
1178 1.1 chopps gfx_on_off(0, ba);
1179 1.1 chopps
1180 1.1 chopps /* Pass-through */
1181 1.3 chopps cvscreen(0, ba - READ_OFFSET);
1182 1.1 chopps
1183 1.2 chopps return (1);
1184 1.1 chopps }
1185 1.1 chopps
1186 1.1 chopps void
1187 1.1 chopps cv_inittextmode(gp)
1188 1.1 chopps struct grf_softc *gp;
1189 1.1 chopps {
1190 1.1 chopps struct grfcvtext_mode *tm = (struct grfcvtext_mode *)gp->g_data;
1191 1.4 jtc volatile caddr_t ba = gp->g_regkva;
1192 1.4 jtc volatile caddr_t fb = gp->g_fbkva;
1193 1.1 chopps unsigned char *c, *f, y;
1194 1.1 chopps unsigned short z;
1195 1.1 chopps
1196 1.1 chopps
1197 1.1 chopps /* load text font into beginning of display memory.
1198 1.2 chopps * Each character cell is 32 bytes long (enough for 4 planes)
1199 1.1 chopps */
1200 1.1 chopps
1201 1.1 chopps SetTextPlane(ba, 0x02);
1202 1.2 chopps cv_memset(fb, 0, 256 * 32);
1203 1.2 chopps c = (unsigned char *) (fb) + (32 * tm->fdstart);
1204 1.1 chopps f = tm->fdata;
1205 1.2 chopps for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy))
1206 1.2 chopps for (y = 0; y < tm->fy; y++)
1207 1.1 chopps *c++ = *f++;
1208 1.1 chopps
1209 1.1 chopps /* clear out text/attr planes (three screens worth) */
1210 1.1 chopps
1211 1.1 chopps SetTextPlane(ba, 0x01);
1212 1.2 chopps cv_memset(fb, 0x07, tm->cols * tm->rows * 3);
1213 1.1 chopps SetTextPlane(ba, 0x00);
1214 1.2 chopps cv_memset(fb, 0x20, tm->cols * tm->rows * 3);
1215 1.1 chopps
1216 1.1 chopps /* print out a little init msg */
1217 1.1 chopps
1218 1.1 chopps c = (unsigned char *)(fb) + (tm->cols-16);
1219 1.1 chopps strcpy(c, "CV64");
1220 1.1 chopps c[6] = 0x20;
1221 1.1 chopps
1222 1.1 chopps /* set colors (B&W) */
1223 1.1 chopps
1224 1.1 chopps vgaw(ba, VDAC_ADDRESS_W, 0);
1225 1.1 chopps for (z=0; z<256; z++) {
1226 1.1 chopps unsigned char r, g, b;
1227 1.1 chopps
1228 1.1 chopps y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1229 1.1 chopps
1230 1.1 chopps r = cvconscolors[y][0];
1231 1.1 chopps g = cvconscolors[y][1];
1232 1.1 chopps b = cvconscolors[y][2];
1233 1.1 chopps vgaw(ba, VDAC_DATA, r >> 2);
1234 1.1 chopps vgaw(ba, VDAC_DATA, g >> 2);
1235 1.1 chopps vgaw(ba, VDAC_DATA, b >> 2);
1236 1.1 chopps }
1237 1.1 chopps }
1238 1.1 chopps
1239 1.1 chopps void
1240 1.1 chopps cv_memset(d, c, l)
1241 1.1 chopps unsigned char *d;
1242 1.1 chopps unsigned char c;
1243 1.1 chopps int l;
1244 1.1 chopps {
1245 1.1 chopps for(; l > 0; l--)
1246 1.1 chopps *d++ = c;
1247 1.1 chopps }
1248 1.1 chopps
1249 1.1 chopps #endif /* NGRFCV */
1250