1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu1.c,v 1.2 2003/01/14 09:34:34 alanh Exp $ */ 2/* 3 * $Workfile: rndr_gu1.c $ 4 * 5 * This file contains routines to program the 2D acceleration hardware for 6 * the first generation graphics unit (GXLV, SC1200). 7 * 8 * gfx_set_bpp 9 * gfx_set_solid_pattern 10 * gfx_set_mono_pattern 11 * gfx_set_color_pattern 12 * gfx_set_solid_source 13 * gfx_set_mono_source 14 * gfx_set_raster_operation 15 * gfx_pattern_fill 16 * gfx_screen_to_screen_blt 17 * gfx_screen_to_screen_xblt 18 * gfx_color_bitmap_to_screen_blt 19 * gfx_color_bitmap_to_screen_xblt 20 * gfx_mono_bitmap_to_screen_blt 21 * gfx_bresenham_line 22 * gfx_wait_until_idle 23 * 24 * NSC_LIC_ALTERNATIVE_PREAMBLE 25 * 26 * Revision 1.0 27 * 28 * National Semiconductor Alternative GPL-BSD License 29 * 30 * National Semiconductor Corporation licenses this software 31 * ("Software"): 32 * 33 * Durango 34 * 35 * under one of the two following licenses, depending on how the 36 * Software is received by the Licensee. 37 * 38 * If this Software is received as part of the Linux Framebuffer or 39 * other GPL licensed software, then the GPL license designated 40 * NSC_LIC_GPL applies to this Software; in all other circumstances 41 * then the BSD-style license designated NSC_LIC_BSD shall apply. 42 * 43 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 44 45/* NSC_LIC_BSD 46 * 47 * National Semiconductor Corporation Open Source License for Durango 48 * 49 * (BSD License with Export Notice) 50 * 51 * Copyright (c) 1999-2001 52 * National Semiconductor Corporation. 53 * All rights reserved. 54 * 55 * Redistribution and use in source and binary forms, with or without 56 * modification, are permitted provided that the following conditions 57 * are met: 58 * 59 * * Redistributions of source code must retain the above copyright 60 * notice, this list of conditions and the following disclaimer. 61 * 62 * * Redistributions in binary form must reproduce the above 63 * copyright notice, this list of conditions and the following 64 * disclaimer in the documentation and/or other materials provided 65 * with the distribution. 66 * 67 * * Neither the name of the National Semiconductor Corporation nor 68 * the names of its contributors may be used to endorse or promote 69 * products derived from this software without specific prior 70 * written permission. 71 * 72 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 73 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 74 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 75 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 76 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 79 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 80 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 81 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 82 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 83 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 84 * OF SUCH DAMAGE. 85 * 86 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 87 * YOUR JURISDICTION. It is licensee's responsibility to comply with 88 * any export regulations applicable in licensee's jurisdiction. Under 89 * CURRENT (2001) U.S. export regulations this software 90 * is eligible for export from the U.S. and can be downloaded by or 91 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 92 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 93 * Syria, Sudan, Afghanistan and any other country to which the U.S. 94 * has embargoed goods and services. 95 * 96 * END_NSC_LIC_BSD */ 97 98/* NSC_LIC_GPL 99 * 100 * National Semiconductor Corporation Gnu General Public License for Durango 101 * 102 * (GPL License with Export Notice) 103 * 104 * Copyright (c) 1999-2001 105 * National Semiconductor Corporation. 106 * All rights reserved. 107 * 108 * Redistribution and use in source and binary forms, with or without 109 * modification, are permitted under the terms of the GNU General 110 * Public License as published by the Free Software Foundation; either 111 * version 2 of the License, or (at your option) any later version 112 * 113 * In addition to the terms of the GNU General Public License, neither 114 * the name of the National Semiconductor Corporation nor the names of 115 * its contributors may be used to endorse or promote products derived 116 * from this software without specific prior written permission. 117 * 118 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 119 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 120 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 121 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 122 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 123 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 124 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 125 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 126 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 127 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 128 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 129 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 130 * OF SUCH DAMAGE. See the GNU General Public License for more details. 131 * 132 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 133 * YOUR JURISDICTION. It is licensee's responsibility to comply with 134 * any export regulations applicable in licensee's jurisdiction. Under 135 * CURRENT (2001) U.S. export regulations this software 136 * is eligible for export from the U.S. and can be downloaded by or 137 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 138 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 139 * Syria, Sudan, Afghanistan and any other country to which the U.S. 140 * has embargoed goods and services. 141 * 142 * You should have received a copy of the GNU General Public License 143 * along with this file; if not, write to the Free Software Foundation, 144 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 145 * 146 * END_NSC_LIC_GPL */ 147 148void gu1_set_bpp(unsigned short bpp); 149void gu1_set_solid_pattern(unsigned long color); 150void gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 151 unsigned long data0, unsigned long data1, 152 unsigned char transparency); 153void gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 154 unsigned long data0, unsigned long data1, 155 unsigned long data2, unsigned long data3, 156 unsigned char transparency); 157void gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8); 158void gu1_set_solid_source(unsigned long color); 159void gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 160 unsigned short transparent); 161void gu1_set_pattern_flags(unsigned short flags); 162void gu1_set_raster_operation(unsigned char rop); 163void gu1_pattern_fill(unsigned short x, unsigned short y, 164 unsigned short width, unsigned short height); 165void gu1_color_pattern_fill(unsigned short x, unsigned short y, 166 unsigned short width, unsigned short height, 167 unsigned long *pattern); 168void gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 169 unsigned short dstx, unsigned short dsty, 170 unsigned short width, unsigned short height); 171void gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 172 unsigned short dstx, unsigned short dsty, 173 unsigned short width, unsigned short height, 174 unsigned long color); 175void gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 176 unsigned short dstx, unsigned short dsty, 177 unsigned short width, 178 unsigned short height, 179 unsigned char *data, long pitch); 180void gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 181 unsigned short dstx, unsigned short dsty, 182 unsigned short width, 183 unsigned short height, 184 unsigned char *data, long pitch, 185 unsigned long color); 186void gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 187 unsigned short dstx, unsigned short dsty, 188 unsigned short width, 189 unsigned short height, unsigned char *data, 190 short pitch); 191void gu1_text_blt(unsigned short dstx, unsigned short dsty, 192 unsigned short width, unsigned short height, 193 unsigned char *data); 194void gu1_bresenham_line(unsigned short x, unsigned short y, 195 unsigned short length, unsigned short initerr, 196 unsigned short axialerr, unsigned short diagerr, 197 unsigned short flags); 198void gu1_wait_until_idle(void); 199 200#if GFX_NO_IO_IN_WAIT_MACROS 201#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { ; } 202#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { ; } 203#define GFX_WAIT_PIPELINE while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { ; } 204#else 205#define GFX_WAIT_PENDING while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) { INB (0x80); } 206#define GFX_WAIT_BUSY while(READ_REG16(GP_BLIT_STATUS) & BS_BLIT_BUSY) { INB (0x80); } 207#define GFX_WAIT_PIPELINE while (READ_REG16(GP_BLIT_STATUS) & BS_PIPELINE_BUSY) { INB (0x80); } 208#endif 209 210void gu1_detect_blt_buffer_base(void); 211int gu1_test_blt_pending(void); 212void gu1_solid_fill(unsigned short x, unsigned short y, 213 unsigned short width, unsigned short height, 214 unsigned long color); 215 216/*--------------------------------------------------------------------------- 217 * GFX_SET_BPP 218 * 219 * This routine sets the bits per pixel value in the graphics engine. 220 * It is also stored in a static variable to use in the future calls to 221 * the rendering routines. 222 *--------------------------------------------------------------------------- 223 */ 224#if GFX_2DACCEL_DYNAMIC 225void 226gu1_set_bpp(unsigned short bpp) 227#else 228void 229gfx_set_bpp(unsigned short bpp) 230#endif 231{ 232 int control = 0; 233 unsigned short pitch = gfx_get_display_pitch(); 234 235 GFXbpp = bpp; 236 237 /* DETECT BASE ADDRESSES FOR BLT BUFFERS */ 238 /* Different for 2K or 3K of scratchpad. Also need to calculate */ 239 /* the number of pixels that can fit in a BLT buffer - need to */ 240 /* subtract 16 for alignment considerations. The 2K case, for */ 241 /* example, is 816 bytes wide, allowing 800 pixels in 8 BPP, which */ 242 /* means rendering operations won't be split for 800x600. */ 243 244 gu1_detect_blt_buffer_base(); 245 GFXbufferWidthPixels = GFXbb1Base - GFXbb0Base - 16; 246 if (bpp > 8) { 247 /* If 16bpp, divide GFXbufferWidthPixels by 2 */ 248 GFXbufferWidthPixels >>= 1; 249 } 250 251 /* SET THE GRAPHICS CONTROLLER BPP AND PITCH */ 252 if (bpp > 8) { 253 /* Set the 16bpp bit if necessary */ 254 control = BC_16BPP; 255 } 256 if ((gfx_cpu_version == GFX_CPU_PYRAMID) && (pitch > 2048)) { 257 control |= BC_FB_WIDTH_4096; 258 } else if (pitch > 1024) { 259 control |= BC_FB_WIDTH_2048; 260 } 261 GFX_WAIT_BUSY; 262 WRITE_REG32(GP_BLIT_STATUS, control); 263} 264 265/* 266//--------------------------------------------------------------------------- 267// GFX_SET_SOLID_SOURCE 268// 269// This routine is used to specify a solid source color. For the Xfree96 270// display driver, the source color is used to specify a planemask and the 271// ROP is adjusted accordingly. 272//--------------------------------------------------------------------------- 273*/ 274#if GFX_2DACCEL_DYNAMIC 275void 276gu1_set_solid_source(unsigned long color) 277#else 278void 279gfx_set_solid_source(unsigned long color) 280#endif 281{ 282 /* CLEAR TRANSPARENCY FLAG */ 283 284 GFXsourceFlags = 0; 285 286 /* FORMAT 8 BPP COLOR */ 287 /* GX requires 8BPP color data be duplicated into bits [15:8]. */ 288 289 if (GFXbpp == 8) { 290 color &= 0x00FF; 291 color |= (color << 8); 292 } 293 294 /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ 295 296 GFX_WAIT_PENDING; 297 WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)color); 298 WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)color); 299} 300 301/* 302//--------------------------------------------------------------------------- 303// GFX_SET_MONO_SOURCE 304// 305// This routine is used to specify the monochrome source colors. 306// It must be called *after* loading any pattern data (those routines 307// clear the source flags). 308//--------------------------------------------------------------------------- 309*/ 310#if GFX_2DACCEL_DYNAMIC 311void 312gu1_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 313 unsigned short transparent) 314#else 315void 316gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 317 unsigned short transparent) 318#endif 319{ 320 /* SET TRANSPARENCY FLAG */ 321 322 GFXsourceFlags = transparent ? RM_SRC_TRANSPARENT : 0; 323 324 /* FORMAT 8 BPP COLOR */ 325 /* GX requires 8BPP color data be duplicated into bits [15:8]. */ 326 327 if (GFXbpp == 8) { 328 bgcolor &= 0x00FF; 329 bgcolor |= (bgcolor << 8); 330 fgcolor &= 0x00FF; 331 fgcolor |= (fgcolor << 8); 332 } 333 334 /* POLL UNTIL ABLE TO WRITE THE SOURCE COLOR */ 335 336 GFX_WAIT_PENDING; 337 WRITE_REG16(GP_SRC_COLOR_0, (unsigned short)bgcolor); 338 WRITE_REG16(GP_SRC_COLOR_1, (unsigned short)fgcolor); 339} 340 341/* 342//--------------------------------------------------------------------------- 343// GFX_SET_SOLID_PATTERN 344// 345// This routine is used to specify a solid pattern color. It is called 346// before performing solid rectangle fills or more complicated BLTs that 347// use a solid pattern color. 348// 349// The driver should always call "gfx_load_raster_operation" after a call 350// to this routine to make sure that the pattern flags are set appropriately. 351//--------------------------------------------------------------------------- 352*/ 353#if GFX_2DACCEL_DYNAMIC 354void 355gu1_set_solid_pattern(unsigned long color) 356#else 357void 358gfx_set_solid_pattern(unsigned long color) 359#endif 360{ 361 /* CLEAR TRANSPARENCY FLAG */ 362 363 GFXsourceFlags = 0; 364 365 /* SET PATTERN FLAGS */ 366 367 GFXpatternFlags = 0; 368 369 /* FORMAT 8 BPP COLOR */ 370 /* GX requires 8BPP color data be duplicated into bits [15:8]. */ 371 372 if (GFXbpp == 8) { 373 color &= 0x00FF; 374 color |= (color << 8); 375 } 376 377 /* SAVE THE REFORMATTED COLOR FOR LATER */ 378 /* Used to call the "GFX_solid_fill" routine for special cases. */ 379 380 GFXsavedColor = color; 381 382 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ 383 384 GFX_WAIT_PENDING; 385 WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); 386} 387 388/* 389//--------------------------------------------------------------------------- 390// GFX_SET_MONO_PATTERN 391// 392// This routine is used to specify a monochrome pattern. 393//--------------------------------------------------------------------------- 394*/ 395#if GFX_2DACCEL_DYNAMIC 396void 397gu1_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 398 unsigned long data0, unsigned long data1, 399 unsigned char transparent) 400#else 401void 402gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 403 unsigned long data0, unsigned long data1, 404 unsigned char transparent) 405#endif 406{ 407 /* CLEAR TRANSPARENCY FLAG */ 408 409 GFXsourceFlags = 0; 410 411 /* SET PATTERN FLAGS */ 412 413 GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : 414 RM_PAT_MONO; 415 416 /* FORMAT 8 BPP COLOR */ 417 /* GXm requires 8BPP color data be duplicated into bits [15:8]. */ 418 419 if (GFXbpp == 8) { 420 bgcolor &= 0x00FF; 421 bgcolor |= (bgcolor << 8); 422 fgcolor &= 0x00FF; 423 fgcolor |= (fgcolor << 8); 424 } 425 426 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ 427 428 GFX_WAIT_PENDING; 429 WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor); 430 WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor); 431 WRITE_REG32(GP_PAT_DATA_0, data0); 432 WRITE_REG32(GP_PAT_DATA_1, data1); 433} 434 435/* 436//--------------------------------------------------------------------------- 437// GFX_SET_COLOR_PATTERN 438// 439// This routine is used to specify a color pattern. 440//--------------------------------------------------------------------------- 441*/ 442#if GFX_2DACCEL_DYNAMIC 443void 444gu1_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 445 unsigned long data0, unsigned long data1, 446 unsigned long data2, unsigned long data3, 447 unsigned char transparent) 448#else 449void 450gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 451 unsigned long data0, unsigned long data1, 452 unsigned long data2, unsigned long data3, 453 unsigned char transparent) 454#endif 455{ 456 /* CLEAR TRANSPARENCY FLAG */ 457 458 GFXsourceFlags = 0; 459 460 /* SET PATTERN FLAGS */ 461 462 GFXpatternFlags = transparent ? RM_PAT_MONO | RM_PAT_TRANSPARENT : 463 RM_PAT_MONO; 464 465 GFXpatternFlags |= RM_PAT_COLOR; 466 /* FORMAT 8 BPP COLOR */ 467 /* GXm requires 8BPP color data be duplicated into bits [15:8]. */ 468 469 if (GFXbpp == 8) { 470 bgcolor &= 0x00FF; 471 bgcolor |= (bgcolor << 8); 472 fgcolor &= 0x00FF; 473 fgcolor |= (fgcolor << 8); 474 } 475 476 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ 477 478 GFX_WAIT_PENDING; 479 WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)bgcolor); 480 WRITE_REG16(GP_PAT_COLOR_1, (unsigned short)fgcolor); 481 WRITE_REG32(GP_PAT_DATA_0, data0); 482 WRITE_REG32(GP_PAT_DATA_1, data1); 483 if (GFXbpp > 8) { 484 WRITE_REG32(GP_PAT_DATA_2, data2); 485 WRITE_REG32(GP_PAT_DATA_3, data3); 486 } 487} 488 489/* 490//--------------------------------------------------------------------------- 491// GFX_LOAD_COLOR_PATTERN_LINE 492// 493// This routine is used to load a single line of a 8x8 color pattern. 494//--------------------------------------------------------------------------- 495*/ 496#if GFX_2DACCEL_DYNAMIC 497void 498gu1_load_color_pattern_line(short y, unsigned long *pattern_8x8) 499#else 500void 501gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8) 502#endif 503{ 504 /* CLEAR TRANSPARENCY FLAG */ 505 506 GFXsourceFlags = 0; 507 508 /* SET PATTERN FLAGS */ 509 510 GFXpatternFlags = RM_PAT_COLOR; 511 512 y &= 7; 513 514 if (GFXbpp > 8) 515 pattern_8x8 += (y << 2); 516 else 517 pattern_8x8 += (y << 1); 518 519 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLORS AND DATA */ 520 521 GFX_WAIT_PENDING; 522 WRITE_REG32(GP_PAT_DATA_0, pattern_8x8[0]); 523 WRITE_REG32(GP_PAT_DATA_1, pattern_8x8[1]); 524 if (GFXbpp > 8) { 525 WRITE_REG32(GP_PAT_DATA_2, pattern_8x8[2]); 526 WRITE_REG32(GP_PAT_DATA_3, pattern_8x8[3]); 527 } 528} 529 530/* 531//--------------------------------------------------------------------------- 532// GFX_SET_RASTER_OPERATION 533// 534// This routine loads the specified raster operation. It sets the pattern 535// flags appropriately. 536//--------------------------------------------------------------------------- 537*/ 538#if GFX_2DACCEL_DYNAMIC 539void 540gu1_set_raster_operation(unsigned char rop) 541#else 542void 543gfx_set_raster_operation(unsigned char rop) 544#endif 545{ 546 unsigned short rop16; 547 548 /* GENERATE 16-BIT VERSION OF ROP WITH PATTERN FLAGS */ 549 550 rop16 = (unsigned short)rop | GFXpatternFlags; 551 if ((rop & 0x33) ^ ((rop >> 2) & 0x33)) 552 rop16 |= GFXsourceFlags; 553 554 /* SAVE ROP FOR LATER COMPARISONS */ 555 /* Need to have the pattern flags included */ 556 557 GFXsavedRop = rop16; 558 559 /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ 560 /* True if even bits (0:2:4:6) do not equal the correspinding */ 561 /* even bits (1:3:5:7). */ 562 563 GFXusesDstData = ((rop & 0x55) ^ ((rop >> 1) & 0x55)); 564 565 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ 566 /* Only one operation can be pending at a time. */ 567 568 GFX_WAIT_PENDING; 569 WRITE_REG16(GP_RASTER_MODE, rop16); 570} 571 572/* 573//--------------------------------------------------------------------------- 574// GFX_SOLID_FILL 575// 576// This routine MUST be used when performing a solid rectangle fill with 577// the ROPs of PATCOPY (0xF0), BLACKNESS (0x00), WHITENESS (0xFF), or 578// PATINVERT (0x0F). There is a bug in GXm for these cases that requires a 579// workaround. 580// 581// For BLACKNESS (ROP = 0x00), set the color to 0x0000. 582// For WHITENESS (ROP = 0xFF), set the color to 0xFFFF. 583// For PATINVERT (ROP = 0x0F), invert the desired color. 584// 585// X screen X position (left) 586// Y screen Y position (top) 587// WIDTH width of rectangle, in pixels 588// HEIGHT height of rectangle, in scanlines 589// COLOR fill color 590// 591// THIS ROUTINE SHOULD NOT BE DIRECTLY CALLED FROM THE DRIVER. The driver 592// should always use GFX_pattern_fill and let that routine call this one 593// when approipriate. This is to hide quirks specific to MediaGX hardware. 594//--------------------------------------------------------------------------- 595*/ 596void 597gu1_solid_fill(unsigned short x, unsigned short y, 598 unsigned short width, unsigned short height, 599 unsigned long color) 600{ 601 unsigned short section; 602 603 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 604 /* Only one operation can be pending at a time. */ 605 606 GFX_WAIT_PENDING; 607 608 /* SET REGISTERS TO DRAW RECTANGLE */ 609 610 WRITE_REG16(GP_DST_XCOOR, x); 611 WRITE_REG16(GP_DST_YCOOR, y); 612 WRITE_REG16(GP_HEIGHT, height); 613 WRITE_REG16(GP_RASTER_MODE, 0x00F0); /* PATCOPY */ 614 WRITE_REG16(GP_PAT_COLOR_0, (unsigned short)color); 615 616 /* CHECK WIDTH FOR GX BUG WORKAROUND */ 617 618 if (width <= 16) { 619 /* OK TO DRAW SMALL RECTANGLE IN ONE PASS */ 620 621 WRITE_REG16(GP_WIDTH, width); 622 WRITE_REG16(GP_BLIT_MODE, 0); 623 } else { 624 /* DRAW FIRST PART OF RECTANGLE */ 625 /* Get to a 16 pixel boundary. */ 626 627 section = 0x10 - (x & 0x0F); 628 WRITE_REG16(GP_WIDTH, section); 629 WRITE_REG16(GP_BLIT_MODE, 0); 630 631 /* POLL UNTIL ABLE TO LOAD THE SECOND RECTANGLE */ 632 633 GFX_WAIT_PENDING; 634 WRITE_REG16(GP_DST_XCOOR, x + section); 635 WRITE_REG16(GP_DST_YCOOR, y); 636 WRITE_REG16(GP_WIDTH, width - section); 637 WRITE_REG16(GP_BLIT_MODE, 0); 638 } 639} 640 641/* 642//---------------------------------------------------------------------------- 643// GFX_PATTERN_FILL 644// 645// This routine is used to fill a rectangular region. The pattern must 646// be previously loaded using one of GFX_load_*_pattern routines. Also, the 647// raster operation must be previously specified using the 648// "GFX_load_raster_operation" routine. 649// 650// X screen X position (left) 651// Y screen Y position (top) 652// WIDTH width of rectangle, in pixels 653// HEIGHT height of rectangle, in scanlines 654//---------------------------------------------------------------------------- 655*/ 656#if GFX_2DACCEL_DYNAMIC 657void 658gu1_pattern_fill(unsigned short x, unsigned short y, 659 unsigned short width, unsigned short height) 660#else 661void 662gfx_pattern_fill(unsigned short x, unsigned short y, 663 unsigned short width, unsigned short height) 664#endif 665{ 666 unsigned short section, buffer_width, blit_mode; 667 668 /* CHECK IF OPTIMIZED SOLID CASES */ 669 /* Check all 16 bits of the ROP to include solid pattern flags. */ 670 671 switch (GFXsavedRop) { 672 /* CHECK FOR SPECIAL CASES WITHOUT DESTINATION DATA */ 673 /* Need hardware workaround for fast "burst write" cases. */ 674 675 case 0x00F0: 676 gu1_solid_fill(x, y, width, height, (unsigned short)GFXsavedColor); 677 break; 678 case 0x000F: 679 gu1_solid_fill(x, y, width, height, (unsigned short)~GFXsavedColor); 680 break; 681 case 0x0000: 682 gu1_solid_fill(x, y, width, height, 0x0000); 683 break; 684 case 0x00FF: 685 gu1_solid_fill(x, y, width, height, 0xFFFF); 686 break; 687 688 /* REMAINING CASES REQUIRE DESTINATION DATA OR NOT SOLID COLOR */ 689 690 default: 691 692 /* DETERMINE BLT MODE VALUE */ 693 /* Still here for non-solid patterns without destination data. */ 694 695 blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0; 696 697 /* SET SOURCE EXPANSION MODE */ 698 /* If the ROP requires source data, then the source data is all 1's */ 699 /* and then expanded into the desired color in GP_SRC_COLOR_1. */ 700 701 blit_mode |= BM_SOURCE_EXPAND; 702 703 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 704 /* Write the registers that do not change for each section. */ 705 706 GFX_WAIT_PENDING; 707 WRITE_REG16(GP_HEIGHT, height); 708 709 /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ 710 /* Therefore, width available = BLT buffer width * 2. */ 711 712 buffer_width = GFXbufferWidthPixels << 1; 713 714 /* REPEAT UNTIL FINISHED WITH RECTANGLE */ 715 /* Perform BLT in vertical sections, as wide as the BLT buffer */ 716 /* allows. Hardware does not split the operations, so */ 717 /* software must do it to avoid large scanlines that would */ 718 /* overflow the BLT buffers. */ 719 720 while (width > 0) { 721 /* DETERMINE WIDTH OF SECTION */ 722 723 if (width > buffer_width) 724 section = buffer_width; 725 else 726 section = width; 727 728 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 729 730 GFX_WAIT_PENDING; 731 WRITE_REG16(GP_DST_XCOOR, x); 732 WRITE_REG16(GP_DST_YCOOR, y); 733 WRITE_REG16(GP_WIDTH, section); 734 WRITE_REG16(GP_BLIT_MODE, blit_mode); 735 736 /* ADJUST PARAMETERS FOR NEXT SECTION */ 737 738 width -= section; 739 x += section; 740 } 741 break; 742 } 743} 744 745/* 746//---------------------------------------------------------------------------- 747// GFX_COLOR_PATTERN_FILL 748// 749// This routine is used to render a rectangle using the current raster 750// operation and the specified color pattern. It allows an 8x8 color 751// pattern to be rendered without multiple calls to the gfx_set_color_pattern 752// and gfx_pattern_fill routines. 753// 754// X screen X position (left) 755// Y screen Y position (top) 756// WIDTH width of rectangle, in pixels 757// HEIGHT height of rectangle, in scanlines 758// *PATTERN pointer to 8x8 color pattern data 759//---------------------------------------------------------------------------- 760*/ 761#if GFX_2DACCEL_DYNAMIC 762void 763gu1_color_pattern_fill(unsigned short x, unsigned short y, 764 unsigned short width, unsigned short height, 765 unsigned long *pattern) 766#else 767void 768gfx_color_pattern_fill(unsigned short x, unsigned short y, 769 unsigned short width, unsigned short height, 770 unsigned long *pattern) 771#endif 772{ 773 unsigned short blit_mode, passes, cur_y, pat_y, i; 774 unsigned short buffer_width, line_width; 775 unsigned short bpp_shift, section, cur_x; 776 777 /* SET APPROPRIATE INCREMENT */ 778 779 bpp_shift = (GFXbpp > 8) ? 2 : 1; 780 781 /* SET DESTINATION REQUIRED */ 782 783 blit_mode = GFXusesDstData ? BM_READ_DST_FB0 : 0; 784 785 /* SET SOURCE EXPANSION */ 786 787 blit_mode |= BM_SOURCE_EXPAND; 788 789 /* OVERRIDE RASTER MODE TO FORCE A COLOR PATTERN */ 790 791 GFX_WAIT_PENDING; 792 WRITE_REG16(GP_RASTER_MODE, 793 (GFXsavedRop & ~RM_PAT_MASK & ~RM_PAT_TRANSPARENT) | 794 RM_PAT_COLOR); 795 796 /* WRITE THE REGISTERS THAT DO NOT CHANGE */ 797 /* If destination data is required, the width and */ 798 /* x position will be overwritten. */ 799 800 WRITE_REG16(GP_HEIGHT, 1); 801 WRITE_REG16(GP_WIDTH, width); 802 WRITE_REG16(GP_DST_XCOOR, x); 803 804 /* THE ENTIRE PATTERN WILL NOT BE DRAWN IF THE HEIGHT IS LESS THAN 8 */ 805 806 passes = (height < 8) ? height : 8; 807 808 /* SINCE ONLY DESTINATION DATA, WE CAN USE BOTH BB0 AND BB1. */ 809 /* Therefore, width available = BLT buffer width * 2. */ 810 811 buffer_width = GFXbufferWidthPixels << 1; 812 813 for (i = 0; i < passes; i++) { 814 pat_y = ((y + i) & 7) << bpp_shift; 815 cur_y = y + i; 816 817 /* WRITE THE PATTERN DATA FOR THE ACTIVE LINE */ 818 819 GFX_WAIT_PENDING; 820 WRITE_REG32(GP_PAT_DATA_0, pattern[pat_y]); 821 WRITE_REG32(GP_PAT_DATA_1, pattern[pat_y + 1]); 822 823 if (GFXbpp > 8) { 824 WRITE_REG32(GP_PAT_DATA_2, pattern[pat_y + 2]); 825 WRITE_REG32(GP_PAT_DATA_3, pattern[pat_y + 3]); 826 } 827 828 /* SPLIT BLT LINE INTO SECTIONS IF REQUIRED */ 829 /* If no destination data is required, we can ignore */ 830 /* the BLT buffers. Otherwise, we must separate the BLT */ 831 /* so as not to overflow the buffers */ 832 833 if (blit_mode & BM_READ_DST_BB0) { 834 line_width = width; 835 cur_x = x; 836 837 while (line_width) { 838 section = (line_width > buffer_width) ? buffer_width : line_width; 839 cur_y = y + i; 840 841 GFX_WAIT_PENDING; 842 WRITE_REG16(GP_DST_XCOOR, cur_x); 843 WRITE_REG16(GP_WIDTH, section); 844 845 while (cur_y < y + height) { 846 GFX_WAIT_PENDING; 847 WRITE_REG16(GP_DST_YCOOR, cur_y); 848 WRITE_REG16(GP_BLIT_MODE, blit_mode); 849 cur_y += 8; 850 } 851 852 cur_x += section; 853 line_width -= section; 854 } 855 856 } else { 857 while (cur_y < y + height) { 858 GFX_WAIT_PENDING; 859 WRITE_REG16(GP_DST_YCOOR, cur_y); 860 WRITE_REG16(GP_BLIT_MODE, blit_mode); 861 cur_y += 8; 862 } 863 } 864 865 } 866 867 /* RESTORE ORIGINAL ROP AND FLAGS */ 868 869 GFX_WAIT_PENDING; 870 WRITE_REG16(GP_RASTER_MODE, GFXsavedRop); 871 872} 873 874/* 875//---------------------------------------------------------------------------- 876// SCREEN TO SCREEN BLT 877// 878// This routine should be used to perform a screen to screen BLT when the 879// ROP does not require destination data. 880// 881// SRCX screen X position to copy from 882// SRCY screen Y position to copy from 883// DSTX screen X position to copy to 884// DSTY screen Y position to copy to 885// WIDTH width of rectangle, in pixels 886// HEIGHT height of rectangle, in scanlines 887//---------------------------------------------------------------------------- 888*/ 889#if GFX_2DACCEL_DYNAMIC 890void 891gu1_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 892 unsigned short dstx, unsigned short dsty, 893 unsigned short width, unsigned short height) 894#else 895void 896gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 897 unsigned short dstx, unsigned short dsty, 898 unsigned short width, unsigned short height) 899#endif 900{ 901 unsigned short section, buffer_width; 902 unsigned short blit_mode; 903 904 /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ 905 906 blit_mode = GFXusesDstData ? BM_READ_DST_FB1 | BM_READ_SRC_FB : 907 BM_READ_SRC_FB; 908 909 /* CHECK Y DIRECTION */ 910 /* Hardware has support for negative Y direction. */ 911 912 if (dsty > srcy) { 913 blit_mode |= BM_REVERSE_Y; 914 srcy += height - 1; 915 dsty += height - 1; 916 } 917 918 /* CHECK X DIRECTION */ 919 /* Hardware does not support negative X direction since at the time */ 920 /* of development all supported resolutions could fit a scanline of */ 921 /* data at once into the BLT buffers (using both BB0 and BB1). This */ 922 /* code is more generic to allow for any size BLT buffer. */ 923 924 if (dstx > srcx) { 925 srcx += width; 926 dstx += width; 927 } 928 929 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 930 /* Write the registers that do not change for each section. */ 931 932 GFX_WAIT_PENDING; 933 WRITE_REG16(GP_HEIGHT, height); 934 935 /* CHECK AVAILABLE BLT BUFFER SIZE */ 936 /* Can use both BLT buffers if no destination data is required. */ 937 938 buffer_width = GFXusesDstData ? GFXbufferWidthPixels : 939 GFXbufferWidthPixels << 1; 940 941 /* REPEAT UNTIL FINISHED WITH RECTANGLE */ 942 /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ 943 /* Hardware does not split the operations, so software must do it to */ 944 /* avoid large scanlines that would overflow the BLT buffers. */ 945 946 while (width > 0) { 947 /* CHECK WIDTH OF CURRENT SECTION */ 948 949 if (width > buffer_width) 950 section = buffer_width; 951 else 952 section = width; 953 954 /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ 955 956 GFX_WAIT_PENDING; 957 WRITE_REG16(GP_SRC_YCOOR, srcy); 958 WRITE_REG16(GP_DST_YCOOR, dsty); 959 WRITE_REG16(GP_WIDTH, section); 960 961 /* CHECK X DIRECTION */ 962 963 if (dstx > srcx) { 964 /* NEGATIVE X DIRECTION */ 965 /* Still positive X direction within the section. */ 966 967 srcx -= section; 968 dstx -= section; 969 WRITE_REG16(GP_SRC_XCOOR, srcx); 970 WRITE_REG16(GP_DST_XCOOR, dstx); 971 WRITE_REG16(GP_BLIT_MODE, blit_mode); 972 } else { 973 /* POSITIVE X DIRECTION */ 974 975 WRITE_REG16(GP_SRC_XCOOR, srcx); 976 WRITE_REG16(GP_DST_XCOOR, dstx); 977 WRITE_REG16(GP_BLIT_MODE, blit_mode); 978 dstx += section; 979 srcx += section; 980 } 981 width -= section; 982 } 983} 984 985/* 986//---------------------------------------------------------------------------- 987// SCREEN TO SCREEN TRANSPARENT BLT 988// 989// This routine should be used to perform a screen to screen BLT when a 990// specified color should by transparent. The only supported ROP is SRCCOPY. 991// 992// SRCX screen X position to copy from 993// SRCY screen Y position to copy from 994// DSTX screen X position to copy to 995// DSTY screen Y position to copy to 996// WIDTH width of rectangle, in pixels 997// HEIGHT height of rectangle, in scanlines 998// COLOR transparent color 999//---------------------------------------------------------------------------- 1000*/ 1001#if GFX_2DACCEL_DYNAMIC 1002void 1003gu1_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 1004 unsigned short dstx, unsigned short dsty, 1005 unsigned short width, unsigned short height, 1006 unsigned long color) 1007#else 1008void 1009gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 1010 unsigned short dstx, unsigned short dsty, 1011 unsigned short width, unsigned short height, 1012 unsigned long color) 1013#endif 1014{ 1015 unsigned short section, buffer_width; 1016 unsigned short blit_mode = BM_READ_SRC_FB; 1017 1018 /* CHECK Y DIRECTION */ 1019 /* Hardware has support for negative Y direction. */ 1020 1021 if (dsty > srcy) { 1022 blit_mode |= BM_REVERSE_Y; 1023 srcy += height - 1; 1024 dsty += height - 1; 1025 } 1026 1027 /* CHECK X DIRECTION */ 1028 /* Hardware does not support negative X direction since at the time */ 1029 /* of development all supported resolutions could fit a scanline of */ 1030 /* data at once into the BLT buffers (using both BB0 and BB1). This */ 1031 /* code is more generic to allow for any size BLT buffer. */ 1032 1033 if (dstx > srcx) { 1034 srcx += width; 1035 dstx += width; 1036 } 1037 1038 /* CALCULATE BLT BUFFER SIZE */ 1039 /* Need to use BB1 to store the BLT buffer data. */ 1040 1041 buffer_width = GFXbufferWidthPixels; 1042 1043 /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ 1044 1045 if (GFXbpp == 8) { 1046 color &= 0x00FF; 1047 color |= (color << 8); 1048 } 1049 color = (color & 0x0000FFFF) | (color << 16); 1050 1051 /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ 1052 /* Need to make sure any previous BLT using BB1 is complete. */ 1053 /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ 1054 1055 GFX_WAIT_BUSY; 1056 WRITE_SCRATCH32(GFXbb1Base, color); 1057 1058 /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ 1059 /* Already know graphics pipeline is idle. */ 1060 /* Only need to latch data into the holding registers for the current */ 1061 /* data from BB1. A 1 pixel wide BLT will suffice. */ 1062 1063 WRITE_REG32(GP_DST_XCOOR, 0); 1064 WRITE_REG32(GP_SRC_XCOOR, 0); 1065 WRITE_REG32(GP_WIDTH, 0x00010001); 1066 WRITE_REG16(GP_RASTER_MODE, 0x00CC); 1067 WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); 1068 1069 /* WRITE REGISTERS FOR REAL SCREEN TO SCREEN BLT */ 1070 1071 GFX_WAIT_PENDING; 1072 WRITE_REG16(GP_HEIGHT, height); 1073 WRITE_REG16(GP_RASTER_MODE, 0x10C6); 1074 WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); 1075 1076 /* REPEAT UNTIL FINISHED WITH RECTANGLE */ 1077 /* Perform BLT in vertical sections, as wide as the BLT buffer allows. */ 1078 /* Hardware does not split the operations, so software must do it to */ 1079 /* avoid large scanlines that would overflow the BLT buffers. */ 1080 1081 while (width > 0) { 1082 /* CHECK WIDTH OF CURRENT SECTION */ 1083 1084 if (width > buffer_width) 1085 section = buffer_width; 1086 else 1087 section = width; 1088 1089 /* PROGRAM REGISTERS THAT ARE THE SAME FOR EITHER X DIRECTION */ 1090 1091 GFX_WAIT_PENDING; 1092 WRITE_REG16(GP_SRC_YCOOR, srcy); 1093 WRITE_REG16(GP_DST_YCOOR, dsty); 1094 WRITE_REG16(GP_WIDTH, section); 1095 1096 /* CHECK X DIRECTION */ 1097 /* Again, this must be done in software, and can be removed if the */ 1098 /* display driver knows that the BLT buffers will always be large */ 1099 /* enough to contain an entire scanline of a screen to screen BLT. */ 1100 1101 if (dstx > srcx) { 1102 /* NEGATIVE X DIRECTION */ 1103 /* Still positive X direction within the section. */ 1104 1105 srcx -= section; 1106 dstx -= section; 1107 WRITE_REG16(GP_SRC_XCOOR, srcx); 1108 WRITE_REG16(GP_DST_XCOOR, dstx); 1109 WRITE_REG16(GP_BLIT_MODE, blit_mode); 1110 } else { 1111 /* POSITIVE X DIRECTION */ 1112 1113 WRITE_REG16(GP_SRC_XCOOR, srcx); 1114 WRITE_REG16(GP_DST_XCOOR, dstx); 1115 WRITE_REG16(GP_BLIT_MODE, blit_mode); 1116 dstx += section; 1117 srcx += section; 1118 } 1119 width -= section; 1120 } 1121} 1122 1123/* 1124//---------------------------------------------------------------------------- 1125// COLOR BITMAP TO SCREEN BLT 1126// 1127// This routine transfers color bitmap data to the screen. For most cases, 1128// when the ROP is SRCCOPY, it may be faster to write a separate routine that 1129// copies the data to the frame buffer directly. This routine should be 1130// used when the ROP requires destination data. 1131// 1132// Transparency is handled by another routine. 1133// 1134// SRCX X offset within source bitmap 1135// SRCY Y offset within source bitmap 1136// DSTX screen X position to render data 1137// DSTY screen Y position to render data 1138// WIDTH width of rectangle, in pixels 1139// HEIGHT height of rectangle, in scanlines 1140// *DATA pointer to bitmap data 1141// PITCH pitch of bitmap data (bytes between scanlines) 1142//---------------------------------------------------------------------------- 1143*/ 1144 1145#if GFX_2DACCEL_DYNAMIC 1146void 1147gu1_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 1148 unsigned short dstx, unsigned short dsty, 1149 unsigned short width, unsigned short height, 1150 unsigned char *data, long pitch) 1151#else 1152void 1153gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 1154 unsigned short dstx, unsigned short dsty, 1155 unsigned short width, unsigned short height, 1156 unsigned char *data, long pitch) 1157#endif 1158{ 1159 unsigned short section, buffer_width; 1160 unsigned short blit_mode = BM_READ_SRC_BB0; 1161 unsigned short temp_height; 1162 unsigned long dword_bytes_needed, bytes_extra; 1163 unsigned long bpp_shift; 1164 long array_offset; 1165 1166 /* CHECK SIZE OF BLT BUFFER */ 1167 1168 buffer_width = GFXbufferWidthPixels; 1169 1170 /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ 1171 /* If no destination data, we have twice the room for */ 1172 /* source data. */ 1173 1174 if (GFXusesDstData) 1175 blit_mode |= BM_READ_DST_FB1; 1176 else 1177 buffer_width <<= 1; 1178 1179 /* SET THE SCRATCHPAD BASE */ 1180 1181 SET_SCRATCH_BASE(GFXbb0Base); 1182 1183 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1184 /* Write the registers that do not change for each section. */ 1185 1186 GFX_WAIT_PENDING; 1187 WRITE_REG16(GP_HEIGHT, 1); 1188 1189 bpp_shift = (GFXbpp + 7) >> 4; 1190 1191 while (width > 0) { 1192 if (width > buffer_width) 1193 section = buffer_width; 1194 else 1195 section = width; 1196 1197 dword_bytes_needed = (section << bpp_shift) & ~3l; 1198 bytes_extra = (section << bpp_shift) & 3l; 1199 1200 temp_height = height; 1201 1202 /* WRITE THE REGISTERS FOR EACH SECTION */ 1203 /* The GX hardware will auto-increment the Y coordinate, meaning */ 1204 /* that we don't have to. */ 1205 1206 WRITE_REG16(GP_WIDTH, section); 1207 WRITE_REG16(GP_DST_XCOOR, dstx); 1208 WRITE_REG16(GP_DST_YCOOR, dsty); 1209 1210 /* CALCULATE THE BITMAP OFFSET */ 1211 1212 array_offset = 1213 (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift); 1214 1215 while (temp_height--) { 1216 GFX_WAIT_PIPELINE; 1217 1218 /* WRITE ALL DATA TO THE BLT BUFFERS */ 1219 /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 1220 /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 1221 1222 WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 1223 array_offset); 1224 WRITE_REG16(GP_BLIT_MODE, blit_mode); 1225 1226 array_offset += pitch; 1227 } 1228 1229 width -= section; 1230 srcx += section; 1231 dstx += section; 1232 } 1233} 1234 1235/* 1236//---------------------------------------------------------------------------- 1237// COLOR BITMAP TO SCREEN TRANSPARENT BLT 1238// 1239// This routine transfers color bitmap data to the screen with transparency. 1240// The transparent color is specified. The only supported ROP is SRCCOPY, 1241// meaning that transparency cannot be applied if the ROP requires 1242// destination data (this is a hardware restriction). 1243// 1244// SRCX X offset within source bitmap 1245// SRCY Y offset within source bitmap 1246// DSTX screen X position to render data 1247// DSTY screen Y position to render data 1248// WIDTH width of rectangle, in pixels 1249// HEIGHT height of rectangle, in scanlines 1250// *DATA pointer to bitmap data 1251// PITCH pitch of bitmap data (bytes between scanlines) 1252// COLOR transparent color 1253//---------------------------------------------------------------------------- 1254*/ 1255#if GFX_2DACCEL_DYNAMIC 1256void 1257gu1_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 1258 unsigned short dstx, unsigned short dsty, 1259 unsigned short width, unsigned short height, 1260 unsigned char *data, long pitch, 1261 unsigned long color) 1262#else 1263void 1264gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 1265 unsigned short dstx, unsigned short dsty, 1266 unsigned short width, unsigned short height, 1267 unsigned char *data, long pitch, 1268 unsigned long color) 1269#endif 1270{ 1271 unsigned short section, buffer_width; 1272 unsigned short temp_height; 1273 unsigned long dword_bytes_needed, bytes_extra; 1274 unsigned long bpp_shift; 1275 long array_offset; 1276 1277 /* CHECK SIZE OF BLT BUFFER */ 1278 1279 buffer_width = GFXbufferWidthPixels; 1280 1281 /* WRITE TRANSPARENCY COLOR TO BLT BUFFER 1 */ 1282 1283 if (GFXbpp == 8) { 1284 color &= 0x00FF; 1285 color |= (color << 8); 1286 } 1287 color = (color & 0x0000FFFF) | (color << 16); 1288 1289 /* WAIT UNTIL PIPELINE IS NOT BUSY BEFORE LOADING DATA INTO BB1 */ 1290 /* Need to make sure any previous BLT using BB1 is complete. */ 1291 /* Only need to load 32 bits of BB1 for the 1 pixel BLT that follows. */ 1292 1293 GFX_WAIT_PIPELINE; 1294 GFX_WAIT_PENDING; 1295 WRITE_SCRATCH32(GFXbb1Base, color); 1296 1297 /* DO BOGUS BLT TO LATCH DATA FROM BB1 */ 1298 /* Already know graphics pipeline is idle. */ 1299 /* Only need to latch data into the holding registers for the current */ 1300 /* data from BB1. A 1 pixel wide BLT will suffice. */ 1301 1302 WRITE_REG32(GP_DST_XCOOR, 0); 1303 WRITE_REG32(GP_SRC_XCOOR, 0); 1304 WRITE_REG32(GP_WIDTH, 0x00010001); 1305 WRITE_REG16(GP_RASTER_MODE, 0x00CC); 1306 WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_FB | BM_READ_DST_BB1); 1307 1308 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1309 /* Write the registers that do not change for each section. */ 1310 1311 GFX_WAIT_PENDING; 1312 WRITE_REG16(GP_HEIGHT, 1); 1313 WRITE_REG16(GP_RASTER_MODE, 0x10C6); 1314 WRITE_REG32(GP_PAT_COLOR_0, 0xFFFFFFFF); 1315 1316 bpp_shift = (GFXbpp + 7) >> 4; 1317 1318 /* SET THE SCRATCHPAD BASE */ 1319 1320 SET_SCRATCH_BASE(GFXbb0Base); 1321 1322 while (width > 0) { 1323 if (width > buffer_width) 1324 section = buffer_width; 1325 else 1326 section = width; 1327 1328 dword_bytes_needed = (section << bpp_shift) & ~3l; 1329 bytes_extra = (section << bpp_shift) & 3l; 1330 1331 temp_height = height; 1332 1333 /* WRITE THE REGISTERS FOR EACH SECTION */ 1334 /* The GX hardware will auto-increment the Y coordinate, meaning */ 1335 /* that we don't have to. */ 1336 1337 WRITE_REG16(GP_WIDTH, section); 1338 WRITE_REG16(GP_DST_XCOOR, dstx); 1339 WRITE_REG16(GP_DST_YCOOR, dsty); 1340 1341 /* CALCULATE THE BITMAP OFFSET */ 1342 1343 array_offset = 1344 (unsigned long)srcy *(long)pitch + ((long)srcx << bpp_shift); 1345 1346 while (temp_height--) { 1347 GFX_WAIT_PIPELINE; 1348 1349 /* WRITE ALL DATA TO THE BLT BUFFERS */ 1350 /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 1351 /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 1352 1353 WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 1354 array_offset); 1355 WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0); 1356 1357 array_offset += pitch; 1358 } 1359 1360 width -= section; 1361 srcx += section; 1362 dstx += section; 1363 } 1364} 1365 1366/* 1367//---------------------------------------------------------------------------- 1368// MONOCHROME BITMAP TO SCREEN BLT 1369// 1370// This routine transfers monochrome bitmap data to the screen. 1371// 1372// SRCX X offset within source bitmap 1373// SRCY Y offset within source bitmap 1374// DSTX screen X position to render data 1375// DSTY screen Y position to render data 1376// WIDTH width of rectangle, in pixels 1377// HEIGHT height of rectangle, in scanlines 1378// *DATA pointer to bitmap data 1379// PITCH pitch of bitmap data (bytes between scanlines) 1380//---------------------------------------------------------------------------- 1381*/ 1382#if GFX_2DACCEL_DYNAMIC 1383void 1384gu1_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 1385 unsigned short dstx, unsigned short dsty, 1386 unsigned short width, unsigned short height, 1387 unsigned char *data, short pitch) 1388#else 1389void 1390gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 1391 unsigned short dstx, unsigned short dsty, 1392 unsigned short width, unsigned short height, 1393 unsigned char *data, short pitch) 1394#endif 1395{ 1396 unsigned short section, buffer_width; 1397 unsigned short blit_mode = BM_READ_SRC_BB0 | BM_SOURCE_EXPAND; 1398 unsigned short temp_height; 1399 unsigned long dword_bytes_needed, bytes_extra; 1400 long array_offset; 1401 1402 /* CHECK IF RASTER OPERATION REQUIRES DESTINATION DATA */ 1403 /* If no destination data, the source data will always fit. */ 1404 /* So, in that event we will set the buffer width to a */ 1405 /* fictitiously large value such that the BLT is never split. */ 1406 1407 if (GFXusesDstData) { 1408 buffer_width = GFXbufferWidthPixels; 1409 blit_mode |= BM_READ_DST_FB1; 1410 } else 1411 buffer_width = 3200; 1412 1413 /* CHECK IF DATA ALREADY IN BLIT BUFFER */ 1414 /* If the pointer is NULL, data for the full BLT is already there */ 1415 /* WARNING: This could cause problems if destination data is */ 1416 /* involved and it overflows the BLT buffer. Need to remove */ 1417 /* this option and change the drivers to use a temporary buffer. */ 1418 1419 if (!data) { 1420 GFX_WAIT_PENDING; 1421 WRITE_REG16(GP_SRC_XCOOR, srcx & 7); 1422 WRITE_REG16(GP_DST_XCOOR, dstx); 1423 WRITE_REG16(GP_DST_YCOOR, dsty); 1424 WRITE_REG16(GP_WIDTH, width); 1425 WRITE_REG16(GP_HEIGHT, height); 1426 WRITE_REG16(GP_BLIT_MODE, blit_mode); 1427 return; 1428 } 1429 1430 /* SET THE SCRATCHPAD BASE */ 1431 1432 SET_SCRATCH_BASE(GFXbb0Base); 1433 1434 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1435 /* Write the registers that do not change for each section. */ 1436 1437 GFX_WAIT_PENDING; 1438 WRITE_REG16(GP_HEIGHT, 1); 1439 1440 while (width > 0) { 1441 if (width > buffer_width) 1442 section = buffer_width; 1443 else 1444 section = width; 1445 1446 /* CALCULATE BYTES NEEDED */ 1447 /* Add 1 for possible alignment issues. */ 1448 1449 dword_bytes_needed = ((section + 7 + (srcx & 7)) >> 3) & ~3l; 1450 bytes_extra = ((section + 7 + (srcx & 7)) >> 3) & 3l; 1451 1452 temp_height = height; 1453 1454 /* WRITE THE REGISTERS FOR EACH SECTION */ 1455 /* The GX hardware will auto-increment the Y coordinate, meaning */ 1456 /* that we don't have to. */ 1457 1458 WRITE_REG16(GP_WIDTH, section); 1459 WRITE_REG16(GP_DST_XCOOR, dstx); 1460 WRITE_REG16(GP_DST_YCOOR, dsty); 1461 WRITE_REG16(GP_SRC_XCOOR, srcx & 7); 1462 1463 /* CALCULATE THE BITMAP OFFSET */ 1464 1465 array_offset = (unsigned long)srcy *(long)pitch + ((long)srcx >> 3); 1466 1467 while (temp_height--) { 1468 GFX_WAIT_PIPELINE; 1469 1470 /* WRITE ALL DATA TO THE BLT BUFFERS */ 1471 /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 1472 /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 1473 1474 WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 1475 array_offset); 1476 WRITE_REG16(GP_BLIT_MODE, blit_mode); 1477 1478 array_offset += pitch; 1479 } 1480 1481 width -= section; 1482 srcx += section; 1483 dstx += section; 1484 } 1485} 1486 1487/* 1488//---------------------------------------------------------------------------- 1489// MONOCHROME TEXT BLT 1490// 1491// This routine transfers contiguous monochrome text data to the screen. 1492// 1493// DSTX screen X position to render data 1494// DSTY screen Y position to render data 1495// WIDTH width of rectangle, in pixels 1496// HEIGHT height of rectangle, in scanlines 1497// *DATA pointer to bitmap data 1498//---------------------------------------------------------------------------- 1499*/ 1500#if GFX_2DACCEL_DYNAMIC 1501void 1502gu1_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, 1503 unsigned short height, unsigned char *data) 1504#else 1505void 1506gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, 1507 unsigned short height, unsigned char *data) 1508#endif 1509{ 1510 unsigned long dword_bytes_needed, bytes_extra; 1511 long pitch, buffer_bytes, data_bytes; 1512 1513 /* CALCULATE DATA SIZE */ 1514 1515 pitch = (width + 7) >> 3; 1516 data_bytes = (long)height *pitch; 1517 1518 /* CHECK FOR SIMPLE CASE */ 1519 /* This routine is designed to render a source copy text glyph. If destination */ 1520 /* data is required or the source data will not fit, we will punt the operation */ 1521 /* to the more versatile (and slow) mono bitmap routine. */ 1522 1523 if (GFXbpp > 8) 1524 buffer_bytes = GFXbufferWidthPixels << 1; 1525 else 1526 buffer_bytes = GFXbufferWidthPixels; 1527 1528 if (GFXusesDstData || data_bytes > buffer_bytes) { 1529 gfx_mono_bitmap_to_screen_blt(0, 0, dstx, dsty, width, height, data, 1530 (short)pitch); 1531 return; 1532 } 1533 1534 /* SET THE SCRATCHPAD BASE */ 1535 1536 SET_SCRATCH_BASE(GFXbb0Base); 1537 1538 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1539 1540 dword_bytes_needed = data_bytes & ~3l; 1541 bytes_extra = data_bytes & 3l; 1542 1543 GFX_WAIT_PENDING; 1544 WRITE_REG16(GP_HEIGHT, height); 1545 WRITE_REG16(GP_WIDTH, width); 1546 WRITE_REG16(GP_DST_XCOOR, dstx); 1547 WRITE_REG16(GP_DST_YCOOR, dsty); 1548 WRITE_REG16(GP_SRC_XCOOR, 0); 1549 1550 /* WRITE ALL DATA TO THE BLT BUFFERS */ 1551 /* The WRITE_SCRATCH_STRING macro assumes that the data begins at the */ 1552 /* scratchpad offset set by the SET_SCRATCH_BASE macro. */ 1553 1554 GFX_WAIT_PIPELINE; 1555 1556 WRITE_SCRATCH_STRING(dword_bytes_needed, bytes_extra, data, 0); 1557 WRITE_REG16(GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_SOURCE_TEXT); 1558} 1559 1560/* 1561//---------------------------------------------------------------------------- 1562// BRESENHAM LINE 1563// 1564// This routine draws a vector using the specified Bresenham parameters. 1565// Currently this file does not support a routine that accepts the two 1566// endpoints of a vector and calculates the Bresenham parameters. If it 1567// ever does, this routine is still required for vectors that have been 1568// clipped. 1569// 1570// X screen X position to start vector 1571// Y screen Y position to start vector 1572// LENGTH length of the vector, in pixels 1573// INITERR Bresenham initial error term 1574// AXIALERR Bresenham axial error term 1575// DIAGERR Bresenham diagonal error term 1576// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC 1577//---------------------------------------------------------------------------- 1578*/ 1579#if GFX_2DACCEL_DYNAMIC 1580void 1581gu1_bresenham_line(unsigned short x, unsigned short y, 1582 unsigned short length, unsigned short initerr, 1583 unsigned short axialerr, unsigned short diagerr, 1584 unsigned short flags) 1585#else 1586void 1587gfx_bresenham_line(unsigned short x, unsigned short y, 1588 unsigned short length, unsigned short initerr, 1589 unsigned short axialerr, unsigned short diagerr, 1590 unsigned short flags) 1591#endif 1592{ 1593 unsigned short vector_mode = flags; 1594 1595 if (GFXusesDstData) 1596 vector_mode |= VM_READ_DST_FB; 1597 1598 /* CHECK NULL LENGTH */ 1599 1600 if (!length) 1601 return; 1602 1603 /* LOAD THE REGISTERS FOR THE VECTOR */ 1604 1605 GFX_WAIT_PENDING; 1606 WRITE_REG16(GP_DST_XCOOR, x); 1607 WRITE_REG16(GP_DST_YCOOR, y); 1608 WRITE_REG16(GP_VECTOR_LENGTH, length); 1609 WRITE_REG16(GP_INIT_ERROR, initerr); 1610 WRITE_REG16(GP_AXIAL_ERROR, axialerr); 1611 WRITE_REG16(GP_DIAG_ERROR, diagerr); 1612 WRITE_REG16(GP_VECTOR_MODE, vector_mode); 1613} 1614 1615/*--------------------------------------------------------------------------- 1616 * GFX_WAIT_UNTIL_IDLE 1617 * 1618 * This routine waits until the graphics engine is idle. This is required 1619 * before allowing direct access to the frame buffer. 1620 *--------------------------------------------------------------------------- 1621 */ 1622#if GFX_2DACCEL_DYNAMIC 1623void 1624gu1_wait_until_idle(void) 1625#else 1626void 1627gfx_wait_until_idle(void) 1628#endif 1629{ 1630 GFX_WAIT_BUSY; 1631} 1632 1633/*--------------------------------------------------------------------------- 1634 * GFX_TEST_BLT_PENDING 1635 * 1636 * This routine returns 1 if a BLT is pending, meaning that a call to 1637 * perform a rendering operation would stall. Otherwise it returns 0. 1638 * It is used by Darwin during random testing to only start a BLT 1639 * operation when it knows the Durango routines won't spin on graphics 1640 * (so Darwin can continue to do frame buffer reads and writes). 1641 *--------------------------------------------------------------------------- 1642 */ 1643#if GFX_2DACCEL_DYNAMIC 1644int 1645gu1_test_blt_pending(void) 1646#else 1647int 1648gfx_test_blt_pending(void) 1649#endif 1650{ 1651 if (READ_REG16(GP_BLIT_STATUS) & BS_BLIT_PENDING) 1652 return (1); 1653 else 1654 return (0); 1655} 1656 1657/*--------------------------------------------------------------------------- 1658 * BLT BUFFERS!!!!! 1659 *--------------------------------------------------------------------------- 1660 */ 1661 1662/* THE BOOT CODE MUST SET THE BLT BUFFER BASES USING THE "CPU_WRITE" */ 1663/* INSTRUCTION TO ONE OF THE FOLLOWING VALUES: */ 1664 1665#define BB0_BASE_2K 0x800 1666#define BB1_BASE_2K 0xB30 1667#define BB0_BASE_3K 0x400 1668#define BB1_BASE_3K 0x930 1669 1670/*--------------------------------------------------------------------------- 1671 * gu1_detect_blt_buffer_base 1672 * 1673 * This detection is hidden from the driver by being called from the 1674 * "gfx_set_bpp" routine. 1675 * 1676 * This is fairly ugly for the following reasons: 1677 * 1678 * - It is the boot code that must set the BLT buffer bases to the 1679 * appropriate values and load the scratchpad tags. 1680 * - The old drivers would also set the base address values to what they 1681 * knew they should be for the 2K or 3K scratchpad configuration. 1682 * - Unfortunately, to set the base addresses requires the use of the 1683 * CPU_WRITE instruction, an instruction specific to GX. 1684 * - Using the CPU_WRITE instruction requires the use of assembly to 1685 * produce the appropriate op codes. 1686 * - Assembly is something that is avoided in Durango because it is not 1687 * platform independent. Some compilers do not support inline assembly. 1688 * - Therefore Durango cannot use the CPU_WRITE instruction. 1689 * - Therefore drivers using Durango must rely on the boot code to set 1690 * the appropriate values. Durango uses this routine to check where 1691 * the base addresses have been set. 1692 * - Unfortunately, it is not as simple as using IO to check for 2K or 3K 1693 * scratchpad size. In VSA1, even though the boot code may set it for 1694 * 3K, SoftVGA comes along and resets it to 2K for it's use in text 1695 * redraws. It used to be that the display driver would set it back 1696 * to 3K. 1697 * - So, the Durango code was changed to just always use 2K. 1698 * - But, the XpressROM code sets it for 3K, and the newer versions of 1699 * SoftVGA do not interfere with that, so then Durango needs to use 1700 * the 3K values to work properly. 1701 * - Therefore, Durango does somewhat of a kludge by writing to directly 1702 * to the scratchpad at both the 2K and 3K locations, then performing 1703 * a unobtrusive BLT that loads data into BB0 (the graphics engine 1704 * always knows the true base). After the BLT, Durango looks to see 1705 * which location changed to know where the base address is. 1706 * - This is a relatively simple way to allow Durango to work on old 1707 * and new platforms without using theCPU_WRITE instructions. 1708 * 1709 * To summarize, the BLT buffers are one of the most painful aspects of 1710 * the GX graphics unit design, and have been removed from future designs 1711 * (the graphics unit has its own dedicated RAM). Durango has tried to 1712 * hide the BLT buffer use from the drivers. 1713 *--------------------------------------------------------------------------- 1714 */ 1715void 1716gu1_detect_blt_buffer_base(void) 1717{ 1718 /* ASSUME 2K */ 1719 1720 GFXbb0Base = BB0_BASE_2K; 1721 GFXbb1Base = BB1_BASE_2K; 1722 1723 /* CHECK IF SCRATCHPAD IS SET TO 3K OR 4K */ 1724 /* Boot code should still set 3K values for 4K. */ 1725 1726 if (gfx_gxm_config_read(GXM_CONFIG_GCR) & 0x08) { 1727 /* WRITE DATA TO 3K LOCATION */ 1728 1729 GFX_WAIT_BUSY; 1730 WRITE_SCRATCH32(BB0_BASE_3K, 0xFEEDFACE); 1731 1732 /* HAVE THE GRAPHICS UNIT STORE SOMETHING IN BB0 */ 1733 1734 WRITE_REG32(GP_DST_XCOOR, 0x00000000); /* AT (0,0) */ 1735 WRITE_REG32(GP_WIDTH, 0x00010004); /* 4x1 BLT */ 1736 WRITE_REG16(GP_RASTER_MODE, 0x00AA); /* KEEP DST */ 1737 WRITE_REG16(GP_BLIT_MODE, BM_READ_DST_FB0); /* STORE IN BB0 */ 1738 1739 /* CHECK 3K LOCATION */ 1740 /* Breaks if data happened to be 0xFEEDFACE - unlikely. */ 1741 1742 GFX_WAIT_BUSY; 1743 if (READ_SCRATCH32(BB0_BASE_3K) != 0xFEEDFACE) { 1744 GFXbb0Base = BB0_BASE_3K; 1745 GFXbb1Base = BB1_BASE_3K; 1746 } 1747 } 1748} 1749 1750/* END OF FILE */ 1751