vidc20config.c revision 1.3 1 1.3 thorpej /* $NetBSD: vidc20config.c,v 1.3 2001/11/22 18:34:34 thorpej Exp $ */
2 1.1 reinoud
3 1.1 reinoud /*
4 1.1 reinoud * Copyright (c) 2001 Reinoud Zandijk
5 1.1 reinoud * Copyright (c) 1996 Mark Brinicombe
6 1.1 reinoud * Copyright (c) 1996 Robert Black
7 1.1 reinoud * Copyright (c) 1994-1995 Melvyn Tang-Richardson
8 1.1 reinoud * Copyright (c) 1994-1995 RiscBSD kernel team
9 1.1 reinoud * All rights reserved.
10 1.1 reinoud *
11 1.1 reinoud * Redistribution and use in source and binary forms, with or without
12 1.1 reinoud * modification, are permitted provided that the following conditions
13 1.1 reinoud * are met:
14 1.1 reinoud * 1. Redistributions of source code must retain the above copyright
15 1.1 reinoud * notice, this list of conditions and the following disclaimer.
16 1.1 reinoud * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 reinoud * notice, this list of conditions and the following disclaimer in the
18 1.1 reinoud * documentation and/or other materials provided with the distribution.
19 1.1 reinoud * 3. All advertising materials mentioning features or use of this software
20 1.1 reinoud * must display the following acknowledgement:
21 1.1 reinoud * This product includes software developed by the RiscBSD kernel team
22 1.1 reinoud * 4. The name of the company nor the name of the author may be used to
23 1.1 reinoud * endorse or promote products derived from this software without specific
24 1.1 reinoud * prior written permission.
25 1.1 reinoud *
26 1.1 reinoud * THIS SOFTWARE IS PROVIDED BY THE RISCBSD TEAM ``AS IS'' AND ANY EXPRESS
27 1.1 reinoud * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 1.1 reinoud * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.1 reinoud * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
30 1.1 reinoud * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 reinoud * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 reinoud * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 reinoud * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 reinoud * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 reinoud * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 1.1 reinoud * THE POSSIBILITY OF SUCH DAMAGE.
37 1.1 reinoud *
38 1.1 reinoud * NetBSD kernel project
39 1.1 reinoud *
40 1.1 reinoud * vidcvideo.c
41 1.1 reinoud *
42 1.1 reinoud * This file is the lower basis of the wscons driver for VIDC based ARM machines.
43 1.1 reinoud * It features the initialisation and all VIDC writing and keeps in internal state
44 1.1 reinoud * copy.
45 1.1 reinoud * Its currenly set up as a library file and not as a device; it could be named
46 1.1 reinoud * vidcvideo0 eventually.
47 1.1 reinoud */
48 1.1 reinoud
49 1.1 reinoud #include <sys/cdefs.h>
50 1.1 reinoud #include <sys/types.h>
51 1.1 reinoud #include <sys/param.h>
52 1.1 reinoud #include <arm/iomd/vidc.h>
53 1.3 thorpej #include <arm/arm32/katelib.h>
54 1.1 reinoud #include <machine/bootconfig.h>
55 1.1 reinoud #include <machine/irqhandler.h>
56 1.1 reinoud
57 1.1 reinoud #include <sys/systm.h>
58 1.1 reinoud #include <sys/device.h>
59 1.1 reinoud #include <uvm/uvm_extern.h>
60 1.1 reinoud
61 1.1 reinoud #include <arm/iomd/iomdreg.h>
62 1.1 reinoud #include <arm/iomd/iomdvar.h>
63 1.1 reinoud #include <arm/iomd/vidc20config.h>
64 1.1 reinoud
65 1.1 reinoud /*
66 1.1 reinoud * A structure containing ALL the information required to restore
67 1.1 reinoud * the VIDC20 to any given state. ALL vidc transactions should
68 1.1 reinoud * go through these procedures, which record the vidc's state.
69 1.1 reinoud * it may be an idea to set the permissions of the vidc base address
70 1.1 reinoud * so we get a fault, so the fault routine can record the state but
71 1.1 reinoud * I guess that's not really necessary for the time being, since we
72 1.1 reinoud * can make the kernel more secure later on. Also, it is possible
73 1.1 reinoud * to write a routine to allow 'reading' of the vidc registers.
74 1.1 reinoud */
75 1.1 reinoud
76 1.1 reinoud static struct vidc_state vidc_lookup = {
77 1.1 reinoud { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
78 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
79 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
80 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
81 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
82 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
83 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
84 1.1 reinoud 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
85 1.1 reinoud },
86 1.1 reinoud
87 1.1 reinoud VIDC_PALREG,
88 1.1 reinoud VIDC_BCOL,
89 1.1 reinoud VIDC_CP1 ,
90 1.1 reinoud VIDC_CP2,
91 1.1 reinoud VIDC_CP3,
92 1.1 reinoud VIDC_HCR,
93 1.1 reinoud VIDC_HSWR,
94 1.1 reinoud VIDC_HBSR,
95 1.1 reinoud VIDC_HDSR,
96 1.1 reinoud VIDC_HDER,
97 1.1 reinoud VIDC_HBER,
98 1.1 reinoud VIDC_HCSR,
99 1.1 reinoud VIDC_HIR,
100 1.1 reinoud VIDC_VCR,
101 1.1 reinoud VIDC_VSWR,
102 1.1 reinoud VIDC_VBSR,
103 1.1 reinoud VIDC_VDSR,
104 1.1 reinoud VIDC_VDER,
105 1.1 reinoud VIDC_VBER,
106 1.1 reinoud VIDC_VCSR,
107 1.1 reinoud VIDC_VCER,
108 1.1 reinoud VIDC_EREG,
109 1.1 reinoud VIDC_FSYNREG,
110 1.1 reinoud VIDC_CONREG,
111 1.1 reinoud VIDC_DCTL
112 1.1 reinoud };
113 1.1 reinoud
114 1.1 reinoud struct vidc_state vidc_current[1];
115 1.1 reinoud
116 1.1 reinoud
117 1.1 reinoud /*
118 1.1 reinoud * Structures defining clock frequenties and their settings...
119 1.1 reinoud * move to a constants header file ?
120 1.1 reinoud */
121 1.1 reinoud
122 1.1 reinoud struct fsyn {
123 1.1 reinoud int r, v, f;
124 1.1 reinoud };
125 1.1 reinoud
126 1.1 reinoud static struct fsyn fsyn_pref[] = {
127 1.1 reinoud { 6, 2, 8000 },
128 1.1 reinoud { 4, 2, 12000 },
129 1.1 reinoud { 3, 2, 16000 },
130 1.1 reinoud { 2, 2, 24000 },
131 1.1 reinoud { 41, 43, 25171 },
132 1.1 reinoud { 50, 59, 28320 },
133 1.1 reinoud { 3, 4, 32000 },
134 1.1 reinoud { 2, 3, 36000 },
135 1.1 reinoud { 31, 58, 44903 },
136 1.1 reinoud { 12, 35, 70000 },
137 1.1 reinoud { 0, 0, 00000 }
138 1.1 reinoud };
139 1.1 reinoud
140 1.1 reinoud
141 1.1 reinoud /*
142 1.1 reinoud * XXX global display variables XXX ... should be a structure
143 1.1 reinoud */
144 1.1 reinoud static int cold_init = 0; /* flags initialisation */
145 1.1 reinoud extern videomemory_t videomemory;
146 1.1 reinoud
147 1.1 reinoud static struct vidc_mode vidc_initialmode;
148 1.1 reinoud static struct vidc_mode *vidc_currentmode;
149 1.1 reinoud
150 1.1 reinoud unsigned int dispstart;
151 1.1 reinoud unsigned int dispsize;
152 1.1 reinoud unsigned int dispbase;
153 1.1 reinoud unsigned int dispend;
154 1.1 reinoud unsigned int ptov;
155 1.1 reinoud unsigned int vmem_base;
156 1.1 reinoud unsigned int phys_base;
157 1.1 reinoud unsigned int transfersize;
158 1.1 reinoud
159 1.1 reinoud
160 1.1 reinoud /* cursor stuff */
161 1.1 reinoud char *cursor_normal;
162 1.1 reinoud char *cursor_transparent;
163 1.1 reinoud int p_cursor_normal;
164 1.1 reinoud int p_cursor_transparent;
165 1.1 reinoud int cursor_width;
166 1.1 reinoud int cursor_height;
167 1.1 reinoud
168 1.1 reinoud
169 1.1 reinoud /*
170 1.1 reinoud * VIDC mode definitions
171 1.1 reinoud * generated from RISC OS mode definition file by an `awk' script
172 1.1 reinoud */
173 1.1 reinoud extern struct vidc_mode vidcmodes[];
174 1.1 reinoud
175 1.1 reinoud
176 1.1 reinoud /*
177 1.1 reinoud * configuration printing
178 1.1 reinoud *
179 1.1 reinoud */
180 1.1 reinoud
181 1.1 reinoud void
182 1.1 reinoud vidcvideo_printdetails(void)
183 1.1 reinoud {
184 1.1 reinoud printf(": refclk=%dMHz %dKB %s ", (vidc_fref / 1000000),
185 1.1 reinoud videomemory.vidm_size / 1024,
186 1.1 reinoud (videomemory.vidm_type == VIDEOMEM_TYPE_VRAM) ? "VRAM" : "DRAM");
187 1.1 reinoud }
188 1.1 reinoud
189 1.1 reinoud /*
190 1.1 reinoud * Common functions to directly access VIDC registers
191 1.1 reinoud */
192 1.1 reinoud int
193 1.1 reinoud vidcvideo_write(reg, value)
194 1.1 reinoud u_int reg;
195 1.1 reinoud int value;
196 1.1 reinoud {
197 1.1 reinoud int counter;
198 1.1 reinoud
199 1.1 reinoud int *current;
200 1.1 reinoud int *tab;
201 1.1 reinoud
202 1.1 reinoud tab = (int *)&vidc_lookup;
203 1.1 reinoud current = (int *)vidc_current;
204 1.1 reinoud
205 1.1 reinoud
206 1.1 reinoud /*
207 1.1 reinoud * OK, the VIDC_PALETTE register is handled differently
208 1.1 reinoud * to the others on the VIDC, so take that into account here
209 1.1 reinoud */
210 1.1 reinoud if (reg==VIDC_PALREG) {
211 1.1 reinoud vidc_current->palreg = 0;
212 1.1 reinoud WriteWord(vidc_base, reg | value);
213 1.1 reinoud return 0;
214 1.1 reinoud }
215 1.1 reinoud
216 1.1 reinoud if (reg==VIDC_PALETTE) {
217 1.1 reinoud WriteWord(vidc_base, reg | value);
218 1.1 reinoud vidc_current->palette[vidc_current->palreg] = value;
219 1.1 reinoud vidc_current->palreg++;
220 1.1 reinoud vidc_current->palreg = vidc_current->palreg & 0xff;
221 1.1 reinoud return 0;
222 1.1 reinoud }
223 1.1 reinoud
224 1.1 reinoud /*
225 1.1 reinoud * Undefine SAFER if you wish to speed things up (a little)
226 1.1 reinoud * although this means the function will assume things abou
227 1.1 reinoud * the structure of vidc_state. i.e. the first 256 words are
228 1.1 reinoud * the palette array
229 1.1 reinoud */
230 1.1 reinoud
231 1.1 reinoud #define SAFER
232 1.1 reinoud
233 1.1 reinoud #ifdef SAFER
234 1.1 reinoud #define INITVALUE 0
235 1.1 reinoud #else
236 1.1 reinoud #define INITVALUE 256
237 1.1 reinoud #endif
238 1.1 reinoud
239 1.1 reinoud for ( counter=INITVALUE; counter<= sizeof(struct vidc_state); counter++ ) {
240 1.1 reinoud if ( reg==tab[counter] ) {
241 1.1 reinoud WriteWord ( vidc_base, reg | value );
242 1.1 reinoud current[counter] = value;
243 1.1 reinoud return 0;
244 1.1 reinoud }
245 1.1 reinoud }
246 1.1 reinoud return -1;
247 1.1 reinoud }
248 1.1 reinoud
249 1.1 reinoud
250 1.1 reinoud void
251 1.1 reinoud vidcvideo_setpalette(vidc)
252 1.1 reinoud struct vidc_state *vidc;
253 1.1 reinoud {
254 1.1 reinoud int counter = 0;
255 1.1 reinoud
256 1.1 reinoud vidcvideo_write(VIDC_PALREG, 0x00000000);
257 1.1 reinoud for (counter = 0; counter < 255; counter++)
258 1.1 reinoud vidcvideo_write(VIDC_PALETTE, vidc->palette[counter]);
259 1.1 reinoud }
260 1.1 reinoud
261 1.1 reinoud
262 1.1 reinoud void
263 1.1 reinoud vidcvideo_setstate(vidc)
264 1.1 reinoud struct vidc_state *vidc;
265 1.1 reinoud {
266 1.1 reinoud vidcvideo_write ( VIDC_PALREG, vidc->palreg );
267 1.1 reinoud vidcvideo_write ( VIDC_BCOL, vidc->bcol );
268 1.1 reinoud vidcvideo_write ( VIDC_CP1, vidc->cp1 );
269 1.1 reinoud vidcvideo_write ( VIDC_CP2, vidc->cp2 );
270 1.1 reinoud vidcvideo_write ( VIDC_CP3, vidc->cp3 );
271 1.1 reinoud vidcvideo_write ( VIDC_HCR, vidc->hcr );
272 1.1 reinoud vidcvideo_write ( VIDC_HSWR, vidc->hswr );
273 1.1 reinoud vidcvideo_write ( VIDC_HBSR, vidc->hbsr );
274 1.1 reinoud vidcvideo_write ( VIDC_HDSR, vidc->hdsr );
275 1.1 reinoud vidcvideo_write ( VIDC_HDER, vidc->hder );
276 1.1 reinoud vidcvideo_write ( VIDC_HBER, vidc->hber );
277 1.1 reinoud vidcvideo_write ( VIDC_HCSR, vidc->hcsr );
278 1.1 reinoud vidcvideo_write ( VIDC_HIR, vidc->hir );
279 1.1 reinoud vidcvideo_write ( VIDC_VCR, vidc->vcr );
280 1.1 reinoud vidcvideo_write ( VIDC_VSWR, vidc->vswr );
281 1.1 reinoud vidcvideo_write ( VIDC_VBSR, vidc->vbsr );
282 1.1 reinoud vidcvideo_write ( VIDC_VDSR, vidc->vdsr );
283 1.1 reinoud vidcvideo_write ( VIDC_VDER, vidc->vder );
284 1.1 reinoud vidcvideo_write ( VIDC_VBER, vidc->vber );
285 1.1 reinoud vidcvideo_write ( VIDC_VCSR, vidc->vcsr );
286 1.1 reinoud vidcvideo_write ( VIDC_VCER, vidc->vcer );
287 1.1 reinoud /*
288 1.1 reinoud * Right, dunno what to set these to yet, but let's keep RiscOS's
289 1.1 reinoud * ones for now, until the time is right to finish this code
290 1.1 reinoud */
291 1.1 reinoud
292 1.1 reinoud /* vidcvideo_write ( VIDC_EREG, vidc->ereg ); */
293 1.1 reinoud /* vidcvideo_write ( VIDC_FSYNREG, vidc->fsynreg ); */
294 1.1 reinoud /* vidcvideo_write ( VIDC_CONREG, vidc->conreg ); */
295 1.1 reinoud /* vidcvideo_write ( VIDC_DCTL, vidc->dctl ); */
296 1.1 reinoud
297 1.1 reinoud }
298 1.1 reinoud
299 1.1 reinoud
300 1.1 reinoud void
301 1.1 reinoud vidcvideo_getstate(vidc)
302 1.1 reinoud struct vidc_state *vidc;
303 1.1 reinoud {
304 1.1 reinoud *vidc = *vidc_current;
305 1.1 reinoud }
306 1.1 reinoud
307 1.1 reinoud
308 1.1 reinoud void
309 1.1 reinoud vidcvideo_getmode(mode)
310 1.1 reinoud struct vidc_mode *mode;
311 1.1 reinoud {
312 1.1 reinoud *mode = *vidc_currentmode;
313 1.1 reinoud }
314 1.1 reinoud
315 1.1 reinoud
316 1.1 reinoud void
317 1.1 reinoud vidcvideo_stdpalette()
318 1.1 reinoud {
319 1.1 reinoud WriteWord(vidc_base, VIDC_PALREG | 0x00000000);
320 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 0, 0));
321 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 0, 0));
322 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 255, 0));
323 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 0));
324 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 0, 255));
325 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 0, 255));
326 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 255, 255));
327 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 255));
328 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 128, 128));
329 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 128, 128));
330 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 255, 128));
331 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 128));
332 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 128, 255));
333 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 128, 255));
334 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 255, 255));
335 1.1 reinoud WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 255));
336 1.1 reinoud }
337 1.1 reinoud
338 1.1 reinoud
339 1.1 reinoud /* small inline mod function ... why here? */
340 1.1 reinoud static __inline int
341 1.1 reinoud mod(int n)
342 1.1 reinoud {
343 1.1 reinoud if (n < 0)
344 1.1 reinoud return(-n);
345 1.1 reinoud else
346 1.1 reinoud return(n);
347 1.1 reinoud }
348 1.1 reinoud
349 1.1 reinoud
350 1.1 reinoud static int
351 1.1 reinoud vidcvideo_coldinit(void)
352 1.1 reinoud {
353 1.1 reinoud int found;
354 1.1 reinoud int loop;
355 1.1 reinoud
356 1.1 reinoud /* Blank out the cursor */
357 1.1 reinoud
358 1.1 reinoud vidcvideo_write(VIDC_CP1, 0x0);
359 1.1 reinoud vidcvideo_write(VIDC_CP2, 0x0);
360 1.1 reinoud vidcvideo_write(VIDC_CP3, 0x0);
361 1.1 reinoud
362 1.1 reinoud /* Try to determine the current mode */
363 1.1 reinoud vidc_initialmode.hder = bootconfig.width+1;
364 1.1 reinoud vidc_initialmode.vder = bootconfig.height+1;
365 1.1 reinoud vidc_initialmode.log2_bpp = bootconfig.log2_bpp;
366 1.1 reinoud
367 1.1 reinoud dispbase = vmem_base = dispstart = videomemory.vidm_vbase;
368 1.1 reinoud phys_base = videomemory.vidm_pbase;
369 1.1 reinoud
370 1.1 reinoud /* Nut - should be using videomemory.vidm_size - mark */
371 1.1 reinoud if (videomemory.vidm_type == VIDEOMEM_TYPE_DRAM) {
372 1.1 reinoud dispsize = videomemory.vidm_size;
373 1.1 reinoud transfersize = 16;
374 1.1 reinoud } else {
375 1.1 reinoud dispsize = bootconfig.vram[0].pages * NBPG;
376 1.1 reinoud transfersize = dispsize >> 10;
377 1.1 reinoud };
378 1.1 reinoud
379 1.1 reinoud ptov = dispbase - phys_base;
380 1.1 reinoud
381 1.1 reinoud dispend = dispstart+dispsize;
382 1.1 reinoud
383 1.1 reinoud /* try to find the current mode from the bootloader in my table */
384 1.1 reinoud vidc_currentmode = &vidcmodes[0];
385 1.1 reinoud loop = 0;
386 1.1 reinoud found = 0;
387 1.1 reinoud while (vidcmodes[loop].pixel_rate != 0) {
388 1.1 reinoud if (vidcmodes[loop].hder == (bootconfig.width + 1)
389 1.1 reinoud && vidcmodes[loop].vder == (bootconfig.height + 1)
390 1.1 reinoud && vidcmodes[loop].frame_rate == bootconfig.framerate) {
391 1.1 reinoud vidc_currentmode = &vidcmodes[loop];
392 1.1 reinoud found = 1;
393 1.1 reinoud }
394 1.1 reinoud ++loop;
395 1.1 reinoud }
396 1.1 reinoud
397 1.1 reinoud /* if not found choose first mode but dont be picky on the framerate */
398 1.1 reinoud if (!found) {
399 1.1 reinoud vidc_currentmode = &vidcmodes[0];
400 1.1 reinoud loop = 0;
401 1.1 reinoud found = 0;
402 1.1 reinoud
403 1.1 reinoud while (vidcmodes[loop].pixel_rate != 0) {
404 1.1 reinoud if (vidcmodes[loop].hder == (bootconfig.width + 1)
405 1.1 reinoud && vidcmodes[loop].vder == (bootconfig.height + 1)) {
406 1.1 reinoud vidc_currentmode = &vidcmodes[loop];
407 1.1 reinoud found = 1;
408 1.1 reinoud }
409 1.1 reinoud ++loop;
410 1.1 reinoud }
411 1.1 reinoud }
412 1.1 reinoud
413 1.1 reinoud vidc_currentmode->log2_bpp = bootconfig.log2_bpp;
414 1.1 reinoud
415 1.1 reinoud dispstart = dispbase;
416 1.1 reinoud dispend = dispstart+dispsize;
417 1.1 reinoud
418 1.1 reinoud IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
419 1.1 reinoud IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
420 1.1 reinoud IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
421 1.1 reinoud return 0;
422 1.1 reinoud }
423 1.1 reinoud
424 1.1 reinoud
425 1.1 reinoud /* simple function to abstract vidc variables ; returns virt start address of screen */
426 1.1 reinoud /* XXX asumption that video memory is mapped in twice */
427 1.1 reinoud void *vidcvideo_hwscroll(int bytes) {
428 1.1 reinoud dispstart += bytes;
429 1.1 reinoud if (dispstart >= dispbase + dispsize) dispstart -= dispsize;
430 1.1 reinoud if (dispstart < dispbase) dispstart += dispsize;
431 1.1 reinoud dispend = dispstart+dispsize;
432 1.1 reinoud
433 1.1 reinoud /* return the start of the bit map of the screen (left top) */
434 1.1 reinoud return (void *) dispstart;
435 1.1 reinoud }
436 1.1 reinoud
437 1.1 reinoud
438 1.1 reinoud /* reset the HW scroll to be at the start for the benefit of f.e. X */
439 1.1 reinoud void *vidcvideo_hwscroll_reset(void) {
440 1.1 reinoud void *cookie = (void *) dispstart;
441 1.1 reinoud
442 1.1 reinoud dispstart = dispbase;
443 1.1 reinoud dispend = dispstart + dispsize;
444 1.1 reinoud return cookie;
445 1.1 reinoud }
446 1.1 reinoud
447 1.1 reinoud
448 1.1 reinoud /* put HW scroll back to where it was */
449 1.1 reinoud void *vidcvideo_hwscroll_back(void *cookie) {
450 1.1 reinoud dispstart = (int) cookie;
451 1.1 reinoud dispend = dispstart + dispsize;
452 1.1 reinoud return cookie;
453 1.1 reinoud }
454 1.1 reinoud
455 1.1 reinoud
456 1.1 reinoud /* this function is to be called at vsync */
457 1.1 reinoud void vidcvideo_progr_scroll(void) {
458 1.1 reinoud IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
459 1.1 reinoud IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
460 1.1 reinoud IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
461 1.1 reinoud }
462 1.1 reinoud
463 1.1 reinoud
464 1.1 reinoud /*
465 1.1 reinoud * Select a new mode by reprogramming the VIDC chip
466 1.1 reinoud * XXX this part is known not to work for 32bpp
467 1.1 reinoud */
468 1.1 reinoud
469 1.1 reinoud struct vidc_mode newmode;
470 1.1 reinoud
471 1.1 reinoud static const int bpp_mask_table[] = {
472 1.1 reinoud 0, /* 1bpp */
473 1.1 reinoud 1, /* 2bpp */
474 1.1 reinoud 2, /* 4bpp */
475 1.1 reinoud 3, /* 8bpp */
476 1.1 reinoud 4, /* 16bpp */
477 1.1 reinoud 6 /* 32bpp */
478 1.1 reinoud };
479 1.1 reinoud
480 1.1 reinoud
481 1.1 reinoud void
482 1.1 reinoud vidcvideo_setmode(struct vidc_mode *mode)
483 1.1 reinoud {
484 1.1 reinoud register int acc;
485 1.1 reinoud int bpp_mask;
486 1.1 reinoud int ereg;
487 1.1 reinoud int best_r, best_v, best_match;
488 1.1 reinoud
489 1.1 reinoud #ifdef NC
490 1.1 reinoud return;
491 1.1 reinoud #endif
492 1.1 reinoud /*
493 1.1 reinoud * Find out what bit mask we need to or with the vidc20 control register
494 1.1 reinoud * in order to generate the desired number of bits per pixel.
495 1.1 reinoud * log_bpp is log base 2 of the number of bits per pixel.
496 1.1 reinoud */
497 1.1 reinoud
498 1.1 reinoud bpp_mask = bpp_mask_table[mode->log2_bpp];
499 1.1 reinoud
500 1.1 reinoud newmode = *mode;
501 1.1 reinoud vidc_currentmode = &newmode;
502 1.1 reinoud
503 1.1 reinoud /* Program the VCO Look-up to a preferred value before choosing one */
504 1.1 reinoud {
505 1.1 reinoud int least_error = mod(fsyn_pref[0].f - vidc_currentmode->pixel_rate);
506 1.1 reinoud int counter;
507 1.1 reinoud best_r = fsyn_pref[0].r;
508 1.1 reinoud best_match = fsyn_pref[0].f;
509 1.1 reinoud best_v = fsyn_pref[0].v;
510 1.1 reinoud
511 1.1 reinoud /* Look up */
512 1.1 reinoud counter=0;
513 1.1 reinoud while (fsyn_pref[counter].r != 0) {
514 1.1 reinoud if (least_error > mod(fsyn_pref[counter].f - vidc_currentmode->pixel_rate)) {
515 1.1 reinoud best_match = fsyn_pref[counter].f;
516 1.1 reinoud least_error = mod(fsyn_pref[counter].f - vidc_currentmode->pixel_rate);
517 1.1 reinoud best_r = fsyn_pref[counter].r;
518 1.1 reinoud best_v = fsyn_pref[counter].v;
519 1.1 reinoud }
520 1.1 reinoud counter++;
521 1.1 reinoud }
522 1.1 reinoud
523 1.1 reinoud if (least_error > 0) { /* Accuracy of 1000Hz */
524 1.1 reinoud int r, v, f;
525 1.1 reinoud for (v = 63; v > 0; v--)
526 1.1 reinoud for (r = 63; r > 0; r--) {
527 1.1 reinoud f = ((v * vidc_fref) /1000) / r;
528 1.1 reinoud if (least_error >= mod(f - vidc_currentmode->pixel_rate)) {
529 1.1 reinoud best_match = f;
530 1.1 reinoud least_error = mod(f - vidc_currentmode->pixel_rate);
531 1.1 reinoud best_r = r;
532 1.1 reinoud best_v = v;
533 1.1 reinoud }
534 1.1 reinoud }
535 1.1 reinoud }
536 1.1 reinoud
537 1.1 reinoud if (best_r > 63) best_r=63;
538 1.1 reinoud if (best_v > 63) best_v=63;
539 1.1 reinoud if (best_r < 1) best_r= 1;
540 1.1 reinoud if (best_v < 1) best_v= 1;
541 1.1 reinoud
542 1.1 reinoud }
543 1.1 reinoud
544 1.2 reinoud vidcvideo_write(VIDC_FSYNREG, (best_v-1)<<8 | (best_r-1)<<0);
545 1.1 reinoud
546 1.1 reinoud acc=0;
547 1.1 reinoud acc+=vidc_currentmode->hswr; vidcvideo_write(VIDC_HSWR, (acc - 8 ) & (~1));
548 1.1 reinoud acc+=vidc_currentmode->hbsr; vidcvideo_write(VIDC_HBSR, (acc - 12) & (~1));
549 1.1 reinoud acc+=vidc_currentmode->hdsr; vidcvideo_write(VIDC_HDSR, (acc - 18) & (~1));
550 1.1 reinoud acc+=vidc_currentmode->hder; vidcvideo_write(VIDC_HDER, (acc - 18) & (~1));
551 1.1 reinoud acc+=vidc_currentmode->hber; vidcvideo_write(VIDC_HBER, (acc - 12) & (~1));
552 1.1 reinoud acc+=vidc_currentmode->hcr; vidcvideo_write(VIDC_HCR, (acc - 8 ) & (~3));
553 1.1 reinoud
554 1.1 reinoud acc=0;
555 1.1 reinoud acc+=vidc_currentmode->vswr; vidcvideo_write(VIDC_VSWR, (acc - 1));
556 1.1 reinoud acc+=vidc_currentmode->vbsr; vidcvideo_write(VIDC_VBSR, (acc - 1));
557 1.1 reinoud acc+=vidc_currentmode->vdsr; vidcvideo_write(VIDC_VDSR, (acc - 1));
558 1.1 reinoud acc+=vidc_currentmode->vder; vidcvideo_write(VIDC_VDER, (acc - 1));
559 1.1 reinoud acc+=vidc_currentmode->vber; vidcvideo_write(VIDC_VBER, (acc - 1));
560 1.1 reinoud acc+=vidc_currentmode->vcr; vidcvideo_write(VIDC_VCR, (acc - 1));
561 1.1 reinoud
562 1.1 reinoud IOMD_WRITE_WORD(IOMD_FSIZE, vidc_currentmode->vcr
563 1.1 reinoud + vidc_currentmode->vswr
564 1.1 reinoud + vidc_currentmode->vber
565 1.1 reinoud + vidc_currentmode->vbsr - 1);
566 1.1 reinoud
567 1.1 reinoud if (dispsize <= 1024*1024)
568 1.1 reinoud vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12);
569 1.1 reinoud else
570 1.1 reinoud vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 3<<16 | 1<<12);
571 1.1 reinoud
572 1.1 reinoud ereg = 1<<12;
573 1.1 reinoud if (vidc_currentmode->sync_pol & 0x01)
574 1.1 reinoud ereg |= 1<<16;
575 1.1 reinoud if (vidc_currentmode->sync_pol & 0x02)
576 1.1 reinoud ereg |= 1<<18;
577 1.1 reinoud vidcvideo_write(VIDC_EREG, ereg);
578 1.1 reinoud if (dispsize > 1024*1024) {
579 1.1 reinoud if (vidc_currentmode->hder >= 800)
580 1.1 reinoud vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
581 1.1 reinoud else
582 1.1 reinoud vidcvideo_write(VIDC_CONREG, 6<<8 | bpp_mask<<5);
583 1.1 reinoud } else {
584 1.1 reinoud vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
585 1.1 reinoud }
586 1.1 reinoud }
587 1.1 reinoud
588 1.1 reinoud
589 1.1 reinoud /* not used for now */
590 1.1 reinoud void
591 1.1 reinoud vidcvideo_set_display_base(base)
592 1.1 reinoud u_int base;
593 1.1 reinoud {
594 1.1 reinoud dispstart = dispstart-dispbase + base;
595 1.1 reinoud dispbase = vmem_base = base;
596 1.1 reinoud dispend = base + dispsize;
597 1.1 reinoud ptov = dispbase - phys_base;
598 1.1 reinoud }
599 1.1 reinoud
600 1.1 reinoud
601 1.1 reinoud /*
602 1.1 reinoud * Main initialisation routine for now
603 1.1 reinoud */
604 1.1 reinoud
605 1.1 reinoud static int cursor_init = 0;
606 1.1 reinoud
607 1.1 reinoud int
608 1.1 reinoud vidcvideo_init(void)
609 1.1 reinoud {
610 1.1 reinoud vidcvideo_coldinit();
611 1.1 reinoud if (cold_init && (cursor_init == 0))
612 1.1 reinoud /* vidcvideo_flash_go() */;
613 1.1 reinoud
614 1.1 reinoud /* setting a mode goes wrong in 32 bpp ... 8 and 16 seem OK */
615 1.1 reinoud vidcvideo_setmode(vidc_currentmode);
616 1.1 reinoud vidcvideo_blank(0); /* display on */
617 1.1 reinoud
618 1.1 reinoud vidcvideo_textpalette();
619 1.1 reinoud
620 1.1 reinoud if (cold_init == 0) {
621 1.1 reinoud vidcvideo_write(VIDC_CP1, 0x0);
622 1.1 reinoud vidcvideo_write(VIDC_CP2, 0x0);
623 1.1 reinoud vidcvideo_write(VIDC_CP3, 0x0);
624 1.1 reinoud } else {
625 1.1 reinoud vidcvideo_cursor_init(CURSOR_MAX_WIDTH, CURSOR_MAX_HEIGHT);
626 1.1 reinoud };
627 1.1 reinoud
628 1.1 reinoud cold_init=1;
629 1.1 reinoud return 0;
630 1.1 reinoud }
631 1.1 reinoud
632 1.1 reinoud
633 1.1 reinoud /* reinitialise the vidcvideo */
634 1.1 reinoud void
635 1.1 reinoud vidcvideo_reinit()
636 1.1 reinoud {
637 1.1 reinoud vidcvideo_coldinit();
638 1.1 reinoud vidcvideo_setmode(vidc_currentmode);
639 1.1 reinoud }
640 1.1 reinoud
641 1.1 reinoud
642 1.1 reinoud paddr_t
643 1.1 reinoud vidcvideo_mmap(vc, offset, nprot)
644 1.1 reinoud struct vconsole *vc;
645 1.1 reinoud off_t offset;
646 1.1 reinoud int nprot;
647 1.1 reinoud {
648 1.1 reinoud if ((u_int)offset >= videomemory.vidm_size)
649 1.1 reinoud return (-1);
650 1.1 reinoud return(arm_byte_to_page(((videomemory.vidm_pbase) + (offset))));
651 1.1 reinoud }
652 1.1 reinoud
653 1.1 reinoud
654 1.1 reinoud int
655 1.1 reinoud vidcvideo_cursor_init(int width, int height)
656 1.1 reinoud {
657 1.1 reinoud static char *cursor_data = NULL;
658 1.1 reinoud int counter;
659 1.1 reinoud int line;
660 1.1 reinoud paddr_t pa;
661 1.1 reinoud
662 1.1 reinoud cursor_width = width;
663 1.1 reinoud cursor_height = height;
664 1.1 reinoud
665 1.1 reinoud if (!cursor_data) {
666 1.1 reinoud /* Allocate cursor memory first time round */
667 1.1 reinoud cursor_data = (char *)uvm_km_zalloc(kernel_map, NBPG);
668 1.1 reinoud if (!cursor_data)
669 1.1 reinoud panic("Cannot allocate memory for hardware cursor\n");
670 1.1 reinoud (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_data, &pa);
671 1.1 reinoud IOMD_WRITE_WORD(IOMD_CURSINIT, pa);
672 1.1 reinoud }
673 1.1 reinoud
674 1.1 reinoud /* Blank the cursor while initialising it's sprite */
675 1.1 reinoud
676 1.1 reinoud vidcvideo_write ( VIDC_CP1, 0x0 );
677 1.1 reinoud vidcvideo_write ( VIDC_CP2, 0x0 );
678 1.1 reinoud vidcvideo_write ( VIDC_CP3, 0x0 );
679 1.1 reinoud
680 1.1 reinoud cursor_normal = cursor_data;
681 1.1 reinoud cursor_transparent = cursor_data + (height * width);
682 1.1 reinoud
683 1.1 reinoud cursor_transparent += 32; /* ALIGN */
684 1.1 reinoud cursor_transparent = (char *)((int)cursor_transparent & (~31) );
685 1.1 reinoud
686 1.1 reinoud for ( line = 0; line<height; ++ line )
687 1.1 reinoud {
688 1.1 reinoud for ( counter=0; counter<width/4;counter++ )
689 1.1 reinoud cursor_normal[line * width + counter]=0x55; /* why 0x55 ? */
690 1.1 reinoud for ( ; counter<8; counter++ )
691 1.1 reinoud cursor_normal[line * width + counter]=0;
692 1.1 reinoud }
693 1.1 reinoud
694 1.1 reinoud for ( line = 0; line<height; ++ line )
695 1.1 reinoud {
696 1.1 reinoud for ( counter=0; counter<width/4;counter++ )
697 1.1 reinoud cursor_transparent[line * width + counter]=0x00;
698 1.1 reinoud for ( ; counter<8; counter++ )
699 1.1 reinoud cursor_transparent[line * width + counter]=0;
700 1.1 reinoud }
701 1.1 reinoud
702 1.1 reinoud
703 1.1 reinoud (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_normal,
704 1.1 reinoud (paddr_t *)&p_cursor_normal);
705 1.1 reinoud (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_transparent,
706 1.1 reinoud (paddr_t *)&p_cursor_transparent);
707 1.1 reinoud
708 1.1 reinoud memset ( cursor_normal, 0x55, width*height ); /* white? */
709 1.1 reinoud memset ( cursor_transparent, 0x00, width*height ); /* to see the diffence */
710 1.1 reinoud
711 1.1 reinoud /* Ok, now program the cursor; should be blank */
712 1.1 reinoud vidcvideo_enablecursor(0);
713 1.1 reinoud
714 1.1 reinoud return 0;
715 1.1 reinoud }
716 1.1 reinoud
717 1.1 reinoud
718 1.1 reinoud void
719 1.1 reinoud vidcvideo_updatecursor(xcur, ycur)
720 1.1 reinoud int xcur, ycur;
721 1.1 reinoud {
722 1.1 reinoud int frontporch = vidc_currentmode->hswr + vidc_currentmode->hbsr + vidc_currentmode->hdsr;
723 1.1 reinoud int topporch = vidc_currentmode->vswr + vidc_currentmode->vbsr + vidc_currentmode->vdsr;
724 1.1 reinoud
725 1.1 reinoud vidcvideo_write(VIDC_HCSR, frontporch -17 + xcur);
726 1.1 reinoud vidcvideo_write(VIDC_VCSR, topporch -2 + (ycur+1)-2 + 3 - cursor_height);
727 1.1 reinoud vidcvideo_write(VIDC_VCER, topporch -2 + (ycur+3)+2 + 3 );
728 1.1 reinoud return;
729 1.1 reinoud }
730 1.1 reinoud
731 1.1 reinoud
732 1.1 reinoud void
733 1.1 reinoud vidcvideo_enablecursor(on)
734 1.1 reinoud int on;
735 1.1 reinoud {
736 1.1 reinoud if (on) {
737 1.1 reinoud IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_normal);
738 1.1 reinoud } else {
739 1.1 reinoud IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_transparent);
740 1.1 reinoud };
741 1.1 reinoud vidcvideo_write ( VIDC_CP1, 0xffffff ); /* enable */
742 1.1 reinoud
743 1.1 reinoud return;
744 1.1 reinoud }
745 1.1 reinoud
746 1.1 reinoud
747 1.1 reinoud int
748 1.1 reinoud vidcvideo_textpalette()
749 1.1 reinoud {
750 1.1 reinoud vidcvideo_write(VIDC_PALREG, 0x00000000);
751 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0));
752 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 0, 0));
753 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 255, 0));
754 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 0));
755 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 0, 255));
756 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 0, 255));
757 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 255, 255));
758 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
759 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 128));
760 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 128));
761 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 255, 128));
762 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 128));
763 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 255));
764 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 255));
765 1.1 reinoud vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
766 1.1 reinoud
767 1.1 reinoud return 0;
768 1.1 reinoud }
769 1.1 reinoud
770 1.1 reinoud int
771 1.1 reinoud vidcvideo_blank(video_off)
772 1.1 reinoud int video_off;
773 1.1 reinoud {
774 1.1 reinoud int ereg;
775 1.1 reinoud
776 1.1 reinoud ereg = 1<<12;
777 1.1 reinoud if (vidc_currentmode->sync_pol & 0x01)
778 1.1 reinoud ereg |= 1<<16;
779 1.1 reinoud if (vidc_currentmode->sync_pol & 0x02)
780 1.1 reinoud ereg |= 1<<18;
781 1.1 reinoud
782 1.1 reinoud if (!video_off) {
783 1.1 reinoud vidcvideo_write(VIDC_EREG, ereg);
784 1.1 reinoud } else {
785 1.1 reinoud vidcvideo_write(VIDC_EREG, 0);
786 1.1 reinoud };
787 1.1 reinoud return 0;
788 1.1 reinoud }
789 1.1 reinoud
790 1.1 reinoud /* end of vidc20config.c */
791