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