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