grf_cv.c revision 1.7 1 1.7 veego /* $NetBSD: grf_cv.c,v 1.7 1996/03/02 14:02:55 veego 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.7 veego *
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.7 veego */
33 1.1 chopps #include "grfcv.h"
34 1.1 chopps #if NGRFCV > 0
35 1.1 chopps
36 1.1 chopps /*
37 1.1 chopps * Graphics routines for the CyberVision 64 board, using the S3 Trio64.
38 1.1 chopps *
39 1.1 chopps * Modified for CV64 from
40 1.1 chopps * Kari Mettinen's Cirrus driver by Michael Teske 10/95
41 1.1 chopps * For questions mail me at teske (at) dice2.desy.de
42 1.1 chopps *
43 1.1 chopps * Thanks to Tekelec Airtronic for providing me with a S3 Trio64 documentation.
44 1.1 chopps * Thanks to Bernd 'the fabulous bug-finder' Ernesti for bringing my messy
45 1.1 chopps * source to NetBSD style :)
46 1.1 chopps *
47 1.1 chopps * TODO:
48 1.1 chopps * Hardware Cursor support
49 1.1 chopps */
50 1.1 chopps
51 1.1 chopps #include <sys/param.h>
52 1.1 chopps #include <sys/errno.h>
53 1.1 chopps #include <sys/ioctl.h>
54 1.1 chopps #include <sys/device.h>
55 1.1 chopps #include <sys/malloc.h>
56 1.1 chopps #include <sys/systm.h>
57 1.1 chopps #include <machine/cpu.h>
58 1.1 chopps #include <dev/cons.h>
59 1.7 veego #include <amiga/dev/itevar.h>
60 1.1 chopps #include <amiga/amiga/device.h>
61 1.1 chopps #include <amiga/dev/grfioctl.h>
62 1.1 chopps #include <amiga/dev/grfvar.h>
63 1.1 chopps #include <amiga/dev/grf_cvreg.h>
64 1.1 chopps #include <amiga/dev/zbusvar.h>
65 1.1 chopps
66 1.4 jtc int grfcvmatch __P((struct device *, struct cfdata *, void *));
67 1.4 jtc void grfcvattach __P((struct device *, struct device *, void *));
68 1.4 jtc int grfcvprint __P((void *, char *));
69 1.4 jtc
70 1.7 veego static int cv_has_4mb __P((volatile caddr_t));
71 1.1 chopps static unsigned short compute_clock __P((unsigned long));
72 1.4 jtc void cv_boardinit __P((struct grf_softc *));
73 1.4 jtc int cv_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
74 1.4 jtc int cv_setvmode __P((struct grf_softc *, unsigned int));
75 1.4 jtc int cv_blank __P((struct grf_softc *, int *));
76 1.4 jtc int cv_mode __P((register struct grf_softc *, int, void *, int, int));
77 1.4 jtc int cv_ioctl __P((register struct grf_softc *gp, int cmd, void *data));
78 1.4 jtc int cv_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
79 1.4 jtc int cv_getcmap __P((struct grf_softc *, struct grf_colormap *));
80 1.4 jtc int cv_putcmap __P((struct grf_softc *, struct grf_colormap *));
81 1.4 jtc int cv_toggle __P((struct grf_softc *));
82 1.4 jtc int cv_mondefok __P((struct grfvideo_mode *));
83 1.4 jtc int cv_load_mon __P((struct grf_softc *, struct grfcvtext_mode *));
84 1.4 jtc void cv_inittextmode __P((struct grf_softc *));
85 1.4 jtc void cv_memset __P((unsigned char *, unsigned char, int));
86 1.7 veego static inline void cv_write_port __P((unsigned short, volatile caddr_t));
87 1.7 veego static inline void cvscreen __P((int, volatile caddr_t));
88 1.7 veego static inline void gfx_on_off __P((int, volatile caddr_t));
89 1.3 chopps
90 1.1 chopps /* Graphics display definitions.
91 1.1 chopps * These are filled by 'grfconfig' using GRFIOCSETMON.
92 1.1 chopps */
93 1.7 veego #define monitor_def_max 24
94 1.7 veego static struct grfvideo_mode monitor_def[24] = {
95 1.7 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
96 1.7 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
97 1.1 chopps {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
98 1.1 chopps };
99 1.1 chopps static struct grfvideo_mode *monitor_current = &monitor_def[0];
100 1.1 chopps #define MAXPIXELCLOCK 135000000 /* safety */
101 1.1 chopps
102 1.1 chopps
103 1.1 chopps /* Console display definition.
104 1.1 chopps * Default hardcoded text mode. This grf_cv is set up to
105 1.1 chopps * use one text mode only, and this is it. You may use
106 1.1 chopps * grfconfig to change the mode after boot.
107 1.1 chopps */
108 1.1 chopps
109 1.1 chopps /* Console font */
110 1.7 veego #ifdef KFONT_8X11
111 1.7 veego #define S3FONT kernel_font_8x11
112 1.7 veego #define S3FONTY 11
113 1.7 veego #else
114 1.1 chopps #define S3FONT kernel_font_8x8
115 1.1 chopps #define S3FONTY 8
116 1.7 veego #endif
117 1.1 chopps extern unsigned char S3FONT[];
118 1.1 chopps
119 1.7 veego /*
120 1.7 veego * Define default console mode
121 1.7 veego * (Internally, we still have to use hvalues/8!)
122 1.7 veego */
123 1.1 chopps struct grfcvtext_mode cvconsole_mode = {
124 1.7 veego {255, "", 25000000, 640, 480, 4, 640/8, 784/8, 680/8, 768/8, 800/8,
125 1.7 veego 481, 521, 491, 493, 525},
126 1.7 veego 8, S3FONTY, 80, 480 / S3FONTY, S3FONT, 32, 255
127 1.1 chopps };
128 1.1 chopps
129 1.1 chopps /* Console colors */
130 1.7 veego unsigned char cvconscolors[4][3] = { /* background, foreground, hilite */
131 1.7 veego {0x30, 0x30, 0x30}, {0, 0, 0}, {0x18, 0x20, 0x34}, {0x2a, 0x2a, 0x2a}
132 1.7 veego };
133 1.7 veego
134 1.7 veego static unsigned char clocks[]={
135 1.7 veego 0x13, 0x61, 0x6b, 0x6d, 0x51, 0x69, 0x54, 0x69,
136 1.7 veego 0x4f, 0x68, 0x6b, 0x6b, 0x18, 0x61, 0x7b, 0x6c,
137 1.7 veego 0x51, 0x67, 0x24, 0x62, 0x56, 0x67, 0x77, 0x6a,
138 1.7 veego 0x1d, 0x61, 0x53, 0x66, 0x6b, 0x68, 0x79, 0x69,
139 1.7 veego 0x7c, 0x69, 0x7f, 0x69, 0x22, 0x61, 0x54, 0x65,
140 1.7 veego 0x56, 0x65, 0x58, 0x65, 0x67, 0x66, 0x41, 0x63,
141 1.7 veego 0x27, 0x61, 0x13, 0x41, 0x37, 0x62, 0x6b, 0x4d,
142 1.7 veego 0x23, 0x43, 0x51, 0x49, 0x79, 0x66, 0x54, 0x49,
143 1.7 veego 0x7d, 0x66, 0x34, 0x56, 0x4f, 0x63, 0x1f, 0x42,
144 1.7 veego 0x6b, 0x4b, 0x7e, 0x4d, 0x18, 0x41, 0x2a, 0x43,
145 1.7 veego 0x7b, 0x4c, 0x74, 0x4b, 0x51, 0x47, 0x65, 0x49,
146 1.7 veego 0x24, 0x42, 0x68, 0x49, 0x56, 0x47, 0x75, 0x4a,
147 1.7 veego 0x77, 0x4a, 0x31, 0x43, 0x1d, 0x41, 0x71, 0x49,
148 1.7 veego 0x53, 0x46, 0x29, 0x42, 0x6b, 0x48, 0x1f, 0x41,
149 1.7 veego 0x79, 0x49, 0x6f, 0x48, 0x7c, 0x49, 0x38, 0x43,
150 1.7 veego 0x7f, 0x49, 0x5d, 0x46, 0x22, 0x41, 0x53, 0x45,
151 1.7 veego 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, 0x57, 0x45,
152 1.7 veego 0x58, 0x45, 0x25, 0x41, 0x67, 0x46, 0x5b, 0x45,
153 1.7 veego 0x41, 0x43, 0x78, 0x47, 0x27, 0x41, 0x51, 0x44,
154 1.7 veego 0x13, 0x21, 0x7d, 0x47, 0x37, 0x42, 0x71, 0x46,
155 1.7 veego 0x6b, 0x2d, 0x14, 0x21, 0x23, 0x23, 0x7d, 0x2f,
156 1.7 veego 0x51, 0x29, 0x61, 0x2b, 0x79, 0x46, 0x1d, 0x22,
157 1.7 veego 0x54, 0x29, 0x45, 0x27, 0x7d, 0x46, 0x7f, 0x46,
158 1.7 veego 0x4f, 0x43, 0x2f, 0x41, 0x1f, 0x22, 0x6a, 0x2b,
159 1.7 veego 0x6b, 0x2b, 0x5b, 0x29, 0x7e, 0x2d, 0x65, 0x44,
160 1.7 veego 0x18, 0x21, 0x5e, 0x29, 0x2a, 0x23, 0x45, 0x26,
161 1.7 veego 0x7b, 0x2c, 0x19, 0x21, 0x74, 0x2b, 0x75, 0x2b,
162 1.7 veego 0x51, 0x27, 0x3f, 0x25, 0x65, 0x29, 0x40, 0x25,
163 1.7 veego 0x24, 0x22, 0x41, 0x25, 0x68, 0x29, 0x42, 0x25,
164 1.7 veego 0x56, 0x27, 0x7e, 0x2b, 0x75, 0x2a, 0x1c, 0x21,
165 1.7 veego 0x77, 0x2a, 0x4f, 0x26, 0x31, 0x23, 0x6f, 0x29,
166 1.7 veego 0x1d, 0x21, 0x32, 0x23, 0x71, 0x29, 0x72, 0x29,
167 1.7 veego 0x53, 0x26, 0x69, 0x28, 0x29, 0x22, 0x75, 0x29,
168 1.7 veego 0x6b, 0x28, 0x1f, 0x21, 0x1f, 0x21, 0x6d, 0x28,
169 1.7 veego 0x79, 0x29, 0x2b, 0x22, 0x6f, 0x28, 0x59, 0x26,
170 1.7 veego 0x7c, 0x29, 0x7d, 0x29, 0x38, 0x23, 0x21, 0x21,
171 1.7 veego 0x7f, 0x29, 0x39, 0x23, 0x5d, 0x26, 0x75, 0x28,
172 1.7 veego 0x22, 0x21, 0x77, 0x28, 0x53, 0x25, 0x6c, 0x27,
173 1.7 veego 0x54, 0x25, 0x61, 0x26, 0x55, 0x25, 0x30, 0x22,
174 1.7 veego 0x56, 0x25, 0x63, 0x26, 0x57, 0x25, 0x71, 0x27,
175 1.7 veego 0x58, 0x25, 0x7f, 0x28, 0x25, 0x21, 0x74, 0x27,
176 1.7 veego 0x67, 0x26, 0x40, 0x23, 0x5b, 0x25, 0x26, 0x21,
177 1.7 veego 0x41, 0x23, 0x34, 0x22, 0x78, 0x27, 0x6b, 0x26,
178 1.7 veego 0x27, 0x21, 0x35, 0x22, 0x51, 0x24, 0x7b, 0x27,
179 1.7 veego 0x13, 0x1, 0x13, 0x1, 0x7d, 0x27, 0x4c, 0x9,
180 1.7 veego 0x37, 0x22, 0x5b, 0xb, 0x71, 0x26, 0x5c, 0xb,
181 1.7 veego 0x6b, 0xd, 0x47, 0x23, 0x14, 0x1, 0x4f, 0x9,
182 1.7 veego 0x23, 0x3, 0x75, 0x26, 0x7d, 0xf, 0x1c, 0x2,
183 1.7 veego 0x51, 0x9, 0x59, 0x24, 0x61, 0xb, 0x69, 0x25,
184 1.7 veego 0x79, 0x26, 0x34, 0x5, 0x1d, 0x2, 0x6b, 0x25,
185 1.7 veego 0x54, 0x9, 0x35, 0x5, 0x45, 0x7, 0x6d, 0x25,
186 1.7 veego 0x7d, 0x26, 0x16, 0x1, 0x7f, 0x26, 0x77, 0xd,
187 1.7 veego 0x4f, 0x23, 0x78, 0xd, 0x2f, 0x21, 0x27, 0x3,
188 1.7 veego 0x1f, 0x2, 0x59, 0x9, 0x6a, 0xb, 0x73, 0x25,
189 1.7 veego 0x6b, 0xb, 0x63, 0x24, 0x5b, 0x9, 0x20, 0x2,
190 1.7 veego 0x7e, 0xd, 0x4b, 0x7, 0x65, 0x24, 0x43, 0x22,
191 1.7 veego 0x18, 0x1, 0x6f, 0xb, 0x5e, 0x9, 0x70, 0xb,
192 1.7 veego 0x2a, 0x3, 0x33, 0x4, 0x45, 0x6, 0x60, 0x9,
193 1.7 veego 0x7b, 0xc, 0x19, 0x1, 0x19, 0x1, 0x7d, 0xc,
194 1.7 veego 0x74, 0xb, 0x50, 0x7, 0x75, 0xb, 0x63, 0x9,
195 1.7 veego 0x51, 0x7, 0x23, 0x2, 0x3f, 0x5, 0x1a, 0x1,
196 1.7 veego 0x65, 0x9, 0x2d, 0x3, 0x40, 0x5, 0x0, 0x0,
197 1.1 chopps };
198 1.1 chopps
199 1.1 chopps
200 1.1 chopps /* Board Address of CV64 */
201 1.4 jtc static volatile caddr_t cv_boardaddr;
202 1.1 chopps static int cv_fbsize;
203 1.1 chopps
204 1.7 veego /*
205 1.7 veego * Memory clock (binpatchable).
206 1.7 veego * Let's be defensive: 45 MHz runs on all boards I know of.
207 1.7 veego * 55 MHz runs on most boards. But you should know what you're doing
208 1.7 veego * if you set this flag. Again: This flag may destroy your CV Board.
209 1.7 veego * Use it at your own risk!!!
210 1.7 veego * Anyway, this doesn't imply that I'm responsible if your board breaks
211 1.7 veego * without setting this flag :-).
212 1.7 veego */
213 1.7 veego #ifdef CV_AGGRESSIVE_TIMING
214 1.7 veego long cv_memclk = 55000000;
215 1.7 veego #else
216 1.7 veego long cv_memclk = 45000000;
217 1.7 veego #endif
218 1.1 chopps
219 1.1 chopps /* standard driver stuff */
220 1.1 chopps struct cfdriver grfcvcd = {
221 1.1 chopps NULL, "grfcv", (cfmatch_t)grfcvmatch, grfcvattach,
222 1.1 chopps DV_DULL, sizeof(struct grf_softc), NULL, 0
223 1.1 chopps };
224 1.1 chopps static struct cfdata *cfdata;
225 1.1 chopps
226 1.1 chopps
227 1.1 chopps /*
228 1.1 chopps * Get frambuffer memory size.
229 1.1 chopps * phase5 didn't provide the bit in CR36,
230 1.1 chopps * so we have to do it this way.
231 1.1 chopps * Return 0 for 2MB, 1 for 4MB
232 1.1 chopps */
233 1.1 chopps static int
234 1.7 veego cv_has_4mb(fb)
235 1.7 veego volatile caddr_t fb;
236 1.1 chopps {
237 1.1 chopps volatile unsigned long *testfbw, *testfbr;
238 1.1 chopps
239 1.1 chopps /* write patterns in memory and test if they can be read */
240 1.7 veego testfbw = (volatile unsigned long *)fb;
241 1.7 veego testfbr = (volatile unsigned long *)(fb + 0x02000000);
242 1.1 chopps *testfbw = 0x87654321;
243 1.1 chopps if (*testfbr != 0x87654321)
244 1.2 chopps return (0);
245 1.7 veego
246 1.1 chopps /* upper memory region */
247 1.1 chopps testfbw = (volatile unsigned long *)(fb + 0x00200000);
248 1.7 veego testfbr = (volatile unsigned long *)(fb + 0x02200000);
249 1.1 chopps *testfbw = 0x87654321;
250 1.1 chopps if (*testfbr != 0x87654321)
251 1.2 chopps return (0);
252 1.1 chopps *testfbw = 0xAAAAAAAA;
253 1.1 chopps if (*testfbr != 0xAAAAAAAA)
254 1.2 chopps return (0);
255 1.1 chopps *testfbw = 0x55555555;
256 1.1 chopps if (*testfbr != 0x55555555)
257 1.2 chopps return (0);
258 1.2 chopps return (1);
259 1.1 chopps }
260 1.1 chopps
261 1.1 chopps int
262 1.1 chopps grfcvmatch(pdp, cfp, auxp)
263 1.1 chopps struct device *pdp;
264 1.1 chopps struct cfdata *cfp;
265 1.1 chopps void *auxp;
266 1.1 chopps {
267 1.1 chopps struct zbus_args *zap;
268 1.7 veego static int cvcons_unit = -1;
269 1.1 chopps
270 1.1 chopps zap = auxp;
271 1.1 chopps
272 1.1 chopps if (amiga_realconfig == 0)
273 1.7 veego #ifdef CV64CONSOLE
274 1.7 veego if (cvcons_unit != -1)
275 1.1 chopps #endif
276 1.7 veego return (0);
277 1.1 chopps
278 1.7 veego /* Lets be Paranoid: Test man and prod id */
279 1.1 chopps if (zap->manid != 8512 || zap->prodid != 34)
280 1.2 chopps return (0);
281 1.1 chopps
282 1.1 chopps cv_boardaddr = zap->va;
283 1.1 chopps
284 1.1 chopps #ifdef CV64CONSOLE
285 1.1 chopps if (amiga_realconfig == 0) {
286 1.7 veego cvcons_unit = cfp->cf_unit;
287 1.1 chopps cfdata = cfp;
288 1.1 chopps }
289 1.1 chopps #endif
290 1.1 chopps
291 1.2 chopps return (1);
292 1.1 chopps }
293 1.1 chopps
294 1.1 chopps void
295 1.1 chopps grfcvattach(pdp, dp, auxp)
296 1.1 chopps struct device *pdp, *dp;
297 1.1 chopps void *auxp;
298 1.1 chopps {
299 1.7 veego static struct grf_softc congrf;
300 1.1 chopps struct zbus_args *zap;
301 1.1 chopps struct grf_softc *gp;
302 1.7 veego static char attachflag = 0;
303 1.1 chopps
304 1.1 chopps zap = auxp;
305 1.1 chopps
306 1.7 veego /*
307 1.7 veego * This function is called twice, once on console init (dp == NULL)
308 1.7 veego * and once on "normal" grf5 init.
309 1.7 veego */
310 1.1 chopps
311 1.7 veego if (dp == NULL) /* console init */
312 1.7 veego gp = &congrf;
313 1.7 veego else
314 1.7 veego gp = (struct grf_softc *)dp;
315 1.1 chopps
316 1.7 veego if (dp != NULL && congrf.g_regkva != 0) {
317 1.7 veego /*
318 1.7 veego * inited earlier, just copy (not device struct)
319 1.7 veego */
320 1.1 chopps
321 1.7 veego printf("\n");
322 1.7 veego #ifdef CV64CONSOLE
323 1.7 veego bcopy(&congrf.g_display, &gp->g_display,
324 1.7 veego (char *) &gp[1] - (char *) &gp->g_display);
325 1.7 veego #else
326 1.7 veego gp->g_regkva = (volatile caddr_t)cv_boardaddr + 0x02000000;
327 1.7 veego gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
328 1.1 chopps
329 1.7 veego gp->g_unit = GRF_CV64_UNIT;
330 1.7 veego gp->g_mode = cv_mode;
331 1.7 veego gp->g_conpri = grfcv_cnprobe();
332 1.7 veego gp->g_flags = GF_ALIVE;
333 1.7 veego #endif
334 1.7 veego } else {
335 1.7 veego gp->g_regkva = (volatile caddr_t)cv_boardaddr + 0x02000000;
336 1.7 veego gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
337 1.7 veego
338 1.7 veego gp->g_unit = GRF_CV64_UNIT;
339 1.7 veego gp->g_mode = cv_mode;
340 1.7 veego gp->g_conpri = grfcv_cnprobe();
341 1.7 veego gp->g_flags = GF_ALIVE;
342 1.7 veego
343 1.7 veego /* wakeup the board */
344 1.7 veego cv_boardinit(gp);
345 1.1 chopps
346 1.1 chopps #ifdef CV64CONSOLE
347 1.7 veego grfcv_iteinit(gp);
348 1.7 veego (void)cv_load_mon(gp, &cvconsole_mode);
349 1.1 chopps #endif
350 1.7 veego }
351 1.1 chopps
352 1.1 chopps /*
353 1.4 jtc * attach grf
354 1.1 chopps */
355 1.7 veego if (amiga_config_found(cfdata, &gp->g_device, gp, grfcvprint)) {
356 1.7 veego if (dp != NULL)
357 1.7 veego printf("grfcv: CyberVision64 with %dMB being used\n", cv_fbsize/0x100000);
358 1.7 veego attachflag = 1;
359 1.7 veego } else {
360 1.7 veego if (!attachflag)
361 1.7 veego /*printf("grfcv unattached!!\n")*/;
362 1.7 veego }
363 1.1 chopps }
364 1.1 chopps
365 1.1 chopps int
366 1.1 chopps grfcvprint(auxp, pnp)
367 1.1 chopps void *auxp;
368 1.1 chopps char *pnp;
369 1.1 chopps {
370 1.1 chopps if (pnp)
371 1.1 chopps printf("ite at %s: ", pnp);
372 1.2 chopps return (UNCONF);
373 1.1 chopps }
374 1.1 chopps
375 1.1 chopps
376 1.1 chopps /*
377 1.1 chopps * Computes M, N, and R values from
378 1.1 chopps * given input frequency. It uses a table of
379 1.1 chopps * precomputed values, to keep CPU time low.
380 1.1 chopps *
381 1.1 chopps * The return value consist of:
382 1.1 chopps * lower byte: Bits 4-0: N Divider Value
383 1.1 chopps * Bits 5-6: R Value for e.g. SR10 or SR12
384 1.1 chopps * higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
385 1.1 chopps */
386 1.1 chopps
387 1.1 chopps static unsigned short
388 1.1 chopps compute_clock(freq)
389 1.1 chopps unsigned long freq;
390 1.1 chopps {
391 1.1 chopps static unsigned char *mnr, *save; /* M, N + R vals */
392 1.1 chopps unsigned long work_freq, r;
393 1.1 chopps unsigned short erg;
394 1.1 chopps long diff, d2;
395 1.1 chopps
396 1.7 veego if (freq < 12500000 || freq > MAXPIXELCLOCK) {
397 1.7 veego printf("grfcv: Illegal clock frequency: %ldMHz\n", freq/1000000);
398 1.7 veego printf("grfcv: Using default frequency: 25MHz\n");
399 1.7 veego printf("grfcv: See the manpage of grfconfig for more informations.\n");
400 1.7 veego freq = 25000000;
401 1.1 chopps }
402 1.1 chopps
403 1.1 chopps mnr = clocks; /* there the vals are stored */
404 1.1 chopps d2 = 0x7fffffff;
405 1.1 chopps
406 1.1 chopps while (*mnr) { /* mnr vals are 0-terminated */
407 1.1 chopps work_freq = (0x37EE * (mnr[0] + 2)) / ((mnr[1] & 0x1F) + 2);
408 1.1 chopps
409 1.1 chopps r = (mnr[1] >> 5) & 0x03;
410 1.7 veego if (r != 0)
411 1.1 chopps work_freq=work_freq >> r; /* r is the freq divider */
412 1.1 chopps
413 1.1 chopps work_freq *= 0x3E8; /* 2nd part of OSC */
414 1.1 chopps
415 1.1 chopps diff = abs(freq - work_freq);
416 1.1 chopps
417 1.1 chopps if (d2 >= diff) {
418 1.1 chopps d2 = diff;
419 1.1 chopps /* In save are the vals for minimal diff */
420 1.1 chopps save = mnr;
421 1.1 chopps }
422 1.1 chopps mnr += 2;
423 1.1 chopps }
424 1.1 chopps erg = *((unsigned short *)save);
425 1.1 chopps
426 1.1 chopps return (erg);
427 1.1 chopps }
428 1.1 chopps
429 1.1 chopps
430 1.1 chopps void
431 1.1 chopps cv_boardinit(gp)
432 1.1 chopps struct grf_softc *gp;
433 1.1 chopps {
434 1.7 veego volatile caddr_t ba;
435 1.1 chopps unsigned char test;
436 1.1 chopps unsigned int clockpar;
437 1.1 chopps int i;
438 1.4 jtc struct grfinfo *gi;
439 1.1 chopps
440 1.7 veego ba = gp->g_regkva;
441 1.1 chopps /* Reset board */
442 1.1 chopps for (i = 0; i < 6; i++)
443 1.7 veego cv_write_port (0xff, ba - 0x02000000); /* Clear all bits */
444 1.1 chopps
445 1.1 chopps /* Return to operational Mode */
446 1.7 veego cv_write_port(0x8004, ba - 0x02000000);
447 1.1 chopps
448 1.1 chopps /* Wakeup Chip */
449 1.1 chopps vgaw(ba, SREG_VIDEO_SUBS_ENABLE, 0x10);
450 1.1 chopps vgaw(ba, SREG_OPTION_SELECT, 0x1);
451 1.1 chopps vgaw(ba, SREG_VIDEO_SUBS_ENABLE, 0x8);
452 1.1 chopps
453 1.1 chopps vgaw(ba, GREG_MISC_OUTPUT_W, 0x23);
454 1.1 chopps
455 1.1 chopps WCrt(ba, CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock S3 VGA regs */
456 1.1 chopps WCrt(ba, CRT_ID_REGISTER_LOCK_2, 0xA5); /* unlock syscontrol */
457 1.1 chopps
458 1.1 chopps test = RCrt(ba, CRT_ID_SYSTEM_CONFIG);
459 1.1 chopps test = test | 0x01; /* enable enhaced register access */
460 1.1 chopps test = test & 0xEF; /* clear bit 4, 0 wait state */
461 1.1 chopps WCrt(ba, CRT_ID_SYSTEM_CONFIG, test);
462 1.1 chopps
463 1.1 chopps /*
464 1.1 chopps * bit 1=1: enable enhanced mode functions
465 1.1 chopps * bit 4=1: enable linear adressing
466 1.7 veego * bit 5=1: enable MMIO
467 1.1 chopps */
468 1.7 veego vgaw(ba, ECR_ADV_FUNC_CNTL, 0x31);
469 1.1 chopps
470 1.1 chopps /* enable cpu acess, color mode, high 64k page */
471 1.1 chopps vgaw(ba, GREG_MISC_OUTPUT_W, 0x23);
472 1.1 chopps
473 1.1 chopps /* Cpu base addr */
474 1.1 chopps WCrt(ba, CRT_ID_EXT_SYS_CNTL_4, 0x0);
475 1.1 chopps
476 1.1 chopps /* Reset. This does nothing, but everyone does it:) */
477 1.1 chopps WSeq(ba, SEQ_ID_RESET, 0x3);
478 1.1 chopps
479 1.1 chopps WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x1); /* 8 Dot Clock */
480 1.1 chopps WSeq(ba, SEQ_ID_MAP_MASK, 0xF); /* Enable write planes */
481 1.1 chopps WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x0); /* Character Font */
482 1.1 chopps
483 1.1 chopps WSeq(ba, SEQ_ID_MEMORY_MODE, 0x2); /* Complete mem access */
484 1.1 chopps
485 1.1 chopps WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x6); /* Unlock extensions */
486 1.1 chopps test = RSeq(ba, SEQ_ID_BUS_REQ_CNTL); /* Bus Request */
487 1.1 chopps
488 1.1 chopps /* enable 4MB fast Page Mode */
489 1.1 chopps test = test | 1 << 6;
490 1.1 chopps WSeq(ba, SEQ_ID_BUS_REQ_CNTL, test);
491 1.4 jtc /* faster LUT write */
492 1.7 veego WSeq(ba, SEQ_ID_RAMDAC_CNTL, 0xC0);
493 1.1 chopps
494 1.1 chopps test = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2); /* Clksyn2 read */
495 1.1 chopps
496 1.1 chopps /* immediately Clkload bit clear */
497 1.1 chopps test = test & 0xDF;
498 1.7 veego
499 1.7 veego /* 2 MCLK Memory Write.... */
500 1.7 veego if (cv_memclk >= 55000000)
501 1.7 veego test |= 0x80;
502 1.7 veego
503 1.1 chopps WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, test);
504 1.1 chopps
505 1.7 veego /* Memory CLK */
506 1.7 veego clockpar = compute_clock(cv_memclk);
507 1.1 chopps test = (clockpar & 0xFF00) >> 8;
508 1.7 veego WSeq(ba, SEQ_ID_MCLK_HI, test); /* PLL N-Divider Value */
509 1.7 veego if (RCrt(ba, CRT_ID_REVISION) == 0x10) /* bugfix for new S3 chips */
510 1.5 chopps WSeq(ba, SEQ_ID_MORE_MAGIC, test);
511 1.5 chopps
512 1.7 veego test = clockpar & 0xFF;
513 1.7 veego WSeq(ba, SEQ_ID_MCLK_LO, test); /* PLL M-Divider Value */
514 1.1 chopps
515 1.1 chopps /* We now load an 25 MHz, 31 kHz, 640x480 standard VGA Mode. */
516 1.1 chopps /* DCLK */
517 1.1 chopps WSeq(ba, SEQ_ID_DCLK_HI, 0x13);
518 1.1 chopps WSeq(ba, SEQ_ID_DCLK_LO, 0x41);
519 1.1 chopps
520 1.1 chopps test = RSeq (ba, SEQ_ID_CLKSYN_CNTL_2);
521 1.1 chopps test = test | 0x22;
522 1.1 chopps
523 1.1 chopps /* DCLK + MCLK Clock immediate load! */
524 1.1 chopps WSeq(ba,SEQ_ID_CLKSYN_CNTL_2, test);
525 1.1 chopps
526 1.1 chopps /* DCLK load */
527 1.1 chopps test = vgar(ba, 0x3cc);
528 1.1 chopps test = test | 0x0c;
529 1.1 chopps vgaw(ba, 0x3c2, test);
530 1.1 chopps
531 1.1 chopps /* Clear bit 5 again, prevent further loading. */
532 1.1 chopps WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, 0x2);
533 1.1 chopps
534 1.1 chopps WCrt(ba, CRT_ID_HOR_TOTAL, 0x5F);
535 1.1 chopps WCrt(ba, CRT_ID_HOR_DISP_ENA_END, 0x4F);
536 1.1 chopps WCrt(ba, CRT_ID_START_HOR_BLANK, 0x50);
537 1.1 chopps WCrt(ba, CRT_ID_END_HOR_BLANK, 0x82);
538 1.1 chopps WCrt(ba, CRT_ID_START_HOR_RETR, 0x54);
539 1.1 chopps WCrt(ba, CRT_ID_END_HOR_RETR, 0x80);
540 1.1 chopps WCrt(ba, CRT_ID_VER_TOTAL, 0xBF);
541 1.1 chopps
542 1.1 chopps WCrt(ba, CRT_ID_OVERFLOW, 0x1F); /* overflow reg */
543 1.1 chopps
544 1.1 chopps WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x0); /* no panning */
545 1.1 chopps
546 1.1 chopps WCrt(ba, CRT_ID_MAX_SCAN_LINE, 0x40); /* vscan */
547 1.1 chopps
548 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, 0x00);
549 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, 0x00);
550 1.1 chopps
551 1.1 chopps /* Display start adress */
552 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
553 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
554 1.1 chopps
555 1.1 chopps /* Cursor location */
556 1.3 chopps WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
557 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
558 1.1 chopps
559 1.1 chopps /* Vertical retrace */
560 1.1 chopps WCrt(ba, CRT_ID_START_VER_RETR, 0x9C);
561 1.1 chopps WCrt(ba, CRT_ID_END_VER_RETR, 0x0E);
562 1.1 chopps
563 1.1 chopps WCrt(ba, CRT_ID_VER_DISP_ENA_END, 0x8F);
564 1.1 chopps WCrt(ba, CRT_ID_SCREEN_OFFSET, 0x50);
565 1.1 chopps
566 1.1 chopps WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x00);
567 1.1 chopps
568 1.1 chopps WCrt(ba, CRT_ID_START_VER_BLANK, 0x96);
569 1.1 chopps WCrt(ba, CRT_ID_END_VER_BLANK, 0xB9);
570 1.1 chopps
571 1.1 chopps WCrt(ba, CRT_ID_MODE_CONTROL, 0xE3);
572 1.1 chopps
573 1.1 chopps WCrt(ba, CRT_ID_LINE_COMPARE, 0xFF);
574 1.1 chopps
575 1.1 chopps WCrt(ba, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
576 1.1 chopps
577 1.1 chopps /* Refresh count 1, High speed text font, enhanced color mode */
578 1.1 chopps WCrt(ba, CRT_ID_MISC_1, 0x35);
579 1.1 chopps
580 1.1 chopps /* start fifo position */
581 1.1 chopps WCrt(ba, CRT_ID_DISPLAY_FIFO, 0x5a);
582 1.1 chopps
583 1.1 chopps WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, 0x70);
584 1.1 chopps
585 1.1 chopps /* address window position */
586 1.1 chopps WCrt(ba, CRT_ID_LAW_POS_LO, 0x40);
587 1.1 chopps
588 1.1 chopps /* N Parameter for Display FIFO */
589 1.1 chopps WCrt(ba, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
590 1.1 chopps
591 1.1 chopps WGfx(ba, GCT_ID_SET_RESET, 0x0);
592 1.1 chopps WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x0);
593 1.1 chopps WGfx(ba, GCT_ID_COLOR_COMPARE, 0x0);
594 1.1 chopps WGfx(ba, GCT_ID_DATA_ROTATE, 0x0);
595 1.1 chopps WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x0);
596 1.1 chopps WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
597 1.1 chopps WGfx(ba, GCT_ID_MISC, 0x01);
598 1.1 chopps WGfx(ba, GCT_ID_COLOR_XCARE, 0x0F);
599 1.1 chopps WGfx(ba, GCT_ID_BITMASK, 0xFF);
600 1.1 chopps
601 1.1 chopps /* colors for text mode */
602 1.1 chopps for (i = 0; i <= 0xf; i++)
603 1.1 chopps WAttr (ba, i, i);
604 1.1 chopps
605 1.4 jtc WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x41);
606 1.4 jtc WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x01);
607 1.4 jtc WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0F);
608 1.4 jtc WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x0);
609 1.4 jtc WAttr(ba, ACT_ID_COLOR_SELECT, 0x0);
610 1.1 chopps
611 1.1 chopps vgaw(ba, VDAC_MASK, 0xFF); /* DAC Mask */
612 1.1 chopps
613 1.1 chopps *((unsigned long *)(ba + ECR_FRGD_COLOR)) = 0xFF;
614 1.1 chopps *((unsigned long *)(ba + ECR_BKGD_COLOR)) = 0;
615 1.1 chopps
616 1.1 chopps /* colors initially set to greyscale */
617 1.1 chopps
618 1.1 chopps vgaw(ba, VDAC_ADDRESS_W, 0);
619 1.1 chopps for (i = 255; i >= 0 ; i--) {
620 1.1 chopps vgaw(ba, VDAC_DATA, i);
621 1.1 chopps vgaw(ba, VDAC_DATA, i);
622 1.1 chopps vgaw(ba, VDAC_DATA, i);
623 1.1 chopps }
624 1.1 chopps
625 1.1 chopps /* GFx hardware cursor off */
626 1.1 chopps WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
627 1.1 chopps
628 1.1 chopps /* Set first to 4 MB, so test will work */
629 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x13);
630 1.1 chopps
631 1.1 chopps /* find *correct* fbsize of z3 board */
632 1.7 veego if (cv_has_4mb((volatile caddr_t)cv_boardaddr + 0x01400000)) {
633 1.1 chopps cv_fbsize = 1024 * 1024 * 4;
634 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x13); /* 4 MB */
635 1.1 chopps } else {
636 1.1 chopps cv_fbsize = 1024 * 1024 * 2;
637 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x12); /* 2 MB */
638 1.1 chopps }
639 1.1 chopps
640 1.7 veego /* Enable Video Display (Set Bit 5) */
641 1.1 chopps WAttr(ba, 0x33, 0);
642 1.4 jtc
643 1.7 veego gi = &gp->g_display;
644 1.7 veego gi->gd_regaddr = (caddr_t) kvtop (ba);
645 1.7 veego gi->gd_regsize = 64 * 1024;
646 1.7 veego gi->gd_fbaddr = (caddr_t) kvtop (gp->g_fbkva);
647 1.7 veego gi->gd_fbsize = cv_fbsize;
648 1.1 chopps }
649 1.1 chopps
650 1.1 chopps
651 1.1 chopps int
652 1.1 chopps cv_getvmode(gp, vm)
653 1.1 chopps struct grf_softc *gp;
654 1.1 chopps struct grfvideo_mode *vm;
655 1.1 chopps {
656 1.1 chopps struct grfvideo_mode *gv;
657 1.1 chopps
658 1.1 chopps #ifdef CV64CONSOLE
659 1.1 chopps /* Handle grabbing console mode */
660 1.1 chopps if (vm->mode_num == 255) {
661 1.1 chopps bcopy(&cvconsole_mode, vm, sizeof(struct grfvideo_mode));
662 1.2 chopps /* XXX so grfconfig can tell us the correct text dimensions. */
663 1.1 chopps vm->depth = cvconsole_mode.fy;
664 1.2 chopps } else
665 1.1 chopps #endif
666 1.2 chopps {
667 1.2 chopps if (vm->mode_num == 0)
668 1.2 chopps vm->mode_num = (monitor_current - monitor_def) + 1;
669 1.2 chopps if (vm->mode_num < 1 || vm->mode_num > monitor_def_max)
670 1.2 chopps return (EINVAL);
671 1.2 chopps gv = monitor_def + (vm->mode_num - 1);
672 1.2 chopps if (gv->mode_num == 0)
673 1.2 chopps return (EINVAL);
674 1.2 chopps
675 1.2 chopps bcopy(gv, vm, sizeof(struct grfvideo_mode));
676 1.2 chopps }
677 1.2 chopps
678 1.2 chopps /* adjust internal values to pixel values */
679 1.2 chopps
680 1.2 chopps vm->hblank_start *= 8;
681 1.2 chopps vm->hblank_stop *= 8;
682 1.2 chopps vm->hsync_start *= 8;
683 1.2 chopps vm->hsync_stop *= 8;
684 1.2 chopps vm->htotal *= 8;
685 1.1 chopps
686 1.2 chopps return (0);
687 1.1 chopps }
688 1.1 chopps
689 1.1 chopps
690 1.1 chopps int
691 1.1 chopps cv_setvmode(gp, mode)
692 1.1 chopps struct grf_softc *gp;
693 1.1 chopps unsigned mode;
694 1.1 chopps {
695 1.7 veego
696 1.1 chopps if (!mode || (mode > monitor_def_max) ||
697 1.4 jtc monitor_def[mode - 1].mode_num == 0)
698 1.2 chopps return (EINVAL);
699 1.1 chopps
700 1.1 chopps monitor_current = monitor_def + (mode - 1);
701 1.1 chopps
702 1.2 chopps return (0);
703 1.1 chopps }
704 1.1 chopps
705 1.1 chopps
706 1.1 chopps int
707 1.1 chopps cv_blank(gp, on)
708 1.1 chopps struct grf_softc *gp;
709 1.1 chopps int *on;
710 1.1 chopps {
711 1.7 veego volatile caddr_t ba;
712 1.1 chopps
713 1.7 veego ba = gp->g_regkva;
714 1.7 veego gfx_on_off(*on ? 0 : 1, ba);
715 1.1 chopps return (0);
716 1.1 chopps }
717 1.1 chopps
718 1.1 chopps
719 1.1 chopps /*
720 1.1 chopps * Change the mode of the display.
721 1.1 chopps * Return a UNIX error number or 0 for success.
722 1.1 chopps */
723 1.1 chopps int
724 1.1 chopps cv_mode(gp, cmd, arg, a2, a3)
725 1.1 chopps register struct grf_softc *gp;
726 1.1 chopps int cmd;
727 1.1 chopps void *arg;
728 1.1 chopps int a2, a3;
729 1.1 chopps {
730 1.1 chopps int error;
731 1.1 chopps
732 1.1 chopps switch (cmd) {
733 1.1 chopps case GM_GRFON:
734 1.1 chopps error = cv_load_mon (gp,
735 1.1 chopps (struct grfcvtext_mode *) monitor_current) ? 0 : EINVAL;
736 1.2 chopps return (error);
737 1.1 chopps
738 1.1 chopps case GM_GRFOFF:
739 1.1 chopps #ifndef CV64CONSOLE
740 1.4 jtc (void)cv_toggle(gp);
741 1.1 chopps #else
742 1.1 chopps cv_load_mon(gp, &cvconsole_mode);
743 1.7 veego ite_reinit(gp->g_itedev);
744 1.1 chopps #endif
745 1.2 chopps return (0);
746 1.1 chopps
747 1.1 chopps case GM_GRFCONFIG:
748 1.2 chopps return (0);
749 1.1 chopps
750 1.1 chopps case GM_GRFGETVMODE:
751 1.2 chopps return (cv_getvmode (gp, (struct grfvideo_mode *) arg));
752 1.1 chopps
753 1.1 chopps case GM_GRFSETVMODE:
754 1.1 chopps error = cv_setvmode (gp, *(unsigned *) arg);
755 1.1 chopps if (!error && (gp->g_flags & GF_GRFON))
756 1.1 chopps cv_load_mon(gp,
757 1.1 chopps (struct grfcvtext_mode *) monitor_current);
758 1.2 chopps return (error);
759 1.1 chopps
760 1.1 chopps case GM_GRFGETNUMVM:
761 1.1 chopps *(int *)arg = monitor_def_max;
762 1.2 chopps return (0);
763 1.1 chopps
764 1.1 chopps case GM_GRFIOCTL:
765 1.2 chopps return (cv_ioctl (gp, (int) arg, (caddr_t) a2));
766 1.1 chopps
767 1.1 chopps default:
768 1.1 chopps break;
769 1.1 chopps }
770 1.1 chopps
771 1.2 chopps return (EINVAL);
772 1.1 chopps }
773 1.1 chopps
774 1.1 chopps int
775 1.1 chopps cv_ioctl (gp, cmd, data)
776 1.1 chopps register struct grf_softc *gp;
777 1.1 chopps int cmd;
778 1.1 chopps void *data;
779 1.1 chopps {
780 1.1 chopps switch (cmd) {
781 1.1 chopps case GRFIOCGSPRITEPOS:
782 1.1 chopps case GRFIOCSSPRITEPOS:
783 1.1 chopps case GRFIOCSSPRITEINF:
784 1.1 chopps case GRFIOCGSPRITEINF:
785 1.1 chopps case GRFIOCGSPRITEMAX:
786 1.1 chopps break;
787 1.1 chopps
788 1.1 chopps case GRFIOCGETCMAP:
789 1.2 chopps return (cv_getcmap (gp, (struct grf_colormap *) data));
790 1.1 chopps
791 1.1 chopps case GRFIOCPUTCMAP:
792 1.2 chopps return (cv_putcmap (gp, (struct grf_colormap *) data));
793 1.1 chopps
794 1.1 chopps case GRFIOCBITBLT:
795 1.1 chopps break;
796 1.1 chopps
797 1.1 chopps case GRFTOGGLE:
798 1.4 jtc return (cv_toggle (gp));
799 1.1 chopps
800 1.1 chopps case GRFIOCSETMON:
801 1.2 chopps return (cv_setmonitor (gp, (struct grfvideo_mode *)data));
802 1.1 chopps
803 1.1 chopps case GRFIOCBLANK:
804 1.2 chopps return (cv_blank (gp, (int *)data));
805 1.1 chopps }
806 1.2 chopps return (EINVAL);
807 1.1 chopps }
808 1.1 chopps
809 1.1 chopps int
810 1.1 chopps cv_setmonitor(gp, gv)
811 1.1 chopps struct grf_softc *gp;
812 1.1 chopps struct grfvideo_mode *gv;
813 1.1 chopps {
814 1.1 chopps struct grfvideo_mode *md;
815 1.1 chopps
816 1.2 chopps if (!cv_mondefok(gv))
817 1.2 chopps return (EINVAL);
818 1.2 chopps
819 1.1 chopps #ifdef CV64CONSOLE
820 1.1 chopps /* handle interactive setting of console mode */
821 1.2 chopps if (gv->mode_num == 255) {
822 1.1 chopps bcopy(gv, &cvconsole_mode.gv, sizeof(struct grfvideo_mode));
823 1.2 chopps cvconsole_mode.gv.hblank_start /= 8;
824 1.2 chopps cvconsole_mode.gv.hblank_stop /= 8;
825 1.2 chopps cvconsole_mode.gv.hsync_start /= 8;
826 1.2 chopps cvconsole_mode.gv.hsync_stop /= 8;
827 1.2 chopps cvconsole_mode.gv.htotal /= 8;
828 1.1 chopps cvconsole_mode.rows = gv->disp_height / cvconsole_mode.fy;
829 1.1 chopps cvconsole_mode.cols = gv->disp_width / cvconsole_mode.fx;
830 1.1 chopps if (!(gp->g_flags & GF_GRFON))
831 1.1 chopps cv_load_mon(gp, &cvconsole_mode);
832 1.1 chopps ite_reinit(gp->g_itedev);
833 1.2 chopps return (0);
834 1.1 chopps }
835 1.1 chopps #endif
836 1.1 chopps
837 1.2 chopps md = monitor_def + (gv->mode_num - 1);
838 1.2 chopps bcopy(gv, md, sizeof(struct grfvideo_mode));
839 1.1 chopps
840 1.2 chopps /* adjust pixel oriented values to internal rep. */
841 1.1 chopps
842 1.2 chopps md->hblank_start /= 8;
843 1.2 chopps md->hblank_stop /= 8;
844 1.2 chopps md->hsync_start /= 8;
845 1.2 chopps md->hsync_stop /= 8;
846 1.2 chopps md->htotal /= 8;
847 1.1 chopps
848 1.2 chopps return (0);
849 1.1 chopps }
850 1.1 chopps
851 1.1 chopps int
852 1.1 chopps cv_getcmap(gfp, cmap)
853 1.1 chopps struct grf_softc *gfp;
854 1.1 chopps struct grf_colormap *cmap;
855 1.1 chopps {
856 1.4 jtc volatile caddr_t ba;
857 1.1 chopps u_char red[256], green[256], blue[256], *rp, *gp, *bp;
858 1.1 chopps short x;
859 1.1 chopps int error;
860 1.1 chopps
861 1.7 veego ba = gfp->g_regkva;
862 1.1 chopps if (cmap->count == 0 || cmap->index >= 256)
863 1.2 chopps return (0);
864 1.1 chopps
865 1.1 chopps if (cmap->index + cmap->count > 256)
866 1.1 chopps cmap->count = 256 - cmap->index;
867 1.1 chopps
868 1.1 chopps /* first read colors out of the chip, then copyout to userspace */
869 1.1 chopps vgaw (ba, VDAC_ADDRESS_W, cmap->index);
870 1.1 chopps x = cmap->count - 1;
871 1.1 chopps
872 1.1 chopps rp = red + cmap->index;
873 1.1 chopps gp = green + cmap->index;
874 1.1 chopps bp = blue + cmap->index;
875 1.1 chopps
876 1.1 chopps do {
877 1.1 chopps *rp++ = vgar (ba, VDAC_DATA) << 2;
878 1.1 chopps *gp++ = vgar (ba, VDAC_DATA) << 2;
879 1.1 chopps *bp++ = vgar (ba, VDAC_DATA) << 2;
880 1.1 chopps } while (x-- > 0);
881 1.1 chopps
882 1.1 chopps if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
883 1.1 chopps && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
884 1.1 chopps && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
885 1.2 chopps return (0);
886 1.1 chopps
887 1.2 chopps return (error);
888 1.1 chopps }
889 1.1 chopps
890 1.1 chopps int
891 1.1 chopps cv_putcmap(gfp, cmap)
892 1.1 chopps struct grf_softc *gfp;
893 1.1 chopps struct grf_colormap *cmap;
894 1.1 chopps {
895 1.4 jtc volatile caddr_t ba;
896 1.1 chopps u_char red[256], green[256], blue[256], *rp, *gp, *bp;
897 1.1 chopps short x;
898 1.1 chopps int error;
899 1.1 chopps
900 1.7 veego ba = gfp->g_regkva;
901 1.1 chopps if (cmap->count == 0 || cmap->index >= 256)
902 1.2 chopps return (0);
903 1.1 chopps
904 1.1 chopps if (cmap->index + cmap->count > 256)
905 1.1 chopps cmap->count = 256 - cmap->index;
906 1.1 chopps
907 1.1 chopps /* first copy the colors into kernelspace */
908 1.1 chopps if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
909 1.1 chopps && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
910 1.1 chopps && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
911 1.1 chopps vgaw (ba, VDAC_ADDRESS_W, cmap->index);
912 1.1 chopps x = cmap->count - 1;
913 1.1 chopps
914 1.1 chopps rp = red + cmap->index;
915 1.1 chopps gp = green + cmap->index;
916 1.1 chopps bp = blue + cmap->index;
917 1.1 chopps
918 1.1 chopps do {
919 1.1 chopps vgaw (ba, VDAC_DATA, *rp++ >> 2);
920 1.1 chopps vgaw (ba, VDAC_DATA, *gp++ >> 2);
921 1.1 chopps vgaw (ba, VDAC_DATA, *bp++ >> 2);
922 1.1 chopps } while (x-- > 0);
923 1.2 chopps return (0);
924 1.2 chopps } else
925 1.2 chopps return (error);
926 1.1 chopps }
927 1.1 chopps
928 1.1 chopps
929 1.1 chopps int
930 1.4 jtc cv_toggle(gp)
931 1.1 chopps struct grf_softc *gp;
932 1.1 chopps {
933 1.4 jtc volatile caddr_t ba;
934 1.1 chopps
935 1.4 jtc ba = gp->g_regkva;
936 1.7 veego cvscreen(1, ba - 0x02000000);
937 1.1 chopps
938 1.2 chopps return (0);
939 1.1 chopps }
940 1.1 chopps
941 1.1 chopps
942 1.1 chopps int
943 1.2 chopps cv_mondefok(gv)
944 1.2 chopps struct grfvideo_mode *gv;
945 1.1 chopps {
946 1.2 chopps unsigned long maxpix;
947 1.7 veego int widthok = 0;
948 1.2 chopps
949 1.7 veego if (gv->mode_num < 1 || gv->mode_num > monitor_def_max) {
950 1.7 veego if (gv->mode_num != 255 || (gv->depth != 4 && gv->depth != 8))
951 1.2 chopps return (0);
952 1.7 veego else
953 1.7 veego /*
954 1.7 veego * We have 8 bit console modes. This _is_
955 1.7 veego * a hack but necessary to be compatible.
956 1.7 veego */
957 1.7 veego gv->depth = 8;
958 1.7 veego }
959 1.1 chopps
960 1.2 chopps switch(gv->depth) {
961 1.1 chopps case 1:
962 1.1 chopps case 4:
963 1.7 veego return (0);
964 1.1 chopps case 8:
965 1.2 chopps maxpix = MAXPIXELCLOCK;
966 1.2 chopps break;
967 1.1 chopps case 15:
968 1.1 chopps case 16:
969 1.7 veego #ifdef CV_AGGRESSIVE_TIMING
970 1.7 veego maxpix = MAXPIXELCLOCK - 35000000;
971 1.7 veego #else
972 1.2 chopps maxpix = MAXPIXELCLOCK - 55000000;
973 1.7 veego #endif
974 1.2 chopps break;
975 1.1 chopps case 24:
976 1.7 veego case 32:
977 1.7 veego #ifdef CV_AGGRESSIVE_TIMING
978 1.7 veego maxpix = MAXPIXELCLOCK - 75000000;
979 1.7 veego #else
980 1.2 chopps maxpix = MAXPIXELCLOCK - 85000000;
981 1.7 veego #endif
982 1.2 chopps break;
983 1.1 chopps default:
984 1.2 chopps return (0);
985 1.1 chopps }
986 1.2 chopps
987 1.2 chopps if (gv->pixel_clock > maxpix)
988 1.2 chopps return (0);
989 1.7 veego
990 1.7 veego /*
991 1.7 veego * These are the supported witdh values for the
992 1.7 veego * graphics engine. To Support other widths, one
993 1.7 veego * has to use one of these widths for memory alignment, i.e.
994 1.7 veego * one has to set CRT_ID_SCREEN_OFFSET to one of these values and
995 1.7 veego * CRT_ID_HOR_DISP_ENA_END to the desired width.
996 1.7 veego * Since a working graphics engine is essential
997 1.7 veego * for the console, console modes of other width are not supported.
998 1.7 veego * We could do that, though, but then you have to tell the Xserver
999 1.7 veego * about this strange configuration and I don't know how at the moment :-)
1000 1.7 veego */
1001 1.7 veego
1002 1.7 veego switch (gv->disp_width) {
1003 1.7 veego case 1024:
1004 1.7 veego case 640:
1005 1.7 veego case 800:
1006 1.7 veego case 1280:
1007 1.7 veego case 1152:
1008 1.7 veego case 1600:
1009 1.7 veego widthok = 1;
1010 1.7 veego break;
1011 1.7 veego default: /* XXX*/
1012 1.7 veego widthok = 0;
1013 1.7 veego break;
1014 1.7 veego }
1015 1.7 veego
1016 1.7 veego if (widthok) return (1);
1017 1.7 veego else {
1018 1.7 veego if (gv->mode_num == 255) { /* console mode */
1019 1.7 veego printf ("This display width is not supported by the CV64 console.\n");
1020 1.7 veego printf ("Use one of 640 800 1024 1152 1280 1600!\n");
1021 1.7 veego return (0);
1022 1.7 veego } else {
1023 1.7 veego printf ("Warning for mode %d:\n", (int) gv->mode_num);
1024 1.7 veego printf ("Don't use a blitter-suporting Xserver with this display width\n");
1025 1.7 veego printf ("Use one of 640 800 1024 1152 1280 1600!\n");
1026 1.7 veego return (1);
1027 1.7 veego }
1028 1.7 veego }
1029 1.2 chopps return (1);
1030 1.1 chopps }
1031 1.1 chopps
1032 1.1 chopps int
1033 1.1 chopps cv_load_mon(gp, md)
1034 1.1 chopps struct grf_softc *gp;
1035 1.1 chopps struct grfcvtext_mode *md;
1036 1.1 chopps {
1037 1.1 chopps struct grfvideo_mode *gv;
1038 1.1 chopps struct grfinfo *gi;
1039 1.4 jtc volatile caddr_t ba, fb;
1040 1.1 chopps unsigned short mnr;
1041 1.2 chopps unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
1042 1.2 chopps VSE, VT;
1043 1.7 veego char LACE, DBLSCAN, TEXT, CONSOLE;
1044 1.1 chopps int uplim, lowlim;
1045 1.7 veego int cr50, cr33, sr15, sr18, clock_mode, test;
1046 1.7 veego int m, n; /* For calc'ing display FIFO */
1047 1.7 veego int tfillm, temptym; /* FIFO fill and empty mclk's */
1048 1.7 veego int hmul; /* Multiplier for hor. Values */
1049 1.1 chopps /* identity */
1050 1.1 chopps gv = &md->gv;
1051 1.7 veego
1052 1.7 veego /*
1053 1.7 veego * No way to get text modes to work.
1054 1.7 veego * Blame phase5, not me!
1055 1.7 veego */
1056 1.7 veego TEXT = 0; /* (gv->depth == 4); */
1057 1.7 veego CONSOLE = (gv->mode_num == 255);
1058 1.1 chopps
1059 1.1 chopps if (!cv_mondefok(gv)) {
1060 1.7 veego printf("grfcv: The monitor definition is not okay.\n");
1061 1.7 veego printf("grfcv: See the manpage of grfconfig for more informations\n");
1062 1.2 chopps return (0);
1063 1.1 chopps }
1064 1.1 chopps ba = gp->g_regkva;
1065 1.1 chopps fb = gp->g_fbkva;
1066 1.1 chopps
1067 1.3 chopps /* turn gfx off, don't mess up the display */
1068 1.3 chopps gfx_on_off(1, ba);
1069 1.3 chopps
1070 1.2 chopps /* provide all needed information in grf device-independant locations */
1071 1.1 chopps gp->g_data = (caddr_t) gv;
1072 1.1 chopps gi = &gp->g_display;
1073 1.1 chopps gi->gd_colors = 1 << gv->depth;
1074 1.1 chopps gi->gd_planes = gv->depth;
1075 1.1 chopps gi->gd_fbwidth = gv->disp_width;
1076 1.1 chopps gi->gd_fbheight = gv->disp_height;
1077 1.1 chopps gi->gd_fbx = 0;
1078 1.1 chopps gi->gd_fby = 0;
1079 1.7 veego if (CONSOLE) {
1080 1.1 chopps gi->gd_dwidth = md->fx * md->cols;
1081 1.1 chopps gi->gd_dheight = md->fy * md->rows;
1082 1.1 chopps } else {
1083 1.1 chopps gi->gd_dwidth = gv->disp_width;
1084 1.1 chopps gi->gd_dheight = gv->disp_height;
1085 1.1 chopps }
1086 1.1 chopps gi->gd_dx = 0;
1087 1.1 chopps gi->gd_dy = 0;
1088 1.1 chopps
1089 1.1 chopps /* get display mode parameters */
1090 1.7 veego switch (gv->depth) {
1091 1.7 veego case 15:
1092 1.7 veego case 16:
1093 1.7 veego hmul = 2;
1094 1.7 veego break;
1095 1.7 veego default:
1096 1.7 veego hmul = 1;
1097 1.7 veego break;
1098 1.7 veego }
1099 1.1 chopps
1100 1.7 veego HBS = gv->hblank_start * hmul;
1101 1.7 veego HBE = gv->hblank_stop * hmul;
1102 1.7 veego HSS = gv->hsync_start * hmul;
1103 1.7 veego HSE = gv->hsync_stop * hmul;
1104 1.7 veego HT = gv->htotal*hmul - 5;
1105 1.4 jtc VBS = gv->vblank_start - 1;
1106 1.1 chopps VSS = gv->vsync_start;
1107 1.1 chopps VSE = gv->vsync_stop;
1108 1.1 chopps VBE = gv->vblank_stop;
1109 1.4 jtc VT = gv->vtotal - 2;
1110 1.1 chopps
1111 1.1 chopps if (TEXT)
1112 1.1 chopps HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
1113 1.1 chopps else
1114 1.7 veego HDE = (gv->disp_width + 3) * hmul / 8 - 1; /*HBS;*/
1115 1.1 chopps VDE = gv->disp_height - 1;
1116 1.1 chopps
1117 1.1 chopps /* figure out whether lace or dblscan is needed */
1118 1.1 chopps
1119 1.1 chopps uplim = gv->disp_height + (gv->disp_height / 4);
1120 1.1 chopps lowlim = gv->disp_height - (gv->disp_height / 4);
1121 1.1 chopps LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
1122 1.1 chopps DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
1123 1.1 chopps
1124 1.1 chopps /* adjustments */
1125 1.1 chopps
1126 1.1 chopps if (LACE)
1127 1.1 chopps VDE /= 2;
1128 1.1 chopps
1129 1.1 chopps WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
1130 1.1 chopps WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1131 1.1 chopps WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff);
1132 1.1 chopps WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
1133 1.1 chopps
1134 1.1 chopps /* Set clock */
1135 1.1 chopps
1136 1.7 veego mnr = compute_clock(gv->pixel_clock);
1137 1.1 chopps WSeq(ba, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8) );
1138 1.1 chopps WSeq(ba, SEQ_ID_DCLK_LO, (mnr & 0xFF));
1139 1.1 chopps
1140 1.1 chopps /* load display parameters into board */
1141 1.1 chopps
1142 1.1 chopps WCrt(ba, CRT_ID_EXT_HOR_OVF,
1143 1.1 chopps ((HT & 0x100) ? 0x01 : 0x00) |
1144 1.1 chopps ((HDE & 0x100) ? 0x02 : 0x00) |
1145 1.1 chopps ((HBS & 0x100) ? 0x04 : 0x00) |
1146 1.3 chopps /* ((HBE & 0x40) ? 0x08 : 0x00) | */ /* Later... */
1147 1.1 chopps ((HSS & 0x100) ? 0x10 : 0x00) |
1148 1.3 chopps /* ((HSE & 0x20) ? 0x20 : 0x00) | */
1149 1.1 chopps (((HT-5) & 0x100) ? 0x40 : 0x00) );
1150 1.1 chopps
1151 1.1 chopps WCrt(ba, CRT_ID_EXT_VER_OVF,
1152 1.1 chopps 0x40 | /* Line compare */
1153 1.1 chopps ((VT & 0x400) ? 0x01 : 0x00) |
1154 1.1 chopps ((VDE & 0x400) ? 0x02 : 0x00) |
1155 1.1 chopps ((VBS & 0x400) ? 0x04 : 0x00) |
1156 1.1 chopps ((VSS & 0x400) ? 0x10 : 0x00) );
1157 1.1 chopps
1158 1.1 chopps WCrt(ba, CRT_ID_HOR_TOTAL, HT);
1159 1.1 chopps WCrt(ba, CRT_ID_DISPLAY_FIFO, HT - 5);
1160 1.1 chopps
1161 1.1 chopps WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
1162 1.1 chopps WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
1163 1.1 chopps WCrt(ba, CRT_ID_END_HOR_BLANK, ((HBE & 0x1f) | 0x80));
1164 1.1 chopps WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
1165 1.1 chopps WCrt(ba, CRT_ID_END_HOR_RETR,
1166 1.1 chopps (HSE & 0x1f) |
1167 1.1 chopps ((HBE & 0x20) ? 0x80 : 0x00) );
1168 1.1 chopps WCrt(ba, CRT_ID_VER_TOTAL, VT);
1169 1.1 chopps WCrt(ba, CRT_ID_OVERFLOW,
1170 1.1 chopps 0x10 |
1171 1.1 chopps ((VT & 0x100) ? 0x01 : 0x00) |
1172 1.1 chopps ((VDE & 0x100) ? 0x02 : 0x00) |
1173 1.1 chopps ((VSS & 0x100) ? 0x04 : 0x00) |
1174 1.1 chopps ((VBS & 0x100) ? 0x08 : 0x00) |
1175 1.1 chopps ((VT & 0x200) ? 0x20 : 0x00) |
1176 1.1 chopps ((VDE & 0x200) ? 0x40 : 0x00) |
1177 1.1 chopps ((VSS & 0x200) ? 0x80 : 0x00) );
1178 1.1 chopps
1179 1.1 chopps WCrt(ba, CRT_ID_MAX_SCAN_LINE,
1180 1.1 chopps 0x40 | /* TEXT ? 0x00 ??? */
1181 1.1 chopps (DBLSCAN ? 0x80 : 0x00) |
1182 1.1 chopps ((VBS & 0x200) ? 0x20 : 0x00) |
1183 1.1 chopps (TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
1184 1.1 chopps
1185 1.1 chopps WCrt(ba, CRT_ID_MODE_CONTROL,
1186 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0xc3 : 0xe3));
1187 1.1 chopps
1188 1.1 chopps /* text cursor */
1189 1.1 chopps
1190 1.1 chopps if (TEXT) {
1191 1.1 chopps #if 1
1192 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
1193 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
1194 1.1 chopps #else
1195 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, 0x00);
1196 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
1197 1.1 chopps #endif
1198 1.1 chopps WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->fy - 1) & 0x1f);
1199 1.1 chopps
1200 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1201 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
1202 1.1 chopps }
1203 1.1 chopps
1204 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
1205 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
1206 1.1 chopps
1207 1.1 chopps WCrt(ba, CRT_ID_START_VER_RETR, VSS);
1208 1.1 chopps WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f));
1209 1.1 chopps WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE);
1210 1.1 chopps WCrt(ba, CRT_ID_START_VER_BLANK, VBS);
1211 1.1 chopps WCrt(ba, CRT_ID_END_VER_BLANK, VBE);
1212 1.1 chopps
1213 1.1 chopps WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
1214 1.1 chopps WCrt(ba, CRT_ID_LACE_RETR_START, HT / 2);
1215 1.1 chopps WCrt(ba, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
1216 1.1 chopps
1217 1.1 chopps WGfx(ba, GCT_ID_GRAPHICS_MODE,
1218 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
1219 1.1 chopps WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1220 1.1 chopps
1221 1.1 chopps WSeq (ba, SEQ_ID_MEMORY_MODE,
1222 1.7 veego ((TEXT || (gv->depth == 1)) ? 0x06 : 0x02));
1223 1.1 chopps
1224 1.1 chopps vgaw(ba, VDAC_MASK, 0xff);
1225 1.1 chopps
1226 1.4 jtc sr15 = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2);
1227 1.4 jtc sr15 &= 0xef;
1228 1.4 jtc sr18 = RSeq(ba, SEQ_ID_RAMDAC_CNTL);
1229 1.4 jtc sr18 &= 0x7f;
1230 1.4 jtc cr33 = RCrt(ba, CRT_ID_BACKWAD_COMP_2);
1231 1.4 jtc cr33 &= 0xdf;
1232 1.4 jtc clock_mode = 0x00;
1233 1.7 veego cr50 = 0x00;
1234 1.1 chopps
1235 1.1 chopps test = RCrt(ba, CRT_ID_EXT_MISC_CNTL_2);
1236 1.4 jtc test &= 0xd;
1237 1.1 chopps
1238 1.7 veego /* clear roxxler byte-swapping... */
1239 1.7 veego cv_write_port(0x0040, cv_boardaddr);
1240 1.7 veego cv_write_port(0x0020, cv_boardaddr);
1241 1.7 veego
1242 1.1 chopps switch (gv->depth) {
1243 1.1 chopps case 1:
1244 1.1 chopps case 4: /* text */
1245 1.1 chopps HDE = gv->disp_width / 16;
1246 1.1 chopps break;
1247 1.1 chopps case 8:
1248 1.4 jtc if (gv->pixel_clock > 80000000) {
1249 1.4 jtc clock_mode = 0x10 | 0x02;
1250 1.4 jtc sr15 |= 0x10;
1251 1.4 jtc sr18 |= 0x80;
1252 1.4 jtc cr33 |= 0x20;
1253 1.4 jtc }
1254 1.1 chopps HDE = gv->disp_width / 8;
1255 1.7 veego cr50 |= 0x00;
1256 1.1 chopps break;
1257 1.1 chopps case 15:
1258 1.7 veego cv_write_port (0x8020, cv_boardaddr);
1259 1.4 jtc clock_mode = 0x30;
1260 1.1 chopps HDE = gv->disp_width / 4;
1261 1.7 veego cr50 |= 0x10;
1262 1.1 chopps break;
1263 1.1 chopps case 16:
1264 1.7 veego cv_write_port (0x8020, cv_boardaddr);
1265 1.4 jtc clock_mode = 0x50;
1266 1.1 chopps HDE = gv->disp_width / 4;
1267 1.7 veego cr50 |= 0x10;
1268 1.1 chopps break;
1269 1.7 veego case 24: /* this is really 32 Bit on CV64 */
1270 1.7 veego case 32:
1271 1.7 veego cv_write_port(0x8040, cv_boardaddr);
1272 1.4 jtc clock_mode = 0xd0;
1273 1.7 veego HDE = (gv->disp_width / 2);
1274 1.7 veego cr50 |= 0x30;
1275 1.1 chopps break;
1276 1.1 chopps }
1277 1.1 chopps
1278 1.4 jtc WCrt(ba, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
1279 1.4 jtc WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, sr15);
1280 1.4 jtc WSeq(ba, SEQ_ID_RAMDAC_CNTL, sr18);
1281 1.4 jtc WCrt(ba, CRT_ID_BACKWAD_COMP_2, cr33);
1282 1.4 jtc WCrt(ba, CRT_ID_SCREEN_OFFSET, HDE);
1283 1.1 chopps
1284 1.1 chopps test = RCrt(ba, CRT_ID_EXT_SYS_CNTL_2);
1285 1.7 veego test &= ~0x30;
1286 1.1 chopps /* HDE Overflow in bits 4-5 */
1287 1.1 chopps test |= (HDE >> 4) & 0x30;
1288 1.1 chopps WCrt(ba, CRT_ID_EXT_SYS_CNTL_2, test);
1289 1.1 chopps
1290 1.7 veego /* Set up graphics engine */
1291 1.7 veego switch (gv->disp_width) {
1292 1.7 veego case 1024:
1293 1.7 veego cr50 |= 0x00;
1294 1.7 veego break;
1295 1.7 veego case 640:
1296 1.7 veego cr50 |= 0x40;
1297 1.7 veego break;
1298 1.7 veego case 800:
1299 1.7 veego cr50 |= 0x80;
1300 1.7 veego break;
1301 1.7 veego case 1280:
1302 1.7 veego cr50 |= 0xc0;
1303 1.7 veego break;
1304 1.7 veego case 1152:
1305 1.7 veego cr50 |= 0x01;
1306 1.7 veego break;
1307 1.7 veego case 1600:
1308 1.7 veego cr50 |= 0x81;
1309 1.7 veego break;
1310 1.7 veego default: /* XXX*/
1311 1.7 veego break;
1312 1.7 veego }
1313 1.7 veego
1314 1.7 veego WCrt(ba, CRT_ID_EXT_SYS_CNTL_1, cr50);
1315 1.7 veego
1316 1.1 chopps delay(100000);
1317 1.1 chopps WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x41));
1318 1.1 chopps delay(100000);
1319 1.1 chopps WAttr(ba, ACT_ID_COLOR_PLANE_ENA,
1320 1.1 chopps (gv->depth == 1) ? 0x01 : 0x0f);
1321 1.1 chopps delay(100000);
1322 1.1 chopps
1323 1.4 jtc /*
1324 1.7 veego * M-Parameter of Display FIFO
1325 1.7 veego * This is dependant on the pixel clock and the memory clock.
1326 1.7 veego * The FIFO filling bandwidth is 240 MHz and the FIFO is 96 Byte wide.
1327 1.7 veego * Then the time to fill the FIFO is tfill = (96/240000000) sec, the time
1328 1.7 veego * to empty the FIFO is tempty = (96/pixelclock) sec.
1329 1.7 veego * Then the M parameter maximum is ((tempty-tfill)*cv_memclk-9)/2.
1330 1.7 veego * This seems to be logical, ain't it?
1331 1.7 veego * Remember: We have to use integer arithmetics :(
1332 1.7 veego * Divide by 1000 to prevent overflows.
1333 1.1 chopps */
1334 1.4 jtc
1335 1.7 veego tfillm = (96 * (cv_memclk/1000))/240000;
1336 1.7 veego
1337 1.7 veego switch(gv->depth) {
1338 1.7 veego case 32:
1339 1.7 veego case 24:
1340 1.7 veego temptym = (24 * (cv_memclk/1000)) / (gv->pixel_clock/1000);
1341 1.7 veego break;
1342 1.7 veego case 15:
1343 1.7 veego case 16:
1344 1.7 veego temptym = (48 * (cv_memclk/1000)) / (gv->pixel_clock/1000);
1345 1.7 veego break;
1346 1.7 veego default:
1347 1.7 veego temptym = (96 * (cv_memclk/1000)) / (gv->pixel_clock/1000);
1348 1.7 veego break;
1349 1.7 veego }
1350 1.7 veego
1351 1.7 veego m = (temptym - tfillm - 9) / 2;
1352 1.7 veego m = (m & 0x1f) << 3;
1353 1.7 veego if (m < 0x18)
1354 1.7 veego m = 0x18;
1355 1.4 jtc n = 0xff;
1356 1.1 chopps
1357 1.4 jtc WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, m);
1358 1.4 jtc WCrt(ba, CRT_ID_EXT_MEM_CNTL_3, n);
1359 1.1 chopps delay(10000);
1360 1.1 chopps
1361 1.3 chopps /* text initialization */
1362 1.3 chopps
1363 1.3 chopps if (TEXT) {
1364 1.3 chopps cv_inittextmode(gp);
1365 1.3 chopps }
1366 1.3 chopps
1367 1.7 veego if (CONSOLE) {
1368 1.7 veego int i;
1369 1.7 veego vgaw(ba, VDAC_ADDRESS_W, 0);
1370 1.7 veego for (i = 0; i < 4; i++) {
1371 1.7 veego vgaw(ba, VDAC_DATA, cvconscolors[i][0]);
1372 1.7 veego vgaw(ba, VDAC_DATA, cvconscolors[i][1]);
1373 1.7 veego vgaw(ba, VDAC_DATA, cvconscolors[i][2]);
1374 1.7 veego }
1375 1.7 veego }
1376 1.7 veego
1377 1.1 chopps /* Some kind of Magic */
1378 1.1 chopps WAttr(ba, 0x33, 0);
1379 1.1 chopps
1380 1.1 chopps /* turn gfx on again */
1381 1.1 chopps gfx_on_off(0, ba);
1382 1.1 chopps
1383 1.1 chopps /* Pass-through */
1384 1.7 veego cvscreen(0, ba - 0x02000000);
1385 1.1 chopps
1386 1.2 chopps return (1);
1387 1.1 chopps }
1388 1.1 chopps
1389 1.1 chopps void
1390 1.1 chopps cv_inittextmode(gp)
1391 1.1 chopps struct grf_softc *gp;
1392 1.1 chopps {
1393 1.1 chopps struct grfcvtext_mode *tm = (struct grfcvtext_mode *)gp->g_data;
1394 1.7 veego volatile caddr_t ba, fb;
1395 1.1 chopps unsigned char *c, *f, y;
1396 1.1 chopps unsigned short z;
1397 1.1 chopps
1398 1.7 veego ba = gp->g_regkva;
1399 1.7 veego fb = gp->g_fbkva;
1400 1.1 chopps
1401 1.1 chopps /* load text font into beginning of display memory.
1402 1.2 chopps * Each character cell is 32 bytes long (enough for 4 planes)
1403 1.1 chopps */
1404 1.1 chopps
1405 1.1 chopps SetTextPlane(ba, 0x02);
1406 1.2 chopps cv_memset(fb, 0, 256 * 32);
1407 1.2 chopps c = (unsigned char *) (fb) + (32 * tm->fdstart);
1408 1.1 chopps f = tm->fdata;
1409 1.2 chopps for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy))
1410 1.2 chopps for (y = 0; y < tm->fy; y++)
1411 1.1 chopps *c++ = *f++;
1412 1.1 chopps
1413 1.1 chopps /* clear out text/attr planes (three screens worth) */
1414 1.1 chopps
1415 1.1 chopps SetTextPlane(ba, 0x01);
1416 1.2 chopps cv_memset(fb, 0x07, tm->cols * tm->rows * 3);
1417 1.1 chopps SetTextPlane(ba, 0x00);
1418 1.2 chopps cv_memset(fb, 0x20, tm->cols * tm->rows * 3);
1419 1.1 chopps
1420 1.1 chopps /* print out a little init msg */
1421 1.1 chopps
1422 1.1 chopps c = (unsigned char *)(fb) + (tm->cols-16);
1423 1.1 chopps strcpy(c, "CV64");
1424 1.1 chopps c[6] = 0x20;
1425 1.1 chopps
1426 1.1 chopps /* set colors (B&W) */
1427 1.1 chopps
1428 1.1 chopps vgaw(ba, VDAC_ADDRESS_W, 0);
1429 1.1 chopps for (z=0; z<256; z++) {
1430 1.1 chopps unsigned char r, g, b;
1431 1.1 chopps
1432 1.1 chopps y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1433 1.1 chopps
1434 1.1 chopps r = cvconscolors[y][0];
1435 1.1 chopps g = cvconscolors[y][1];
1436 1.1 chopps b = cvconscolors[y][2];
1437 1.1 chopps vgaw(ba, VDAC_DATA, r >> 2);
1438 1.1 chopps vgaw(ba, VDAC_DATA, g >> 2);
1439 1.1 chopps vgaw(ba, VDAC_DATA, b >> 2);
1440 1.1 chopps }
1441 1.1 chopps }
1442 1.1 chopps
1443 1.1 chopps void
1444 1.1 chopps cv_memset(d, c, l)
1445 1.1 chopps unsigned char *d;
1446 1.1 chopps unsigned char c;
1447 1.1 chopps int l;
1448 1.1 chopps {
1449 1.1 chopps for(; l > 0; l--)
1450 1.1 chopps *d++ = c;
1451 1.7 veego }
1452 1.7 veego
1453 1.7 veego
1454 1.7 veego static inline void
1455 1.7 veego cv_write_port(bits, BoardAddr)
1456 1.7 veego unsigned short bits;
1457 1.7 veego volatile caddr_t BoardAddr;
1458 1.7 veego {
1459 1.7 veego volatile caddr_t addr;
1460 1.7 veego static unsigned char CVPortBits = 0; /* mirror port bits here */
1461 1.7 veego
1462 1.7 veego addr = BoardAddr + 0x40001;
1463 1.7 veego if (bits & 0x8000)
1464 1.7 veego CVPortBits |= bits & 0xFF; /* Set bits */
1465 1.7 veego else {
1466 1.7 veego bits = bits & 0xFF;
1467 1.7 veego bits = (~bits) & 0xFF ;
1468 1.7 veego CVPortBits &= bits; /* Clear bits */
1469 1.7 veego }
1470 1.7 veego
1471 1.7 veego *addr = CVPortBits;
1472 1.7 veego }
1473 1.7 veego
1474 1.7 veego
1475 1.7 veego /*
1476 1.7 veego * Monitor Switch
1477 1.7 veego * 0 = CyberVision Signal
1478 1.7 veego * 1 = Amiga Signal,
1479 1.7 veego * ba = boardaddr
1480 1.7 veego */
1481 1.7 veego static inline void
1482 1.7 veego cvscreen(toggle, ba)
1483 1.7 veego int toggle;
1484 1.7 veego volatile caddr_t ba;
1485 1.7 veego {
1486 1.7 veego
1487 1.7 veego if (toggle == 1)
1488 1.7 veego cv_write_port (0x10, ba);
1489 1.7 veego else
1490 1.7 veego cv_write_port (0x8010, ba);
1491 1.7 veego }
1492 1.7 veego
1493 1.7 veego /* 0 = on, 1= off */
1494 1.7 veego /* ba= registerbase */
1495 1.7 veego static inline void
1496 1.7 veego gfx_on_off(toggle, ba)
1497 1.7 veego int toggle;
1498 1.7 veego volatile caddr_t ba;
1499 1.7 veego {
1500 1.7 veego int r;
1501 1.7 veego
1502 1.7 veego toggle &= 0x1;
1503 1.7 veego toggle = toggle << 5;
1504 1.7 veego
1505 1.7 veego r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
1506 1.7 veego r &= 0xdf; /* set Bit 5 to 0 */
1507 1.7 veego
1508 1.7 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, r | toggle);
1509 1.1 chopps }
1510 1.1 chopps
1511 1.1 chopps #endif /* NGRFCV */
1512