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