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