grf_cv.c revision 1.8 1 1.8 is /* $NetBSD: grf_cv.c,v 1.8 1996/03/04 20:36:56 is 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.8 is
509 1.8 is if (RCrt(ba, CRT_ID_REVISION) == 0x10) {
510 1.8 is WSeq(ba, SEQ_ID_MCLK_HI, test); /* PLL N-Divider Value */
511 1.8 is
512 1.8 is test = clockpar & 0xFF;
513 1.8 is WSeq(ba, SEQ_ID_MCLK_LO, test); /* PLL M-Divider Value */
514 1.8 is
515 1.8 is test = (clockpar & 0xFF00) >> 8;
516 1.5 chopps WSeq(ba, SEQ_ID_MORE_MAGIC, test);
517 1.8 is } else {
518 1.8 is WSeq(ba, SEQ_ID_MCLK_HI, test); /* PLL N-Divider Value */
519 1.5 chopps
520 1.8 is test = clockpar & 0xFF;
521 1.8 is WSeq(ba, SEQ_ID_MCLK_LO, test); /* PLL M-Divider Value */
522 1.8 is }
523 1.1 chopps
524 1.1 chopps /* We now load an 25 MHz, 31 kHz, 640x480 standard VGA Mode. */
525 1.1 chopps /* DCLK */
526 1.1 chopps WSeq(ba, SEQ_ID_DCLK_HI, 0x13);
527 1.1 chopps WSeq(ba, SEQ_ID_DCLK_LO, 0x41);
528 1.1 chopps
529 1.1 chopps test = RSeq (ba, SEQ_ID_CLKSYN_CNTL_2);
530 1.1 chopps test = test | 0x22;
531 1.1 chopps
532 1.1 chopps /* DCLK + MCLK Clock immediate load! */
533 1.1 chopps WSeq(ba,SEQ_ID_CLKSYN_CNTL_2, test);
534 1.1 chopps
535 1.1 chopps /* DCLK load */
536 1.1 chopps test = vgar(ba, 0x3cc);
537 1.1 chopps test = test | 0x0c;
538 1.1 chopps vgaw(ba, 0x3c2, test);
539 1.1 chopps
540 1.1 chopps /* Clear bit 5 again, prevent further loading. */
541 1.1 chopps WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, 0x2);
542 1.1 chopps
543 1.1 chopps WCrt(ba, CRT_ID_HOR_TOTAL, 0x5F);
544 1.1 chopps WCrt(ba, CRT_ID_HOR_DISP_ENA_END, 0x4F);
545 1.1 chopps WCrt(ba, CRT_ID_START_HOR_BLANK, 0x50);
546 1.1 chopps WCrt(ba, CRT_ID_END_HOR_BLANK, 0x82);
547 1.1 chopps WCrt(ba, CRT_ID_START_HOR_RETR, 0x54);
548 1.1 chopps WCrt(ba, CRT_ID_END_HOR_RETR, 0x80);
549 1.1 chopps WCrt(ba, CRT_ID_VER_TOTAL, 0xBF);
550 1.1 chopps
551 1.1 chopps WCrt(ba, CRT_ID_OVERFLOW, 0x1F); /* overflow reg */
552 1.1 chopps
553 1.1 chopps WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x0); /* no panning */
554 1.1 chopps
555 1.1 chopps WCrt(ba, CRT_ID_MAX_SCAN_LINE, 0x40); /* vscan */
556 1.1 chopps
557 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, 0x00);
558 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, 0x00);
559 1.1 chopps
560 1.1 chopps /* Display start adress */
561 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
562 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
563 1.1 chopps
564 1.1 chopps /* Cursor location */
565 1.3 chopps WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
566 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
567 1.1 chopps
568 1.1 chopps /* Vertical retrace */
569 1.1 chopps WCrt(ba, CRT_ID_START_VER_RETR, 0x9C);
570 1.1 chopps WCrt(ba, CRT_ID_END_VER_RETR, 0x0E);
571 1.1 chopps
572 1.1 chopps WCrt(ba, CRT_ID_VER_DISP_ENA_END, 0x8F);
573 1.1 chopps WCrt(ba, CRT_ID_SCREEN_OFFSET, 0x50);
574 1.1 chopps
575 1.1 chopps WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x00);
576 1.1 chopps
577 1.1 chopps WCrt(ba, CRT_ID_START_VER_BLANK, 0x96);
578 1.1 chopps WCrt(ba, CRT_ID_END_VER_BLANK, 0xB9);
579 1.1 chopps
580 1.1 chopps WCrt(ba, CRT_ID_MODE_CONTROL, 0xE3);
581 1.1 chopps
582 1.1 chopps WCrt(ba, CRT_ID_LINE_COMPARE, 0xFF);
583 1.1 chopps
584 1.1 chopps WCrt(ba, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
585 1.1 chopps
586 1.1 chopps /* Refresh count 1, High speed text font, enhanced color mode */
587 1.1 chopps WCrt(ba, CRT_ID_MISC_1, 0x35);
588 1.1 chopps
589 1.1 chopps /* start fifo position */
590 1.1 chopps WCrt(ba, CRT_ID_DISPLAY_FIFO, 0x5a);
591 1.1 chopps
592 1.1 chopps WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, 0x70);
593 1.1 chopps
594 1.1 chopps /* address window position */
595 1.1 chopps WCrt(ba, CRT_ID_LAW_POS_LO, 0x40);
596 1.1 chopps
597 1.1 chopps /* N Parameter for Display FIFO */
598 1.1 chopps WCrt(ba, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
599 1.1 chopps
600 1.1 chopps WGfx(ba, GCT_ID_SET_RESET, 0x0);
601 1.1 chopps WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x0);
602 1.1 chopps WGfx(ba, GCT_ID_COLOR_COMPARE, 0x0);
603 1.1 chopps WGfx(ba, GCT_ID_DATA_ROTATE, 0x0);
604 1.1 chopps WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x0);
605 1.1 chopps WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
606 1.1 chopps WGfx(ba, GCT_ID_MISC, 0x01);
607 1.1 chopps WGfx(ba, GCT_ID_COLOR_XCARE, 0x0F);
608 1.1 chopps WGfx(ba, GCT_ID_BITMASK, 0xFF);
609 1.1 chopps
610 1.1 chopps /* colors for text mode */
611 1.1 chopps for (i = 0; i <= 0xf; i++)
612 1.1 chopps WAttr (ba, i, i);
613 1.1 chopps
614 1.4 jtc WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x41);
615 1.4 jtc WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x01);
616 1.4 jtc WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0F);
617 1.4 jtc WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x0);
618 1.4 jtc WAttr(ba, ACT_ID_COLOR_SELECT, 0x0);
619 1.1 chopps
620 1.1 chopps vgaw(ba, VDAC_MASK, 0xFF); /* DAC Mask */
621 1.1 chopps
622 1.1 chopps *((unsigned long *)(ba + ECR_FRGD_COLOR)) = 0xFF;
623 1.1 chopps *((unsigned long *)(ba + ECR_BKGD_COLOR)) = 0;
624 1.1 chopps
625 1.1 chopps /* colors initially set to greyscale */
626 1.1 chopps
627 1.1 chopps vgaw(ba, VDAC_ADDRESS_W, 0);
628 1.1 chopps for (i = 255; i >= 0 ; i--) {
629 1.1 chopps vgaw(ba, VDAC_DATA, i);
630 1.1 chopps vgaw(ba, VDAC_DATA, i);
631 1.1 chopps vgaw(ba, VDAC_DATA, i);
632 1.1 chopps }
633 1.1 chopps
634 1.1 chopps /* GFx hardware cursor off */
635 1.1 chopps WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
636 1.1 chopps
637 1.1 chopps /* Set first to 4 MB, so test will work */
638 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x13);
639 1.1 chopps
640 1.1 chopps /* find *correct* fbsize of z3 board */
641 1.7 veego if (cv_has_4mb((volatile caddr_t)cv_boardaddr + 0x01400000)) {
642 1.1 chopps cv_fbsize = 1024 * 1024 * 4;
643 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x13); /* 4 MB */
644 1.1 chopps } else {
645 1.1 chopps cv_fbsize = 1024 * 1024 * 2;
646 1.1 chopps WCrt(ba, CRT_ID_LAW_CNTL, 0x12); /* 2 MB */
647 1.1 chopps }
648 1.1 chopps
649 1.7 veego /* Enable Video Display (Set Bit 5) */
650 1.1 chopps WAttr(ba, 0x33, 0);
651 1.4 jtc
652 1.7 veego gi = &gp->g_display;
653 1.7 veego gi->gd_regaddr = (caddr_t) kvtop (ba);
654 1.7 veego gi->gd_regsize = 64 * 1024;
655 1.7 veego gi->gd_fbaddr = (caddr_t) kvtop (gp->g_fbkva);
656 1.7 veego gi->gd_fbsize = cv_fbsize;
657 1.1 chopps }
658 1.1 chopps
659 1.1 chopps
660 1.1 chopps int
661 1.1 chopps cv_getvmode(gp, vm)
662 1.1 chopps struct grf_softc *gp;
663 1.1 chopps struct grfvideo_mode *vm;
664 1.1 chopps {
665 1.1 chopps struct grfvideo_mode *gv;
666 1.1 chopps
667 1.1 chopps #ifdef CV64CONSOLE
668 1.1 chopps /* Handle grabbing console mode */
669 1.1 chopps if (vm->mode_num == 255) {
670 1.1 chopps bcopy(&cvconsole_mode, vm, sizeof(struct grfvideo_mode));
671 1.2 chopps /* XXX so grfconfig can tell us the correct text dimensions. */
672 1.1 chopps vm->depth = cvconsole_mode.fy;
673 1.2 chopps } else
674 1.1 chopps #endif
675 1.2 chopps {
676 1.2 chopps if (vm->mode_num == 0)
677 1.2 chopps vm->mode_num = (monitor_current - monitor_def) + 1;
678 1.2 chopps if (vm->mode_num < 1 || vm->mode_num > monitor_def_max)
679 1.2 chopps return (EINVAL);
680 1.2 chopps gv = monitor_def + (vm->mode_num - 1);
681 1.2 chopps if (gv->mode_num == 0)
682 1.2 chopps return (EINVAL);
683 1.2 chopps
684 1.2 chopps bcopy(gv, vm, sizeof(struct grfvideo_mode));
685 1.2 chopps }
686 1.2 chopps
687 1.2 chopps /* adjust internal values to pixel values */
688 1.2 chopps
689 1.2 chopps vm->hblank_start *= 8;
690 1.2 chopps vm->hblank_stop *= 8;
691 1.2 chopps vm->hsync_start *= 8;
692 1.2 chopps vm->hsync_stop *= 8;
693 1.2 chopps vm->htotal *= 8;
694 1.1 chopps
695 1.2 chopps return (0);
696 1.1 chopps }
697 1.1 chopps
698 1.1 chopps
699 1.1 chopps int
700 1.1 chopps cv_setvmode(gp, mode)
701 1.1 chopps struct grf_softc *gp;
702 1.1 chopps unsigned mode;
703 1.1 chopps {
704 1.7 veego
705 1.1 chopps if (!mode || (mode > monitor_def_max) ||
706 1.4 jtc monitor_def[mode - 1].mode_num == 0)
707 1.2 chopps return (EINVAL);
708 1.1 chopps
709 1.1 chopps monitor_current = monitor_def + (mode - 1);
710 1.1 chopps
711 1.2 chopps return (0);
712 1.1 chopps }
713 1.1 chopps
714 1.1 chopps
715 1.1 chopps int
716 1.1 chopps cv_blank(gp, on)
717 1.1 chopps struct grf_softc *gp;
718 1.1 chopps int *on;
719 1.1 chopps {
720 1.7 veego volatile caddr_t ba;
721 1.1 chopps
722 1.7 veego ba = gp->g_regkva;
723 1.7 veego gfx_on_off(*on ? 0 : 1, ba);
724 1.1 chopps return (0);
725 1.1 chopps }
726 1.1 chopps
727 1.1 chopps
728 1.1 chopps /*
729 1.1 chopps * Change the mode of the display.
730 1.1 chopps * Return a UNIX error number or 0 for success.
731 1.1 chopps */
732 1.1 chopps int
733 1.1 chopps cv_mode(gp, cmd, arg, a2, a3)
734 1.1 chopps register struct grf_softc *gp;
735 1.1 chopps int cmd;
736 1.1 chopps void *arg;
737 1.1 chopps int a2, a3;
738 1.1 chopps {
739 1.1 chopps int error;
740 1.1 chopps
741 1.1 chopps switch (cmd) {
742 1.1 chopps case GM_GRFON:
743 1.1 chopps error = cv_load_mon (gp,
744 1.1 chopps (struct grfcvtext_mode *) monitor_current) ? 0 : EINVAL;
745 1.2 chopps return (error);
746 1.1 chopps
747 1.1 chopps case GM_GRFOFF:
748 1.1 chopps #ifndef CV64CONSOLE
749 1.4 jtc (void)cv_toggle(gp);
750 1.1 chopps #else
751 1.1 chopps cv_load_mon(gp, &cvconsole_mode);
752 1.7 veego ite_reinit(gp->g_itedev);
753 1.1 chopps #endif
754 1.2 chopps return (0);
755 1.1 chopps
756 1.1 chopps case GM_GRFCONFIG:
757 1.2 chopps return (0);
758 1.1 chopps
759 1.1 chopps case GM_GRFGETVMODE:
760 1.2 chopps return (cv_getvmode (gp, (struct grfvideo_mode *) arg));
761 1.1 chopps
762 1.1 chopps case GM_GRFSETVMODE:
763 1.1 chopps error = cv_setvmode (gp, *(unsigned *) arg);
764 1.1 chopps if (!error && (gp->g_flags & GF_GRFON))
765 1.1 chopps cv_load_mon(gp,
766 1.1 chopps (struct grfcvtext_mode *) monitor_current);
767 1.2 chopps return (error);
768 1.1 chopps
769 1.1 chopps case GM_GRFGETNUMVM:
770 1.1 chopps *(int *)arg = monitor_def_max;
771 1.2 chopps return (0);
772 1.1 chopps
773 1.1 chopps case GM_GRFIOCTL:
774 1.2 chopps return (cv_ioctl (gp, (int) arg, (caddr_t) a2));
775 1.1 chopps
776 1.1 chopps default:
777 1.1 chopps break;
778 1.1 chopps }
779 1.1 chopps
780 1.2 chopps return (EINVAL);
781 1.1 chopps }
782 1.1 chopps
783 1.1 chopps int
784 1.1 chopps cv_ioctl (gp, cmd, data)
785 1.1 chopps register struct grf_softc *gp;
786 1.1 chopps int cmd;
787 1.1 chopps void *data;
788 1.1 chopps {
789 1.1 chopps switch (cmd) {
790 1.1 chopps case GRFIOCGSPRITEPOS:
791 1.1 chopps case GRFIOCSSPRITEPOS:
792 1.1 chopps case GRFIOCSSPRITEINF:
793 1.1 chopps case GRFIOCGSPRITEINF:
794 1.1 chopps case GRFIOCGSPRITEMAX:
795 1.1 chopps break;
796 1.1 chopps
797 1.1 chopps case GRFIOCGETCMAP:
798 1.2 chopps return (cv_getcmap (gp, (struct grf_colormap *) data));
799 1.1 chopps
800 1.1 chopps case GRFIOCPUTCMAP:
801 1.2 chopps return (cv_putcmap (gp, (struct grf_colormap *) data));
802 1.1 chopps
803 1.1 chopps case GRFIOCBITBLT:
804 1.1 chopps break;
805 1.1 chopps
806 1.1 chopps case GRFTOGGLE:
807 1.4 jtc return (cv_toggle (gp));
808 1.1 chopps
809 1.1 chopps case GRFIOCSETMON:
810 1.2 chopps return (cv_setmonitor (gp, (struct grfvideo_mode *)data));
811 1.1 chopps
812 1.1 chopps case GRFIOCBLANK:
813 1.2 chopps return (cv_blank (gp, (int *)data));
814 1.1 chopps }
815 1.2 chopps return (EINVAL);
816 1.1 chopps }
817 1.1 chopps
818 1.1 chopps int
819 1.1 chopps cv_setmonitor(gp, gv)
820 1.1 chopps struct grf_softc *gp;
821 1.1 chopps struct grfvideo_mode *gv;
822 1.1 chopps {
823 1.1 chopps struct grfvideo_mode *md;
824 1.1 chopps
825 1.2 chopps if (!cv_mondefok(gv))
826 1.2 chopps return (EINVAL);
827 1.2 chopps
828 1.1 chopps #ifdef CV64CONSOLE
829 1.1 chopps /* handle interactive setting of console mode */
830 1.2 chopps if (gv->mode_num == 255) {
831 1.1 chopps bcopy(gv, &cvconsole_mode.gv, sizeof(struct grfvideo_mode));
832 1.2 chopps cvconsole_mode.gv.hblank_start /= 8;
833 1.2 chopps cvconsole_mode.gv.hblank_stop /= 8;
834 1.2 chopps cvconsole_mode.gv.hsync_start /= 8;
835 1.2 chopps cvconsole_mode.gv.hsync_stop /= 8;
836 1.2 chopps cvconsole_mode.gv.htotal /= 8;
837 1.1 chopps cvconsole_mode.rows = gv->disp_height / cvconsole_mode.fy;
838 1.1 chopps cvconsole_mode.cols = gv->disp_width / cvconsole_mode.fx;
839 1.1 chopps if (!(gp->g_flags & GF_GRFON))
840 1.1 chopps cv_load_mon(gp, &cvconsole_mode);
841 1.1 chopps ite_reinit(gp->g_itedev);
842 1.2 chopps return (0);
843 1.1 chopps }
844 1.1 chopps #endif
845 1.1 chopps
846 1.2 chopps md = monitor_def + (gv->mode_num - 1);
847 1.2 chopps bcopy(gv, md, sizeof(struct grfvideo_mode));
848 1.1 chopps
849 1.2 chopps /* adjust pixel oriented values to internal rep. */
850 1.1 chopps
851 1.2 chopps md->hblank_start /= 8;
852 1.2 chopps md->hblank_stop /= 8;
853 1.2 chopps md->hsync_start /= 8;
854 1.2 chopps md->hsync_stop /= 8;
855 1.2 chopps md->htotal /= 8;
856 1.1 chopps
857 1.2 chopps return (0);
858 1.1 chopps }
859 1.1 chopps
860 1.1 chopps int
861 1.1 chopps cv_getcmap(gfp, cmap)
862 1.1 chopps struct grf_softc *gfp;
863 1.1 chopps struct grf_colormap *cmap;
864 1.1 chopps {
865 1.4 jtc volatile caddr_t ba;
866 1.1 chopps u_char red[256], green[256], blue[256], *rp, *gp, *bp;
867 1.1 chopps short x;
868 1.1 chopps int error;
869 1.1 chopps
870 1.7 veego ba = gfp->g_regkva;
871 1.1 chopps if (cmap->count == 0 || cmap->index >= 256)
872 1.2 chopps return (0);
873 1.1 chopps
874 1.1 chopps if (cmap->index + cmap->count > 256)
875 1.1 chopps cmap->count = 256 - cmap->index;
876 1.1 chopps
877 1.1 chopps /* first read colors out of the chip, then copyout to userspace */
878 1.1 chopps vgaw (ba, VDAC_ADDRESS_W, cmap->index);
879 1.1 chopps x = cmap->count - 1;
880 1.1 chopps
881 1.1 chopps rp = red + cmap->index;
882 1.1 chopps gp = green + cmap->index;
883 1.1 chopps bp = blue + cmap->index;
884 1.1 chopps
885 1.1 chopps do {
886 1.1 chopps *rp++ = vgar (ba, VDAC_DATA) << 2;
887 1.1 chopps *gp++ = vgar (ba, VDAC_DATA) << 2;
888 1.1 chopps *bp++ = vgar (ba, VDAC_DATA) << 2;
889 1.1 chopps } while (x-- > 0);
890 1.1 chopps
891 1.1 chopps if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
892 1.1 chopps && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
893 1.1 chopps && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
894 1.2 chopps return (0);
895 1.1 chopps
896 1.2 chopps return (error);
897 1.1 chopps }
898 1.1 chopps
899 1.1 chopps int
900 1.1 chopps cv_putcmap(gfp, cmap)
901 1.1 chopps struct grf_softc *gfp;
902 1.1 chopps struct grf_colormap *cmap;
903 1.1 chopps {
904 1.4 jtc volatile caddr_t ba;
905 1.1 chopps u_char red[256], green[256], blue[256], *rp, *gp, *bp;
906 1.1 chopps short x;
907 1.1 chopps int error;
908 1.1 chopps
909 1.7 veego ba = gfp->g_regkva;
910 1.1 chopps if (cmap->count == 0 || cmap->index >= 256)
911 1.2 chopps return (0);
912 1.1 chopps
913 1.1 chopps if (cmap->index + cmap->count > 256)
914 1.1 chopps cmap->count = 256 - cmap->index;
915 1.1 chopps
916 1.1 chopps /* first copy the colors into kernelspace */
917 1.1 chopps if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
918 1.1 chopps && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
919 1.1 chopps && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
920 1.1 chopps vgaw (ba, VDAC_ADDRESS_W, cmap->index);
921 1.1 chopps x = cmap->count - 1;
922 1.1 chopps
923 1.1 chopps rp = red + cmap->index;
924 1.1 chopps gp = green + cmap->index;
925 1.1 chopps bp = blue + cmap->index;
926 1.1 chopps
927 1.1 chopps do {
928 1.1 chopps vgaw (ba, VDAC_DATA, *rp++ >> 2);
929 1.1 chopps vgaw (ba, VDAC_DATA, *gp++ >> 2);
930 1.1 chopps vgaw (ba, VDAC_DATA, *bp++ >> 2);
931 1.1 chopps } while (x-- > 0);
932 1.2 chopps return (0);
933 1.2 chopps } else
934 1.2 chopps return (error);
935 1.1 chopps }
936 1.1 chopps
937 1.1 chopps
938 1.1 chopps int
939 1.4 jtc cv_toggle(gp)
940 1.1 chopps struct grf_softc *gp;
941 1.1 chopps {
942 1.4 jtc volatile caddr_t ba;
943 1.1 chopps
944 1.4 jtc ba = gp->g_regkva;
945 1.7 veego cvscreen(1, ba - 0x02000000);
946 1.1 chopps
947 1.2 chopps return (0);
948 1.1 chopps }
949 1.1 chopps
950 1.1 chopps
951 1.1 chopps int
952 1.2 chopps cv_mondefok(gv)
953 1.2 chopps struct grfvideo_mode *gv;
954 1.1 chopps {
955 1.2 chopps unsigned long maxpix;
956 1.7 veego int widthok = 0;
957 1.2 chopps
958 1.7 veego if (gv->mode_num < 1 || gv->mode_num > monitor_def_max) {
959 1.7 veego if (gv->mode_num != 255 || (gv->depth != 4 && gv->depth != 8))
960 1.2 chopps return (0);
961 1.7 veego else
962 1.7 veego /*
963 1.7 veego * We have 8 bit console modes. This _is_
964 1.7 veego * a hack but necessary to be compatible.
965 1.7 veego */
966 1.7 veego gv->depth = 8;
967 1.7 veego }
968 1.1 chopps
969 1.2 chopps switch(gv->depth) {
970 1.1 chopps case 1:
971 1.1 chopps case 4:
972 1.7 veego return (0);
973 1.1 chopps case 8:
974 1.2 chopps maxpix = MAXPIXELCLOCK;
975 1.2 chopps break;
976 1.1 chopps case 15:
977 1.1 chopps case 16:
978 1.7 veego #ifdef CV_AGGRESSIVE_TIMING
979 1.7 veego maxpix = MAXPIXELCLOCK - 35000000;
980 1.7 veego #else
981 1.2 chopps maxpix = MAXPIXELCLOCK - 55000000;
982 1.7 veego #endif
983 1.2 chopps break;
984 1.1 chopps case 24:
985 1.7 veego case 32:
986 1.7 veego #ifdef CV_AGGRESSIVE_TIMING
987 1.7 veego maxpix = MAXPIXELCLOCK - 75000000;
988 1.7 veego #else
989 1.2 chopps maxpix = MAXPIXELCLOCK - 85000000;
990 1.7 veego #endif
991 1.2 chopps break;
992 1.1 chopps default:
993 1.2 chopps return (0);
994 1.1 chopps }
995 1.2 chopps
996 1.2 chopps if (gv->pixel_clock > maxpix)
997 1.2 chopps return (0);
998 1.7 veego
999 1.7 veego /*
1000 1.7 veego * These are the supported witdh values for the
1001 1.7 veego * graphics engine. To Support other widths, one
1002 1.7 veego * has to use one of these widths for memory alignment, i.e.
1003 1.7 veego * one has to set CRT_ID_SCREEN_OFFSET to one of these values and
1004 1.7 veego * CRT_ID_HOR_DISP_ENA_END to the desired width.
1005 1.7 veego * Since a working graphics engine is essential
1006 1.7 veego * for the console, console modes of other width are not supported.
1007 1.7 veego * We could do that, though, but then you have to tell the Xserver
1008 1.7 veego * about this strange configuration and I don't know how at the moment :-)
1009 1.7 veego */
1010 1.7 veego
1011 1.7 veego switch (gv->disp_width) {
1012 1.7 veego case 1024:
1013 1.7 veego case 640:
1014 1.7 veego case 800:
1015 1.7 veego case 1280:
1016 1.7 veego case 1152:
1017 1.7 veego case 1600:
1018 1.7 veego widthok = 1;
1019 1.7 veego break;
1020 1.7 veego default: /* XXX*/
1021 1.7 veego widthok = 0;
1022 1.7 veego break;
1023 1.7 veego }
1024 1.7 veego
1025 1.7 veego if (widthok) return (1);
1026 1.7 veego else {
1027 1.7 veego if (gv->mode_num == 255) { /* console mode */
1028 1.7 veego printf ("This display width is not supported by the CV64 console.\n");
1029 1.7 veego printf ("Use one of 640 800 1024 1152 1280 1600!\n");
1030 1.7 veego return (0);
1031 1.7 veego } else {
1032 1.7 veego printf ("Warning for mode %d:\n", (int) gv->mode_num);
1033 1.7 veego printf ("Don't use a blitter-suporting Xserver with this display width\n");
1034 1.7 veego printf ("Use one of 640 800 1024 1152 1280 1600!\n");
1035 1.7 veego return (1);
1036 1.7 veego }
1037 1.7 veego }
1038 1.2 chopps return (1);
1039 1.1 chopps }
1040 1.1 chopps
1041 1.1 chopps int
1042 1.1 chopps cv_load_mon(gp, md)
1043 1.1 chopps struct grf_softc *gp;
1044 1.1 chopps struct grfcvtext_mode *md;
1045 1.1 chopps {
1046 1.1 chopps struct grfvideo_mode *gv;
1047 1.1 chopps struct grfinfo *gi;
1048 1.4 jtc volatile caddr_t ba, fb;
1049 1.1 chopps unsigned short mnr;
1050 1.2 chopps unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
1051 1.2 chopps VSE, VT;
1052 1.7 veego char LACE, DBLSCAN, TEXT, CONSOLE;
1053 1.1 chopps int uplim, lowlim;
1054 1.7 veego int cr50, cr33, sr15, sr18, clock_mode, test;
1055 1.7 veego int m, n; /* For calc'ing display FIFO */
1056 1.7 veego int tfillm, temptym; /* FIFO fill and empty mclk's */
1057 1.7 veego int hmul; /* Multiplier for hor. Values */
1058 1.1 chopps /* identity */
1059 1.1 chopps gv = &md->gv;
1060 1.7 veego
1061 1.7 veego /*
1062 1.7 veego * No way to get text modes to work.
1063 1.7 veego * Blame phase5, not me!
1064 1.7 veego */
1065 1.7 veego TEXT = 0; /* (gv->depth == 4); */
1066 1.7 veego CONSOLE = (gv->mode_num == 255);
1067 1.1 chopps
1068 1.1 chopps if (!cv_mondefok(gv)) {
1069 1.7 veego printf("grfcv: The monitor definition is not okay.\n");
1070 1.7 veego printf("grfcv: See the manpage of grfconfig for more informations\n");
1071 1.2 chopps return (0);
1072 1.1 chopps }
1073 1.1 chopps ba = gp->g_regkva;
1074 1.1 chopps fb = gp->g_fbkva;
1075 1.1 chopps
1076 1.3 chopps /* turn gfx off, don't mess up the display */
1077 1.3 chopps gfx_on_off(1, ba);
1078 1.3 chopps
1079 1.2 chopps /* provide all needed information in grf device-independant locations */
1080 1.1 chopps gp->g_data = (caddr_t) gv;
1081 1.1 chopps gi = &gp->g_display;
1082 1.1 chopps gi->gd_colors = 1 << gv->depth;
1083 1.1 chopps gi->gd_planes = gv->depth;
1084 1.1 chopps gi->gd_fbwidth = gv->disp_width;
1085 1.1 chopps gi->gd_fbheight = gv->disp_height;
1086 1.1 chopps gi->gd_fbx = 0;
1087 1.1 chopps gi->gd_fby = 0;
1088 1.7 veego if (CONSOLE) {
1089 1.1 chopps gi->gd_dwidth = md->fx * md->cols;
1090 1.1 chopps gi->gd_dheight = md->fy * md->rows;
1091 1.1 chopps } else {
1092 1.1 chopps gi->gd_dwidth = gv->disp_width;
1093 1.1 chopps gi->gd_dheight = gv->disp_height;
1094 1.1 chopps }
1095 1.1 chopps gi->gd_dx = 0;
1096 1.1 chopps gi->gd_dy = 0;
1097 1.1 chopps
1098 1.1 chopps /* get display mode parameters */
1099 1.7 veego switch (gv->depth) {
1100 1.7 veego case 15:
1101 1.7 veego case 16:
1102 1.7 veego hmul = 2;
1103 1.7 veego break;
1104 1.7 veego default:
1105 1.7 veego hmul = 1;
1106 1.7 veego break;
1107 1.7 veego }
1108 1.1 chopps
1109 1.7 veego HBS = gv->hblank_start * hmul;
1110 1.7 veego HBE = gv->hblank_stop * hmul;
1111 1.7 veego HSS = gv->hsync_start * hmul;
1112 1.7 veego HSE = gv->hsync_stop * hmul;
1113 1.7 veego HT = gv->htotal*hmul - 5;
1114 1.4 jtc VBS = gv->vblank_start - 1;
1115 1.1 chopps VSS = gv->vsync_start;
1116 1.1 chopps VSE = gv->vsync_stop;
1117 1.1 chopps VBE = gv->vblank_stop;
1118 1.4 jtc VT = gv->vtotal - 2;
1119 1.1 chopps
1120 1.1 chopps if (TEXT)
1121 1.1 chopps HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
1122 1.1 chopps else
1123 1.7 veego HDE = (gv->disp_width + 3) * hmul / 8 - 1; /*HBS;*/
1124 1.1 chopps VDE = gv->disp_height - 1;
1125 1.1 chopps
1126 1.1 chopps /* figure out whether lace or dblscan is needed */
1127 1.1 chopps
1128 1.1 chopps uplim = gv->disp_height + (gv->disp_height / 4);
1129 1.1 chopps lowlim = gv->disp_height - (gv->disp_height / 4);
1130 1.1 chopps LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
1131 1.1 chopps DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
1132 1.1 chopps
1133 1.1 chopps /* adjustments */
1134 1.1 chopps
1135 1.1 chopps if (LACE)
1136 1.1 chopps VDE /= 2;
1137 1.1 chopps
1138 1.1 chopps WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
1139 1.1 chopps WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1140 1.1 chopps WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff);
1141 1.1 chopps WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
1142 1.1 chopps
1143 1.1 chopps /* Set clock */
1144 1.1 chopps
1145 1.7 veego mnr = compute_clock(gv->pixel_clock);
1146 1.1 chopps WSeq(ba, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8) );
1147 1.1 chopps WSeq(ba, SEQ_ID_DCLK_LO, (mnr & 0xFF));
1148 1.1 chopps
1149 1.1 chopps /* load display parameters into board */
1150 1.1 chopps
1151 1.1 chopps WCrt(ba, CRT_ID_EXT_HOR_OVF,
1152 1.1 chopps ((HT & 0x100) ? 0x01 : 0x00) |
1153 1.1 chopps ((HDE & 0x100) ? 0x02 : 0x00) |
1154 1.1 chopps ((HBS & 0x100) ? 0x04 : 0x00) |
1155 1.3 chopps /* ((HBE & 0x40) ? 0x08 : 0x00) | */ /* Later... */
1156 1.1 chopps ((HSS & 0x100) ? 0x10 : 0x00) |
1157 1.3 chopps /* ((HSE & 0x20) ? 0x20 : 0x00) | */
1158 1.1 chopps (((HT-5) & 0x100) ? 0x40 : 0x00) );
1159 1.1 chopps
1160 1.1 chopps WCrt(ba, CRT_ID_EXT_VER_OVF,
1161 1.1 chopps 0x40 | /* Line compare */
1162 1.1 chopps ((VT & 0x400) ? 0x01 : 0x00) |
1163 1.1 chopps ((VDE & 0x400) ? 0x02 : 0x00) |
1164 1.1 chopps ((VBS & 0x400) ? 0x04 : 0x00) |
1165 1.1 chopps ((VSS & 0x400) ? 0x10 : 0x00) );
1166 1.1 chopps
1167 1.1 chopps WCrt(ba, CRT_ID_HOR_TOTAL, HT);
1168 1.1 chopps WCrt(ba, CRT_ID_DISPLAY_FIFO, HT - 5);
1169 1.1 chopps
1170 1.1 chopps WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
1171 1.1 chopps WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
1172 1.1 chopps WCrt(ba, CRT_ID_END_HOR_BLANK, ((HBE & 0x1f) | 0x80));
1173 1.1 chopps WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
1174 1.1 chopps WCrt(ba, CRT_ID_END_HOR_RETR,
1175 1.1 chopps (HSE & 0x1f) |
1176 1.1 chopps ((HBE & 0x20) ? 0x80 : 0x00) );
1177 1.1 chopps WCrt(ba, CRT_ID_VER_TOTAL, VT);
1178 1.1 chopps WCrt(ba, CRT_ID_OVERFLOW,
1179 1.1 chopps 0x10 |
1180 1.1 chopps ((VT & 0x100) ? 0x01 : 0x00) |
1181 1.1 chopps ((VDE & 0x100) ? 0x02 : 0x00) |
1182 1.1 chopps ((VSS & 0x100) ? 0x04 : 0x00) |
1183 1.1 chopps ((VBS & 0x100) ? 0x08 : 0x00) |
1184 1.1 chopps ((VT & 0x200) ? 0x20 : 0x00) |
1185 1.1 chopps ((VDE & 0x200) ? 0x40 : 0x00) |
1186 1.1 chopps ((VSS & 0x200) ? 0x80 : 0x00) );
1187 1.1 chopps
1188 1.1 chopps WCrt(ba, CRT_ID_MAX_SCAN_LINE,
1189 1.1 chopps 0x40 | /* TEXT ? 0x00 ??? */
1190 1.1 chopps (DBLSCAN ? 0x80 : 0x00) |
1191 1.1 chopps ((VBS & 0x200) ? 0x20 : 0x00) |
1192 1.1 chopps (TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
1193 1.1 chopps
1194 1.1 chopps WCrt(ba, CRT_ID_MODE_CONTROL,
1195 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0xc3 : 0xe3));
1196 1.1 chopps
1197 1.1 chopps /* text cursor */
1198 1.1 chopps
1199 1.1 chopps if (TEXT) {
1200 1.1 chopps #if 1
1201 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
1202 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
1203 1.1 chopps #else
1204 1.1 chopps WCrt(ba, CRT_ID_CURSOR_START, 0x00);
1205 1.1 chopps WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
1206 1.1 chopps #endif
1207 1.1 chopps WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->fy - 1) & 0x1f);
1208 1.1 chopps
1209 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1210 1.1 chopps WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
1211 1.1 chopps }
1212 1.1 chopps
1213 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
1214 1.1 chopps WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
1215 1.1 chopps
1216 1.1 chopps WCrt(ba, CRT_ID_START_VER_RETR, VSS);
1217 1.1 chopps WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f));
1218 1.1 chopps WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE);
1219 1.1 chopps WCrt(ba, CRT_ID_START_VER_BLANK, VBS);
1220 1.1 chopps WCrt(ba, CRT_ID_END_VER_BLANK, VBE);
1221 1.1 chopps
1222 1.1 chopps WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
1223 1.1 chopps WCrt(ba, CRT_ID_LACE_RETR_START, HT / 2);
1224 1.1 chopps WCrt(ba, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
1225 1.1 chopps
1226 1.1 chopps WGfx(ba, GCT_ID_GRAPHICS_MODE,
1227 1.1 chopps ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
1228 1.1 chopps WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1229 1.1 chopps
1230 1.1 chopps WSeq (ba, SEQ_ID_MEMORY_MODE,
1231 1.7 veego ((TEXT || (gv->depth == 1)) ? 0x06 : 0x02));
1232 1.1 chopps
1233 1.1 chopps vgaw(ba, VDAC_MASK, 0xff);
1234 1.1 chopps
1235 1.4 jtc sr15 = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2);
1236 1.4 jtc sr15 &= 0xef;
1237 1.4 jtc sr18 = RSeq(ba, SEQ_ID_RAMDAC_CNTL);
1238 1.4 jtc sr18 &= 0x7f;
1239 1.4 jtc cr33 = RCrt(ba, CRT_ID_BACKWAD_COMP_2);
1240 1.4 jtc cr33 &= 0xdf;
1241 1.4 jtc clock_mode = 0x00;
1242 1.7 veego cr50 = 0x00;
1243 1.1 chopps
1244 1.1 chopps test = RCrt(ba, CRT_ID_EXT_MISC_CNTL_2);
1245 1.4 jtc test &= 0xd;
1246 1.1 chopps
1247 1.7 veego /* clear roxxler byte-swapping... */
1248 1.7 veego cv_write_port(0x0040, cv_boardaddr);
1249 1.7 veego cv_write_port(0x0020, cv_boardaddr);
1250 1.7 veego
1251 1.1 chopps switch (gv->depth) {
1252 1.1 chopps case 1:
1253 1.1 chopps case 4: /* text */
1254 1.1 chopps HDE = gv->disp_width / 16;
1255 1.1 chopps break;
1256 1.1 chopps case 8:
1257 1.4 jtc if (gv->pixel_clock > 80000000) {
1258 1.4 jtc clock_mode = 0x10 | 0x02;
1259 1.4 jtc sr15 |= 0x10;
1260 1.4 jtc sr18 |= 0x80;
1261 1.4 jtc cr33 |= 0x20;
1262 1.4 jtc }
1263 1.1 chopps HDE = gv->disp_width / 8;
1264 1.7 veego cr50 |= 0x00;
1265 1.1 chopps break;
1266 1.1 chopps case 15:
1267 1.7 veego cv_write_port (0x8020, cv_boardaddr);
1268 1.4 jtc clock_mode = 0x30;
1269 1.1 chopps HDE = gv->disp_width / 4;
1270 1.7 veego cr50 |= 0x10;
1271 1.1 chopps break;
1272 1.1 chopps case 16:
1273 1.7 veego cv_write_port (0x8020, cv_boardaddr);
1274 1.4 jtc clock_mode = 0x50;
1275 1.1 chopps HDE = gv->disp_width / 4;
1276 1.7 veego cr50 |= 0x10;
1277 1.1 chopps break;
1278 1.7 veego case 24: /* this is really 32 Bit on CV64 */
1279 1.7 veego case 32:
1280 1.7 veego cv_write_port(0x8040, cv_boardaddr);
1281 1.4 jtc clock_mode = 0xd0;
1282 1.7 veego HDE = (gv->disp_width / 2);
1283 1.7 veego cr50 |= 0x30;
1284 1.1 chopps break;
1285 1.1 chopps }
1286 1.1 chopps
1287 1.4 jtc WCrt(ba, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
1288 1.4 jtc WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, sr15);
1289 1.4 jtc WSeq(ba, SEQ_ID_RAMDAC_CNTL, sr18);
1290 1.4 jtc WCrt(ba, CRT_ID_BACKWAD_COMP_2, cr33);
1291 1.4 jtc WCrt(ba, CRT_ID_SCREEN_OFFSET, HDE);
1292 1.1 chopps
1293 1.1 chopps test = RCrt(ba, CRT_ID_EXT_SYS_CNTL_2);
1294 1.7 veego test &= ~0x30;
1295 1.1 chopps /* HDE Overflow in bits 4-5 */
1296 1.1 chopps test |= (HDE >> 4) & 0x30;
1297 1.1 chopps WCrt(ba, CRT_ID_EXT_SYS_CNTL_2, test);
1298 1.1 chopps
1299 1.7 veego /* Set up graphics engine */
1300 1.7 veego switch (gv->disp_width) {
1301 1.7 veego case 1024:
1302 1.7 veego cr50 |= 0x00;
1303 1.7 veego break;
1304 1.7 veego case 640:
1305 1.7 veego cr50 |= 0x40;
1306 1.7 veego break;
1307 1.7 veego case 800:
1308 1.7 veego cr50 |= 0x80;
1309 1.7 veego break;
1310 1.7 veego case 1280:
1311 1.7 veego cr50 |= 0xc0;
1312 1.7 veego break;
1313 1.7 veego case 1152:
1314 1.7 veego cr50 |= 0x01;
1315 1.7 veego break;
1316 1.7 veego case 1600:
1317 1.7 veego cr50 |= 0x81;
1318 1.7 veego break;
1319 1.7 veego default: /* XXX*/
1320 1.7 veego break;
1321 1.7 veego }
1322 1.7 veego
1323 1.7 veego WCrt(ba, CRT_ID_EXT_SYS_CNTL_1, cr50);
1324 1.7 veego
1325 1.1 chopps delay(100000);
1326 1.1 chopps WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x41));
1327 1.1 chopps delay(100000);
1328 1.1 chopps WAttr(ba, ACT_ID_COLOR_PLANE_ENA,
1329 1.1 chopps (gv->depth == 1) ? 0x01 : 0x0f);
1330 1.1 chopps delay(100000);
1331 1.1 chopps
1332 1.4 jtc /*
1333 1.7 veego * M-Parameter of Display FIFO
1334 1.7 veego * This is dependant on the pixel clock and the memory clock.
1335 1.7 veego * The FIFO filling bandwidth is 240 MHz and the FIFO is 96 Byte wide.
1336 1.7 veego * Then the time to fill the FIFO is tfill = (96/240000000) sec, the time
1337 1.7 veego * to empty the FIFO is tempty = (96/pixelclock) sec.
1338 1.7 veego * Then the M parameter maximum is ((tempty-tfill)*cv_memclk-9)/2.
1339 1.7 veego * This seems to be logical, ain't it?
1340 1.7 veego * Remember: We have to use integer arithmetics :(
1341 1.7 veego * Divide by 1000 to prevent overflows.
1342 1.1 chopps */
1343 1.4 jtc
1344 1.7 veego tfillm = (96 * (cv_memclk/1000))/240000;
1345 1.7 veego
1346 1.7 veego switch(gv->depth) {
1347 1.7 veego case 32:
1348 1.7 veego case 24:
1349 1.7 veego temptym = (24 * (cv_memclk/1000)) / (gv->pixel_clock/1000);
1350 1.7 veego break;
1351 1.7 veego case 15:
1352 1.7 veego case 16:
1353 1.7 veego temptym = (48 * (cv_memclk/1000)) / (gv->pixel_clock/1000);
1354 1.7 veego break;
1355 1.7 veego default:
1356 1.7 veego temptym = (96 * (cv_memclk/1000)) / (gv->pixel_clock/1000);
1357 1.7 veego break;
1358 1.7 veego }
1359 1.7 veego
1360 1.7 veego m = (temptym - tfillm - 9) / 2;
1361 1.7 veego m = (m & 0x1f) << 3;
1362 1.7 veego if (m < 0x18)
1363 1.7 veego m = 0x18;
1364 1.4 jtc n = 0xff;
1365 1.1 chopps
1366 1.4 jtc WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, m);
1367 1.4 jtc WCrt(ba, CRT_ID_EXT_MEM_CNTL_3, n);
1368 1.1 chopps delay(10000);
1369 1.1 chopps
1370 1.3 chopps /* text initialization */
1371 1.3 chopps
1372 1.3 chopps if (TEXT) {
1373 1.3 chopps cv_inittextmode(gp);
1374 1.3 chopps }
1375 1.3 chopps
1376 1.7 veego if (CONSOLE) {
1377 1.7 veego int i;
1378 1.7 veego vgaw(ba, VDAC_ADDRESS_W, 0);
1379 1.7 veego for (i = 0; i < 4; i++) {
1380 1.7 veego vgaw(ba, VDAC_DATA, cvconscolors[i][0]);
1381 1.7 veego vgaw(ba, VDAC_DATA, cvconscolors[i][1]);
1382 1.7 veego vgaw(ba, VDAC_DATA, cvconscolors[i][2]);
1383 1.7 veego }
1384 1.7 veego }
1385 1.7 veego
1386 1.1 chopps /* Some kind of Magic */
1387 1.1 chopps WAttr(ba, 0x33, 0);
1388 1.1 chopps
1389 1.1 chopps /* turn gfx on again */
1390 1.1 chopps gfx_on_off(0, ba);
1391 1.1 chopps
1392 1.1 chopps /* Pass-through */
1393 1.7 veego cvscreen(0, ba - 0x02000000);
1394 1.1 chopps
1395 1.2 chopps return (1);
1396 1.1 chopps }
1397 1.1 chopps
1398 1.1 chopps void
1399 1.1 chopps cv_inittextmode(gp)
1400 1.1 chopps struct grf_softc *gp;
1401 1.1 chopps {
1402 1.1 chopps struct grfcvtext_mode *tm = (struct grfcvtext_mode *)gp->g_data;
1403 1.7 veego volatile caddr_t ba, fb;
1404 1.1 chopps unsigned char *c, *f, y;
1405 1.1 chopps unsigned short z;
1406 1.1 chopps
1407 1.7 veego ba = gp->g_regkva;
1408 1.7 veego fb = gp->g_fbkva;
1409 1.1 chopps
1410 1.1 chopps /* load text font into beginning of display memory.
1411 1.2 chopps * Each character cell is 32 bytes long (enough for 4 planes)
1412 1.1 chopps */
1413 1.1 chopps
1414 1.1 chopps SetTextPlane(ba, 0x02);
1415 1.2 chopps cv_memset(fb, 0, 256 * 32);
1416 1.2 chopps c = (unsigned char *) (fb) + (32 * tm->fdstart);
1417 1.1 chopps f = tm->fdata;
1418 1.2 chopps for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy))
1419 1.2 chopps for (y = 0; y < tm->fy; y++)
1420 1.1 chopps *c++ = *f++;
1421 1.1 chopps
1422 1.1 chopps /* clear out text/attr planes (three screens worth) */
1423 1.1 chopps
1424 1.1 chopps SetTextPlane(ba, 0x01);
1425 1.2 chopps cv_memset(fb, 0x07, tm->cols * tm->rows * 3);
1426 1.1 chopps SetTextPlane(ba, 0x00);
1427 1.2 chopps cv_memset(fb, 0x20, tm->cols * tm->rows * 3);
1428 1.1 chopps
1429 1.1 chopps /* print out a little init msg */
1430 1.1 chopps
1431 1.1 chopps c = (unsigned char *)(fb) + (tm->cols-16);
1432 1.1 chopps strcpy(c, "CV64");
1433 1.1 chopps c[6] = 0x20;
1434 1.1 chopps
1435 1.1 chopps /* set colors (B&W) */
1436 1.1 chopps
1437 1.1 chopps vgaw(ba, VDAC_ADDRESS_W, 0);
1438 1.1 chopps for (z=0; z<256; z++) {
1439 1.1 chopps unsigned char r, g, b;
1440 1.1 chopps
1441 1.1 chopps y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1442 1.1 chopps
1443 1.1 chopps r = cvconscolors[y][0];
1444 1.1 chopps g = cvconscolors[y][1];
1445 1.1 chopps b = cvconscolors[y][2];
1446 1.1 chopps vgaw(ba, VDAC_DATA, r >> 2);
1447 1.1 chopps vgaw(ba, VDAC_DATA, g >> 2);
1448 1.1 chopps vgaw(ba, VDAC_DATA, b >> 2);
1449 1.1 chopps }
1450 1.1 chopps }
1451 1.1 chopps
1452 1.1 chopps void
1453 1.1 chopps cv_memset(d, c, l)
1454 1.1 chopps unsigned char *d;
1455 1.1 chopps unsigned char c;
1456 1.1 chopps int l;
1457 1.1 chopps {
1458 1.1 chopps for(; l > 0; l--)
1459 1.1 chopps *d++ = c;
1460 1.7 veego }
1461 1.7 veego
1462 1.7 veego
1463 1.7 veego static inline void
1464 1.7 veego cv_write_port(bits, BoardAddr)
1465 1.7 veego unsigned short bits;
1466 1.7 veego volatile caddr_t BoardAddr;
1467 1.7 veego {
1468 1.7 veego volatile caddr_t addr;
1469 1.7 veego static unsigned char CVPortBits = 0; /* mirror port bits here */
1470 1.7 veego
1471 1.7 veego addr = BoardAddr + 0x40001;
1472 1.7 veego if (bits & 0x8000)
1473 1.7 veego CVPortBits |= bits & 0xFF; /* Set bits */
1474 1.7 veego else {
1475 1.7 veego bits = bits & 0xFF;
1476 1.7 veego bits = (~bits) & 0xFF ;
1477 1.7 veego CVPortBits &= bits; /* Clear bits */
1478 1.7 veego }
1479 1.7 veego
1480 1.7 veego *addr = CVPortBits;
1481 1.7 veego }
1482 1.7 veego
1483 1.7 veego
1484 1.7 veego /*
1485 1.7 veego * Monitor Switch
1486 1.7 veego * 0 = CyberVision Signal
1487 1.7 veego * 1 = Amiga Signal,
1488 1.7 veego * ba = boardaddr
1489 1.7 veego */
1490 1.7 veego static inline void
1491 1.7 veego cvscreen(toggle, ba)
1492 1.7 veego int toggle;
1493 1.7 veego volatile caddr_t ba;
1494 1.7 veego {
1495 1.7 veego
1496 1.7 veego if (toggle == 1)
1497 1.7 veego cv_write_port (0x10, ba);
1498 1.7 veego else
1499 1.7 veego cv_write_port (0x8010, ba);
1500 1.7 veego }
1501 1.7 veego
1502 1.7 veego /* 0 = on, 1= off */
1503 1.7 veego /* ba= registerbase */
1504 1.7 veego static inline void
1505 1.7 veego gfx_on_off(toggle, ba)
1506 1.7 veego int toggle;
1507 1.7 veego volatile caddr_t ba;
1508 1.7 veego {
1509 1.7 veego int r;
1510 1.7 veego
1511 1.7 veego toggle &= 0x1;
1512 1.7 veego toggle = toggle << 5;
1513 1.7 veego
1514 1.7 veego r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
1515 1.7 veego r &= 0xdf; /* set Bit 5 to 0 */
1516 1.7 veego
1517 1.7 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, r | toggle);
1518 1.1 chopps }
1519 1.1 chopps
1520 1.1 chopps #endif /* NGRFCV */
1521