1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/vid_1400.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ 2/*----------------------------------------------------------------------------- 3 * VID_1400.C 4 * 5 * Version 2.0 - February 21, 2000 6 * 7 * This file contains routines to control the SC1400 video overlay hardware. 8 * 9 * History: 10 * Versions 0.1 through 2.0 by Brian Falardeau. 11 * 12 * Copyright (c) 1999-2000 National Semiconductor. 13 *----------------------------------------------------------------------------- 14 */ 15 16/*---------------------------------------------------------------------------- 17 * SC1400 PLL TABLE 18 *---------------------------------------------------------------------------- 19 */ 20 21typedef struct tagSC1400PLL 22{ 23 long frequency; /* 16.16 fixed point frequency */ 24 unsigned long clock_select; /* clock select register (0x2C) */ 25} 26SC1400PLL; 27 28SC1400PLL gfx_sc1400_clock_table[] = { 29 {0x00192CCC, 0x00000000}, /* 25.1750 */ 30 {0x001C526E, 0x00010000}, /* 28.3220 */ 31 {0x001F8000, 0x00020000}, /* 31.5000 */ 32 {0x00240000, 0x000E0000}, /* 36.0000 */ 33 {0x00258000, 0x0010110C}, /* 37.5000 */ 34 {0x00280000, 0x00040000}, /* 40.0000 */ 35 {0x002CE666, 0x00090000}, /* 44.9000 */ 36 {0x00320000, 0x00100C06}, /* 50.0000 */ 37 {0x00325999, 0x0050600C}, /* 50.3500 */ 38 {0x00360000, 0x00100100}, /* 54.0000 */ 39 {0x0038643F, 0x0010160A}, /* 56.3916 */ 40 {0x0038A3D7, 0x00506C0C}, /* 56.6440 */ 41 {0x003B0000, 0x0010170A}, /* 59.6583 */ 42 {0x003BA886, 0x00100A04}, /* 59.6583 */ 43 {0x003F0000, 0x00100602}, /* 63.0000 */ 44 {0x00410000, 0x00060000}, /* 65.0000 */ 45 {0x00438000, 0x00100401}, /* 67.5000 */ 46 {0x0046CCCC, 0x00101407}, /* 70.8000 */ 47 {0x00480000, 0x00100702}, /* 72.0000 */ 48 {0x004B0000, 0x00070000}, /* 75.0000 */ 49 {0x004EC000, 0x0010220B}, /* 78.7500 */ 50 {0x00500000, 0x00304C0C}, /* 80.0000 */ 51 {0x00510000, 0x00100200}, /* 81.0000 */ 52 {0x00550000, 0x00080000}, /* 85.0000 */ 53 {0x0059CCCC, 0x00100902}, /* 89.8000 */ 54 {0x00630000, 0x00100A02}, /* 99.0000 */ 55 {0x00640000, 0x00102409}, /* 100.0000 */ 56 {0x006C0000, 0x00100300}, /* 108.0000 */ 57 {0x00870000, 0x00050000}, /* 135.0000 */ 58 {0x009D8000, 0x00102205}, /* 157.5000 */ 59 {0x00A20000, 0x00100500}, /* 162.0000 */ 60 {0x00AA0000, 0x000B0000}, /* 170.0000 */ 61 {0x00AF0000, 0x00100C01}, /* 175.0000 */ 62 {0x00BD0000, 0x00100600}, /* 189.0000 */ 63 {0x00CA0000, 0x00100E01}, /* 202.0000 */ 64 {0x00E80000, 0x00102A04}, /* 232.0000 */ 65}; 66 67#define NUM_SC1400_FREQUENCIES sizeof(gfx_sc1400_clock_table)/sizeof(SC1400PLL) 68 69/*--------------------------------------------------------------------------- 70 * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API) 71 * 72 * This routine is used to disable all components of video overlay before 73 * performing a mode switch. 74 *--------------------------------------------------------------------------- 75 */ 76#if GFX_VIDEO_DYNAMIC 77void 78sc1400_reset_video(void) 79#else 80void 81gfx_reset_video(void) 82#endif 83{ 84 gfx_set_video_enable(0); 85} 86 87/*--------------------------------------------------------------------------- 88 * gfx_set_clock_frequency 89 * 90 * This routine sets the clock frequency, specified as a 16.16 fixed point 91 * value (0x00318000 = 49.5 MHz). It will set the closest frequency found 92 * in the lookup table. 93 *--------------------------------------------------------------------------- 94 */ 95#if GFX_VIDEO_DYNAMIC 96void 97sc1400_set_clock_frequency(unsigned long frequency) 98#else 99void 100gfx_set_clock_frequency(unsigned long frequency) 101#endif 102{ 103 int index; 104 unsigned long value; 105 long min, diff; 106 107 /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 108 /* Search the table for the closest frequency (16.16 format). */ 109 110 value = gfx_sc1400_clock_table[0].clock_select; 111 min = (long)gfx_sc1400_clock_table[0].frequency - frequency; 112 if (min < 0L) 113 min = -min; 114 for (index = 1; index < NUM_SC1400_FREQUENCIES; index++) { 115 diff = (long)gfx_sc1400_clock_table[index].frequency - frequency; 116 if (diff < 0L) 117 diff = -diff; 118 if (diff < min) { 119 min = diff; 120 value = gfx_sc1400_clock_table[index].clock_select; 121 } 122 } 123 124 /* SET THE DOT CLOCK REGISTER */ 125 126 WRITE_VID32(SC1400_VID_MISC, 0x00001000); 127 WRITE_VID32(SC1400_VID_CLOCK_SELECT, value); 128 return; 129} 130 131/*----------------------------------------------------------------------------- 132 * gfx_set_video_enable 133 * 134 * This routine enables or disables the video overlay functionality. 135 *----------------------------------------------------------------------------- 136 */ 137#if GFX_VIDEO_DYNAMIC 138int 139sc1400_set_video_enable(int enable) 140#else 141int 142gfx_set_video_enable(int enable) 143#endif 144{ 145 unsigned long vcfg; 146 147 /* WAIT FOR VERTICAL BLANK TO START */ 148 /* Otherwise a glitch can be observed. */ 149 150 if (gfx_test_timing_active()) { 151 if (!gfx_test_vertical_active()) { 152 while (!gfx_test_vertical_active()) ; 153 } 154 while (gfx_test_vertical_active()) ; 155 } 156 vcfg = READ_VID32(SC1400_VIDEO_CONFIG); 157 if (enable) { 158 /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ 159 /* Use private routine to abstract the display controller. */ 160 161 gfx_set_display_video_enable(1); 162 163 /* SET SC1400 BUS CONTROL PARAMETERS */ 164 /* Currently always high speed, 8-bit interface. */ 165 166 vcfg |= SC1400_VCFG_HIGH_SPD_INT; 167 vcfg &= ~(SC1400_VCFG_EARLY_VID_RDY | SC1400_VCFG_16_BIT_EN); 168 169 /* ENABLE SC1400 VIDEO OVERLAY */ 170 171 vcfg |= SC1400_VCFG_VID_EN; 172 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 173 } else { 174 /* DISABLE SC1400 VIDEO OVERLAY */ 175 176 vcfg &= ~SC1400_VCFG_VID_EN; 177 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 178 179 /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */ 180 /* Use private routine to abstract the display controller. */ 181 182 gfx_set_display_video_enable(0); 183 } 184 return (0); 185} 186 187/*----------------------------------------------------------------------------- 188 * gfx_set_video_format 189 * 190 * Currently only sets 4:2:0 format, Y1 V Y0 U. 191 *----------------------------------------------------------------------------- 192 */ 193#if GFX_VIDEO_DYNAMIC 194int 195sc1400_set_video_format(unsigned long format) 196#else 197int 198gfx_set_video_format(unsigned long format) 199#endif 200{ 201 unsigned long vcfg = 0; 202 203 /* SET THE SC1400 VIDEO INPUT FORMAT */ 204 205 vcfg = READ_VID32(SC1400_VIDEO_CONFIG); 206 vcfg &= ~(SC1400_VCFG_VID_INP_FORMAT | SC1400_VCFG_4_2_0_MODE); 207 vcfg &= ~(SC1400_VCFG_CSC_BYPASS); 208 if (format < 4) 209 vcfg |= (format << 2); 210 else 211 vcfg |= SC1400_VCFG_CSC_BYPASS; 212 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 213 return (0); 214} 215 216/*----------------------------------------------------------------------------- 217 * gfx_set_video_size 218 * 219 * This routine specifies the size of the source data. It is used only 220 * to determine how much data to transfer per frame, and is not used to 221 * calculate the scaling value (that is handled by a separate routine). 222 *----------------------------------------------------------------------------- 223 */ 224#if GFX_VIDEO_DYNAMIC 225int 226sc1400_set_video_size(unsigned short width, unsigned short height) 227#else 228int 229gfx_set_video_size(unsigned short width, unsigned short height) 230#endif 231{ 232 unsigned long size, vcfg; 233 234 /* SET THE SC1400 VIDEO LINE SIZE */ 235 236 vcfg = READ_VID32(SC1400_VIDEO_CONFIG); 237 vcfg &= ~(SC1400_VCFG_LINE_SIZE_LOWER_MASK | SC1400_VCFG_LINE_SIZE_UPPER); 238 size = (width >> 1); 239 vcfg |= (size & 0x00FF) << 8; 240 if (size & 0x0100) 241 vcfg |= SC1400_VCFG_LINE_SIZE_UPPER; 242 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 243 244 /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */ 245 /* Use private routine to abstract the display controller. */ 246 247 gfx_set_display_video_size(width, height); 248 return (0); 249} 250 251/*----------------------------------------------------------------------------- 252 * gfx_set_video_offset 253 * 254 * This routine sets the starting offset for the video buffer when only 255 * one offset needs to be specified. 256 *----------------------------------------------------------------------------- 257 */ 258#if GFX_VIDEO_DYNAMIC 259int 260sc1400_set_video_offset(unsigned long offset) 261#else 262int 263gfx_set_video_offset(unsigned long offset) 264#endif 265{ 266 /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */ 267 268 gfx_vid_offset = offset; 269 270 /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ 271 /* Use private routine to abstract the display controller. */ 272 273 gfx_set_display_video_offset(offset); 274 return (0); 275} 276 277/*--------------------------------------------------------------------------- 278 * gfx_set_video_scale 279 * 280 * This routine sets the scale factor for the video overlay window. The 281 * size of the source and destination regions are specified in pixels. 282 *--------------------------------------------------------------------------- 283 */ 284#if GFX_VIDEO_DYNAMIC 285int 286sc1400_set_video_scale(unsigned short srcw, unsigned short srch, 287 unsigned short dstw, unsigned short dsth) 288#else 289int 290gfx_set_video_scale(unsigned short srcw, unsigned short srch, 291 unsigned short dstw, unsigned short dsth) 292#endif 293{ 294 unsigned long xscale, yscale; 295 296 /* SAVE PARAMETERS */ 297 /* These are needed for clipping the video window later. */ 298 299 gfx_vid_srcw = srcw; 300 gfx_vid_srch = srch; 301 gfx_vid_dstw = dstw; 302 gfx_vid_dsth = dsth; 303 304 /* CALCULATE SC1400 SCALE FACTORS */ 305 /* No downscaling in SC1400 so force to 1x if attempted. */ 306 307 if (srcw < dstw) 308 xscale = (0x2000 * (srcw - 1)) / (dstw - 1); 309 else 310 xscale = 0x1FFF; 311 if (srch < dsth) 312 yscale = (0x2000 * (srch - 1)) / (dsth - 1); 313 else 314 yscale = 0x1FFF; 315 WRITE_VID32(SC1400_VIDEO_SCALE, (yscale << 16) | xscale); 316 317 /* CALL ROUTINE TO UPDATE WINDOW POSITION */ 318 /* This is required because the scale values effect the number of */ 319 /* source data pixels that need to be clipped, as well as the */ 320 /* amount of data that needs to be transferred. */ 321 322 gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width, 323 gfx_vid_height); 324 return (0); 325} 326 327/*--------------------------------------------------------------------------- 328 * gfx_set_video_window 329 * 330 * This routine sets the position and size of the video overlay window. The 331 * position is specified in screen relative coordinates, and may be negative. 332 * The size of destination region is specified in pixels. The line size 333 * indicates the number of bytes of source data per scanline. 334 *--------------------------------------------------------------------------- 335 */ 336#if GFX_VIDEO_DYNAMIC 337int 338sc1400_set_video_window(short x, short y, unsigned short w, unsigned short h) 339#else 340int 341gfx_set_video_window(short x, short y, unsigned short w, unsigned short h) 342#endif 343{ 344 unsigned long vcfg = 0; 345 unsigned long hadjust, vadjust; 346 unsigned long initread; 347 unsigned long xstart, ystart, xend, yend; 348 unsigned long offset, line_size; 349 350 /* SAVE PARAMETERS */ 351 /* These are needed to call this routine if the scale value changes. */ 352 353 gfx_vid_xpos = x; 354 gfx_vid_ypos = y; 355 gfx_vid_width = w; 356 gfx_vid_height = h; 357 358 /* GET ADJUSTMENT VALUES */ 359 /* Use routines to abstract version of display controller. */ 360 361 hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13; 362 vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1; 363 364 if (x > 0) { 365 /* NO CLIPPING ON LEFT */ 366 367 xstart = x + hadjust; 368 initread = 0; 369 } else { 370 /* CLIPPING ON LEFT */ 371 /* Adjust initial read for scale, checking for divide by zero */ 372 373 xstart = hadjust; 374 initread = -x; 375 if (gfx_vid_dstw) 376 initread = ((-x) * gfx_vid_srcw) / gfx_vid_dstw; 377 else 378 initread = 0; 379 } 380 381 /* CLIPPING ON RIGHT */ 382 383 xend = x + w; 384 if (xend > gfx_get_hactive()) 385 xend = gfx_get_hactive(); 386 xend += hadjust; 387 388 /* CLIPPING ON TOP */ 389 390 offset = gfx_vid_offset; 391 if (y >= 0) { 392 ystart = y + vadjust; 393 } else { 394 ystart = vadjust; 395 line_size = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; 396 if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) 397 line_size += 512; 398 if (gfx_vid_dsth) 399 offset = gfx_vid_offset + (line_size << 1) * 400 (((-y) * gfx_vid_srch) / gfx_vid_dsth); 401 } 402 403 /* CLIPPING ON BOTTOM */ 404 405 yend = y + h; 406 if (yend >= gfx_get_vactive()) 407 yend = gfx_get_vactive(); 408 yend += vadjust; 409 410 /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */ 411 /* Use private routine to abstract the display controller. */ 412 413 gfx_set_display_video_offset(offset); 414 415 /* DISABLE REGISTER UPDATES */ 416 417 vcfg = READ_VID32(SC1400_VIDEO_CONFIG); 418 vcfg &= ~SC1400_VCFG_VID_REG_UPDATE; 419 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 420 421 /* SET VIDEO POSITION */ 422 423 WRITE_VID32(SC1400_VIDEO_X_POS, (xend << 16) | xstart); 424 WRITE_VID32(SC1400_VIDEO_Y_POS, (yend << 16) | ystart); 425 426 /* SET INITIAL READ ADDRESS AND ENABLE REGISTER UPDATES */ 427 428 vcfg &= ~SC1400_VCFG_INIT_READ_MASK; 429 vcfg |= (initread << 15) & SC1400_VCFG_INIT_READ_MASK; 430 vcfg |= SC1400_VCFG_VID_REG_UPDATE; 431 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 432 return (0); 433} 434 435/*--------------------------------------------------------------------------- 436 * gfx_set_video_color_key 437 * 438 * This routine specifies the color key value and mask for the video overlay 439 * hardware. To disable color key, the color and mask should both be set to 440 * zero. The hardware uses the color key in the following equation: 441 * 442 * ((source data) & (color key mask)) == ((color key) & (color key mask)) 443 * 444 * The source data can be either graphics data or video data. The bluescreen 445 * parameter is set to have the hardware compare video data and clear to 446 * comapare graphics data. 447 *--------------------------------------------------------------------------- 448 */ 449#if GFX_VIDEO_DYNAMIC 450int 451sc1400_set_video_color_key(unsigned long key, unsigned long mask, 452 int graphics) 453#else 454int 455gfx_set_video_color_key(unsigned long key, unsigned long mask, int graphics) 456#endif 457{ 458 unsigned long dcfg = 0; 459 460 /* SET SC1400 COLOR KEY VALUE */ 461 462 WRITE_VID32(SC1400_VIDEO_COLOR_KEY, key); 463 WRITE_VID32(SC1400_VIDEO_COLOR_MASK, mask); 464 465 /* SELECT GRAPHICS OR VIDEO DATA TO COMPARE TO THE COLOR KEY */ 466 467 dcfg = READ_VID32(SC1400_DISPLAY_CONFIG); 468 if (graphics & 0x01) 469 dcfg &= ~SC1400_DCFG_VG_CK; 470 else 471 dcfg |= SC1400_DCFG_VG_CK; 472 WRITE_VID32(SC1400_DISPLAY_CONFIG, dcfg); 473 return (0); 474} 475 476/*--------------------------------------------------------------------------- 477 * gfx_set_video_filter 478 * 479 * This routine enables or disables the video overlay filters. 480 *--------------------------------------------------------------------------- 481 */ 482#if GFX_VIDEO_DYNAMIC 483int 484sc1400_set_video_filter(int xfilter, int yfilter) 485#else 486int 487gfx_set_video_filter(int xfilter, int yfilter) 488#endif 489{ 490 unsigned long vcfg = 0; 491 492 /* ENABLE OR DISABLE SC1400 VIDEO OVERLAY FILTERS */ 493 494 vcfg = READ_VID32(SC1400_VIDEO_CONFIG); 495 vcfg &= ~(SC1400_VCFG_X_FILTER_EN | SC1400_VCFG_Y_FILTER_EN); 496 if (xfilter) 497 vcfg |= SC1400_VCFG_X_FILTER_EN; 498 if (yfilter) 499 vcfg |= SC1400_VCFG_Y_FILTER_EN; 500 WRITE_VID32(SC1400_VIDEO_CONFIG, vcfg); 501 return (0); 502} 503 504/*--------------------------------------------------------------------------- 505 * gfx_set_video_palette 506 * 507 * This routine loads the video hardware palette. If a NULL pointer is 508 * specified, the palette is bypassed (for SC1400, this means loading the 509 * palette with identity values). 510 *--------------------------------------------------------------------------- 511 */ 512#if GFX_VIDEO_DYNAMIC 513int 514sc1400_set_video_palette(unsigned long *palette) 515#else 516int 517gfx_set_video_palette(unsigned long *palette) 518#endif 519{ 520 unsigned long i, entry; 521 522 /* LOAD SC1400 VIDEO PALETTE */ 523 524 WRITE_VID32(SC1400_PALETTE_ADDRESS, 0); 525 for (i = 0; i < 256; i++) { 526 if (palette) 527 entry = palette[i]; 528 else 529 entry = i | (i << 8) | (i << 16); 530 WRITE_VID32(SC1400_PALETTE_DATA, entry); 531 } 532 return (0); 533} 534 535/*************************************************************/ 536/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ 537/*************************************************************/ 538 539#if GFX_READ_ROUTINES 540 541/*--------------------------------------------------------------------------- 542 * gfx_get_sync_polarities 543 * 544 * This routine returns the polarities of the sync pulses: 545 * Bit 0: Set if negative horizontal polarity. 546 * Bit 1: Set if negative vertical polarity. 547 *--------------------------------------------------------------------------- 548 */ 549#if GFX_VIDEO_DYNAMIC 550int 551sc1400_get_sync_polarities(void) 552#else 553int 554gfx_get_sync_polarities(void) 555#endif 556{ 557 int polarities = 0; 558 559 if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000100) 560 polarities |= 1; 561 if (READ_VID32(SC1400_DISPLAY_CONFIG) & 0x00000200) 562 polarities |= 2; 563 return (polarities); 564} 565 566/*----------------------------------------------------------------------------- 567 * gfx_get_video_enable 568 * 569 * This routine returns the value "one" if video overlay is currently enabled, 570 * otherwise it returns the value "zero". 571 *----------------------------------------------------------------------------- 572 */ 573#if GFX_VIDEO_DYNAMIC 574int 575sc1400_get_video_enable(void) 576#else 577int 578gfx_get_video_enable(void) 579#endif 580{ 581 if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_VID_EN) 582 return (1); 583 return (0); 584} 585 586/*----------------------------------------------------------------------------- 587 * gfx_get_video_format 588 * 589 * This routine returns the current video overlay format. 590 *----------------------------------------------------------------------------- 591 */ 592#if GFX_VIDEO_DYNAMIC 593int 594sc1400_get_video_format(void) 595#else 596int 597gfx_get_video_format(void) 598#endif 599{ 600 unsigned long vcfg; 601 602 vcfg = READ_VID32(SC1400_VIDEO_CONFIG); 603 if (vcfg & SC1400_VCFG_CSC_BYPASS) 604 return (4); 605 else 606 return ((vcfg >> 2) & 3); 607} 608 609/*----------------------------------------------------------------------------- 610 * gfx_get_video_src_size 611 * 612 * This routine returns the size of the source video overlay buffer. The 613 * return value is (height << 16) | width. 614 *----------------------------------------------------------------------------- 615 */ 616#if GFX_VIDEO_DYNAMIC 617unsigned long 618sc1400_get_video_src_size(void) 619#else 620unsigned long 621gfx_get_video_src_size(void) 622#endif 623{ 624 unsigned long width = 0, height = 0; 625 626 /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ 627 628 width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; 629 if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) 630 width += 512; 631 632 if (width) { 633 /* DETERMINE HEIGHT BY DIVIDING TOTAL SIZE BY WIDTH */ 634 /* Get total size from display controller - abtracted. */ 635 636 height = gfx_get_display_video_size() / (width << 1); 637 } 638 return ((height << 16) | width); 639} 640 641/*----------------------------------------------------------------------------- 642 * gfx_get_video_line_size 643 * 644 * This routine returns the line size of the source video overlay buffer, in 645 * pixels. 646 *----------------------------------------------------------------------------- 647 */ 648#if GFX_VIDEO_DYNAMIC 649unsigned long 650sc1400_get_video_line_size(void) 651#else 652unsigned long 653gfx_get_video_line_size(void) 654#endif 655{ 656 unsigned long width = 0; 657 658 /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ 659 660 width = (READ_VID32(SC1400_VIDEO_CONFIG) >> 7) & 0x000001FE; 661 if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_LINE_SIZE_UPPER) 662 width += 512; 663 return (width); 664} 665 666/*----------------------------------------------------------------------------- 667 * gfx_get_video_xclip 668 * 669 * This routine returns the number of bytes clipped on the left side of a 670 * video overlay line (skipped at beginning). 671 *----------------------------------------------------------------------------- 672 */ 673#if GFX_VIDEO_DYNAMIC 674unsigned long 675sc1400_get_video_xclip(void) 676#else 677unsigned long 678gfx_get_video_xclip(void) 679#endif 680{ 681 unsigned long clip = 0; 682 683 /* DETERMINE SOURCE WIDTH FROM THE SC1400 VIDEO LINE SIZE */ 684 685 clip = (READ_VID32(SC1400_VIDEO_CONFIG) >> 14) & 0x000007FC; 686 return (clip); 687} 688 689/*----------------------------------------------------------------------------- 690 * gfx_get_video_offset 691 * 692 * This routine returns the current offset for the video overlay buffer. 693 *----------------------------------------------------------------------------- 694 */ 695#if GFX_VIDEO_DYNAMIC 696unsigned long 697sc1400_get_video_offset(void) 698#else 699unsigned long 700gfx_get_video_offset(void) 701#endif 702{ 703 return (gfx_get_display_video_offset()); 704} 705 706/*--------------------------------------------------------------------------- 707 * gfx_get_video_scale 708 * 709 * This routine returns the scale factor for the video overlay window. 710 *--------------------------------------------------------------------------- 711 */ 712#if GFX_VIDEO_DYNAMIC 713unsigned long 714sc1400_get_video_scale(void) 715#else 716unsigned long 717gfx_get_video_scale(void) 718#endif 719{ 720 return (READ_VID32(SC1400_VIDEO_SCALE)); 721} 722 723/*--------------------------------------------------------------------------- 724 * gfx_get_video_dst_size 725 * 726 * This routine returns the size of the displayed video overlay window. 727 *--------------------------------------------------------------------------- 728 */ 729#if GFX_VIDEO_DYNAMIC 730unsigned long 731sc1400_get_video_dst_size(void) 732#else 733unsigned long 734gfx_get_video_dst_size(void) 735#endif 736{ 737 unsigned long xsize, ysize; 738 739 xsize = READ_VID32(SC1400_VIDEO_X_POS); 740 xsize = ((xsize >> 16) & 0x3FF) - (xsize & 0x03FF); 741 ysize = READ_VID32(SC1400_VIDEO_Y_POS); 742 ysize = ((ysize >> 16) & 0x3FF) - (ysize & 0x03FF); 743 return ((ysize << 16) | xsize); 744} 745 746/*--------------------------------------------------------------------------- 747 * gfx_get_video_position 748 * 749 * This routine returns the position of the video overlay window. The 750 * return value is (ypos << 16) | xpos. 751 *--------------------------------------------------------------------------- 752 */ 753#if GFX_VIDEO_DYNAMIC 754unsigned long 755sc1400_get_video_position(void) 756#else 757unsigned long 758gfx_get_video_position(void) 759#endif 760{ 761 unsigned long hadjust, vadjust; 762 unsigned long xpos, ypos; 763 764 /* READ HARDWARE POSITION */ 765 766 xpos = READ_VID32(SC1400_VIDEO_X_POS) & 0x000003FF; 767 ypos = READ_VID32(SC1400_VIDEO_Y_POS) & 0x000003FF; 768 769 /* GET ADJUSTMENT VALUES */ 770 /* Use routines to abstract version of display controller. */ 771 772 hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13; 773 vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1; 774 xpos -= hadjust; 775 ypos -= vadjust; 776 return ((ypos << 16) | (xpos & 0x0000FFFF)); 777} 778 779/*--------------------------------------------------------------------------- 780 * gfx_get_video_color_key 781 * 782 * This routine returns the current video color key value. 783 *--------------------------------------------------------------------------- 784 */ 785#if GFX_VIDEO_DYNAMIC 786unsigned long 787sc1400_get_video_color_key(void) 788#else 789unsigned long 790gfx_get_video_color_key(void) 791#endif 792{ 793 return (READ_VID32(SC1400_VIDEO_COLOR_KEY)); 794} 795 796/*--------------------------------------------------------------------------- 797 * gfx_get_video_color_key_mask 798 * 799 * This routine returns the current video color mask value. 800 *--------------------------------------------------------------------------- 801 */ 802#if GFX_VIDEO_DYNAMIC 803unsigned long 804sc1400_get_video_color_key_mask(void) 805#else 806unsigned long 807gfx_get_video_color_key_mask(void) 808#endif 809{ 810 return (READ_VID32(SC1400_VIDEO_COLOR_MASK)); 811} 812 813/*--------------------------------------------------------------------------- 814 * gfx_get_video_color_key_src 815 * 816 * This routine returns 0 for video data compare, 1 for graphics data. 817 *--------------------------------------------------------------------------- 818 */ 819#if GFX_VIDEO_DYNAMIC 820int 821sc1400_get_video_color_key_src(void) 822#else 823int 824gfx_get_video_color_key_src(void) 825#endif 826{ 827 if (READ_VID32(SC1400_DISPLAY_CONFIG) & SC1400_DCFG_VG_CK) 828 return (0); 829 return (1); 830} 831 832/*--------------------------------------------------------------------------- 833 * gfx_get_video_filter 834 * 835 * This routine returns if the filters are currently enabled. 836 *--------------------------------------------------------------------------- 837 */ 838#if GFX_VIDEO_DYNAMIC 839int 840sc1400_get_video_filter(void) 841#else 842int 843gfx_get_video_filter(void) 844#endif 845{ 846 int retval = 0; 847 848 if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_X_FILTER_EN) 849 retval |= 1; 850 if (READ_VID32(SC1400_VIDEO_CONFIG) & SC1400_VCFG_Y_FILTER_EN) 851 retval |= 2; 852 return (retval); 853} 854 855/*--------------------------------------------------------------------------- 856 * gfx_get_clock_frequency 857 * 858 * This routine returns the current clock frequency in 16.16 format. 859 * It reads the current register value and finds the match in the table. 860 * If no match is found, this routine returns 0. 861 *--------------------------------------------------------------------------- 862 */ 863#if GFX_VIDEO_DYNAMIC 864unsigned long 865sc1400_get_clock_frequency(void) 866#else 867unsigned long 868gfx_get_clock_frequency(void) 869#endif 870{ 871 int index; 872 unsigned long value, mask; 873 874 mask = 0x007FFF0F; 875 value = READ_VID32(SC1400_VID_CLOCK_SELECT) & mask; 876 for (index = 0; index < NUM_SC1400_FREQUENCIES; index++) { 877 if ((gfx_sc1400_clock_table[index].clock_select & mask) == value) 878 return (gfx_sc1400_clock_table[index].frequency); 879 } 880 return (0); 881} 882 883/*--------------------------------------------------------------------------- 884 * gfx_read_crc 885 * 886 * This routine returns the hardware CRC value, which is used for automated 887 * testing. The value is like a checksum, but will change if pixels move 888 * locations. 889 *--------------------------------------------------------------------------- 890 */ 891#if GFX_VIDEO_DYNAMIC 892unsigned long 893sc1400_read_crc(void) 894#else 895unsigned long 896gfx_read_crc(void) 897#endif 898{ 899 unsigned long crc = 0xFFFFFFFF; 900 901 if (gfx_test_timing_active()) { 902 // WAIT UNTIL ACTIVE DISPLAY 903 904 while (!gfx_test_vertical_active()) ; 905 906 // RESET CRC DURING ACTIVE DISPLAY 907 908 WRITE_VID32(SC1400_VID_CRC, 0); 909 WRITE_VID32(SC1400_VID_CRC, 1); 910 911 // WAIT UNTIL NOT ACTIVE, THEN ACTIVE, NOT ACTIVE, THEN ACTIVE 912 913 while (gfx_test_vertical_active()) ; 914 while (!gfx_test_vertical_active()) ; 915 while (gfx_test_vertical_active()) ; 916 while (!gfx_test_vertical_active()) ; 917 crc = READ_VID32(SC1400_VID_CRC) >> 8; 918 } 919 return (crc); 920} 921 922#endif /* GFX_READ_ROUTINES */ 923 924/* END OF FILE */ 925