1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/disp_gu1.c,v 1.4 2003/02/06 17:46:02 alanh Exp $ */ 2/* 3 * $Workfile: disp_gu1.c $ 4 * 5 * This file contains routines for the first generation display controller. 6 * 7 * NSC_LIC_ALTERNATIVE_PREAMBLE 8 * 9 * Revision 1.0 10 * 11 * National Semiconductor Alternative GPL-BSD License 12 * 13 * National Semiconductor Corporation licenses this software 14 * ("Software"): 15 * 16 * Durango 17 * 18 * under one of the two following licenses, depending on how the 19 * Software is received by the Licensee. 20 * 21 * If this Software is received as part of the Linux Framebuffer or 22 * other GPL licensed software, then the GPL license designated 23 * NSC_LIC_GPL applies to this Software; in all other circumstances 24 * then the BSD-style license designated NSC_LIC_BSD shall apply. 25 * 26 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 27 28/* NSC_LIC_BSD 29 * 30 * National Semiconductor Corporation Open Source License for Durango 31 * 32 * (BSD License with Export Notice) 33 * 34 * Copyright (c) 1999-2001 35 * National Semiconductor Corporation. 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 42 * * Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 45 * * Redistributions in binary form must reproduce the above 46 * copyright notice, this list of conditions and the following 47 * disclaimer in the documentation and/or other materials provided 48 * with the distribution. 49 * 50 * * Neither the name of the National Semiconductor Corporation nor 51 * the names of its contributors may be used to endorse or promote 52 * products derived from this software without specific prior 53 * written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 56 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 57 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 58 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 59 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 60 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 62 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 64 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 65 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 67 * OF SUCH DAMAGE. 68 * 69 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 70 * YOUR JURISDICTION. It is licensee's responsibility to comply with 71 * any export regulations applicable in licensee's jurisdiction. Under 72 * CURRENT (2001) U.S. export regulations this software 73 * is eligible for export from the U.S. and can be downloaded by or 74 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 75 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 76 * Syria, Sudan, Afghanistan and any other country to which the U.S. 77 * has embargoed goods and services. 78 * 79 * END_NSC_LIC_BSD */ 80 81/* NSC_LIC_GPL 82 * 83 * National Semiconductor Corporation Gnu General Public License for Durango 84 * 85 * (GPL License with Export Notice) 86 * 87 * Copyright (c) 1999-2001 88 * National Semiconductor Corporation. 89 * All rights reserved. 90 * 91 * Redistribution and use in source and binary forms, with or without 92 * modification, are permitted under the terms of the GNU General 93 * Public License as published by the Free Software Foundation; either 94 * version 2 of the License, or (at your option) any later version 95 * 96 * In addition to the terms of the GNU General Public License, neither 97 * the name of the National Semiconductor Corporation nor the names of 98 * its contributors may be used to endorse or promote products derived 99 * from this software without specific prior written permission. 100 * 101 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 102 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 103 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 104 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 105 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 106 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 107 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 108 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 109 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 110 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 111 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 112 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 113 * OF SUCH DAMAGE. See the GNU General Public License for more details. 114 * 115 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 116 * YOUR JURISDICTION. It is licensee's responsibility to comply with 117 * any export regulations applicable in licensee's jurisdiction. Under 118 * CURRENT (2001) U.S. export regulations this software 119 * is eligible for export from the U.S. and can be downloaded by or 120 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 121 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 122 * Syria, Sudan, Afghanistan and any other country to which the U.S. 123 * has embargoed goods and services. 124 * 125 * You should have received a copy of the GNU General Public License 126 * along with this file; if not, write to the Free Software Foundation, 127 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 128 * 129 * END_NSC_LIC_GPL */ 130 131void gu1_enable_compression(void); /* private routine definition */ 132void gu1_disable_compression(void); /* private routine definition */ 133void gfx_reset_video(void); /* private routine definition */ 134int gfx_set_display_control(int sync_polarities); /* private routine definition */ 135void gu1_delay_approximate(unsigned long milliseconds); 136void gu1_delay_precise(unsigned long milliseconds); 137int gu1_set_display_bpp(unsigned short bpp); 138int gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz); 139int gu1_set_display_mode(int xres, int yres, int bpp, int hz); 140int gu1_set_display_timings(unsigned short bpp, unsigned short flags, 141 unsigned short hactive, 142 unsigned short hblank_start, 143 unsigned short hsync_start, 144 unsigned short hsync_end, 145 unsigned short hblank_end, unsigned short htotal, 146 unsigned short vactive, 147 unsigned short vblank_start, 148 unsigned short vsync_start, 149 unsigned short vsync_end, 150 unsigned short vblank_end, unsigned short vtotal, 151 unsigned long frequency); 152int gu1_set_vtotal(unsigned short vtotal); 153void gu1_set_display_pitch(unsigned short pitch); 154void gu1_set_display_offset(unsigned long offset); 155int gu1_set_display_palette_entry(unsigned long index, unsigned long palette); 156int gu1_set_display_palette(unsigned long *palette); 157void gu1_video_shutdown(void); 158void gu1_set_clock_frequency(unsigned long frequency); 159int gu1_set_crt_enable(int enable); 160void gu1_set_cursor_enable(int enable); 161void gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor); 162void gu1_set_cursor_position(unsigned long memoffset, 163 unsigned short xpos, unsigned short ypos, 164 unsigned short xhotspot, 165 unsigned short yhotspot); 166void gu1_set_cursor_shape32(unsigned long memoffset, unsigned long *andmask, 167 unsigned long *xormask); 168void gu1_set_cursor_shape64(unsigned long memoffset, unsigned long *andmask, 169 unsigned long *xormask); 170void gu1_set_icon_enable(int enable); 171void gu1_set_icon_colors(unsigned long color0, unsigned long color1, 172 unsigned long color2); 173void gu1_set_icon_position(unsigned long memoffset, unsigned short xpos); 174void gu1_set_icon_shape64(unsigned long memoffset, unsigned long *andmask, 175 unsigned long *xormask, unsigned int lines); 176 177int gu1_set_compression_enable(int enable); 178int gu1_set_compression_offset(unsigned long offset); 179int gu1_set_compression_pitch(unsigned short pitch); 180int gu1_set_compression_size(unsigned short size); 181void gu1_set_display_priority_high(int enable); 182int gu1_test_timing_active(void); 183int gu1_test_vertical_active(void); 184int gu1_wait_vertical_blank(void); 185void gu1_delay_milliseconds(unsigned long milliseconds); 186void gu1_delay_microseconds(unsigned long microseconds); 187void gu1_enable_panning(int x, int y); 188int gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width, 189 unsigned short height, unsigned short bpp); 190int gu1_set_panel_present(int panelResX, int panelResY, unsigned short width, 191 unsigned short height, unsigned short bpp); 192void gu1_reset_timing_lock(void); 193 194int gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz); 195unsigned short gu1_get_display_pitch(void); 196int gu1_get_vsa2_softvga_enable(void); 197int gu1_get_sync_polarities(void); 198unsigned long gu1_get_clock_frequency(void); 199unsigned long gu1_get_max_supported_pixel_clock(void); 200int gu1_mode_frequency_supported(int xres, int yres, int bpp, 201 unsigned long frequency); 202int gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, 203 unsigned long frequency); 204int gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, 205 unsigned long frequency); 206int gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, 207 int *frequency); 208int gu1_get_display_mode_count(void); 209int gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz); 210unsigned long gu1_get_frame_buffer_line_size(void); 211unsigned short gu1_get_hactive(void); 212unsigned short gu1_get_hblank_start(void); 213unsigned short gu1_get_hsync_start(void); 214unsigned short gu1_get_hsync_end(void); 215unsigned short gu1_get_hblank_end(void); 216unsigned short gu1_get_htotal(void); 217unsigned short gu1_get_vactive(void); 218unsigned short gu1_get_vline(void); 219unsigned short gu1_get_vblank_start(void); 220unsigned short gu1_get_vsync_start(void); 221unsigned short gu1_get_vsync_end(void); 222unsigned short gu1_get_vblank_end(void); 223unsigned short gu1_get_vtotal(void); 224unsigned short gu1_get_display_bpp(void); 225unsigned long gu1_get_display_offset(void); 226int gu1_get_display_palette_entry(unsigned long index, 227 unsigned long *palette); 228void gu1_get_display_palette(unsigned long *palette); 229unsigned long gu1_get_cursor_enable(void); 230unsigned long gu1_get_cursor_offset(void); 231unsigned long gu1_get_cursor_position(void); 232unsigned long gu1_get_cursor_clip(void); 233unsigned long gu1_get_cursor_color(int color); 234unsigned long gu1_get_icon_enable(void); 235unsigned long gu1_get_icon_offset(void); 236unsigned long gu1_get_icon_position(void); 237unsigned long gu1_get_icon_color(int color); 238int gu1_get_compression_enable(void); 239unsigned long gu1_get_compression_offset(void); 240unsigned short gu1_get_compression_pitch(void); 241unsigned short gu1_get_compression_size(void); 242int gu1_get_display_priority_high(void); 243int gu1_get_valid_bit(int line); 244void gu1_set_display_video_enable(int enable); 245int gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp); 246void gu1_set_display_video_size(unsigned short width, unsigned short height); 247void gu1_set_display_video_offset(unsigned long offset); 248unsigned long gu1_get_display_video_offset(void); 249unsigned long gu1_get_display_video_size(void); 250 251/* VIDEO BUFFER SIZE */ 252 253unsigned long vid_buf_size = 0; 254int vid_enabled = 0; 255 256/*----------------------------------------------------------------------------- 257 * GU1_DELAY_APPROXIMATE (PRIVATE ROUTINE - NOT PART OF DURANGO API) 258 * 259 * Delay the requested number of milliseconds by reading a register. This function 260 * generally takes longer than the requested time. 261 *-----------------------------------------------------------------------------*/ 262void 263gu1_delay_approximate(unsigned long milliseconds) 264{ 265 /* ASSUME 300 MHz, 5 CLOCKS PER READ */ 266 267# define READS_PER_MILLISECOND 60000L 268 269 unsigned long loop; 270 271 loop = milliseconds * READS_PER_MILLISECOND; 272 while (loop-- > 0) { 273 READ_REG32(DC_UNLOCK); 274 } 275} 276 277/*----------------------------------------------------------------------------- 278 * GU1_DELAY_PRECISE (PRIVATE ROUTINE - NOT PART OF DURANGO API) 279 * 280 * Delay the number of milliseconds on a more precise level, varying only by 281 * 1/10 of a ms. This function should only be called if an SC1200 is present. 282 *-----------------------------------------------------------------------------*/ 283void 284gu1_delay_precise(unsigned long milliseconds) 285{ 286#if GFX_VIDEO_SC1200 287 288#define LOOP 1000 289 unsigned long i, timer_start, timer_end, total_ticks, previous_ticks, 290 temp_ticks; 291 292 /* Get current time */ 293 timer_start = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE); 294 295 /* Calculate expected end time */ 296 if (INB(SC1200_CB_BASE_ADDR + SC1200_CB_TMCNFG) & SC1200_TMCLKSEL_27MHZ) 297 total_ticks = 27000 * milliseconds; /* timer resolution is 27 MHz */ 298 else 299 total_ticks = 1000 * milliseconds; /* timer resolution is 1 MHz */ 300 301 if (total_ticks > ((unsigned long)0xffffffff - timer_start)) /* wrap-around */ 302 timer_end = total_ticks - ((unsigned long)0xffffffff - timer_start); 303 else 304 timer_end = timer_start + total_ticks; 305 306 /* in case of wrap around */ 307 if (timer_end < timer_start) { 308 previous_ticks = timer_start; 309 while (1) { 310 temp_ticks = IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE); 311 if (temp_ticks < previous_ticks) 312 break; 313 else 314 previous_ticks = temp_ticks; 315 for (i = 0; i < LOOP; i++) 316 READ_REG32(DC_UNLOCK); 317 } 318 } 319 /* now the non-wrap around part */ 320 while (1) { 321 for (i = 0; i < LOOP; i++) 322 READ_REG32(DC_UNLOCK); 323 if (IND(SC1200_CB_BASE_ADDR + SC1200_CB_TMVALUE) > timer_end) 324 break; 325 } 326 327#endif /* GFX_VIDEO_SC1200 */ 328} 329 330/*----------------------------------------------------------------------------- 331 * WARNING!!!! INACCURATE DELAY MECHANISM 332 * 333 * In an effort to keep the code self contained and operating system 334 * independent, the delay loop just performs reads of a display controller 335 * register. This time will vary for faster processors. The delay can always 336 * be longer than intended, only effecting the time of the mode switch 337 * (obviously want it to still be under a second). Problems with the hardware 338 * only arise if the delay is not long enough. 339 * 340 * For the SC1200, the high resolution timer can be used as an accurate mechanism 341 * for keeping time. However, in order to avoid a busy loop of IO reads, the 342 * timer is polled in-between busy loops, and therefore the actual delay might 343 * be longer than the requested delay by the time of one busy loop 344 * (which on a 200 MHz system took 95 us) 345 * 346 * There are thus two delay functions which are called from the main API routine. 347 * One is meant to be more precise and should only called if an SC1200 is present. 348 *----------------------------------------------------------------------------- 349 */ 350#if GFX_DISPLAY_DYNAMIC 351void 352gu1_delay_milliseconds(unsigned long milliseconds) 353#else 354void 355gfx_delay_milliseconds(unsigned long milliseconds) 356#endif 357{ 358#if GFX_VIDEO_SC1200 359 360#if GFX_VIDEO_DYNAMIC 361 if (gfx_video_type == GFX_VIDEO_TYPE_SC1200) { 362#endif 363 gu1_delay_precise(milliseconds); 364 return; 365#if GFX_VIDEO_DYNAMIC 366 } 367#endif 368 369#endif /* GFX_VIDEO_SC1200 */ 370 371 gu1_delay_approximate(milliseconds); 372} 373 374#if GFX_DISPLAY_DYNAMIC 375void 376gu1_delay_microseconds(unsigned long microseconds) 377#else 378void 379gfx_delay_microseconds(unsigned long microseconds) 380#endif 381{ 382 /* ASSUME 300 MHz, 2 CLOCKS PER INCREMENT */ 383 384 unsigned long loop_count = microseconds * 150; 385 386 while (loop_count-- > 0) { 387 ; 388 } 389} 390 391/*----------------------------------------------------------------------------- 392 * GFX_VIDEO_SHUTDOWN 393 * 394 * This routine disables the display controller output. 395 *----------------------------------------------------------------------------- 396 */ 397void 398gu1_video_shutdown(void) 399{ 400 unsigned long unlock; 401 unsigned long gcfg, tcfg; 402 403 /* DISABLE COMPRESSION */ 404 405 gu1_disable_compression(); 406 407 /* ALSO DISABLE VIDEO */ 408 /* Use private "reset video" routine to do all that is needed. */ 409 /* SC1200, for example, also disables the alpha blending regions. */ 410 411 gfx_reset_video(); 412 413 /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ 414 415 unlock = READ_REG32(DC_UNLOCK); 416 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 417 418 /* READ THE CURRENT GX VALUES */ 419 420 gcfg = READ_REG32(DC_GENERAL_CFG); 421 tcfg = READ_REG32(DC_TIMING_CFG); 422 423 /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */ 424 425 tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN); 426 WRITE_REG32(DC_TIMING_CFG, tcfg); 427 428 /* DELAY: WAIT FOR PENDING MEMORY REQUESTS */ 429 /* This delay is used to make sure that all pending requests to the */ 430 /* memory controller have completed before disabling the FIFO load. */ 431 432 gfx_delay_milliseconds(1); 433 434 /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */ 435 436 gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); 437 WRITE_REG32(DC_GENERAL_CFG, gcfg); 438 WRITE_REG32(DC_UNLOCK, unlock); 439 return; 440} 441 442/*----------------------------------------------------------------------------- 443 * GFX_SET_DISPLAY_BPP 444 * 445 * This routine programs the bpp in the display controller. 446 *----------------------------------------------------------------------------- 447 */ 448#if GFX_DISPLAY_DYNAMIC 449int 450gu1_set_display_bpp(unsigned short bpp) 451#else 452int 453gfx_set_display_bpp(unsigned short bpp) 454#endif 455{ 456 unsigned long ocfg, lock; 457 458 lock = READ_REG32(DC_UNLOCK); 459 ocfg = READ_REG32(DC_OUTPUT_CFG) & ~(DC_OCFG_8BPP | DC_OCFG_555); 460 461 /* SET DC PIXEL FORMAT */ 462 463 if (bpp == 8) 464 ocfg |= DC_OCFG_8BPP; 465 else if (bpp == 15) 466 ocfg |= DC_OCFG_555; 467 else if (bpp != 16) 468 return GFX_STATUS_BAD_PARAMETER; 469 470 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 471 WRITE_REG32(DC_OUTPUT_CFG, ocfg); 472 WRITE_REG32(DC_UNLOCK, lock); 473 474 /* SET BPP IN GRAPHICS PIPELINE */ 475 476 gfx_set_bpp(bpp); 477 478 return 0; 479} 480 481/*----------------------------------------------------------------------------- 482 * GFX_SET_SPECIFIED_MODE 483 * This routine uses the parameters in the specified display mode structure 484 * to program the display controller hardware. 485 *----------------------------------------------------------------------------- 486 */ 487int 488gu1_set_specified_mode(DISPLAYMODE * pMode, int bpp) 489{ 490 unsigned long unlock, value; 491 unsigned long gcfg, tcfg, ocfg; 492 unsigned long size, pitch; 493 unsigned long vid_buffer_size; 494 unsigned long hactive, vactive; 495 496 gbpp = bpp; 497 498 /* CHECK WHETHER TIMING CHANGE IS ALLOWED */ 499 /* Flag used for locking also overrides timing change restriction */ 500 501 if (gfx_timing_lock && !(pMode->flags & GFX_MODE_LOCK_TIMING)) 502 return GFX_STATUS_ERROR; 503 504 /* SET GLOBAL FLAG */ 505 506 if (pMode->flags & GFX_MODE_LOCK_TIMING) 507 gfx_timing_lock = 1; 508 509 /* DISABLE COMPRESSION */ 510 511 gu1_disable_compression(); 512 513 /* ALSO DISABLE VIDEO */ 514 /* Use private "reset video" routine to do all that is needed. */ 515 /* SC1200, for example, also disables the alpha blending regions. */ 516 517 gfx_reset_video(); 518 519 /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ 520 521 unlock = READ_REG32(DC_UNLOCK); 522 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 523 524 /* READ THE CURRENT GX VALUES */ 525 526 gcfg = READ_REG32(DC_GENERAL_CFG); 527 tcfg = READ_REG32(DC_TIMING_CFG); 528 529 /* BLANK THE GX DISPLAY AND DISABLE THE TIMING GENERATOR */ 530 531 tcfg &= ~((unsigned long)DC_TCFG_BLKE | (unsigned long)DC_TCFG_TGEN); 532 WRITE_REG32(DC_TIMING_CFG, tcfg); 533 534 /* DELAY: WAIT FOR PENDING MEMORY REQUESTS 535 * This delay is used to make sure that all pending requests to the 536 * memory controller have completed before disabling the FIFO load. 537 */ 538 539 gfx_delay_milliseconds(1); 540 541 /* DISABLE DISPLAY FIFO LOAD AND DISABLE COMPRESSION */ 542 543 gcfg &= ~(unsigned long)(DC_GCFG_DFLE | DC_GCFG_CMPE | DC_GCFG_DECE); 544 WRITE_REG32(DC_GENERAL_CFG, gcfg); 545 546 /* CLEAR THE "DCLK_MUL" FIELD */ 547 548 gcfg &= ~(unsigned long)(DC_GCFG_DDCK | DC_GCFG_DPCK | DC_GCFG_DFCK); 549 gcfg &= ~(unsigned long)DC_GCFG_DCLK_MASK; 550 WRITE_REG32(DC_GENERAL_CFG, gcfg); 551 552 /* SET THE DOT CLOCK FREQUENCY */ 553 /* Mask off the divide by two bit (bit 31) */ 554 555 gfx_set_clock_frequency(pMode->frequency & 0x7FFFFFFF); 556 557 /* DELAY: WAIT FOR THE PLL TO SETTLE */ 558 /* This allows the dot clock frequency that was just set to settle. */ 559 560 gfx_delay_milliseconds(1); 561 562 /* SET THE "DCLK_MUL" FIELD OF DC_GENERAL_CFG */ 563 /* The GX hardware divides the dot clock, so 2x really means that the */ 564 /* internal dot clock equals the external dot clock. */ 565 566 if (pMode->frequency & 0x80000000) 567 gcfg |= 0x0040; 568 else 569 gcfg |= 0x0080; 570 WRITE_REG32(DC_GENERAL_CFG, gcfg); 571 572 /* DELAY: WAIT FOR THE ADL TO LOCK */ 573 /* This allows the clock generatation within GX to settle. This is */ 574 /* needed since some of the register writes that follow require that */ 575 /* clock to be present. */ 576 577 /* We do a few to ensure we're synced */ 578 gfx_delay_milliseconds(1); 579 gfx_delay_milliseconds(1); 580 gfx_delay_milliseconds(1); 581 gfx_delay_milliseconds(1); 582 gfx_delay_milliseconds(1); 583 gfx_delay_milliseconds(1); 584 585 /* SET THE GX DISPLAY CONTROLLER PARAMETERS */ 586 587 WRITE_REG32(DC_FB_ST_OFFSET, 0); 588 WRITE_REG32(DC_CB_ST_OFFSET, 0); 589 WRITE_REG32(DC_CURS_ST_OFFSET, 0); 590 591 /* SET LINE SIZE AND PITCH */ 592 /* Flat panels use the current flat panel line size to */ 593 /* calculate the pitch, but load the true line size */ 594 /* for the mode into the "Frame Buffer Line Size" field */ 595 /* of DC_BUF_SIZE. */ 596 597 if (PanelEnable) 598 size = ModeWidth; 599 else 600 size = pMode->hactive; 601 602 if (bpp > 8) 603 size <<= 1; 604 605 /* ONLY PYRAMID SUPPORTS 4K LINE SIZE */ 606 607 if (size <= 1024) { 608 pitch = 1024; 609 610 /* SPECIAL CASE */ 611 /* Graphics acceleration in 16-bit pixel line double modes */ 612 /* requires a pitch of 2048. */ 613 614 if ((pMode->flags & GFX_MODE_LINE_DOUBLE) && bpp > 8) 615 pitch <<= 1; 616 } else { 617 if (gfx_cpu_version == GFX_CPU_PYRAMID) 618 pitch = (size <= 2048) ? 2048 : 4096; 619 else 620 pitch = 2048; 621 } 622 WRITE_REG32(DC_LINE_DELTA, pitch >> 2); 623 624 if (PanelEnable) { 625 size = pMode->hactive; 626 if (bpp > 8) 627 size <<= 1; 628 } 629 630 /* SAVE PREVIOUSLY STORED VIDEO BUFFER SIZE */ 631 632 vid_buffer_size = READ_REG32(DC_BUF_SIZE) & 0x3FFF0000; 633 634 /* ADD 2 TO SIZE FOR POSSIBLE START ADDRESS ALIGNMENTS */ 635 636 WRITE_REG32(DC_BUF_SIZE, ((size >> 3) + 2) | vid_buffer_size); 637 638 /* ALWAYS ENABLE "PANEL" DATA FROM MEDIAGX */ 639 /* That is really just the 18 BPP data bus to the companion chip */ 640 641 ocfg = DC_OCFG_PCKE | DC_OCFG_PDEL | DC_OCFG_PDEH; 642 643 /* SET PIXEL FORMAT */ 644 645 if (bpp == 8) 646 ocfg |= DC_OCFG_8BPP; 647 else if (bpp == 15) 648 ocfg |= DC_OCFG_555; 649 650 /* ENABLE TIMING GENERATOR, SYNCS, AND FP DATA */ 651 652 tcfg = DC_TCFG_FPPE | DC_TCFG_HSYE | DC_TCFG_VSYE | DC_TCFG_BLKE | 653 DC_TCFG_TGEN; 654 655 /* SET FIFO PRIORITY, DCLK MULTIPLIER, AND FIFO ENABLE */ 656 /* Default 6/5 for FIFO, 2x for DCLK multiplier. */ 657 658 gcfg = (6 << DC_GCFG_DFHPEL_POS) | (5 << DC_GCFG_DFHPSL_POS) | 659 DC_GCFG_DFLE; 660 661 /* INCREASE FIFO PRIORITY FOR LARGE MODES */ 662 663 if (pMode->hactive == 1280 && pMode->vactive == 1024) { 664 if ((bpp == 8) && (pMode->flags & GFX_MODE_85HZ)) 665 gcfg = (8l << DC_GCFG_DFHPEL_POS) | (7l << DC_GCFG_DFHPSL_POS) | 666 DC_GCFG_DFLE; 667 if ((bpp > 8) && (pMode->flags & GFX_MODE_75HZ)) 668 gcfg = (7l << DC_GCFG_DFHPEL_POS) | (6l << DC_GCFG_DFHPSL_POS) | 669 DC_GCFG_DFLE; 670 if ((bpp > 8) && (pMode->flags & GFX_MODE_85HZ)) 671 gcfg = (9l << DC_GCFG_DFHPEL_POS) | (8l << DC_GCFG_DFHPSL_POS) | 672 DC_GCFG_DFLE; 673 } 674 675 /* SET DOT CLOCK MULTIPLIER */ 676 /* Bit 31 of frequency indicates divide frequency by two */ 677 678 if (pMode->frequency & 0x80000000) 679 gcfg |= (1l << DC_GCFG_DCLK_POS); 680 else 681 gcfg |= (2l << DC_GCFG_DCLK_POS); 682 683 /* DIVIDE VIDEO CLOCK */ 684 /* CPU core frequencies above 266 MHz will divide the video */ 685 /* clock by 4 to ensure that we are running below 150 MHz. */ 686 687 if (gfx_cpu_frequency > 266) 688 gcfg |= DC_GCFG_VCLK_DIV; 689 690 /* SET THE PIXEL AND LINE DOUBLE BITS IF NECESSARY */ 691 692 hactive = pMode->hactive; 693 vactive = pMode->vactive; 694 gfx_line_double = 0; 695 gfx_pixel_double = 0; 696 697 if (pMode->flags & GFX_MODE_LINE_DOUBLE) { 698 gcfg |= DC_GCFG_LDBL; 699 hactive <<= 1; 700 701 /* SET GLOBAL FLAG */ 702 703 gfx_line_double = 1; 704 } 705 706 if (pMode->flags & GFX_MODE_PIXEL_DOUBLE) { 707 tcfg |= DC_TCFG_PXDB; 708 vactive <<= 1; 709 710 /* SET GLOBAL FLAG */ 711 712 gfx_pixel_double = 1; 713 } 714 715 /* COMBINE AND SET TIMING VALUES */ 716 717 value = (unsigned long)(hactive - 1) | 718 (((unsigned long)(pMode->htotal - 1)) << 16); 719 WRITE_REG32(DC_H_TIMING_1, value); 720 value = (unsigned long)(pMode->hblankstart - 1) | 721 (((unsigned long)(pMode->hblankend - 1)) << 16); 722 WRITE_REG32(DC_H_TIMING_2, value); 723 value = (unsigned long)(pMode->hsyncstart - 1) | 724 (((unsigned long)(pMode->hsyncend - 1)) << 16); 725 WRITE_REG32(DC_H_TIMING_3, value); 726 WRITE_REG32(DC_FP_H_TIMING, value); 727 value = (unsigned long)(vactive - 1) | 728 (((unsigned long)(pMode->vtotal - 1)) << 16); 729 WRITE_REG32(DC_V_TIMING_1, value); 730 value = (unsigned long)(pMode->vblankstart - 1) | 731 (((unsigned long)(pMode->vblankend - 1)) << 16); 732 WRITE_REG32(DC_V_TIMING_2, value); 733 value = (unsigned long)(pMode->vsyncstart - 1) | 734 (((unsigned long)(pMode->vsyncend - 1)) << 16); 735 WRITE_REG32(DC_V_TIMING_3, value); 736 value = (unsigned long)(pMode->vsyncstart - 2) | 737 (((unsigned long)(pMode->vsyncend - 2)) << 16); 738 WRITE_REG32(DC_FP_V_TIMING, value); 739 740 WRITE_REG32(DC_OUTPUT_CFG, ocfg); 741 WRITE_REG32(DC_TIMING_CFG, tcfg); 742 gfx_delay_milliseconds(1); /* delay after TIMING_CFG */ 743 WRITE_REG32(DC_GENERAL_CFG, gcfg); 744 745 /* ENABLE FLAT PANEL CENTERING */ 746 /* For 640x480 modes displayed with the 9211 within a 800x600 */ 747 /* flat panel display, turn on flat panel centering. */ 748 749 if (PanelEnable) { 750 if (ModeWidth < PanelWidth) { 751 tcfg = READ_REG32(DC_TIMING_CFG); 752 tcfg = tcfg | DC_TCFG_FCEN; 753 WRITE_REG32(DC_TIMING_CFG, tcfg); 754 gfx_delay_milliseconds(1); /* delay after TIMING_CFG */ 755 } 756 } 757 758 /* CONFIGURE DISPLAY OUTPUT FROM VIDEO PROCESSOR */ 759 760 gfx_set_display_control(((pMode->flags & GFX_MODE_NEG_HSYNC) ? 1 : 0) | 761 ((pMode->flags & GFX_MODE_NEG_VSYNC) ? 2 : 0)); 762 763 /* RESTORE VALUE OF DC_UNLOCK */ 764 765 WRITE_REG32(DC_UNLOCK, unlock); 766 767 /* ALSO WRITE GP_BLIT_STATUS FOR PITCH AND 8/18 BPP */ 768 /* Remember, only Pyramid supports 4K line pitch */ 769 770 value = 0; 771 if (bpp > 8) 772 value |= BC_16BPP; 773 if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) 774 value |= BC_FB_WIDTH_4096; 775 else if (pitch > 1024) 776 value |= BC_FB_WIDTH_2048; 777 WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value); 778 779 return GFX_STATUS_OK; 780 781} /* end gfx_set_specified_mode() */ 782 783/*---------------------------------------------------------------------------- 784 * GFX_IS_DISPLAY_MODE_SUPPORTED 785 * 786 * This routine sets the specified display mode. 787 * 788 * Returns the index of the mode if successful and mode returned, -1 if the mode 789 * could not be found. 790 *---------------------------------------------------------------------------- 791 */ 792#if GFX_DISPLAY_DYNAMIC 793int 794gu1_is_display_mode_supported(int xres, int yres, int bpp, int hz) 795#else 796int 797gfx_is_display_mode_supported(int xres, int yres, int bpp, int hz) 798#endif 799{ 800 unsigned int mode = 0; 801 unsigned long hz_flag = 0, bpp_flag = 0; 802 803 /* SET FLAGS TO MATCH REFRESH RATE */ 804 805 if (hz == 56) 806 hz_flag = GFX_MODE_56HZ; 807 else if (hz == 60) 808 hz_flag = GFX_MODE_60HZ; 809 else if (hz == 70) 810 hz_flag = GFX_MODE_70HZ; 811 else if (hz == 72) 812 hz_flag = GFX_MODE_72HZ; 813 else if (hz == 75) 814 hz_flag = GFX_MODE_75HZ; 815 else if (hz == 85) 816 hz_flag = GFX_MODE_85HZ; 817 else 818 return -1; 819 820 /* SET BPP FLAGS TO LIMIT MODE SELECTION */ 821 822 if (bpp == 8) 823 bpp_flag = GFX_MODE_8BPP; 824 else if (bpp == 15) 825 bpp_flag = GFX_MODE_15BPP; 826 else if (bpp == 16) 827 bpp_flag = GFX_MODE_16BPP; 828 else 829 return -1; 830 831 /* ONLY PYRAMID SUPPORTS 4K PITCH */ 832 833 if (gfx_cpu_version != GFX_CPU_PYRAMID && xres > 1024) { 834 if (bpp > 8) 835 return (-1); /* return with mode not found */ 836 } 837 838 /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ 839 840 for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) { 841 if ((DisplayParams[mode].hactive == (unsigned short)xres) && 842 (DisplayParams[mode].vactive == (unsigned short)yres) && 843 (DisplayParams[mode].flags & hz_flag) && 844 (DisplayParams[mode].flags & bpp_flag)) { 845 846 /* SET THE DISPLAY CONTROLLER FOR THE SELECTED MODE */ 847 848 return (mode); 849 } 850 } 851 return (-1); 852} 853 854/*---------------------------------------------------------------------------- 855 * GFX_SET_DISPLAY_MODE 856 * 857 * This routine sets the specified display mode. 858 * 859 * Returns 1 if successful, 0 if mode could not be set. 860 *---------------------------------------------------------------------------- 861 */ 862#if GFX_DISPLAY_DYNAMIC 863int 864gu1_set_display_mode(int xres, int yres, int bpp, int hz) 865#else 866int 867gfx_set_display_mode(int xres, int yres, int bpp, int hz) 868#endif 869{ 870 int mode; 871 872 /* DISABLE FLAT PANEL */ 873 /* Flat Panel settings are enabled by the function gfx_set_fixed_timings */ 874 /* and disabled by gfx_set_display_mode. */ 875 876 PanelEnable = 0; 877 878 mode = gfx_is_display_mode_supported(xres, yres, bpp, hz); 879 if (mode >= 0) { 880 if (gu1_set_specified_mode(&DisplayParams[mode], bpp) == GFX_STATUS_OK) 881 return (1); 882 } 883 return (0); 884} 885 886/*---------------------------------------------------------------------------- 887 * GFX_SET_DISPLAY_TIMINGS 888 * 889 * This routine sets the display controller mode using the specified timing 890 * values (as opposed to using the tables internal to Durango). 891 * 892 * Returns GFX_STATUS_OK on success, GFX_STATUS_ERROR otherwise. 893 *---------------------------------------------------------------------------- 894 */ 895#if GFX_DISPLAY_DYNAMIC 896int 897gu1_set_display_timings(unsigned short bpp, unsigned short flags, 898 unsigned short hactive, unsigned short hblankstart, 899 unsigned short hsyncstart, unsigned short hsyncend, 900 unsigned short hblankend, unsigned short htotal, 901 unsigned short vactive, unsigned short vblankstart, 902 unsigned short vsyncstart, unsigned short vsyncend, 903 unsigned short vblankend, unsigned short vtotal, 904 unsigned long frequency) 905#else 906int 907gfx_set_display_timings(unsigned short bpp, unsigned short flags, 908 unsigned short hactive, unsigned short hblankstart, 909 unsigned short hsyncstart, unsigned short hsyncend, 910 unsigned short hblankend, unsigned short htotal, 911 unsigned short vactive, unsigned short vblankstart, 912 unsigned short vsyncstart, unsigned short vsyncend, 913 unsigned short vblankend, unsigned short vtotal, 914 unsigned long frequency) 915#endif 916{ 917 /* SET MODE STRUCTURE WITH SPECIFIED VALUES */ 918 919 gfx_display_mode.flags = 0; 920 if (flags & 1) 921 gfx_display_mode.flags |= GFX_MODE_NEG_HSYNC; 922 if (flags & 2) 923 gfx_display_mode.flags |= GFX_MODE_NEG_VSYNC; 924 if (flags & 0x1000) 925 gfx_display_mode.flags |= GFX_MODE_LOCK_TIMING; 926 gfx_display_mode.hactive = hactive; 927 gfx_display_mode.hblankstart = hblankstart; 928 gfx_display_mode.hsyncstart = hsyncstart; 929 gfx_display_mode.hsyncend = hsyncend; 930 gfx_display_mode.hblankend = hblankend; 931 gfx_display_mode.htotal = htotal; 932 gfx_display_mode.vactive = vactive; 933 gfx_display_mode.vblankstart = vblankstart; 934 gfx_display_mode.vsyncstart = vsyncstart; 935 gfx_display_mode.vsyncend = vsyncend; 936 gfx_display_mode.vblankend = vblankend; 937 gfx_display_mode.vtotal = vtotal; 938 gfx_display_mode.frequency = frequency; 939 940 /* CALL ROUTINE TO SET MODE */ 941 942 return (gu1_set_specified_mode(&gfx_display_mode, bpp)); 943} 944 945/*---------------------------------------------------------------------------- 946 * GFX_SET_VTOTAL 947 * 948 * This routine sets the display controller vertical total to 949 * "vtotal". As a side effect it also sets vertical blank end. 950 * It should be used when only this value needs to be changed, 951 * due to speed considerations. 952 * 953 * Note: it is the caller's responsibility to make sure that 954 * a legal vtotal is used, i.e. that "vtotal" is greater than or 955 * equal to vsync end. 956 * 957 * Always returns 0. 958 *---------------------------------------------------------------------------- 959 */ 960#if GFX_DISPLAY_DYNAMIC 961int 962gu1_set_vtotal(unsigned short vtotal) 963#else 964int 965gfx_set_vtotal(unsigned short vtotal) 966#endif 967{ 968 unsigned long unlock, tcfg, timing1, timing2; 969 970 /* UNLOCK THE DISPLAY CONTROLLER REGISTERS */ 971 972 unlock = READ_REG32(DC_UNLOCK); 973 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 974 975 /* READ THE CURRENT GX VALUES */ 976 977 tcfg = READ_REG32(DC_TIMING_CFG); 978 timing1 = READ_REG32(DC_V_TIMING_1); 979 timing2 = READ_REG32(DC_V_TIMING_2); 980 981 /* DISABLE THE TIMING GENERATOR */ 982 983 WRITE_REG32(DC_TIMING_CFG, tcfg & ~(unsigned long)DC_TCFG_TGEN); 984 985 /* WRITE NEW TIMING VALUES */ 986 987 WRITE_REG32(DC_V_TIMING_1, 988 (timing1 & 0xffff) | (unsigned long)(vtotal - 1) << 16); 989 WRITE_REG32(DC_V_TIMING_2, 990 (timing2 & 0xffff) | (unsigned long)(vtotal - 1) << 16); 991 992 /* RESTORE GX VALUES */ 993 994 WRITE_REG32(DC_TIMING_CFG, tcfg); 995 WRITE_REG32(DC_UNLOCK, unlock); 996 997 return (0); 998} 999 1000/*--------------------------------------------------------------------------- 1001 * gfx_set_display_pitch 1002 * 1003 * This routine sets the pitch of the frame buffer to the specified value. 1004 *--------------------------------------------------------------------------- 1005 */ 1006#if GFX_DISPLAY_DYNAMIC 1007void 1008gu1_set_display_pitch(unsigned short pitch) 1009#else 1010void 1011gfx_set_display_pitch(unsigned short pitch) 1012#endif 1013{ 1014 unsigned long value = 0; 1015 unsigned long lock = READ_REG32(DC_UNLOCK); 1016 1017 value = READ_REG32(DC_LINE_DELTA) & 0xFFFFF000; 1018 value |= (pitch >> 2); 1019 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1020 WRITE_REG32(DC_LINE_DELTA, value); 1021 WRITE_REG32(DC_UNLOCK, lock); 1022 1023 /* ALSO UPDATE PITCH IN GRAPHICS ENGINE */ 1024 /* Pyramid alone supports 4K line pitch */ 1025 1026 value = (unsigned long)READ_REG16(GP_BLIT_STATUS); 1027 value &= ~(BC_FB_WIDTH_2048 | BC_FB_WIDTH_4096); 1028 1029 if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) 1030 value |= BC_FB_WIDTH_4096; 1031 1032 else if (pitch > 1024) 1033 value |= BC_FB_WIDTH_2048; 1034 1035 WRITE_REG16(GP_BLIT_STATUS, (unsigned short)value); 1036 return; 1037} 1038 1039/*--------------------------------------------------------------------------- 1040 * gfx_set_display_offset 1041 * 1042 * This routine sets the start address of the frame buffer. It is 1043 * typically used to pan across a virtual desktop (frame buffer larger than 1044 * the displayed screen) or to flip the display between multiple buffers. 1045 *--------------------------------------------------------------------------- 1046 */ 1047#if GFX_DISPLAY_DYNAMIC 1048void 1049gu1_set_display_offset(unsigned long offset) 1050#else 1051void 1052gfx_set_display_offset(unsigned long offset) 1053#endif 1054{ 1055 /* UPDATE FRAME BUFFER OFFSET */ 1056 1057 unsigned long lock; 1058 1059 lock = READ_REG32(DC_UNLOCK); 1060 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1061 1062 /* START ADDRESS EFFECTS DISPLAY COMPRESSION */ 1063 /* Disable compression for non-zero start addresss values. */ 1064 /* Enable compression if offset is zero and comression is intended to */ 1065 /* be enabled from a previous call to "gfx_set_compression_enable". */ 1066 /* Compression should be disabled BEFORE the offset is changed */ 1067 /* and enabled AFTER the offset is changed. */ 1068 1069 if (offset == 0) { 1070 WRITE_REG32(DC_FB_ST_OFFSET, offset); 1071 if (gfx_compression_enabled) { 1072 /* WAIT FOR THE OFFSET TO BE LATCHED */ 1073 gfx_wait_vertical_blank(); 1074 gu1_enable_compression(); 1075 } 1076 } else { 1077 /* ONLY DISABLE COMPRESSION ONCE */ 1078 1079 if (gfx_compression_active) 1080 gu1_disable_compression(); 1081 1082 WRITE_REG32(DC_FB_ST_OFFSET, offset); 1083 } 1084 1085 WRITE_REG32(DC_UNLOCK, lock); 1086} 1087 1088/*--------------------------------------------------------------------------- 1089 * gfx_set_display_palette_entry 1090 * 1091 * This routine sets an palette entry in the display controller. 1092 * A 32-bit X:R:G:B value. 1093 *--------------------------------------------------------------------------- 1094 */ 1095#if GFX_DISPLAY_DYNAMIC 1096int 1097gu1_set_display_palette_entry(unsigned long index, unsigned long palette) 1098#else 1099int 1100gfx_set_display_palette_entry(unsigned long index, unsigned long palette) 1101#endif 1102{ 1103 unsigned long data; 1104 1105 if (index > 0xFF) 1106 return GFX_STATUS_BAD_PARAMETER; 1107 1108 WRITE_REG32(DC_PAL_ADDRESS, index); 1109 data = ((palette >> 2) & 0x0003F) | 1110 ((palette >> 4) & 0x00FC0) | ((palette >> 6) & 0x3F000); 1111 WRITE_REG32(DC_PAL_DATA, data); 1112 1113 return (0); 1114} 1115 1116/*--------------------------------------------------------------------------- 1117 * gfx_set_display_palette 1118 * 1119 * This routine sets the entire palette in the display controller. 1120 * A pointer is provided to a 256 entry table of 32-bit X:R:G:B values. 1121 * Restriction: 1122 * Due to SC1200 Issue #748 (in Notes DB) this function should be called only 1123 * when DCLK is active, i.e PLL is already powered up and genlock is not active. 1124 *--------------------------------------------------------------------------- 1125 */ 1126#if GFX_DISPLAY_DYNAMIC 1127int 1128gu1_set_display_palette(unsigned long *palette) 1129#else 1130int 1131gfx_set_display_palette(unsigned long *palette) 1132#endif 1133{ 1134 unsigned long data, i; 1135 1136 WRITE_REG32(DC_PAL_ADDRESS, 0); 1137 if (palette) { 1138 for (i = 0; i < 256; i++) { 1139 /* CONVERT 24 BPP COLOR DATA TO 18 BPP COLOR DATA */ 1140 1141 data = ((palette[i] >> 2) & 0x0003F) | 1142 ((palette[i] >> 4) & 0x00FC0) | ((palette[i] >> 6) & 0x3F000); 1143 WRITE_REG32(DC_PAL_DATA, data); 1144 } 1145 } 1146 return (0); 1147} 1148 1149/*--------------------------------------------------------------------------- 1150 * gfx_set_cursor_enable 1151 * 1152 * This routine enables or disables the hardware cursor. 1153 * 1154 * WARNING: The cusrsor start offset must be set by setting the cursor 1155 * position before calling this routine to assure that memory reads do not 1156 * go past the end of graphics memory (this can hang GXm). 1157 *--------------------------------------------------------------------------- 1158 */ 1159#if GFX_DISPLAY_DYNAMIC 1160void 1161gu1_set_cursor_enable(int enable) 1162#else 1163void 1164gfx_set_cursor_enable(int enable) 1165#endif 1166{ 1167 unsigned long unlock, gcfg; 1168 1169 /* SET OR CLEAR CURSOR ENABLE BIT */ 1170 1171 unlock = READ_REG32(DC_UNLOCK); 1172 gcfg = READ_REG32(DC_GENERAL_CFG); 1173 if (enable) 1174 gcfg |= DC_GCFG_CURE; 1175 else 1176 gcfg &= ~(DC_GCFG_CURE); 1177 1178 /* WRITE NEW REGISTER VALUE */ 1179 1180 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1181 WRITE_REG32(DC_GENERAL_CFG, gcfg); 1182 WRITE_REG32(DC_UNLOCK, unlock); 1183} 1184 1185/*--------------------------------------------------------------------------- 1186 * gfx_set_cursor_colors 1187 * 1188 * This routine sets the colors of the hardware cursor. 1189 * Restriction: 1190 * Due to SC1200 Issue #748 (in Notes DB) this function should be called only 1191 * when DCLK is active, i.e PLL is already powered up. 1192 *--------------------------------------------------------------------------- 1193 */ 1194#if GFX_DISPLAY_DYNAMIC 1195void 1196gu1_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) 1197#else 1198void 1199gfx_set_cursor_colors(unsigned long bkcolor, unsigned long fgcolor) 1200#endif 1201{ 1202 unsigned long value; 1203 1204 /* If genlock is enabled DCLK might be disabled in vertical blank. */ 1205 /* Due to SC1200 Issue #748 in Notes DB this would fail the cursor color settings */ 1206 /* So Wait for vertical blank to end */ 1207 1208#if GFX_VIDEO_SC1200 1209 if (gfx_test_timing_active()) 1210 while ((gfx_get_vline()) > gfx_get_vactive()) ; 1211#endif 1212 1213 /* SET CURSOR COLORS */ 1214 1215 WRITE_REG32(DC_PAL_ADDRESS, 0x100); 1216 value = ((bkcolor & 0x000000FC) >> 2) | 1217 ((bkcolor & 0x0000FC00) >> (2 + 8 - 6)) | 1218 ((bkcolor & 0x00FC0000) >> (2 + 16 - 12)); 1219 WRITE_REG32(DC_PAL_DATA, value); 1220 value = ((fgcolor & 0x000000FC) >> 2) | 1221 ((fgcolor & 0x0000FC00) >> (2 + 8 - 6)) | 1222 ((fgcolor & 0x00FC0000) >> (2 + 16 - 12)); 1223 WRITE_REG32(DC_PAL_DATA, value); 1224} 1225 1226/*--------------------------------------------------------------------------- 1227 * gfx_set_cursor_position 1228 * 1229 * This routine sets the position of the hardware cusror. The starting 1230 * offset of the cursor buffer must be specified so that the routine can 1231 * properly clip scanlines if the cursor is off the top of the screen. 1232 *--------------------------------------------------------------------------- 1233 */ 1234#if GFX_DISPLAY_DYNAMIC 1235void 1236gu1_set_cursor_position(unsigned long memoffset, 1237 unsigned short xpos, unsigned short ypos, 1238 unsigned short xhotspot, unsigned short yhotspot) 1239#else 1240void 1241gfx_set_cursor_position(unsigned long memoffset, 1242 unsigned short xpos, unsigned short ypos, 1243 unsigned short xhotspot, unsigned short yhotspot) 1244#endif 1245{ 1246 unsigned long unlock; 1247 1248 short x, y; 1249 short xoffset = 0; 1250 short yoffset = 0; 1251 1252 /* SUPPORT CURSOR IN EMULATED VGA MODES */ 1253 /* Timings are for twice the resolution */ 1254 1255 if (gfx_pixel_double) 1256 xpos <<= 1; 1257 if (gfx_line_double) 1258 ypos <<= 1; 1259 1260 x = (short)xpos - (short)xhotspot; 1261 y = (short)ypos - (short)yhotspot; 1262 if (x < -31) 1263 return; 1264 if (y < -31) 1265 return; 1266 if (x < 0) { 1267 xoffset = -x; 1268 x = 0; 1269 } 1270 if (y < 0) { 1271 yoffset = -y; 1272 y = 0; 1273 } 1274 memoffset += (unsigned long)yoffset << 3; 1275 1276 if (PanelEnable) { 1277 if ((ModeWidth > PanelWidth) || (ModeHeight > PanelHeight)) { 1278 gfx_enable_panning(xpos, ypos); 1279 x = x - (short)panelLeft; 1280 y = y - (short)panelTop; 1281 } 1282 } 1283 1284 /* SET CURSOR POSITION */ 1285 1286 unlock = READ_REG32(DC_UNLOCK); 1287 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1288 WRITE_REG32(DC_CURS_ST_OFFSET, memoffset); 1289 WRITE_REG32(DC_CURSOR_X, (unsigned long)x | 1290 (((unsigned long)xoffset) << 11)); 1291 WRITE_REG32(DC_CURSOR_Y, (unsigned long)y | 1292 (((unsigned long)yoffset) << 11)); 1293 WRITE_REG32(DC_UNLOCK, unlock); 1294} 1295 1296/*--------------------------------------------------------------------------- 1297 * gfx_set_cursor_shape32 1298 * 1299 * This routine loads 32x32 cursor data into the specified location in 1300 * graphics memory. 1301 *--------------------------------------------------------------------------- 1302 */ 1303#if GFX_DISPLAY_DYNAMIC 1304void 1305gu1_set_cursor_shape32(unsigned long memoffset, 1306 unsigned long *andmask, unsigned long *xormask) 1307#else 1308void 1309gfx_set_cursor_shape32(unsigned long memoffset, 1310 unsigned long *andmask, unsigned long *xormask) 1311#endif 1312{ 1313 int i; 1314 unsigned long value; 1315 1316 for (i = 0; i < 32; i++) { 1317 /* CONVERT TO 16 BITS AND MASK, 16 BITS XOR MASK PER DWORD */ 1318 1319 value = (andmask[i] & 0xFFFF0000) | (xormask[i] >> 16); 1320 WRITE_FB32(memoffset, value); 1321 memoffset += 4; 1322 value = (andmask[i] << 16) | (xormask[i] & 0x0000FFFF); 1323 WRITE_FB32(memoffset, value); 1324 memoffset += 4; 1325 } 1326} 1327 1328/*--------------------------------------------------------------------------- 1329 * gu1_enable_compression 1330 * 1331 * This is a private routine to this module (not exposed in the Durango API). 1332 * It enables display compression. 1333 *--------------------------------------------------------------------------- 1334 */ 1335void 1336gu1_enable_compression(void) 1337{ 1338 int i; 1339 unsigned long unlock, gcfg, offset; 1340 1341 /* DO NOT ENABLE IF START ADDRESS IS NOT ZERO */ 1342 1343 offset = READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF; 1344 if (offset != 0) 1345 return; 1346 1347 /* DO NOT ENABLE IF WE ARE WITHIN AN EMULATED VGA MODE */ 1348 1349 if (gfx_line_double || gfx_pixel_double) 1350 return; 1351 1352 /* SET GLOBAL INDICATOR */ 1353 1354 gfx_compression_active = 1; 1355 1356 /* CLEAR DIRTY/VALID BITS IN MEMORY CONTROLLER */ 1357 /* Software is required to do this before enabling compression. */ 1358 /* Don't want controller to think that old lines are still valid. */ 1359 1360 for (i = 0; i < 1024; i++) { 1361 WRITE_REG32(MC_DR_ADD, i); 1362 WRITE_REG32(MC_DR_ACC, 0); 1363 } 1364 1365 /* TURN ON COMPRESSION CONTROL BITS */ 1366 1367 unlock = READ_REG32(DC_UNLOCK); 1368 gcfg = READ_REG32(DC_GENERAL_CFG); 1369 gcfg |= DC_GCFG_CMPE | DC_GCFG_DECE; 1370 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1371 WRITE_REG32(DC_GENERAL_CFG, gcfg); 1372 WRITE_REG32(DC_UNLOCK, unlock); 1373} 1374 1375/*--------------------------------------------------------------------------- 1376 * gu1_disable_compression 1377 * 1378 * This is a private routine to this module (not exposed in the Durango API). 1379 * It disables display compression. 1380 *--------------------------------------------------------------------------- 1381 */ 1382void 1383gu1_disable_compression(void) 1384{ 1385 unsigned long unlock, gcfg; 1386 1387 /* SET GLOBAL INDICATOR */ 1388 1389 gfx_compression_active = 0; 1390 1391 /* TURN OFF COMPRESSION CONTROL BITS */ 1392 1393 unlock = READ_REG32(DC_UNLOCK); 1394 gcfg = READ_REG32(DC_GENERAL_CFG); 1395 gcfg &= ~(DC_GCFG_CMPE | DC_GCFG_DECE); 1396 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1397 WRITE_REG32(DC_GENERAL_CFG, gcfg); 1398 WRITE_REG32(DC_UNLOCK, unlock); 1399} 1400 1401/*--------------------------------------------------------------------------- 1402 * gfx_set_compression_enable 1403 * 1404 * This routine enables or disables display compression. 1405 *--------------------------------------------------------------------------- 1406 */ 1407#if GFX_DISPLAY_DYNAMIC 1408int 1409gu1_set_compression_enable(int enable) 1410#else 1411int 1412gfx_set_compression_enable(int enable) 1413#endif 1414{ 1415 /* SET GLOBAL VARIABLE FOR INTENDED STATE */ 1416 /* Compression can only be enabled for non-zero start address values. */ 1417 /* Keep state to enable compression on start address changes. */ 1418 1419 gfx_compression_enabled = enable; 1420 if (enable) 1421 gu1_enable_compression(); 1422 else 1423 gu1_disable_compression(); 1424 return (0); 1425} 1426 1427/*--------------------------------------------------------------------------- 1428 * gfx_set_compression_offset 1429 * 1430 * This routine sets the base offset for the compression buffer. 1431 *--------------------------------------------------------------------------- 1432 */ 1433#if GFX_DISPLAY_DYNAMIC 1434int 1435gu1_set_compression_offset(unsigned long offset) 1436#else 1437int 1438gfx_set_compression_offset(unsigned long offset) 1439#endif 1440{ 1441 unsigned long lock; 1442 1443 /* MUST BE 16-BYTE ALIGNED FOR GXLV */ 1444 1445 if (offset & 0x0F) 1446 return (1); 1447 1448 /* SET REGISTER VALUE */ 1449 1450 lock = READ_REG32(DC_UNLOCK); 1451 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1452 WRITE_REG32(DC_CB_ST_OFFSET, offset); 1453 WRITE_REG32(DC_UNLOCK, lock); 1454 return (0); 1455} 1456 1457/*--------------------------------------------------------------------------- 1458 * gfx_set_compression_pitch 1459 * 1460 * This routine sets the pitch, in bytes, of the compression buffer. 1461 *--------------------------------------------------------------------------- 1462 */ 1463#if GFX_DISPLAY_DYNAMIC 1464int 1465gu1_set_compression_pitch(unsigned short pitch) 1466#else 1467int 1468gfx_set_compression_pitch(unsigned short pitch) 1469#endif 1470{ 1471 unsigned long lock, line_delta; 1472 1473 /* SET REGISTER VALUE */ 1474 1475 lock = READ_REG32(DC_UNLOCK); 1476 line_delta = READ_REG32(DC_LINE_DELTA) & 0xFF800FFF; 1477 line_delta |= ((unsigned long)pitch << 10l) & 0x007FF000; 1478 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1479 WRITE_REG32(DC_LINE_DELTA, line_delta); 1480 WRITE_REG32(DC_UNLOCK, lock); 1481 return (0); 1482} 1483 1484/*--------------------------------------------------------------------------- 1485 * gfx_set_compression_size 1486 * 1487 * This routine sets the line size of the compression buffer, which is the 1488 * maximum number of bytes allowed to store a compressed line. 1489 *--------------------------------------------------------------------------- 1490 */ 1491#if GFX_DISPLAY_DYNAMIC 1492int 1493gu1_set_compression_size(unsigned short size) 1494#else 1495int 1496gfx_set_compression_size(unsigned short size) 1497#endif 1498{ 1499 unsigned long lock, buf_size; 1500 1501 /* SUBTRACT 16 FROM SIZE */ 1502 /* The display controller will actually write */ 1503 /* 2 extra QWords. So, if we assume that "size" */ 1504 /* refers to the allocated size, we must subtract */ 1505 /* 16 bytes. */ 1506 1507 size -= 16; 1508 1509 /* SET REGISTER VALUE */ 1510 1511 lock = READ_REG32(DC_UNLOCK); 1512 buf_size = READ_REG32(DC_BUF_SIZE) & 0xFFFF01FF; 1513 buf_size |= (((size >> 2) + 1) & 0x7F) << 9; 1514 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1515 WRITE_REG32(DC_BUF_SIZE, buf_size); 1516 WRITE_REG32(DC_UNLOCK, lock); 1517 return (0); 1518} 1519 1520/*--------------------------------------------------------------------------- 1521 * gfx_set_display_video_enable (PRIVATE ROUTINE - NOT PART OF API) 1522 * 1523 * This routine enables/disables video on GX. 1524 *--------------------------------------------------------------------------- 1525 */ 1526#if GFX_DISPLAY_DYNAMIC 1527void 1528gu1_set_display_video_enable(int enable) 1529#else 1530void 1531gfx_set_display_video_enable(int enable) 1532#endif 1533{ 1534 unsigned long lock, gcfg, buf_size; 1535 1536 lock = READ_REG32(DC_UNLOCK); 1537 gcfg = READ_REG32(DC_GENERAL_CFG); 1538 buf_size = READ_REG32(DC_BUF_SIZE); 1539 1540 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1541 1542 vid_enabled = enable; 1543 1544 /* SET THE BUFFER SIZE TO A NON-ZERO VALUE ONLY WHEN */ 1545 /* ENABLING VIDEO */ 1546 1547 if (enable) { 1548 gcfg |= (DC_GCFG_VIDE | DC_GCFG_VRDY); 1549 WRITE_REG32(DC_GENERAL_CFG, gcfg); 1550 1551 WRITE_REG32(DC_BUF_SIZE, (buf_size & 0x0000FFFFl) | vid_buf_size); 1552 } 1553 1554 /* CLEAR THE VIDEO BUFFER SIZE WHEN DISABLING VIDEO */ 1555 1556 else { 1557 gcfg &= ~(DC_GCFG_VIDE); 1558 WRITE_REG32(DC_GENERAL_CFG, gcfg); 1559 1560 vid_buf_size = buf_size & 0xFFFF0000l; 1561 WRITE_REG32(DC_BUF_SIZE, buf_size & 0x0000FFFFl); 1562 } 1563 1564 WRITE_REG32(DC_UNLOCK, lock); 1565 return; 1566} 1567 1568/*--------------------------------------------------------------------------- 1569 * gfx_set_display_video_size (PRIVATE ROUTINE - NOT PART OF API) 1570 * 1571 * This routine is called by "gfx_set_video_size". It abstracts the 1572 * version of the display controller from the video overlay routines. 1573 *--------------------------------------------------------------------------- 1574 */ 1575#if GFX_DISPLAY_DYNAMIC 1576void 1577gu1_set_display_video_size(unsigned short width, unsigned short height) 1578#else 1579void 1580gfx_set_display_video_size(unsigned short width, unsigned short height) 1581#endif 1582{ 1583 unsigned long lock, size, value; 1584 1585 size = (unsigned long)(width << 1) * (unsigned long)height; 1586 1587 /* STORE THE VIDEO BUFFER SIZE AS A GLOBAL */ 1588 1589 vid_buf_size = ((size + 63) >> 6) << 16; 1590 1591 /* DO NOT SET THE VIDEO SIZE IF VIDEO IS DISABLED */ 1592 1593 if (!vid_enabled) 1594 return; 1595 1596 lock = READ_REG32(DC_UNLOCK); 1597 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1598 value = READ_REG32(DC_BUF_SIZE) & 0x0000FFFF; 1599 value |= vid_buf_size; 1600 WRITE_REG32(DC_BUF_SIZE, value); 1601 WRITE_REG32(DC_UNLOCK, lock); 1602} 1603 1604/*--------------------------------------------------------------------------- 1605 * gfx_set_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) 1606 * 1607 * This routine is called by "gfx_set_video_offset". It abstracts the 1608 * version of the display controller from the video overlay routines. 1609 *--------------------------------------------------------------------------- 1610 */ 1611#if GFX_DISPLAY_DYNAMIC 1612void 1613gu1_set_display_video_offset(unsigned long offset) 1614#else 1615void 1616gfx_set_display_video_offset(unsigned long offset) 1617#endif 1618{ 1619 unsigned long lock; 1620 1621 lock = READ_REG32(DC_UNLOCK); 1622 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1623 offset &= 0x003FFFFF; 1624 WRITE_REG32(DC_VID_ST_OFFSET, offset); 1625 WRITE_REG32(DC_UNLOCK, lock); 1626} 1627 1628/*--------------------------------------------------------------------------- 1629 * gfx_set_display_priority_high 1630 * 1631 * This routine controls the x-bus round robin arbitration mechanism. 1632 * When enable is TRUE, graphics pipeline requests and non-critical display 1633 * controller requests are arbitrated at the same priority as processor 1634 * requests. When FALSE processor requests are arbitrated at a higher priority. 1635 *--------------------------------------------------------------------------- 1636 */ 1637#if GFX_DISPLAY_DYNAMIC 1638void 1639gu1_set_display_priority_high(int enable) 1640#else 1641void 1642gfx_set_display_priority_high(int enable) 1643#endif 1644{ 1645 unsigned long lock, control; 1646 1647 lock = READ_REG32(DC_UNLOCK); 1648 control = READ_REG32(MC_MEM_CNTRL1); 1649 WRITE_REG32(DC_UNLOCK, DC_UNLOCK_VALUE); 1650 if (enable) 1651 control |= MC_XBUSARB; 1652 else 1653 control &= ~(MC_XBUSARB); 1654 WRITE_REG32(MC_MEM_CNTRL1, control); 1655 WRITE_REG32(DC_UNLOCK, lock); 1656 return; 1657} 1658 1659/*--------------------------------------------------------------------------- 1660 * gfx_test_timing_active 1661 *--------------------------------------------------------------------------- 1662 */ 1663#if GFX_DISPLAY_DYNAMIC 1664int 1665gu1_test_timing_active(void) 1666#else 1667int 1668gfx_test_timing_active(void) 1669#endif 1670{ 1671 if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_TGEN) 1672 return (1); 1673 else 1674 return (0); 1675} 1676 1677/*--------------------------------------------------------------------------- 1678 * gfx_test_vertical_active 1679 *--------------------------------------------------------------------------- 1680 */ 1681#if GFX_DISPLAY_DYNAMIC 1682int 1683gu1_test_vertical_active(void) 1684#else 1685int 1686gfx_test_vertical_active(void) 1687#endif 1688{ 1689 if (READ_REG32(DC_TIMING_CFG) & DC_TCFG_VNA) 1690 return (0); 1691 else 1692 return (1); 1693} 1694 1695/*--------------------------------------------------------------------------- 1696 * gfx_wait_vertical_blank 1697 *--------------------------------------------------------------------------- 1698 */ 1699#if GFX_DISPLAY_DYNAMIC 1700int 1701gu1_wait_vertical_blank(void) 1702#else 1703int 1704gfx_wait_vertical_blank(void) 1705#endif 1706{ 1707 if (gfx_test_timing_active()) { 1708 while (!gfx_test_vertical_active()) ; 1709 while (gfx_test_vertical_active()) ; 1710 } 1711 return (0); 1712} 1713 1714/*--------------------------------------------------------------------------- 1715 * gfx_enable_panning 1716 * 1717 * This routine enables the panning when the Mode is bigger than the panel 1718 * size. 1719 *--------------------------------------------------------------------------- 1720 */ 1721#if GFX_DISPLAY_DYNAMIC 1722void 1723gu1_enable_panning(int x, int y) 1724#else 1725void 1726gfx_enable_panning(int x, int y) 1727#endif 1728{ 1729 unsigned long modeBytesPerPixel; 1730 unsigned long modeBytesPerScanline = 0; 1731 unsigned long startAddress = 0; 1732 1733 modeBytesPerPixel = (gbpp + 7) / 8; 1734 modeBytesPerScanline = 1735 (((ModeWidth + 1023) / 1024) * 1024) * modeBytesPerPixel; 1736 1737 /* TEST FOR NO-WORK */ 1738 1739 if (x >= DeltaX && (unsigned short)x < (PanelWidth + DeltaX) && 1740 y >= DeltaY && (unsigned short)y < (PanelHeight + DeltaY)) 1741 return; 1742 1743 /* ADJUST PANNING VARIABLES WHEN CURSOR EXCEEDS BOUNDARY */ 1744 /* Test the boundary conditions for each coordinate and update */ 1745 /* all variables and the starting offset accordingly. */ 1746 1747 if (x < DeltaX) 1748 DeltaX = x; 1749 1750 else if ((unsigned short)x >= (DeltaX + PanelWidth)) 1751 DeltaX = x - PanelWidth + 1; 1752 1753 if (y < DeltaY) 1754 DeltaY = y; 1755 1756 else if ((unsigned short)y >= (DeltaY + PanelHeight)) 1757 DeltaY = y - PanelHeight + 1; 1758 1759 /* CALCULATE THE START OFFSET */ 1760 1761 startAddress = 1762 (DeltaX * modeBytesPerPixel) + (DeltaY * modeBytesPerScanline); 1763 1764 gfx_set_display_offset(startAddress); 1765 1766 /* SET PANEL COORDINATES */ 1767 /* Panel's x position must be DWORD aligned */ 1768 1769 panelTop = DeltaY; 1770 panelLeft = DeltaX * modeBytesPerPixel; 1771 1772 if (panelLeft & 3) 1773 panelLeft = (panelLeft & 0xFFFFFFFC) + 4; 1774 1775 panelLeft /= modeBytesPerPixel; 1776 1777} 1778 1779/*--------------------------------------------------------------------------- 1780 * gfx_set_fixed_timings 1781 *--------------------------------------------------------------------------- 1782 */ 1783#if GFX_DISPLAY_DYNAMIC 1784int 1785gu1_set_fixed_timings(int panelResX, int panelResY, unsigned short width, 1786 unsigned short height, unsigned short bpp) 1787#else 1788int 1789gfx_set_fixed_timings(int panelResX, int panelResY, unsigned short width, 1790 unsigned short height, unsigned short bpp) 1791#endif 1792{ 1793 unsigned int mode; 1794 1795 ModeWidth = width; 1796 ModeHeight = height; 1797 PanelWidth = (unsigned short)panelResX; 1798 PanelHeight = (unsigned short)panelResY; 1799 PanelEnable = 1; 1800 1801 /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ 1802 for (mode = 0; mode < NUM_FIXED_TIMINGS_MODES; mode++) { 1803 if ((FixedParams[mode].xres == width) && 1804 (FixedParams[mode].yres == height) && 1805 (FixedParams[mode].panelresx == panelResX) && 1806 (FixedParams[mode].panelresy == panelResY)) { 1807 1808 /* SET THE 92xx FOR THE SELECTED MODE */ 1809 FIXEDTIMINGS *fmode = &FixedParams[mode]; 1810 1811 gfx_set_display_timings(bpp, 3, fmode->hactive, fmode->hblankstart, 1812 fmode->hsyncstart, fmode->hsyncend, 1813 fmode->hblankend, fmode->htotal, 1814 fmode->vactive, fmode->vblankstart, 1815 fmode->vsyncstart, fmode->vsyncend, 1816 fmode->vblankend, fmode->vtotal, 1817 fmode->frequency); 1818 1819 return (1); 1820 } /* end if() */ 1821 } /* end for() */ 1822 1823 return (-1); 1824} 1825 1826/*--------------------------------------------------------------------------- 1827 * gfx_set_panel_present 1828 *--------------------------------------------------------------------------- 1829 */ 1830#if GFX_DISPLAY_DYNAMIC 1831int 1832gu1_set_panel_present(int panelResX, int panelResY, unsigned short width, 1833 unsigned short height, unsigned short bpp) 1834#else 1835int 1836gfx_set_panel_present(int panelResX, int panelResY, unsigned short width, 1837 unsigned short height, unsigned short bpp) 1838#endif 1839{ 1840 /* SET VALID BPP */ 1841 /* 16BPP is the default. */ 1842 1843 if (bpp != 8 && bpp != 15 && bpp != 16) 1844 bpp = 16; 1845 1846 /* RECORD PANEL PARAMETERS */ 1847 /* This routine does not touch any panel timings. It is used when custom panel */ 1848 /* settings are set up in advance by the BIOS or an application, but the */ 1849 /* application still requires access to other panel functionality provided by */ 1850 /* Durango (i.e. panning). */ 1851 1852 ModeWidth = width; 1853 ModeHeight = height; 1854 PanelWidth = (unsigned short)panelResX; 1855 PanelHeight = (unsigned short)panelResY; 1856 PanelEnable = 1; 1857 gbpp = bpp; 1858 1859 /* PROGRAM THE BPP IN THE DISPLAY CONTROLLER */ 1860 1861 gfx_set_display_bpp(bpp); 1862 1863 return (GFX_STATUS_OK); 1864} 1865 1866/*-----------------------------------------------------------------------* 1867 * THE FOLLOWING READ ROUTINES ARE ALWAYS INCLUDED: * 1868 * gfx_get_hsync_end, gfx_get_htotal, gfx_get_vsync_end, gfx_get_vtotal * 1869 * are used by the video overlay routines. * 1870 * * 1871 * gfx_get_vline and gfx_vactive are used to prevent an issue for the * 1872 * SC1200. * 1873 * * 1874 * The others are part of the Durango API. * 1875 *-----------------------------------------------------------------------*/ 1876 1877/*--------------------------------------------------------------------------- 1878 * gfx_get_display_pitch 1879 * 1880 * This routine returns the current pitch of the frame buffer, in bytes. 1881 *--------------------------------------------------------------------------- 1882 */ 1883#if GFX_DISPLAY_DYNAMIC 1884unsigned short 1885gu1_get_display_pitch(void) 1886#else 1887unsigned short 1888gfx_get_display_pitch(void) 1889#endif 1890{ 1891 unsigned long value; 1892 1893 if (gfx_cpu_version == GFX_CPU_PYRAMID) { /* Pyramid update for 4KB line pitch */ 1894 value = (READ_REG32(DC_LINE_DELTA) & 0x07FF) << 2; 1895 } else { 1896 value = (READ_REG32(DC_LINE_DELTA) & 0x03FF) << 2; 1897 } 1898 1899 return ((unsigned short)value); 1900} 1901 1902/*---------------------------------------------------------------------------- 1903 * GFX_GET_DISPLAY_DETAILS 1904 * 1905 * This routine gets the specified display mode. 1906 * 1907 * Returns 1 if successful, 0 if mode could not be get. 1908 *---------------------------------------------------------------------------- 1909 */ 1910#if GFX_DISPLAY_DYNAMIC 1911int 1912gu1_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) 1913#else 1914int 1915gfx_get_display_details(unsigned int mode, int *xres, int *yres, int *hz) 1916#endif 1917{ 1918 if (mode < NUM_GX_DISPLAY_MODES) { 1919 if (DisplayParams[mode].flags & GFX_MODE_56HZ) 1920 *hz = 56; 1921 else if (DisplayParams[mode].flags & GFX_MODE_60HZ) 1922 *hz = 60; 1923 else if (DisplayParams[mode].flags & GFX_MODE_70HZ) 1924 *hz = 70; 1925 else if (DisplayParams[mode].flags & GFX_MODE_72HZ) 1926 *hz = 72; 1927 else if (DisplayParams[mode].flags & GFX_MODE_75HZ) 1928 *hz = 75; 1929 else if (DisplayParams[mode].flags & GFX_MODE_85HZ) 1930 *hz = 85; 1931 1932 *xres = DisplayParams[mode].hactive; 1933 *yres = DisplayParams[mode].vactive; 1934 1935 return (1); 1936 } 1937 return (0); 1938} 1939 1940/*---------------------------------------------------------------------------- 1941 * GFX_GET_DISPLAY_MODE_COUNT 1942 * 1943 * Returns number of modes supported. 1944 *---------------------------------------------------------------------------- 1945 */ 1946#if GFX_DISPLAY_DYNAMIC 1947int 1948gu1_get_display_mode_count(void) 1949#else 1950int 1951gfx_get_display_mode_count(void) 1952#endif 1953{ 1954 return (NUM_GX_DISPLAY_MODES); 1955} 1956 1957/*---------------------------------------------------------------------------- 1958 * gfx_get_frame_buffer_line_size 1959 * 1960 * Returns the current frame buffer line size, in bytes 1961 *---------------------------------------------------------------------------- 1962 */ 1963#if GFX_DISPLAY_DYNAMIC 1964unsigned long 1965gu1_get_frame_buffer_line_size(void) 1966#else 1967unsigned long 1968gfx_get_frame_buffer_line_size(void) 1969#endif 1970{ 1971 return ((READ_REG32(DC_BUF_SIZE) & 0x1FF) << 3); 1972} 1973 1974/*---------------------------------------------------------------------------- 1975 * gfx_mode_frequency_supported 1976 * 1977 * This routine examines if the requested mode with pixel frequency is supported. 1978 * 1979 * Returns >0 if successful , <0 if freq. could not be found and matched. 1980 *---------------------------------------------------------------------------- 1981 */ 1982#if GFX_DISPLAY_DYNAMIC 1983int 1984gu1_mode_frequency_supported(int xres, int yres, int bpp, 1985 unsigned long frequency) 1986#else 1987int 1988gfx_mode_frequency_supported(int xres, int yres, int bpp, 1989 unsigned long frequency) 1990#endif 1991{ 1992 unsigned int index; 1993 unsigned long value; 1994 unsigned long bpp_flag = 0; 1995 1996 bpp_flag = GFX_MODE_8BPP; 1997 if (bpp > 8) 1998 bpp_flag = GFX_MODE_16BPP; 1999 2000 for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 2001 if ((DisplayParams[index].hactive == (unsigned short)xres) && 2002 (DisplayParams[index].vactive == (unsigned short)yres) && 2003 (DisplayParams[index].flags & bpp_flag) && 2004 (DisplayParams[index].frequency == frequency)) { 2005 int hz = 0; 2006 2007 value = DisplayParams[index].flags; 2008 2009 if (value & GFX_MODE_60HZ) 2010 hz = 60; 2011 else if (value & GFX_MODE_70HZ) 2012 hz = 70; 2013 else if (value & GFX_MODE_72HZ) 2014 hz = 72; 2015 else if (value & GFX_MODE_75HZ) 2016 hz = 75; 2017 else if (value & GFX_MODE_85HZ) 2018 hz = 85; 2019 return (hz); 2020 } 2021 } 2022 return (-1); 2023} 2024 2025/*---------------------------------------------------------------------------- 2026 * gfx_refreshrate_from_frequency 2027 * 2028 * This routine maps the frequency to close match refresh rate 2029 * 2030 * Returns . 2031 *---------------------------------------------------------------------------- 2032 */ 2033#if GFX_DISPLAY_DYNAMIC 2034int 2035gu1_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, 2036 unsigned long frequency) 2037#else 2038int 2039gfx_get_refreshrate_from_frequency(int xres, int yres, int bpp, int *hz, 2040 unsigned long frequency) 2041#endif 2042{ 2043 unsigned int index, closematch = 0; 2044 unsigned long value; 2045 unsigned long bpp_flag = 0; 2046 long min, diff; 2047 2048 *hz = 60; 2049 2050 bpp_flag = GFX_MODE_8BPP; 2051 if (bpp > 8) 2052 bpp_flag = GFX_MODE_16BPP; 2053 2054 /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 2055 /* Search the table for the closest frequency (16.16 format). */ 2056 2057 min = 0x7fffffff; 2058 for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 2059 if ((DisplayParams[index].htotal == (unsigned short)xres) && 2060 (DisplayParams[index].vtotal == (unsigned short)yres) && 2061 (DisplayParams[index].flags & bpp_flag)) { 2062 diff = (long)frequency - (long)DisplayParams[index].frequency; 2063 if (diff < 0) 2064 diff = -diff; 2065 2066 if (diff < min) { 2067 min = diff; 2068 closematch = index; 2069 } 2070 } 2071 } 2072 2073 value = DisplayParams[closematch].flags; 2074 2075 if (value & GFX_MODE_60HZ) 2076 *hz = 60; 2077 else if (value & GFX_MODE_70HZ) 2078 *hz = 70; 2079 else if (value & GFX_MODE_72HZ) 2080 *hz = 72; 2081 else if (value & GFX_MODE_75HZ) 2082 *hz = 75; 2083 else if (value & GFX_MODE_85HZ) 2084 *hz = 85; 2085 2086 return (1); 2087} 2088 2089/*---------------------------------------------------------------------------- 2090 * gfx_refreshrate_from_mode 2091 * 2092 * This routine is identical to the gfx_get_refreshrate_from_frequency, 2093 * except that the active timing values are compared instead of the total 2094 * values. Some modes (such as 70Hz and 72Hz) may be confused in this routine. 2095 * 2096 * Returns . 2097 *---------------------------------------------------------------------------- 2098 */ 2099#if GFX_DISPLAY_DYNAMIC 2100int 2101gu1_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, 2102 unsigned long frequency) 2103#else 2104int 2105gfx_get_refreshrate_from_mode(int xres, int yres, int bpp, int *hz, 2106 unsigned long frequency) 2107#endif 2108{ 2109 unsigned int index, closematch = 0; 2110 unsigned long value; 2111 unsigned long bpp_flag = 0; 2112 long min, diff; 2113 2114 *hz = 60; 2115 2116 bpp_flag = GFX_MODE_8BPP; 2117 if (bpp > 8) 2118 bpp_flag = GFX_MODE_16BPP; 2119 2120 /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 2121 /* Search the table for the closest frequency (16.16 format). */ 2122 2123 min = 0x7fffffff; 2124 for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 2125 if ((DisplayParams[index].hactive == (unsigned short)xres) && 2126 (DisplayParams[index].vactive == (unsigned short)yres) && 2127 (DisplayParams[index].flags & bpp_flag)) { 2128 diff = (long)frequency - (long)DisplayParams[index].frequency; 2129 if (diff < 0) 2130 diff = -diff; 2131 2132 if (diff < min) { 2133 min = diff; 2134 closematch = index; 2135 } 2136 } 2137 } 2138 2139 value = DisplayParams[closematch].flags; 2140 2141 if (value & GFX_MODE_60HZ) 2142 *hz = 60; 2143 else if (value & GFX_MODE_70HZ) 2144 *hz = 70; 2145 else if (value & GFX_MODE_72HZ) 2146 *hz = 72; 2147 else if (value & GFX_MODE_75HZ) 2148 *hz = 75; 2149 else if (value & GFX_MODE_85HZ) 2150 *hz = 85; 2151 2152 return (1); 2153} 2154 2155/*---------------------------------------------------------------------------- 2156 * gfx_get_frequency_from_refreshrate 2157 * 2158 * This routine maps the refresh rate to the closest matching PLL frequency. 2159 *---------------------------------------------------------------------------- 2160 */ 2161#if GFX_DISPLAY_DYNAMIC 2162int 2163gu1_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, 2164 int *frequency) 2165#else 2166int 2167gfx_get_frequency_from_refreshrate(int xres, int yres, int bpp, int hz, 2168 int *frequency) 2169#endif 2170{ 2171 int retval = -1; 2172 unsigned long hz_flag = 0; 2173 unsigned long index, bpp_flag = 0; 2174 2175 *frequency = 0; 2176 2177 if (hz == 60) 2178 hz_flag = GFX_MODE_60HZ; 2179 else if (hz == 70) 2180 hz_flag = GFX_MODE_70HZ; 2181 else if (hz == 72) 2182 hz_flag = GFX_MODE_72HZ; 2183 else if (hz == 75) 2184 hz_flag = GFX_MODE_75HZ; 2185 else if (hz == 85) 2186 hz_flag = GFX_MODE_85HZ; 2187 2188 bpp_flag = GFX_MODE_8BPP; 2189 if (bpp > 8) 2190 bpp_flag = GFX_MODE_16BPP; 2191 2192 /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */ 2193 2194 for (index = 0; index < NUM_GX_DISPLAY_MODES; index++) { 2195 if ((DisplayParams[index].hactive == (unsigned short)xres) && 2196 (DisplayParams[index].vactive == (unsigned short)yres) && 2197 (DisplayParams[index].flags & bpp_flag) && 2198 (DisplayParams[index].flags & hz_flag)) { 2199 *frequency = DisplayParams[index].frequency; 2200 retval = 1; 2201 } 2202 } 2203 return retval; 2204} 2205 2206/*--------------------------------------------------------------------------- 2207 * gfx_get_max_supported_pixel_clock 2208 * 2209 * This routine returns the maximum recommended speed for the pixel clock. The 2210 * return value is an integer of the format xxxyyy, where xxx.yyy is the maximum 2211 * floating point pixel clock speed. 2212 *--------------------------------------------------------------------------- 2213 */ 2214#if GFX_DISPLAY_DYNAMIC 2215unsigned long 2216gu1_get_max_supported_pixel_clock(void) 2217#else 2218unsigned long 2219gfx_get_max_supported_pixel_clock(void) 2220#endif 2221{ 2222 /* ALL CHIPS CAN HANDLE 1280X1024@85HZ - 157.5 MHz */ 2223 2224 return 157500; 2225} 2226 2227/*---------------------------------------------------------------------------- 2228 * gfx_get_display_mode 2229 * 2230 * This routine gets the specified display mode. 2231 * 2232 * Returns >0 if successful and mode returned, <0 if mode could not be found. 2233 *---------------------------------------------------------------------------- 2234 */ 2235#if GFX_DISPLAY_DYNAMIC 2236int 2237gu1_get_display_mode(int *xres, int *yres, int *bpp, int *hz) 2238#else 2239int 2240gfx_get_display_mode(int *xres, int *yres, int *bpp, int *hz) 2241#endif 2242{ 2243 unsigned int mode = 0; 2244 unsigned long pll_freq = 0, bpp_flag = 0; 2245 2246 *xres = gfx_get_hactive(); 2247 *yres = gfx_get_vactive(); 2248 *bpp = gfx_get_display_bpp(); 2249 pll_freq = gfx_get_clock_frequency(); 2250 2251 /* SUPPORT EMULATED VGA MODES */ 2252 2253 if (gfx_pixel_double) 2254 *xres >>= 1; 2255 2256 if (gfx_line_double) 2257 *yres >>= 1; 2258 2259 /* SET BPP FLAGS TO LIMIT MODE SELECTION */ 2260 2261 bpp_flag = GFX_MODE_8BPP; 2262 if (*bpp > 8) 2263 bpp_flag = GFX_MODE_16BPP; 2264 2265 for (mode = 0; mode < NUM_GX_DISPLAY_MODES; mode++) { 2266 if ((DisplayParams[mode].hactive == (unsigned short)*xres) && 2267 (DisplayParams[mode].vactive == (unsigned short)*yres) && 2268 (DisplayParams[mode].frequency == pll_freq) && 2269 (DisplayParams[mode].flags & bpp_flag)) { 2270 2271 pll_freq = DisplayParams[mode].flags; 2272 2273 if (pll_freq & GFX_MODE_56HZ) 2274 *hz = 56; 2275 else if (pll_freq & GFX_MODE_60HZ) 2276 *hz = 60; 2277 else if (pll_freq & GFX_MODE_70HZ) 2278 *hz = 70; 2279 else if (pll_freq & GFX_MODE_72HZ) 2280 *hz = 72; 2281 else if (pll_freq & GFX_MODE_75HZ) 2282 *hz = 75; 2283 else if (pll_freq & GFX_MODE_85HZ) 2284 *hz = 85; 2285 2286 return (1); 2287 } 2288 } 2289 return (-1); 2290} 2291 2292/*--------------------------------------------------------------------------- 2293 * gfx_get_hactive 2294 *--------------------------------------------------------------------------- 2295 */ 2296#if GFX_DISPLAY_DYNAMIC 2297unsigned short 2298gu1_get_hactive(void) 2299#else 2300unsigned short 2301gfx_get_hactive(void) 2302#endif 2303{ 2304 return ((unsigned short)((READ_REG32(DC_H_TIMING_1) & 0x07F8) + 8)); 2305} 2306 2307/*--------------------------------------------------------------------------- 2308 * gfx_get_hsync_start 2309 *--------------------------------------------------------------------------- 2310 */ 2311#if GFX_DISPLAY_DYNAMIC 2312unsigned short 2313gu1_get_hsync_start(void) 2314#else 2315unsigned short 2316gfx_get_hsync_start(void) 2317#endif 2318{ 2319 return ((unsigned short)((READ_REG32(DC_H_TIMING_3) & 0x07F8) + 8)); 2320} 2321 2322/*--------------------------------------------------------------------------- 2323 * gfx_get_hsync_end 2324 *--------------------------------------------------------------------------- 2325 */ 2326#if GFX_DISPLAY_DYNAMIC 2327unsigned short 2328gu1_get_hsync_end(void) 2329#else 2330unsigned short 2331gfx_get_hsync_end(void) 2332#endif 2333{ 2334 return ((unsigned short)(((READ_REG32(DC_H_TIMING_3) >> 16) & 0x07F8) + 2335 8)); 2336} 2337 2338/*--------------------------------------------------------------------------- 2339 * gfx_get_htotal 2340 *--------------------------------------------------------------------------- 2341 */ 2342#if GFX_DISPLAY_DYNAMIC 2343unsigned short 2344gu1_get_htotal(void) 2345#else 2346unsigned short 2347gfx_get_htotal(void) 2348#endif 2349{ 2350 return ((unsigned short)(((READ_REG32(DC_H_TIMING_1) >> 16) & 0x07F8) + 2351 8)); 2352} 2353 2354/*--------------------------------------------------------------------------- 2355 * gfx_get_vactive 2356 *--------------------------------------------------------------------------- 2357 */ 2358#if GFX_DISPLAY_DYNAMIC 2359unsigned short 2360gu1_get_vactive(void) 2361#else 2362unsigned short 2363gfx_get_vactive(void) 2364#endif 2365{ 2366 return ((unsigned short)((READ_REG32(DC_V_TIMING_1) & 0x07FF) + 1)); 2367} 2368 2369/*--------------------------------------------------------------------------- 2370 * gfx_get_vsync_end 2371 *--------------------------------------------------------------------------- 2372 */ 2373#if GFX_DISPLAY_DYNAMIC 2374unsigned short 2375gu1_get_vsync_end(void) 2376#else 2377unsigned short 2378gfx_get_vsync_end(void) 2379#endif 2380{ 2381 return ((unsigned short)(((READ_REG32(DC_V_TIMING_3) >> 16) & 0x07FF) + 2382 1)); 2383} 2384 2385/*--------------------------------------------------------------------------- 2386 * gfx_get_vtotal 2387 *--------------------------------------------------------------------------- 2388 */ 2389#if GFX_DISPLAY_DYNAMIC 2390unsigned short 2391gu1_get_vtotal(void) 2392#else 2393unsigned short 2394gfx_get_vtotal(void) 2395#endif 2396{ 2397 return ((unsigned short)(((READ_REG32(DC_V_TIMING_1) >> 16) & 0x07FF) + 2398 1)); 2399} 2400 2401/*----------------------------------------------------------------------------- 2402 * gfx_get_display_bpp 2403 * 2404 * This routine returns the current color depth of the active display. 2405 *----------------------------------------------------------------------------- 2406 */ 2407#if GFX_DISPLAY_DYNAMIC 2408unsigned short 2409gu1_get_display_bpp(void) 2410#else 2411unsigned short 2412gfx_get_display_bpp(void) 2413#endif 2414{ 2415 switch (READ_REG32(DC_OUTPUT_CFG) & 3) { 2416 case 0: 2417 return (16); 2418 case 2: 2419 return (15); 2420 } 2421 return (8); 2422} 2423 2424/*--------------------------------------------------------------------------- 2425 * gfx_get_vline 2426 *--------------------------------------------------------------------------- 2427 */ 2428#if GFX_DISPLAY_DYNAMIC 2429unsigned short 2430gu1_get_vline(void) 2431#else 2432unsigned short 2433gfx_get_vline(void) 2434#endif 2435{ 2436 unsigned short current_scan_line; 2437 2438 /* Read similar value twice to ensure that the value is not transitioning */ 2439 2440 do 2441 current_scan_line = (unsigned short)READ_REG32(DC_V_LINE_CNT) & 0x07FF; 2442 while (current_scan_line != 2443 (unsigned short)(READ_REG32(DC_V_LINE_CNT) & 0x07FF)); 2444 2445 return (current_scan_line); 2446} 2447 2448/*----------------------------------------------------------------------------- 2449 * gfx_get_display_offset 2450 *----------------------------------------------------------------------------- 2451 */ 2452#if GFX_DISPLAY_DYNAMIC 2453unsigned long 2454gu1_get_display_offset(void) 2455#else 2456unsigned long 2457gfx_get_display_offset(void) 2458#endif 2459{ 2460 return (READ_REG32(DC_FB_ST_OFFSET) & 0x003FFFFF); 2461} 2462 2463/*----------------------------------------------------------------------------- 2464 * gfx_get_cursor_offset 2465 *----------------------------------------------------------------------------- 2466 */ 2467#if GFX_DISPLAY_DYNAMIC 2468unsigned long 2469gu1_get_cursor_offset(void) 2470#else 2471unsigned long 2472gfx_get_cursor_offset(void) 2473#endif 2474{ 2475 return (READ_REG32(DC_CURS_ST_OFFSET) & 0x003FFFFF); 2476} 2477 2478#if GFX_READ_ROUTINES 2479 2480/*************************************************************/ 2481/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ 2482/*************************************************************/ 2483 2484/*--------------------------------------------------------------------------- 2485 * gfx_get_hblank_start 2486 *--------------------------------------------------------------------------- 2487 */ 2488#if GFX_DISPLAY_DYNAMIC 2489unsigned short 2490gu1_get_hblank_start(void) 2491#else 2492unsigned short 2493gfx_get_hblank_start(void) 2494#endif 2495{ 2496 return ((unsigned short)((READ_REG32(DC_H_TIMING_2) & 0x07F8) + 8)); 2497} 2498 2499/*--------------------------------------------------------------------------- 2500 * gfx_get_hblank_end 2501 *--------------------------------------------------------------------------- 2502 */ 2503#if GFX_DISPLAY_DYNAMIC 2504unsigned short 2505gu1_get_hblank_end(void) 2506#else 2507unsigned short 2508gfx_get_hblank_end(void) 2509#endif 2510{ 2511 return ((unsigned short)(((READ_REG32(DC_H_TIMING_2) >> 16) & 0x07F8) + 2512 8)); 2513} 2514 2515/*--------------------------------------------------------------------------- 2516 * gfx_get_vblank_start 2517 *--------------------------------------------------------------------------- 2518 */ 2519#if GFX_DISPLAY_DYNAMIC 2520unsigned short 2521gu1_get_vblank_start(void) 2522#else 2523unsigned short 2524gfx_get_vblank_start(void) 2525#endif 2526{ 2527 return ((unsigned short)((READ_REG32(DC_V_TIMING_2) & 0x07FF) + 1)); 2528} 2529 2530/*--------------------------------------------------------------------------- 2531 * gfx_get_vsync_start 2532 *--------------------------------------------------------------------------- 2533 */ 2534#if GFX_DISPLAY_DYNAMIC 2535unsigned short 2536gu1_get_vsync_start(void) 2537#else 2538unsigned short 2539gfx_get_vsync_start(void) 2540#endif 2541{ 2542 return ((unsigned short)((READ_REG32(DC_V_TIMING_3) & 0x07FF) + 1)); 2543} 2544 2545/*--------------------------------------------------------------------------- 2546 * gfx_get_vblank_end 2547 *--------------------------------------------------------------------------- 2548 */ 2549#if GFX_DISPLAY_DYNAMIC 2550unsigned short 2551gu1_get_vblank_end(void) 2552#else 2553unsigned short 2554gfx_get_vblank_end(void) 2555#endif 2556{ 2557 return ((unsigned short)(((READ_REG32(DC_V_TIMING_2) >> 16) & 0x07FF) + 2558 1)); 2559} 2560 2561/*----------------------------------------------------------------------------- 2562 * gfx_get_display_palette_entry 2563 *----------------------------------------------------------------------------- 2564 */ 2565#if GFX_DISPLAY_DYNAMIC 2566int 2567gu1_get_display_palette_entry(unsigned long index, unsigned long *palette) 2568#else 2569int 2570gfx_get_display_palette_entry(unsigned long index, unsigned long *palette) 2571#endif 2572{ 2573 unsigned long data; 2574 2575 if (index > 0xFF) 2576 return GFX_STATUS_BAD_PARAMETER; 2577 2578 WRITE_REG32(DC_PAL_ADDRESS, index); 2579 data = READ_REG32(DC_PAL_DATA); 2580 data = ((data << 2) & 0x000000FC) | 2581 ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000); 2582 2583 *palette = data; 2584 2585 return 0; 2586} 2587 2588/*----------------------------------------------------------------------------- 2589 * gfx_get_display_palette 2590 *----------------------------------------------------------------------------- 2591 */ 2592#if GFX_DISPLAY_DYNAMIC 2593void 2594gu1_get_display_palette(unsigned long *palette) 2595#else 2596void 2597gfx_get_display_palette(unsigned long *palette) 2598#endif 2599{ 2600 unsigned long i, data; 2601 2602 WRITE_REG32(DC_PAL_ADDRESS, 0); 2603 for (i = 0; i < 256; i++) { 2604 data = READ_REG32(DC_PAL_DATA); 2605 data = ((data << 2) & 0x000000FC) | 2606 ((data << 4) & 0x0000FC00) | ((data << 6) & 0x00FC0000); 2607 palette[i] = data; 2608 } 2609} 2610 2611/*----------------------------------------------------------------------------- 2612 * gfx_get_cursor_enable 2613 *----------------------------------------------------------------------------- 2614 */ 2615#if GFX_DISPLAY_DYNAMIC 2616unsigned long 2617gu1_get_cursor_enable(void) 2618#else 2619unsigned long 2620gfx_get_cursor_enable(void) 2621#endif 2622{ 2623 return (READ_REG32(DC_GENERAL_CFG) & DC_GCFG_CURE); 2624} 2625 2626/*----------------------------------------------------------------------------- 2627 * gfx_get_cursor_position 2628 *----------------------------------------------------------------------------- 2629 */ 2630#if GFX_DISPLAY_DYNAMIC 2631unsigned long 2632gu1_get_cursor_position(void) 2633#else 2634unsigned long 2635gfx_get_cursor_position(void) 2636#endif 2637{ 2638 return ((READ_REG32(DC_CURSOR_X) & 0x07FF) | 2639 ((READ_REG32(DC_CURSOR_Y) << 16) & 0x03FF0000)); 2640} 2641 2642/*----------------------------------------------------------------------------- 2643 * gfx_get_cursor_clip 2644 *----------------------------------------------------------------------------- 2645 */ 2646#if GFX_DISPLAY_DYNAMIC 2647unsigned long 2648gu1_get_cursor_clip(void) 2649#else 2650unsigned long 2651gfx_get_cursor_clip(void) 2652#endif 2653{ 2654 return (((READ_REG32(DC_CURSOR_X) >> 11) & 0x01F) | 2655 ((READ_REG32(DC_CURSOR_Y) << 5) & 0x1F0000)); 2656} 2657 2658/*----------------------------------------------------------------------------- 2659 * gfx_get_cursor_color 2660 *----------------------------------------------------------------------------- 2661 */ 2662#if GFX_DISPLAY_DYNAMIC 2663unsigned long 2664gu1_get_cursor_color(int color) 2665#else 2666unsigned long 2667gfx_get_cursor_color(int color) 2668#endif 2669{ 2670 unsigned long data; 2671 2672 if (color) { 2673 WRITE_REG32(DC_PAL_ADDRESS, 0x101); 2674 } else { 2675 WRITE_REG32(DC_PAL_ADDRESS, 0x100); 2676 } 2677 data = READ_REG32(DC_PAL_DATA); 2678 data = ((data << 6) & 0x00FC0000) | 2679 ((data << 4) & 0x0000FC00) | ((data << 2) & 0x000000FC); 2680 return (data); 2681} 2682 2683/*----------------------------------------------------------------------------- 2684 * gfx_get_compression_enable 2685 *----------------------------------------------------------------------------- 2686 */ 2687#if GFX_DISPLAY_DYNAMIC 2688int 2689gu1_get_compression_enable(void) 2690#else 2691int 2692gfx_get_compression_enable(void) 2693#endif 2694{ 2695 unsigned long gcfg; 2696 2697 gcfg = READ_REG32(DC_GENERAL_CFG); 2698 if (gcfg & DC_GCFG_CMPE) 2699 return (1); 2700 else 2701 return (0); 2702} 2703 2704/*----------------------------------------------------------------------------- 2705 * gfx_get_compression_offset 2706 *----------------------------------------------------------------------------- 2707 */ 2708#if GFX_DISPLAY_DYNAMIC 2709unsigned long 2710gu1_get_compression_offset(void) 2711#else 2712unsigned long 2713gfx_get_compression_offset(void) 2714#endif 2715{ 2716 unsigned long offset; 2717 2718 offset = READ_REG32(DC_CB_ST_OFFSET) & 0x003FFFFF; 2719 return (offset); 2720} 2721 2722/*----------------------------------------------------------------------------- 2723 * gfx_get_compression_pitch 2724 *----------------------------------------------------------------------------- 2725 */ 2726#if GFX_DISPLAY_DYNAMIC 2727unsigned short 2728gu1_get_compression_pitch(void) 2729#else 2730unsigned short 2731gfx_get_compression_pitch(void) 2732#endif 2733{ 2734 unsigned short pitch; 2735 2736 pitch = (unsigned short)(READ_REG32(DC_LINE_DELTA) >> 12) & 0x07FF; 2737 return (pitch << 2); 2738} 2739 2740/*----------------------------------------------------------------------------- 2741 * gfx_get_compression_size 2742 *----------------------------------------------------------------------------- 2743 */ 2744#if GFX_DISPLAY_DYNAMIC 2745unsigned short 2746gu1_get_compression_size(void) 2747#else 2748unsigned short 2749gfx_get_compression_size(void) 2750#endif 2751{ 2752 unsigned short size; 2753 2754 size = (unsigned short)((READ_REG32(DC_BUF_SIZE) >> 9) & 0x7F) - 1; 2755 return ((size << 2) + 16); 2756} 2757 2758/*----------------------------------------------------------------------------- 2759 * gfx_get_valid_bit 2760 *----------------------------------------------------------------------------- 2761 */ 2762#if GFX_DISPLAY_DYNAMIC 2763int 2764gu1_get_valid_bit(int line) 2765#else 2766int 2767gfx_get_valid_bit(int line) 2768#endif 2769{ 2770 int valid; 2771 2772 WRITE_REG32(MC_DR_ADD, line); 2773 valid = (int)READ_REG32(MC_DR_ACC) & 1; 2774 return (valid); 2775} 2776 2777/*--------------------------------------------------------------------------- 2778 * gfx_get_display_video_offset (PRIVATE ROUTINE - NOT PART OF API) 2779 * 2780 * This routine is called by "gfx_get_video_offset". It abstracts the 2781 * version of the display controller from the video overlay routines. 2782 *--------------------------------------------------------------------------- 2783 */ 2784#if GFX_DISPLAY_DYNAMIC 2785unsigned long 2786gu1_get_display_video_offset(void) 2787#else 2788unsigned long 2789gfx_get_display_video_offset(void) 2790#endif 2791{ 2792 return (READ_REG32(DC_VID_ST_OFFSET) & 0x003FFFFF); 2793} 2794 2795/*--------------------------------------------------------------------------- 2796 * gfx_get_display_video_size (PRIVATE ROUTINE - NOT PART OF API) 2797 * 2798 * This routine is called by "gfx_get_video_size". It abstracts the 2799 * version of the display controller from the video overlay routines. 2800 *--------------------------------------------------------------------------- 2801 */ 2802#if GFX_DISPLAY_DYNAMIC 2803unsigned long 2804gu1_get_display_video_size(void) 2805#else 2806unsigned long 2807gfx_get_display_video_size(void) 2808#endif 2809{ 2810 /* RETURN TOTAL SIZE, IN BYTES */ 2811 2812 return ((READ_REG32(DC_BUF_SIZE) >> 10) & 0x000FFFC0); 2813} 2814 2815/*----------------------------------------------------------------------------- 2816 * gfx_get_display_priority_high 2817 *----------------------------------------------------------------------------- 2818 */ 2819#if GFX_DISPLAY_DYNAMIC 2820int 2821gu1_get_display_priority_high(void) 2822#else 2823int 2824gfx_get_display_priority_high(void) 2825#endif 2826{ 2827 if (READ_REG32(MC_MEM_CNTRL1) & MC_XBUSARB) 2828 return (1); 2829 else 2830 return (0); 2831} 2832 2833#endif /* GFX_READ_ROUTINES */ 2834 2835/* END OF FILE */ 2836