vidc20config.c revision 1.6 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