via_display.c revision 861b9fee
1/* 2 * Copyright 2015-2016 Kevin Brace 3 * Copyright 2005-2016 The OpenChrome Project 4 * [https://www.freedesktop.org/wiki/Openchrome] 5 * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] 6 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 7 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sub license, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial portions 18 * of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28#ifdef HAVE_CONFIG_H 29#include "config.h" 30#endif 31 32#include <stdint.h> 33#include "via_driver.h" 34 35static ViaExpireNumberTable CLE266AExpireNumber[] = { 36 {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x3}, 37 {1600,1200,16,0x03,0x4}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA}, 38 {1400,1050,16,0x03,0x3}, {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4}, 39 { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0} 40}; 41 42static ViaExpireNumberTable CLE266CExpireNumber[] = { 43 {1280, 768,32,0x03,0x3}, {1280,1024,32,0x03,0x4}, {1280,1024,32,0x04,0x4}, 44 {1600,1200,32,0x03,0x3}, {1600,1200,32,0x04,0x4}, {1024, 768,32,0x03,0xA}, 45 {1400,1050,32,0x03,0x4}, {1400,1050,32,0x04,0x4}, 46 { 800, 600,32,0x03,0xA}, { 0, 0, 0, 0, 0} 47}; 48 49static ViaExpireNumberTable KM400ExpireNumber[]={ 50 {1280,1024,32,0x03,0x3}, {1280,1024,32,0x04,0x9}, {1280, 768,32,0x03,0x3}, 51 {1280, 768,32,0x04,0x9}, {1400,1050,32,0x03,0x3}, {1400,1050,32,0x04,0x9}, 52 {1600,1200,32,0x03,0x4}, {1600,1200,32,0x04,0xA}, { 0, 0, 0, 0, 0} 53}; 54 55 56static void 57ViaPrintMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 58{ 59 xf86PrintModeline(pScrn->scrnIndex, mode); 60 61 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%x\n", 62 mode->CrtcHDisplay); 63 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%x\n", 64 mode->CrtcHBlankStart); 65 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%x\n", 66 mode->CrtcHSyncStart); 67 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%x\n", 68 mode->CrtcHSyncEnd); 69 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%x\n", 70 mode->CrtcHBlankEnd); 71 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%x\n", 72 mode->CrtcHTotal); 73 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSkew: 0x%x\n", 74 mode->CrtcHSkew); 75 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%x\n", 76 mode->CrtcVDisplay); 77 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%x\n", 78 mode->CrtcVBlankStart); 79 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%x\n", 80 mode->CrtcVSyncStart); 81 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%x\n", 82 mode->CrtcVSyncEnd); 83 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%x\n", 84 mode->CrtcVBlankEnd); 85 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%x\n", 86 mode->CrtcVTotal); 87 88} 89 90/* 91 * Sets IGA1 or IGA2 for palette LUT access. 92 * This function should be called before changing the 93 * contents of the palette. 94 */ 95static void 96viaSetPaletteLUTAccess(ScrnInfoPtr pScrn, CARD8 displaySource) 97{ 98 vgaHWPtr hwp = VGAHWPTR(pScrn); 99 100 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 101 "Entered viaSetPaletteLUTAccess.\n")); 102 103 ViaSeqMask(hwp, 0x1A, displaySource, 0x01); 104 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 105 "Palette LUT Access: IGA%d\n", 106 (displaySource & 0x01) + 1); 107 108 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 109 "Exiting viaSetPaletteLUTAccess.\n")); 110} 111 112/* 113 * Resets IGA1 hardware. 114 */ 115static void 116viaIGA1HWReset(ScrnInfoPtr pScrn, CARD8 resetState) 117{ 118 vgaHWPtr hwp = VGAHWPTR(pScrn); 119 120 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 121 "Entered viaIGA1HWReset.\n")); 122 123 /* 3X5.17[7] - IGA1 HW Reset 124 * 0: Reset 125 * 1: Normal Operation */ 126 ViaCrtcMask(hwp, 0x17, resetState << 7, 0x80); 127 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 128 "IGA1 HW Reset: %s\n", 129 (resetState & 0x01) ? "Off" : "On"); 130 131 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 132 "Exiting viaIGA1HWReset.\n")); 133} 134 135/* 136 * Controls IGA1 DPMS State. 137 */ 138static void 139viaIGA1DPMSControl(ScrnInfoPtr pScrn, CARD8 dpmsControl) 140{ 141 vgaHWPtr hwp = VGAHWPTR(pScrn); 142 143 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 144 "Entered viaIGA1DPMSControl.\n")); 145 146 /* 3X5.36[5:4] - DPMS Control 147 * 00: On 148 * 01: Stand-by 149 * 10: Suspend 150 * 11: Off */ 151 ViaCrtcMask(hwp, 0x36, dpmsControl << 4, 0x30); 152 153 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 154 "Exiting viaIGA1DPMSControl.\n")); 155} 156 157/* 158 * Sets IGA1 color depth. 159 */ 160static void 161viaIGA1SetColorDepth(ScrnInfoPtr pScrn, CARD8 bitsPerPixel) 162{ 163 vgaHWPtr hwp = VGAHWPTR(pScrn); 164 165 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 166 "Entered viaIGA1SetColorDepth.\n")); 167 168 /* Set the color depth for IGA1. */ 169 switch (bitsPerPixel) { 170 case 8: 171 /* 3C5.15[4] - Hi Color Mode Select 172 * 0: 555 173 * 1: 565 174 * 3C5.15[3:2] - Display Color Depth Select 175 * 00: 8bpp 176 * 01: 16bpp 177 * 10: 30bpp 178 * 11: 32bpp */ 179 ViaSeqMask(hwp, 0x15, 0x00, 0x1C); 180 break; 181 case 16: 182 ViaSeqMask(hwp, 0x15, 0x14, 0x1C); 183 break; 184 case 24: 185 case 32: 186 ViaSeqMask(hwp, 0x15, 0x1C, 0x1C); 187 break; 188 default: 189 break; 190 } 191 192 if ((bitsPerPixel == 8) 193 || (bitsPerPixel == 16) 194 || (bitsPerPixel == 24) 195 || (bitsPerPixel == 32)) { 196 197 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 198 "IGA1 Color Depth: %d bit\n", 199 bitsPerPixel); 200 } else { 201 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 202 "Unsupported IGA1 Color Depth: %d bit\n", 203 bitsPerPixel); 204 } 205 206 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 207 "Exiting viaIGA1SetColorDepth.\n")); 208} 209 210/* 211 * Sets IGA1 palette LUT resolution. (6-bit or 8-bit) 212 */ 213static void 214viaIGA1SetPaletteLUTResolution(ScrnInfoPtr pScrn, CARD8 paletteLUT) 215{ 216 vgaHWPtr hwp = VGAHWPTR(pScrn); 217 218 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 219 "Entered viaIGA1SetPaletteLUTResolution.\n")); 220 221 /* Set the palette LUT resolution for IGA1. */ 222 /* 3C5.15[7] - IGA1 6 / 8 Bit LUT 223 * 0: 6-bit 224 * 1: 8-bit */ 225 ViaSeqMask(hwp, 0x15, paletteLUT << 7, 0x80); 226 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 227 "IGA1 Palette LUT Resolution: %s bit\n", 228 (paletteLUT & 0x01) ? "8" : "6"); 229 230 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 231 "Exiting viaIGA1SetPaletteLUTResolution.\n")); 232} 233 234/* 235 * Controls IGA1 gamma correction state. 236 */ 237static void 238viaIGA1SetGamma(ScrnInfoPtr pScrn, CARD8 gammaCorrection) 239{ 240 VIAPtr pVia = VIAPTR(pScrn); 241 vgaHWPtr hwp = VGAHWPTR(pScrn); 242 243 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 244 "Entered viaIGA1SetGamma.\n")); 245 246 switch (pVia->Chipset) { 247 case VIA_CLE266: 248 case VIA_KM400: 249 /* 3C5.16[7] - IGA1 Gamma Correction 250 * 0: Disable 251 * 1: Enable */ 252 ViaSeqMask(hwp, 0x16, gammaCorrection << 7, 0x80); 253 break; 254 default: 255 /* 3X5.33[7] - IGA1 Gamma Correction 256 * 0: Disable 257 * 1: Enable */ 258 ViaCrtcMask(hwp, 0x33, gammaCorrection << 7, 0x80); 259 break; 260 } 261 262 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 263 "IGA1 Gamma Correction: %s\n", 264 (gammaCorrection & 0x01) ? "On" : "Off"); 265 266 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 267 "Exiting viaIGA1SetGamma.\n")); 268} 269 270static void 271viaIGA1InitHI(ScrnInfoPtr pScrn) 272{ 273 VIAPtr pVia = VIAPTR(pScrn); 274 275 switch(pVia->Chipset) { 276 case VIA_PM800: 277 case VIA_CX700: 278 case VIA_P4M890: 279 case VIA_P4M900: 280 case VIA_VX800: 281 case VIA_VX855: 282 case VIA_VX900: 283 VIASETREG(PRIM_HI_TRANSCOLOR, 0x00000000); 284 VIASETREG(PRIM_HI_INVTCOLOR, 0x00FFFFFF); 285 286 /* Not setting up V327_HI_INVTCOLOR register contributes to 287 * an X Server boot time crash. */ 288 VIASETREG(V327_HI_INVTCOLOR, 0x00FFFFFF); 289 VIASETREG(PRIM_HI_FIFO, 0x0D000D0F); 290 VIASETREG(PRIM_HI_CTRL, 0x36000004); 291 break; 292 default: 293 VIASETREG(HI_TRANSPARENT_COLOR, 0x00000000); 294 VIASETREG(HI_INVTCOLOR, 0x00FFFFFF); 295 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0x000E0000); 296 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 297 VIASETREG(HI_CONTROL, 0x76000004); 298 break; 299 } 300} 301 302static void 303viaIGA1SetHIStartingAddress(xf86CrtcPtr crtc) 304{ 305 306 drmmode_crtc_private_ptr iga = crtc->driver_private; 307 ScrnInfoPtr pScrn = crtc->scrn; 308 VIAPtr pVia = VIAPTR(pScrn); 309 310 switch(pVia->Chipset) { 311 case VIA_PM800: 312 case VIA_CX700: 313 case VIA_P4M890: 314 case VIA_P4M900: 315 case VIA_VX800: 316 case VIA_VX855: 317 case VIA_VX900: 318 VIASETREG(PRIM_HI_FBOFFSET, iga->cursor_bo->offset); 319 break; 320 default: 321 /* Mono Cursor Display Path [bit31]: Primary */ 322 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 323 break; 324 } 325} 326 327/* 328 * This function displays or hides IGA1 hardware icon (HI). 329 */ 330static void 331viaIGA1DisplayHI(ScrnInfoPtr pScrn, Bool HI_Status) 332{ 333 VIAPtr pVia = VIAPTR(pScrn); 334 CARD32 temp; 335 336 switch(pVia->Chipset) { 337 case VIA_PM800: 338 case VIA_CX700: 339 case VIA_P4M890: 340 case VIA_P4M900: 341 case VIA_VX800: 342 case VIA_VX855: 343 case VIA_VX900: 344 temp = VIAGETREG(PRIM_HI_CTRL); 345 temp &= 0xFFFFFFFE; 346 temp |= HI_Status ? 0x00000001 : 0x00000000; 347 348 /* PRIM_HI_CTRL[0] - Hardware Icon (HI) Enable */ 349 VIASETREG(PRIM_HI_CTRL, temp); 350 break; 351 default: 352 temp = VIAGETREG(HI_CONTROL); 353 temp &= 0xFFFFFFFE; 354 temp |= HI_Status ? 0x00000001 : 0x00000000; 355 356 /* HI_CONTROL[0] - Hardware Icon (HI) Enable */ 357 VIASETREG(HI_CONTROL, temp); 358 break; 359 } 360} 361 362static void 363viaIGA1SetHIDisplayLocation(ScrnInfoPtr pScrn, 364 int x, unsigned int xoff, 365 int y, unsigned int yoff) 366{ 367 VIAPtr pVia = VIAPTR(pScrn); 368 369 switch(pVia->Chipset) { 370 case VIA_PM800: 371 case VIA_CX700: 372 case VIA_P4M890: 373 case VIA_P4M900: 374 case VIA_VX800: 375 case VIA_VX855: 376 case VIA_VX900: 377 VIASETREG(PRIM_HI_POSSTART, ((x << 16) | (y & 0x07ff))); 378 VIASETREG(PRIM_HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 379 break; 380 default: 381 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 382 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 383 break; 384 } 385} 386 387/* 388 * Resets IGA2 hardware. 389 */ 390static void 391viaIGA2HWReset(ScrnInfoPtr pScrn, CARD8 resetState) 392{ 393 vgaHWPtr hwp = VGAHWPTR(pScrn); 394 395 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 396 "Entered viaIGA2HWReset.\n")); 397 398 /* 3X5.6A[6] - Second Display Channel Reset 399 * 0: Reset 400 * 1: Normal Operation */ 401 ViaCrtcMask(hwp, 0x6A, resetState << 6, 0x40); 402 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 403 "IGA2 HW Reset: %s\n", 404 (resetState & 0x01) ? "Off" : "On"); 405 406 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 407 "Exiting viaIGA2HWReset.\n")); 408} 409 410/* 411 * Controls IGA2 display output on or off state. 412 */ 413static void 414viaIGA2DisplayOutput(ScrnInfoPtr pScrn, Bool outputState) 415{ 416 vgaHWPtr hwp = VGAHWPTR(pScrn); 417 418 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 419 "Entered viaIGA2DisplayOutput.\n")); 420 421 /* 3X5.6B[2] - IGA2 Screen Off 422 * 0: Screen on 423 * 1: Screen off */ 424 ViaCrtcMask(hwp, 0x6B, outputState ? 0x00 : 0x04, 0x04); 425 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 426 "IGA2 Display Output: %s\n", 427 outputState ? "On" : "Off"); 428 429 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 430 "Exiting viaIGA2DisplayOutput.\n")); 431} 432 433/* 434 * Controls IGA2 display channel state. 435 */ 436void 437viaIGA2DisplayChannel(ScrnInfoPtr pScrn, Bool channelState) 438{ 439 vgaHWPtr hwp = VGAHWPTR(pScrn); 440 441 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 442 "Entered viaIGA2DisplayChannel.\n")); 443 444 /* 3X5.6A[7] - Second Display Channel Enable */ 445 ViaCrtcMask(hwp, 0x6A, channelState << 7, 0x80); 446 447 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 448 "IGA2 Display Channel: %s\n", 449 channelState ? "On" : "Off"); 450 451 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 452 "Exiting viaIGA2DisplayChannel.\n")); 453} 454 455/* 456 * Sets IGA2 color depth. 457 */ 458static void 459viaIGA2SetColorDepth(ScrnInfoPtr pScrn, CARD8 bitsPerPixel) 460{ 461 vgaHWPtr hwp = VGAHWPTR(pScrn); 462 463 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 464 "Entered viaIGA2SetColorDepth.\n")); 465 466 /* Set the color depth for IGA2. */ 467 switch (pScrn->bitsPerPixel) { 468 case 8: 469 /* 3X5.67[7:6] - Display Color Depth Select 470 * 00: 8bpp 471 * 01: 16bpp 472 * 10: 30bpp 473 * 11: 32bpp */ 474 ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); 475 break; 476 case 16: 477 ViaCrtcMask(hwp, 0x67, 0x40, 0xC0); 478 break; 479 case 24: 480 case 32: 481 ViaCrtcMask(hwp, 0x67, 0xC0, 0xC0); 482 break; 483 default: 484 break; 485 } 486 487 if ((bitsPerPixel == 8) 488 || (bitsPerPixel == 16) 489 || (bitsPerPixel == 24) 490 || (bitsPerPixel == 32)) { 491 492 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 493 "IGA2 Color Depth: %d bit\n", 494 bitsPerPixel); 495 } else { 496 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 497 "Unsupported IGA2 Color Depth: %d bit\n", 498 bitsPerPixel); 499 } 500 501 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 502 "Exiting viaIGA2SetColorDepth.\n")); 503} 504 505/* 506 * Sets IGA2 palette LUT resolution. (6-bit or 8-bit) 507 */ 508static void 509viaIGA2SetPaletteLUTResolution(ScrnInfoPtr pScrn, CARD8 paletteLUT) 510{ 511 vgaHWPtr hwp = VGAHWPTR(pScrn); 512 513 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 514 "Entered viaIGA2SetPaletteLUTResolution.\n")); 515 516 /* Set the palette LUT resolution for IGA2. */ 517 /* 3X5.6A[5] - IGA2 6 / 8 Bit LUT 518 * 0: 6-bit 519 * 1: 8-bit */ 520 ViaCrtcMask(hwp, 0x6A, paletteLUT << 5, 0x20); 521 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 522 "IGA2 Palette LUT Resolution: %s bit\n", 523 (paletteLUT & 0x01) ? "8" : "6"); 524 525 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 526 "Exiting viaIGA2SetPaletteLUTResolution.\n")); 527} 528 529/* 530 * Controls IGA2 gamma correction state. 531 */ 532static void 533viaIGA2SetGamma(ScrnInfoPtr pScrn, CARD8 gammaCorrection) 534{ 535 vgaHWPtr hwp = VGAHWPTR(pScrn); 536 537 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 538 "Entered viaIGA2SetGamma.\n")); 539 540 /* 3X5.6A[1] - IGA2 Gamma Correction 541 * 0: Disable 542 * 1: Enable */ 543 ViaCrtcMask(hwp, 0x6A, gammaCorrection << 1, 0x02); 544 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 545 "IGA2 Gamma Correction: %s\n", 546 (gammaCorrection & 0x01) ? "On" : "Off"); 547 548 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 549 "Exiting viaIGA2SetGamma.\n")); 550} 551 552static void 553viaIGA2InitHI(ScrnInfoPtr pScrn) 554{ 555 VIAPtr pVia = VIAPTR(pScrn); 556 557 switch(pVia->Chipset) { 558 case VIA_PM800: 559 case VIA_CX700: 560 case VIA_P4M890: 561 case VIA_P4M900: 562 case VIA_VX800: 563 case VIA_VX855: 564 case VIA_VX900: 565 VIASETREG(HI_TRANSPARENT_COLOR, 0x00000000); 566 VIASETREG(HI_INVTCOLOR, 0x00FFFFFF); 567 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0x000E0000); 568 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0x0E0F0000); 569 VIASETREG(HI_CONTROL, 0xB6000004); 570 break; 571 default: 572 VIASETREG(HI_TRANSPARENT_COLOR, 0x00000000); 573 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 574 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0x000E0000); 575 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 576 VIASETREG(HI_CONTROL, 0xF6000004); 577 break; 578 } 579} 580 581static void 582viaIGA2SetHIStartingAddress(xf86CrtcPtr crtc) 583{ 584 drmmode_crtc_private_ptr iga = crtc->driver_private; 585 ScrnInfoPtr pScrn = crtc->scrn; 586 VIAPtr pVia = VIAPTR(pScrn); 587 588 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 589} 590 591/* 592 * This function displays or hides IGA2 hardware icon (HI). 593 */ 594static void 595viaIGA2DisplayHI(ScrnInfoPtr pScrn, Bool HI_Status) 596{ 597 VIAPtr pVia = VIAPTR(pScrn); 598 CARD32 temp; 599 600 switch(pVia->Chipset) { 601 case VIA_PM800: 602 case VIA_CX700: 603 case VIA_P4M890: 604 case VIA_P4M900: 605 case VIA_VX800: 606 case VIA_VX855: 607 case VIA_VX900: 608 temp = VIAGETREG(HI_CONTROL); 609 temp &= 0xFFFFFFFE; 610 temp |= HI_Status ? 0x00000001 : 0x00000000; 611 612 /* HI_CONTROL[0] - Hardware Icon (HI) Enable */ 613 VIASETREG(HI_CONTROL, temp); 614 break; 615 default: 616 temp = VIAGETREG(HI_CONTROL); 617 temp &= 0xFFFFFFFE; 618 temp |= HI_Status ? 0x00000001 : 0x00000000; 619 620 /* HI_CONTROL[0] - Hardware Icon (HI) Enable */ 621 VIASETREG(HI_CONTROL, temp); 622 break; 623 } 624} 625 626static void 627viaIGA2SetHIDisplayLocation(ScrnInfoPtr pScrn, 628 int x, unsigned int xoff, 629 int y, unsigned int yoff) 630{ 631 VIAPtr pVia = VIAPTR(pScrn); 632 633 switch(pVia->Chipset) { 634 case VIA_PM800: 635 case VIA_CX700: 636 case VIA_P4M890: 637 case VIA_P4M900: 638 case VIA_VX800: 639 case VIA_VX855: 640 case VIA_VX900: 641 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07FF))); 642 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07FF))); 643 break; 644 default: 645 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07FF))); 646 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07FF))); 647 break; 648 } 649} 650 651/* 652 * Initial settings for displays. 653 */ 654void 655viaDisplayInit(ScrnInfoPtr pScrn) 656{ 657 VIAPtr pVia = VIAPTR(pScrn); 658 vgaHWPtr hwp = VGAHWPTR(pScrn); 659 660 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 661 "Entered viaDisplayInit.\n")); 662 663 ViaCrtcMask(hwp, 0x6A, 0x00, 0x3D); 664 hwp->writeCrtc(hwp, 0x6B, 0x00); 665 hwp->writeCrtc(hwp, 0x6C, 0x00); 666 hwp->writeCrtc(hwp, 0x79, 0x00); 667 668 /* (IGA1 Timing Plus 2, added in VT3259 A3 or later) */ 669 if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) 670 ViaCrtcMask(hwp, 0x47, 0x00, 0xC8); 671 672 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 673 "Exiting viaDisplayInit.\n")); 674} 675 676/* 677 * Sets the primary or secondary display stream on internal TMDS. 678 */ 679void 680ViaDisplaySetStreamOnDFP(ScrnInfoPtr pScrn, Bool primary) 681{ 682 vgaHWPtr hwp = VGAHWPTR(pScrn); 683 684 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnDFP\n")); 685 686 if (primary) 687 ViaCrtcMask(hwp, 0x99, 0x00, 0x10); 688 else 689 ViaCrtcMask(hwp, 0x99, 0x10, 0x10); 690} 691 692void 693VIALoadRgbLut(ScrnInfoPtr pScrn, int start, int numColors, LOCO *colors) 694{ 695 vgaHWPtr hwp = VGAHWPTR(pScrn); 696 int i, j; 697 698 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadRgbLut\n")); 699 700 hwp->enablePalette(hwp); 701 hwp->writeDacMask(hwp, 0xFF); 702 703 /* We need the same palette contents for both 16 and 24 bits, but X doesn't 704 * play: X's colormap handling is hopelessly intertwined with almost every 705 * X subsystem. So we just space out RGB values over the 256*3. */ 706 707 switch (pScrn->bitsPerPixel) { 708 case 15: 709 for (i = start; i < numColors; i++) { 710 hwp->writeDacWriteAddr(hwp, i * 4); 711 for (j = 0; j < 4; j++) { 712 hwp->writeDacData(hwp, colors[i / 2].red); 713 hwp->writeDacData(hwp, colors[i].green); 714 hwp->writeDacData(hwp, colors[i / 2].blue); 715 } 716 } 717 break; 718 case 8: 719 case 16: 720 case 24: 721 case 32: 722 for (i = start; i < numColors; i++) { 723 hwp->writeDacWriteAddr(hwp, i); 724 hwp->writeDacData(hwp, colors[i].red); 725 hwp->writeDacData(hwp, colors[i].green); 726 hwp->writeDacData(hwp, colors[i].blue); 727 } 728 break; 729 default: 730 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 731 "Unsupported bitdepth: %d\n", pScrn->bitsPerPixel); 732 break; 733 } 734 hwp->disablePalette(hwp); 735} 736 737void 738ViaGammaDisable(ScrnInfoPtr pScrn) 739{ 740 VIAPtr pVia = VIAPTR(pScrn); 741 vgaHWPtr hwp = VGAHWPTR(pScrn); 742 743 switch (pVia->Chipset) { 744 case VIA_CLE266: 745 case VIA_KM400: 746 ViaSeqMask(hwp, 0x16, 0x00, 0x80); 747 break; 748 default: 749 ViaCrtcMask(hwp, 0x33, 0x00, 0x80); 750 break; 751 } 752 753 /* Disable gamma on secondary */ 754 /* This is needed or the hardware will lockup */ 755 ViaSeqMask(hwp, 0x1A, 0x00, 0x01); 756 ViaCrtcMask(hwp, 0x6A, 0x00, 0x02); 757 switch (pVia->Chipset) { 758 case VIA_CLE266: 759 case VIA_KM400: 760 case VIA_K8M800: 761 case VIA_PM800: 762 break; 763 default: 764 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 765 break; 766 } 767} 768 769/* 770 * Initialize common IGA (Integrated Graphics Accelerator) registers. 771 */ 772void 773viaIGAInitCommon(ScrnInfoPtr pScrn) 774{ 775 vgaHWPtr hwp = VGAHWPTR(pScrn); 776 VIAPtr pVia = VIAPTR(pScrn); 777 CARD8 i; 778#ifdef HAVE_DEBUG 779 CARD8 temp; 780#endif 781 782 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 783 "Entered viaIGAInitCommon.\n")); 784 785 temp = hwp->readEnable(hwp); 786 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 787 "Enable Register: 0x%02X\n", temp)); 788 hwp->writeEnable(hwp, temp | 0x01); 789 790 temp = hwp->readMiscOut(hwp); 791 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 792 "Misc. Register: 0x%02X\n", temp)); 793 hwp->writeMiscOut(hwp, temp | 0x22); 794 795 temp = hwp->readEnable(hwp); 796 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 797 "Enable Register: 0x%02X\n", temp)); 798 temp = hwp->readMiscOut(hwp); 799 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 800 "Misc. Register: 0x%02X\n", temp)); 801 802 803 /* Sequencer Registers */ 804 ViaSeqMask(hwp, 0x00, 0x03, 0x03); 805 ViaSeqMask(hwp, 0x01, 0x01, 0x35); 806 ViaSeqMask(hwp, 0x02, 0x0F, 0x0F); 807 ViaSeqMask(hwp, 0x03, 0x00, 0x3F); 808 ViaSeqMask(hwp, 0x04, 0x0E, 0x0E); 809 810 811 /* Graphics Registers */ 812 hwp->writeGr(hwp, 0x00, 0x00); 813 hwp->writeGr(hwp, 0x01, 0x00); 814 hwp->writeGr(hwp, 0x02, 0x00); 815 hwp->writeGr(hwp, 0x03, 0x00); 816 hwp->writeGr(hwp, 0x04, 0x00); 817 hwp->writeGr(hwp, 0x05, 0x40); 818 hwp->writeGr(hwp, 0x06, 0x05); 819 hwp->writeGr(hwp, 0x07, 0x0F); 820 hwp->writeGr(hwp, 0x08, 0xFF); 821 822 823 /* Attribute Registers */ 824 for (i = 0; i <= 15; i++) { 825 hwp->writeAttr(hwp, i, i); 826 } 827 828 hwp->writeAttr(hwp, 0x10, 0x41); 829 hwp->writeAttr(hwp, 0x11, 0xFF); 830 hwp->writeAttr(hwp, 0x12, 0x0F); 831 hwp->writeAttr(hwp, 0x13, 0x00); 832 hwp->writeAttr(hwp, 0x14, 0x00); 833 834 835 /* Unlock VIA Technologies extended VGA registers. */ 836 /* 3C5.10[0] - Unlock Accessing of I/O Space 837 * 0: Disable 838 * 1: Enable */ 839 ViaSeqMask(hwp, 0x10, 0x01, 0x01); 840 841 switch (pVia->Chipset) { 842 case VIA_CLE266: 843 case VIA_KM400: 844 case VIA_K8M800: 845 case VIA_PM800: 846 case VIA_P4M800PRO: 847 case VIA_CX700: 848 case VIA_P4M890: 849 case VIA_K8M890: 850 case VIA_P4M900: 851 case VIA_VX800: 852 /* 3X5.47[7] - IGA1 Timing Plus 2 VCK 853 * 3X5.47[6] - IGA1 Timing Plus 4 VCK 854 * 3X5.47[5] - Peep at the PCI-bus 855 * 0: Disable 856 * 1: Enable 857 * 3X5.47[4] - Reserved 858 * 3X5.47[3] - IGA1 Timing Plus 6 VCK 859 * 3X5.47[2] - DACOFF Backdoor Register 860 * 3X5.47[1] - LCD Simultaneous Mode Backdoor Register for 861 * 8/9 Dot Clocks 862 * 3X5.47[0] - LCD Simultaneous Mode Backdoor Register for 863 * Clock Select and CRTC Register Protect */ 864 ViaCrtcMask(hwp, 0x47, 0x00, 0x01); 865 break; 866 case VIA_VX855: 867 case VIA_VX900: 868 /* 3X5.47[7] - IGA1 Timing Plus 2 VCK 869 * 3X5.47[6] - IGA1 Timing Plus 4 VCK 870 * 3X5.47[5] - Peep at the PCI-bus 871 * 0: Disable 872 * 1: Enable 873 * 3X5.47[4] - CRT Timing Register Protect 874 * 3X5.47[3] - IGA1 Timing Plus 6 VCK 875 * 3X5.47[2] - DACOFF Backdoor Register 876 * 3X5.47[1] - LCD Simultaneous Mode Backdoor Register for 877 * 8/9 Dot Clocks 878 * 3X5.47[0] - LCD Simultaneous Mode Backdoor Register for 879 * Clock Select */ 880 ViaCrtcMask(hwp, 0x47, 0x00, 0x10); 881 break; 882 default: 883 break; 884 } 885 886#ifdef HAVE_DEBUG 887 temp = hwp->readSeq(hwp, 0x15); 888 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 889 "SR15: 0x%02X\n", temp)); 890 temp = hwp->readSeq(hwp, 0x19); 891 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 892 "SR19: 0x%02X\n", temp)); 893 temp = hwp->readSeq(hwp, 0x1A); 894 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 895 "SR1A: 0x%02X\n", temp)); 896 temp = hwp->readSeq(hwp, 0x1E); 897 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 898 "SR1E: 0x%02X\n", temp)); 899 temp = hwp->readSeq(hwp, 0x2D); 900 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 901 "SR2D: 0x%02X\n", temp)); 902 temp = hwp->readSeq(hwp, 0x2E); 903 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 904 "SR2E: 0x%02X\n", temp)); 905 temp = hwp->readSeq(hwp, 0x3F); 906 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 907 "SR3F: 0x%02X\n", temp)); 908 temp = hwp->readCrtc(hwp, 0x36); 909 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 910 "CR36: 0x%02X\n", temp)); 911 temp = hwp->readCrtc(hwp, 0x3B); 912 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 913 "CR3B: 0x%02X\n", temp)); 914 temp = hwp->readCrtc(hwp, 0x3C); 915 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 916 "CR3C: 0x%02X\n", temp)); 917 temp = hwp->readCrtc(hwp, 0x3D); 918 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 919 "CR3D: 0x%02X\n", temp)); 920 temp = hwp->readCrtc(hwp, 0x3E); 921 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 922 "CR3E: 0x%02X\n", temp)); 923 temp = hwp->readCrtc(hwp, 0x3F); 924 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 925 "CR3F: 0x%02X\n", temp)); 926 temp = hwp->readCrtc(hwp, 0x47); 927 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 928 "CR47: 0x%02X\n", temp)); 929 temp = hwp->readCrtc(hwp, 0x6B); 930 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 931 "CR6B: 0x%02X\n", temp)); 932 933 if (pVia->Chipset == VIA_CLE266) { 934 temp = hwp->readCrtc(hwp, 0x6C); 935 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 936 "CR6C: 0x%02X\n", temp)); 937 } 938 939#endif 940 941 942 /* VIA Technologies Chrome Extended Graphics Registers */ 943 ViaGrMask(hwp, 0x20, 0, 0xFF); 944 ViaGrMask(hwp, 0x21, 0, 0xFF); 945 ViaGrMask(hwp, 0x22, 0, 0xFF); 946 947 948 /* Be careful with 3C5.15[5] - Wrap Around Disable. 949 * It must be set to 1 for correct operation. */ 950 /* 3C5.15[7] - 8/6 Bits LUT 951 * 0: 6-bit 952 * 1: 8-bit 953 * 3C5.15[6] - Text Column Control 954 * 0: 80 column 955 * 1: 132 column 956 * 3C5.15[5] - Wrap Around Disable 957 * 0: Disable (For Mode 0-13) 958 * 1: Enable 959 * 3C5.15[4] - Hi Color Mode Select 960 * 0: 555 961 * 1: 565 962 * 3C5.15[3:2] - Display Color Depth Select 963 * 00: 8bpp 964 * 01: 16bpp 965 * 10: 30bpp 966 * 11: 32bpp 967 * 3C5.15[1] - Extended Display Mode Enable 968 * 0: Disable 969 * 1: Enable 970 * 3C5.15[0] - Reserved */ 971 ViaSeqMask(hwp, 0x15, 0x22, 0x62); 972 973 /* 3C5.19[7] - Reserved 974 * 3C5.19[6] - MIU/AGP Interface Clock Control 975 * 0: Clocks always on 976 * 1: Enable clock gating 977 * 3C5.19[5] - P-Arbiter Interface Clock Control 978 * 0: Clocks always on 979 * 1: Enable clock gating 980 * 3C5.19[4] - AGP Interface Clock Control 981 * 0: Clocks always on 982 * 1: Enable clock gating 983 * 3C5.19[3] - Typical Arbiter Interface Clock Control 984 * 0: Clocks always on 985 * 1: Enable clock gating 986 * 3C5.19[2] - MC Interface Clock Control 987 * 0: Clocks always on 988 * 1: Enable clock gating 989 * 3C5.19[1] - Display Interface Clock Control 990 * 0: Clocks always on 991 * 1: Enable clock gating 992 * 3C5.19[0] - CPU Interface Clock Control 993 * 0: Clocks always on 994 * 1: Enable clock gating */ 995 ViaSeqMask(hwp, 0x19, 0x7F, 0x7F); 996 997 /* 3C5.1A[7] - Read Cache Enable 998 * 0: Disable 999 * 1: Enable 1000 * 3C5.1A[6] - Software Reset 1001 * 0: Default value 1002 * 1: Reset 1003 * 3C5.1A[5] - DVI Sense 1004 * 0: No connect 1005 * 1: Connected 1006 * 3C5.1A[4] - Second DVI Sense 1007 * 0: No connect 1008 * 1: Connected 1009 * 3C5.1A[3] - Extended Mode Memory Access Enable 1010 * 0: Disable 1011 * 1: Enable 1012 * 3C5.1A[2] - PCI Burst Write Wait State Select 1013 * 0: 0 Wait state 1014 * 1: 1 Wait state 1015 * 3C5.1A[1] - Reserved 1016 * 3C5.1A[0] - LUT Shadow Access 1017 * 0: 3C6/3C7/3C8/3C9 addresses map to 1018 * Primary Display’s LUT 1019 * 1: 3C6/3C7/3C8/3C9 addresses map to 1020 * Secondary Display’s LUT */ 1021 ViaSeqMask(hwp, 0x1A, 0x88, 0xC8); 1022 1023 /* 3C5.1E[3] - Spread Spectrum On/Off 1024 * 0: Off 1025 * 1: On 1026 * 3C5.1E[1] - Replace ECK by MCK 1027 * For BIST purpose. 1028 * 3C5.1E[0] - On/Off ROC ECK 1029 * 0: Off 1030 * 1: On */ 1031 ViaSeqMask(hwp, 0x1E, 0x01, 0x09); 1032 1033 /* 3C5.2D[7:6] - E3_ECK_N Selection 1034 * 00: E3_ECK_N 1035 * 01: E3_ECK 1036 * 10: delayed E3_ECK_N 1037 * 11: delayed E3_ECK 1038 * 3C5.2D[5:4] - VCK (Primary Display Clock) PLL Power Control 1039 * 0x: PLL power-off 1040 * 10: PLL always on 1041 * 11: PLL on/off according to the PMS 1042 * 3C5.2D[3:2] - LCK (Secondary Display Clock) PLL Power Control 1043 * 0x: PLL power-off 1044 * 10: PLL always on 1045 * 11: PLL on/off according to the PMS 1046 * 3C5.2D[1:0] - ECK (Engine Clock) PLL Power Control 1047 * 0x: PLL power-off 1048 * 10: PLL always on 1049 * 11: PLL on/off according to the PMS */ 1050 ViaSeqMask(hwp, 0x2D, 0x03, 0xC3); 1051 1052 /* In Wyse X class mobile thin client, it was observed that setting 1053 * SR2E[3:2] (3C5.2E[3:2]; PCI Master / DMA) to 0b11 (clock on / off 1054 * according to the engine IDLE status) causes an X.Org Server boot 1055 * failure. Setting this register to 0b10 (clock always on) corrects 1056 * the problem. */ 1057 /* 3C5.2E[7:6] - Capturer (Gated Clock <ECK>) 1058 * 0x: Clock off 1059 * 10: Clock always on 1060 * 11: Clock on/off according to the engine IDLE status 1061 * 3C5.2E[5:4] - Video Processor (Gated Clock <ECK>) 1062 * 0x: Clock off 1063 * 10: Clock always on 1064 * 11: Clock on/off according to the engine IDLE status 1065 * 3C5.2E[3:2] - PCI Master/DMA (Gated Clock <ECK/CPUCK>) 1066 * 0x: Clock off 1067 * 10: Clock always on 1068 * 11: Clock on/off according to the engine IDLE status 1069 * 3C5.2E[1:0] - Video Playback Engine (V3/V4 Gated Clock <VCK>) 1070 * 0x: Clock off 1071 * 10: Clock always on 1072 * 11: Clock on/off according to the engine IDLE status */ 1073 ViaSeqMask(hwp, 0x2E, 0xFB, 0xFF); 1074 1075 /* 3C5.3F[7:6] - CR Clock Control (Gated Clock <ECK>) 1076 * 0x: Clock off 1077 * 10: Clock always on 1078 * 11: Clock on/off according to the engine IDLE status 1079 * 3C5.3F[5:4] - 3D Clock Control (Gated Clock <ECK>) 1080 * 0x: Clock off 1081 * 10: Clock always on 1082 * 11: Clock on/off according to the engine IDLE status 1083 * 3C5.3F[3:2] - 2D Clock Control (Gated Clock <ECK/CPUCK>) 1084 * 0x: Clock off 1085 * 10: Clock always on 1086 * 11: Clock on/off according to the engine IDLE status 1087 * 3C5.3F[1:0] - Video Clock Control (Gated Clock <ECK>) 1088 * 0x: Clock off 1089 * 10: Clock always on 1090 * 11: Clock on/off according to each engine IDLE status */ 1091 ViaSeqMask(hwp, 0x3F, 0xFF, 0xFF); 1092 1093 /* 3X5.36[7] - DPMS VSYNC Output 1094 * 3X5.36[6] - DPMS HSYNC Output 1095 * 3X5.36[5:4] - DPMS Control 1096 * 00: On 1097 * 01: Stand-by 1098 * 10: Suspend 1099 * 11: Off 1100 * When the DPMS state is off, both HSYNC and VSYNC 1101 * are grounded, saving monitor power consumption. 1102 * 3X5.36[3] - Horizontal Total Bit [8] 1103 * 3X5.36[2:1] - Reserved 1104 * 3X5.36[0] - PCI Power Management Control 1105 * 0: Disable 1106 * 1: Enable */ 1107 ViaCrtcMask(hwp, 0x36, 0x01, 0x01); 1108 1109 /* 3X5.3B through 3X5.3F are scratch pad registers. */ 1110 ViaCrtcMask(hwp, 0x3B, pVia->originalCR3B, 0xFF); 1111 ViaCrtcMask(hwp, 0x3C, pVia->originalCR3C, 0xFF); 1112 ViaCrtcMask(hwp, 0x3D, pVia->originalCR3D, 0xFF); 1113 ViaCrtcMask(hwp, 0x3E, pVia->originalCR3E, 0xFF); 1114 ViaCrtcMask(hwp, 0x3F, pVia->originalCR3F, 0xFF); 1115 1116 /* 3X5.47[5] - Peep at the PCI-bus 1117 * 0: Disable 1118 * 1: Enable 1119 * 3X5.47[1] - LCD Simultaneous Mode Backdoor Register for 1120 * 8/9 Dot Clocks 1121 * 3X5.47[0] - LCD Simultaneous Mode Backdoor Register for 1122 * Clock Select and CRTC Register Protect */ 1123 ViaCrtcMask(hwp, 0x47, 0x00, 0x23); 1124 1125 /* 3X5.6B[3] - Simultaneous Display Enable 1126 * 0: Disable 1127 * 1: Enable */ 1128 ViaCrtcMask(hwp, 0x6B, 0x00, 0x08); 1129 1130 /* CLE266 only. */ 1131 if (pVia->Chipset == VIA_CLE266) { 1132 /* The following register fields are for CLE266 only. */ 1133 /* 3X5.6C - Digital Interface Port 0 (DIP0) Control 1134 * 3X5.6C[7] - DIP0 Source 1135 * 0: IGA1 1136 * 1: IGA2 1137 * 3X5.6C[4:2] - Appears to be related to DIP0 signal polarity 1138 * control. Used by CLE266A2 to workaround a bug when 1139 * it is utilizing an external TV encoder. 1140 * 3X5.6C[1] - Appears to be utilized when CLE266 is utilizing an 1141 * external TV encoder. 1142 * 3X5.6C[0] - Appears to be a bit to control internal / external 1143 * clock source or whether or not the VCK (IGA1 clock 1144 * source) comes from VCK PLL or from an external 1145 * source. This bit should be set to 1 when TV encoder 1146 * is in use. */ 1147 ViaCrtcMask(hwp, 0x6C, 0x00, 0x01); 1148 } 1149 1150 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1151 "Exiting viaIGAInitCommon.\n")); 1152} 1153 1154/* 1155 * Initialize IGA1 (Integrated Graphics Accelerator) registers. 1156 */ 1157void 1158viaIGA1Init(ScrnInfoPtr pScrn) 1159{ 1160 vgaHWPtr hwp = VGAHWPTR(pScrn); 1161 VIAPtr pVia = VIAPTR(pScrn); 1162#ifdef HAVE_DEBUG 1163 CARD8 temp; 1164#endif 1165 1166 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1167 "Entered viaIGA1Init.\n")); 1168 1169#ifdef HAVE_DEBUG 1170 temp = hwp->readSeq(hwp, 0x1B); 1171 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1172 "SR1B: 0x%02X\n", temp)); 1173 temp = hwp->readSeq(hwp, 0x2D); 1174 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1175 "SR2D: 0x%02X\n", temp)); 1176 temp = hwp->readCrtc(hwp, 0x32); 1177 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1178 "CR32: 0x%02X\n", temp)); 1179 temp = hwp->readCrtc(hwp, 0x33); 1180 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1181 "CR33: 0x%02X\n", temp)); 1182 1183 /* For UniChrome Pro and Chrome9. */ 1184 if ((pVia->Chipset != VIA_CLE266) 1185 && (pVia->Chipset != VIA_KM400)) { 1186 temp = hwp->readCrtc(hwp, 0x47); 1187 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1188 "CR47: 0x%02X\n", temp)); 1189 } 1190 1191 temp = hwp->readCrtc(hwp, 0x6B); 1192 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1193 "CR6B: 0x%02X\n", temp)); 1194 1195 /* For UniChrome Pro and Chrome9. */ 1196 if ((pVia->Chipset != VIA_CLE266) 1197 && (pVia->Chipset != VIA_KM400)) { 1198 temp = hwp->readCrtc(hwp, 0x6C); 1199 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1200 "CR6C: 0x%02X\n", temp)); 1201 } 1202 1203#endif 1204 1205 /* 3C5.1B[7:6] - Secondary Display Engine (Gated Clock <LCK>) 1206 * 0x: Clock always off 1207 * 10: Clock always on 1208 * 11: Clock on/off according to the 1209 * Power Management Status (PMS) 1210 * 3C5.1B[5:4] - Primary Display Engine (Gated Clock <VCK>) 1211 * 0x: Clock always off 1212 * 10: Clock always on 1213 * 11: Clock on/off according to the PMS 1214 * 3C5.1B[3:1] - Reserved 1215 * 3C5.1B[0] - Primary Display’s LUT On/Off 1216 * 0: On 1217 * 1: Off */ 1218 ViaSeqMask(hwp, 0x1B, 0x30, 0x31); 1219 1220 /* 3C5.2D[7:6] - E3_ECK_N Selection 1221 * 00: E3_ECK_N 1222 * 01: E3_ECK 1223 * 10: delayed E3_ECK_N 1224 * 11: delayed E3_ECK 1225 * 3C5.2D[5:4] - VCK (Primary Display Clock) PLL Power Control 1226 * 0x: PLL power-off 1227 * 10: PLL always on 1228 * 11: PLL on/off according to the PMS 1229 * 3C5.2D[3:2] - LCK (Secondary Display Clock) PLL Power Control 1230 * 0x: PLL power-off 1231 * 10: PLL always on 1232 * 11: PLL on/off according to the PMS 1233 * 3C5.2D[1:0] - ECK (Engine Clock) PLL Power Control 1234 * 0x: PLL power-off 1235 * 10: PLL always on 1236 * 11: PLL on/off according to the PMS */ 1237 ViaSeqMask(hwp, 0x2D, 0x30, 0x30); 1238 1239 /* 3X5.32[7:5] - HSYNC Delay Number by VCLK 1240 * 000: No delay 1241 * 001: Delay + 4 VCKs 1242 * 010: Delay + 8 VCKs 1243 * 011: Delay + 12 VCKs 1244 * 100: Delay + 16 VCKs 1245 * 101: Delay + 20 VCKs 1246 * Others: Undefined 1247 * 3X5.32[4] - Reserved 1248 * 3X5.32[3] - CRT SYNC Driving Selection 1249 * 0: Low 1250 * 1: High 1251 * 3X5.32[2] - Display End Blanking Enable 1252 * 0: Disable 1253 * 1: Enable 1254 * 3X5.32[1] - Digital Video Port (DVP) Gamma Correction 1255 * If the gamma correction of primary display is 1256 * turned on, the gamma correction in DVP can be 1257 * enabled / disabled by this bit. 1258 * 0: Disable 1259 * 1: Enable 1260 * 3X5.32[0] - Real-Time Flipping 1261 * 0: Flip by the frame 1262 * 1: Flip by each scan line */ 1263 ViaCrtcMask(hwp, 0x32, 0x04, 0xEF); 1264 1265 /* Keep interlace mode off. 1266 * No shift for HSYNC.*/ 1267 /* 3X5.33[7] - Primary Display Gamma Correction 1268 * 0: Disable 1269 * 1: Enable 1270 * 3X5.33[6] - Primary Display Interlace Mode 1271 * 0: Disable 1272 * 1: Enable 1273 * 3X5.33[5] - Horizontal Blanking End Bit [6] 1274 * 3X5.33[4] - Horizontal Synchronization Start Bit [8] 1275 * 3X5.33[3] - Prefetch Mode 1276 * 0: Disable 1277 * 1: Enable 1278 * 3X5.33[2:0] - The Value will Shift the HSYNC to be Early than Planned 1279 * 000: Shift to early time by 3 characters 1280 * (VGA mode suggested value; default value) 1281 * 001: Shift to early time by 4 characters 1282 * 010: Shift to early time by 5 characters 1283 * 011: Shift to early time by 6 characters 1284 * 100: Shift to early time by 7 characters 1285 * 101: Shift to early time by 0 character 1286 * (Non-VGA mode suggested value) 1287 * 110: Shift to early time by 1 character 1288 * 111: Shift to early time by 2 characters */ 1289 ViaCrtcMask(hwp, 0x33, 0x05, 0xCF); 1290 1291 /* For UniChrome Pro and Chrome9. */ 1292 if ((pVia->Chipset != VIA_CLE266) 1293 && (pVia->Chipset != VIA_KM400)) { 1294 /* 3X5.47[7] - IGA1 Timing Plus 2 VCK 1295 * 3X5.47[6] - IGA1 Timing Plus 4 VCK 1296 * 3X5.47[5] - Peep at the PCI-bus 1297 * 0: Disable 1298 * 1: Enable 1299 * 3X5.47[4] - Reserved 1300 * 3X5.47[3] - IGA1 Timing Plus 6 VCK 1301 * 3X5.47[2] - DACOFF Backdoor Register 1302 * 3X5.47[1] - LCD Simultaneous Mode Backdoor Register for 1303 * 8/9 Dot Clocks 1304 * 3X5.47[0] - LCD Simultaneous Mode Backdoor Register for 1305 * Clock Select and CRTC Register Protect */ 1306 ViaCrtcMask(hwp, 0x47, 0x00, 0xCC); 1307 } 1308 1309 /* TV out uses division by 2 mode. 1310 * Other devices like analog (VGA), DVI, flat panel, etc., 1311 * use normal mode. */ 1312 /* 3X5.6B[7:6] - First Display Channel Clock Mode Selection 1313 * 0x: Normal 1314 * 1x: Division by 2 */ 1315 ViaCrtcMask(hwp, 0x6B, 0x00, 0xC0); 1316 1317 /* For UniChrome Pro and Chrome9. */ 1318 if ((pVia->Chipset != VIA_CLE266) 1319 && (pVia->Chipset != VIA_KM400)) { 1320 /* The following register fields are for UniChrome Pro and Chrome9. */ 1321 /* 3X5.6C[7:5] - VCK PLL Reference Clock Source Selection 1322 * 000: From XI pin 1323 * 001: From TVXI 1324 * 01x: From TVPLL 1325 * 100: DVP0TVCLKR 1326 * 101: DVP1TVCLKR 1327 * 110: CAP0 Clock 1328 * 111: CAP1 Clock 1329 * 3X5.6C[4] - VCK Source Selection 1330 * 0: VCK PLL output clock 1331 * 1: VCK PLL reference clock */ 1332 ViaCrtcMask(hwp, 0x6C, 0x00, 0xF0); 1333 } 1334 1335 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1336 "Exiting viaIGA1Init.\n")); 1337} 1338 1339void 1340viaIGA1SetFBStartingAddress(xf86CrtcPtr crtc, int x, int y) 1341{ 1342 ScrnInfoPtr pScrn = crtc->scrn; 1343 VIAPtr pVia = VIAPTR(pScrn); 1344 vgaHWPtr hwp = VGAHWPTR(pScrn); 1345 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1346 drmmode_ptr drmmode = drmmode_crtc->drmmode; 1347 CARD32 Base; 1348 CARD8 cr0c, cr0d, cr34, cr48; 1349 1350 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1351 "Entered viaIGA1SetFBStartingAddress.\n")); 1352 1353 Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); 1354 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1355 "Base Address: 0x%"PRIx32"x\n", 1356 (uint32_t)Base)); 1357 Base = (Base + drmmode->front_bo->offset) >> 1; 1358 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1359 "DRI Base Address: 0x%"PRIx32"\n", 1360 (uint32_t)Base); 1361 1362 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 1363 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 1364 1365 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) { 1366 ViaCrtcMask(hwp, 0x48, Base >> 24, 0x1F); 1367 } 1368 1369 /* CR34 are fire bits. Must be written after CR0C, CR0D, and CR48. */ 1370 hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16); 1371 1372#ifdef HAVE_DEBUG 1373 cr0d = hwp->readCrtc(hwp, 0x0D); 1374 cr0c = hwp->readCrtc(hwp, 0x0C); 1375 cr34 = hwp->readCrtc(hwp, 0x34); 1376 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) { 1377 cr48 = hwp->readCrtc(hwp, 0x48); 1378 } 1379 1380 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1381 "CR0D: 0x%02X\n", cr0d)); 1382 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1383 "CR0C: 0x%02X\n", cr0c)); 1384 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1385 "CR34: 0x%02X\n", cr34)); 1386 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) { 1387 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1388 "CR48: 0x%02X\n", cr48)); 1389 } 1390 1391#endif 1392 1393 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1394 "Exiting viaIGA1SetFBStartingAddress.\n")); 1395} 1396 1397void 1398viaIGA1SetDisplayRegister(ScrnInfoPtr pScrn, DisplayModePtr mode) 1399{ 1400 vgaHWPtr hwp = VGAHWPTR(pScrn); 1401 VIAPtr pVia = VIAPTR(pScrn); 1402 CARD16 temp; 1403 1404 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1405 "Entered viaIGA1SetDisplayRegister.\n")); 1406 1407 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1408 "IGA1 Requested Screen Mode: %s\n", mode->name); 1409 1410 if (mode->Flags & V_CLKDIV2) { 1411 ViaSeqMask(hwp, 0x01, 0x08, 0x08); 1412 } else { 1413 ViaSeqMask(hwp, 0x01, 0x00, 0x08); 1414 } 1415 1416 ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */ 1417 1418 /* Setting maximum scan line to 0. */ 1419 /* 3X5.09[4:0] - Maximum Scan Line */ 1420 ViaCrtcMask(hwp, 0x09, 0x00, 0x1F); 1421 1422 ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */ 1423 1424 /* 3X5.14[6] - Double Word Mode 1425 * Allows normal addressing or double-word addressing. 1426 * 0: Normal word addressing 1427 * 1: Double word addressing 1428 * 3X5.14[4:0] - Underline Location */ 1429 ViaCrtcMask(hwp, 0x14, 0x00, 0x5F); 1430 1431 1432 /* We are not using the split screen feature so line compare register 1433 * should be set to 0x7FF. */ 1434 temp = 0x7FF; 1435 1436 /* 3X5.18[7:0] - Line Compare Bits [7:0] */ 1437 hwp->writeCrtc(hwp, 0x18, temp & 0xFF); 1438 1439 /* 3X5.07[4] - Line Compare Bit [8] */ 1440 ViaCrtcMask(hwp, 0x07, temp >> 4, 0x10); 1441 1442 /* 3X5.09[6] - Line Compare Bit [9] */ 1443 ViaCrtcMask(hwp, 0x09, temp >> 3, 0x40); 1444 1445 /* 3X5.35[4] - Line Compare Bit [10] */ 1446 ViaCrtcMask(hwp, 0x35, temp >> 6, 0x10); 1447 1448 1449 /* 3X5.32[7:5] - HSYNC Delay Number by VCLK 1450 * 000: No delay 1451 * 001: Delay + 4 VCKs 1452 * 010: Delay + 8 VCKs 1453 * 011: Delay + 12 VCKs 1454 * 100: Delay + 16 VCKs 1455 * 101: Delay + 20 VCKs 1456 * Others: Undefined 1457 * 3X5.32[4] - Reserved 1458 * 3X5.32[3] - CRT SYNC Driving Selection 1459 * 0: Low 1460 * 1: High 1461 * 3X5.32[2] - Display End Blanking Enable 1462 * 0: Disable 1463 * 1: Enable 1464 * 3X5.32[1] - Digital Video Port (DVP) Gamma Correction 1465 * If the gamma correction of primary display is 1466 * turned on, the gamma correction in DVP can be 1467 * enabled / disabled by this bit. 1468 * 0: Disable 1469 * 1: Enable 1470 * 3X5.32[0] - Real-Time Flipping 1471 * 0: Flip by the frame 1472 * 1: Flip by each scan line */ 1473 ViaCrtcMask(hwp, 0x32, 0x04, 0xEC); 1474 1475 /* Keep interlace mode off. 1476 * No shift for HSYNC.*/ 1477 /* 3X5.33[7] - Primary Display Gamma Correction 1478 * 0: Disable 1479 * 1: Enable 1480 * 3X5.33[6] - Primary Display Interlace Mode 1481 * 0: Disable 1482 * 1: Enable 1483 * 3X5.33[5] - Horizontal Blanking End Bit [6] 1484 * 3X5.33[4] - Horizontal Synchronization Start Bit [8] 1485 * 3X5.33[3] - Prefetch Mode 1486 * 0: Disable 1487 * 1: Enable 1488 * 3X5.33[2:0] - The Value will Shift the HSYNC to be Early than Planned 1489 * 000: Shift to early time by 3 characters 1490 * (VGA mode suggested value; default value) 1491 * 001: Shift to early time by 4 characters 1492 * 010: Shift to early time by 5 characters 1493 * 011: Shift to early time by 6 characters 1494 * 100: Shift to early time by 7 characters 1495 * 101: Shift to early time by 0 character 1496 * (Non-VGA mode suggested value) 1497 * 110: Shift to early time by 1 character 1498 * 111: Shift to early time by 2 characters */ 1499 ViaCrtcMask(hwp, 0x33, 0x05, 0x4F); 1500 1501 /* UniChrome Pro or later */ 1502 if ((pVia->Chipset != VIA_CLE266) && (pVia->Chipset != VIA_KM400)) { 1503 /* Set IGA1 to linear mode. */ 1504 /* 3X5.43[2] - IGA1 Address Mode Selection 1505 * 0: Linear 1506 * 1: Tile */ 1507 ViaCrtcMask(hwp, 0x43, 0x00, 0x04); 1508 } 1509 1510 /* Set IGA1 horizontal total.*/ 1511 /* Due to IGA1 horizontal total being only 9 bits wide, 1512 * the adjusted horizontal total needs to be shifted by 1513 * 3 bit positions to the right. 1514 * In addition to that, this particular register requires the 1515 * value to be 5 less than the actual value being written. */ 1516 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1517 "IGA1 CrtcHTotal: %d\n", mode->CrtcHTotal)); 1518 temp = (mode->CrtcHTotal >> 3) - 5; 1519 1520 /* 3X5.00[7:0] - Horizontal Total Bits [7:0] */ 1521 hwp->writeCrtc(hwp, 0x00, temp & 0xFF); 1522 1523 /* 3X5.36[3] - Horizontal Total Bit [8] */ 1524 ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08); 1525 1526 1527 /* Set IGA1 horizontal display end. */ 1528 /* Due to IGA1 horizontal display end being only 8 bits 1529 * or 9 bits (for VX900 chipset) wide, the adjusted horizontal 1530 * display end needs to be shifted by 3 bit positions to the right. 1531 * In addition to that, this particular register requires the 1532 * value to be 1 less than the actual value being written. */ 1533 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1534 "IGA1 CrtcHDisplay: %d\n", mode->CrtcHDisplay)); 1535 temp = (mode->CrtcHDisplay >> 3) - 1; 1536 1537 /* 3X5.01[7:0] - Horizontal Display End Bits [7:0] */ 1538 hwp->writeCrtc(hwp, 0x01, temp & 0xFF); 1539 1540 if (pVia->Chipset == VIA_VX900) { 1541 /* 3X5.45[1] - Horizontal Display End Bit [8] */ 1542 ViaCrtcMask(hwp, 0x45, temp >> 7, 0x02); 1543 } 1544 1545 1546 /* Set IGA1 horizontal blank start. */ 1547 /* Due to IGA1 horizontal blank start being only 8 bits or 1548 * 9 bits (for VX900 chipset) wide, the adjusted horizontal 1549 * blank start needs to be shifted by 3 bit positions to the 1550 * right. */ 1551 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1552 "IGA1 CrtcHBlankStart: %d\n", mode->CrtcHBlankStart)); 1553 temp = mode->CrtcHBlankStart >> 3; 1554 1555 /* 3X5.02[7:0] - Horizontal Blanking Start Bits [7:0] */ 1556 hwp->writeCrtc(hwp, 0x02, temp & 0xFF); 1557 1558 if (pVia->Chipset == VIA_VX900) { 1559 /* 3X5.45[2] - Horizontal Blanking Start Bit [8] */ 1560 ViaCrtcMask(hwp, 0x45, temp >> 6, 0x04); 1561 } 1562 1563 1564 /* Set IGA1 horizontal blank end. */ 1565 /* After shifting horizontal blank end by 3 bit positions to the 1566 * right, the 7 least significant bits are actually used. 1567 * In addition to that, this particular register requires the 1568 * value to be 1 less than the actual value being written. */ 1569 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1570 "IGA1 CrtcHBlankEnd: %d\n", mode->CrtcHBlankEnd)); 1571 temp = (mode->CrtcHBlankEnd >> 3) - 1; 1572 1573 /* 3X5.03[4:0] - Horizontal Blanking End Bits [4:0] */ 1574 ViaCrtcMask(hwp, 0x03, temp, 0x1F); 1575 1576 /* 3X5.05[7] - Horizontal Blanking End Bit [5] */ 1577 ViaCrtcMask(hwp, 0x05, temp << 2, 0x80); 1578 1579 /* 3X5.33[5] - Horizontal Blanking End Bit [6] */ 1580 ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20); 1581 1582 1583 /* Set IGA1 horizontal synchronization start. */ 1584 /* Due to IGA1 horizontal synchronization start being only 9 bits wide, 1585 * the adjusted horizontal synchronization start needs to be shifted by 1586 * 3 bit positions to the right. */ 1587 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1588 "IGA1 CrtcHSyncStart: %d\n", mode->CrtcHSyncStart)); 1589 temp = mode->CrtcHSyncStart >> 3; 1590 1591 /* 3X5.04[7:0] - Horizontal Retrace Start Bits [7:0] */ 1592 hwp->writeCrtc(hwp, 0x04, temp & 0xFF); 1593 1594 /* 3X5.33[4] - Horizontal Retrace Start Bit [8] */ 1595 ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10); 1596 1597 1598 /* Set IGA1 horizontal synchronization end. */ 1599 /* After shifting horizontal synchronization end by 3 bit positions 1600 * to the right, the 5 least significant bits are actually used. 1601 * In addition to that, this particular register requires the 1602 * value to be 1 less than the actual value being written. */ 1603 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1604 "IGA1 CrtcHSyncEnd: %d\n", mode->CrtcHSyncEnd)); 1605 temp = (mode->CrtcHSyncEnd >> 3) - 1; 1606 1607 /* 3X5.05[4:0] - Horizontal Retrace End Bits [4:0] */ 1608 ViaCrtcMask(hwp, 0x05, temp, 0x1F); 1609 1610 1611 /* Set IGA1 vertical total. */ 1612 /* Vertical total requires the value to be 2 less 1613 * than the actual value being written. */ 1614 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1615 "IGA1 CrtcVTotal: %d\n", mode->CrtcVTotal)); 1616 temp = mode->CrtcVTotal - 2; 1617 1618 /* 3X5.06[7:0] - Vertical Total Period Bits [7:0] */ 1619 hwp->writeCrtc(hwp, 0x06, temp & 0xFF); 1620 1621 /* 3X5.07[0] - Vertical Total Period Bit [8] */ 1622 ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01); 1623 1624 /* 3X5.07[5] - Vertical Total Period Bit [9] */ 1625 ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20); 1626 1627 /* 3X5.35[0] - Vertical Total Period Bit [10] */ 1628 ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01); 1629 1630 1631 /* Set IGA1 vertical display end. */ 1632 /* Vertical display end requires the value to be 1 less 1633 * than the actual value being written. */ 1634 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1635 "IGA1 CrtcVDisplay: %d\n", mode->CrtcVDisplay)); 1636 temp = mode->CrtcVDisplay - 1; 1637 1638 /* 3X5.12[7:0] - Vertical Active Data Period Bits [7:0] */ 1639 hwp->writeCrtc(hwp, 0x12, temp & 0xFF); 1640 1641 /* 3X5.07[1] - Vertical Active Data Period Bit [8] */ 1642 ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02); 1643 1644 /* 3X5.07[6] - Vertical Active Data Period Bit [9] */ 1645 ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40); 1646 1647 /* 3X5.35[2] - Vertical Active Data Period Bit [10] */ 1648 ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04); 1649 1650 1651 /* Set IGA1 vertical blank start. */ 1652 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1653 "IGA1 CrtcVBlankStart: %d\n", mode->CrtcVBlankStart)); 1654 temp = mode->CrtcVBlankStart; 1655 1656 /* 3X5.15[7:0] - Vertical Blanking Start Bits [7:0] */ 1657 hwp->writeCrtc(hwp, 0x15, temp & 0xFF); 1658 1659 /* 3X5.07[3] - Vertical Blanking Start Bit [8] */ 1660 ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08); 1661 1662 /* 3X5.09[5] - Vertical Blanking Start Bit [9] */ 1663 ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20); 1664 1665 /* 3X5.35[3] - Vertical Blanking Start Bit [10] */ 1666 ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08); 1667 1668 1669 /* Set IGA1 vertical blank end. */ 1670 /* Vertical blank end requires the value to be 1 less 1671 * than the actual value being written, and 8 LSB 1672 * (Least Significant Bits) are written straight into the 1673 * relevant register. */ 1674 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1675 "IGA1 CrtcVBlankEnd: %d\n", mode->CrtcVBlankEnd)); 1676 temp = mode->CrtcVBlankEnd - 1; 1677 1678 /* 3X5.16[7:0] - Vertical Blanking End Bits [7:0] */ 1679 hwp->writeCrtc(hwp, 0x16, temp & 0xFF); 1680 1681 1682 /* Set IGA1 vertical synchronization start. */ 1683 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1684 "IGA1 CrtcVSyncStart: %d\n", mode->CrtcVSyncStart)); 1685 temp = mode->CrtcVSyncStart; 1686 1687 /* 3X5.10[7:0] - Vertical Retrace Start Bits [7:0] */ 1688 hwp->writeCrtc(hwp, 0x10, temp & 0xFF); 1689 1690 /* 3X5.07[2] - Vertical Retrace Start Bit [8] */ 1691 ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04); 1692 1693 /* 3X5.07[7] - Vertical Retrace Start Bit [9] */ 1694 ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80); 1695 1696 /* 3X5.35[1] - Vertical Retrace Start Bit [10] */ 1697 ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02); 1698 1699 1700 /* Set IGA1 vertical synchronization end. */ 1701 /* Vertical synchronization end requires the value to be 1 less 1702 * than the actual value being written, and 4 LSB 1703 * (Least Significant Bits) are written straight into the 1704 * relevant register. */ 1705 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1706 "IGA1 CrtcVSyncEnd: %d\n", mode->CrtcVSyncEnd)); 1707 temp = mode->CrtcVSyncEnd - 1; 1708 1709 /*3X5.11[3:0] - Vertical Retrace End Bits [3:0] */ 1710 ViaCrtcMask(hwp, 0x11, temp & 0x0F, 0x0F); 1711 1712 1713 /* Set IGA1 horizontal offset adjustment. */ 1714 temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; 1715 1716 /* 3X5.13[7:0] - Primary Display Horizontal Offset Bits [7:0] */ 1717 hwp->writeCrtc(hwp, 0x13, temp & 0xFF); 1718 1719 /* 3X5.35[7:5] - Primary Display Horizontal Offset Bits [10:8] */ 1720 ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0); 1721 1722 1723 /* Set IGA1 horizontal display fetch (read) count. */ 1724 temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 4; 1725 1726 /* 3C5.1C[7:0] - Primary Display Horizontal Display 1727 * Fetch Count Data Bits [7:0] */ 1728 hwp->writeSeq(hwp, 0x1C, temp & 0xFF); 1729 1730 /* 3C5.1D[1:0] - Primary Display Horizontal Display 1731 * Fetch Count Data Bits [9:8] */ 1732 ViaSeqMask(hwp, 0x1D, temp >> 8, 0x03); 1733 1734 1735 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1736 "Exiting viaIGA1SetDisplayRegister.\n")); 1737} 1738 1739/* 1740 * Checks for limitations imposed by the available VGA timing registers. 1741 */ 1742static ModeStatus 1743viaIGA1ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 1744{ 1745 VIAPtr pVia = VIAPTR(pScrn); 1746 1747 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1748 "Entered viaIGA1ModeValid.\n")); 1749 1750 /* Note that horizontal total being written to VGA registers is 1751 * shifted to the right by 3 bit positions since only 9 bits are 1752 * available, and then 5 is subtracted from it. Hence, to check if 1753 * the screen can even be valid, opposite of that needs to happen. 1754 * That being said, to check if the number is within an acceptable range, 1755 * 1 is subtracted from 5, hence, 4 (5 - 1) is multiplied with 8 (i.e., 1756 * 1 is shifted 3 bit positions to the left), and the resulting 32 is 1757 * added to 4096 (9 + 3 bits) to calculate the maximum horizontal total 1758 * IGA1 can handle. Ultimately, 4128 is the largest number VIA IGP's 1759 * IGA1 can handle. */ 1760 if (mode->CrtcHTotal > (4096 + ((1 << 3) * (5 - 1)))) 1761 return MODE_BAD_HVALUE; 1762 1763 if (((pVia->Chipset != VIA_VX900) 1764 && (mode->CrtcHDisplay > 2048)) 1765 || ((pVia->Chipset == VIA_VX900) 1766 && (mode->CrtcHDisplay > 4096))) 1767 return MODE_BAD_HVALUE; 1768 1769 if (((pVia->Chipset != VIA_VX900) 1770 && (mode->CrtcHBlankStart > 2048)) 1771 || ((pVia->Chipset == VIA_VX900) 1772 && (mode->CrtcHBlankStart > 4096))) 1773 return MODE_BAD_HVALUE; 1774 1775 if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025) 1776 return MODE_HBLANK_WIDE; 1777 1778 if (mode->CrtcHSyncStart > 4095) 1779 return MODE_BAD_HVALUE; 1780 1781 if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256) 1782 return MODE_HSYNC_WIDE; 1783 1784 if (mode->CrtcVTotal > 2049) 1785 return MODE_BAD_VVALUE; 1786 1787 if (mode->CrtcVDisplay > 2048) 1788 return MODE_BAD_VVALUE; 1789 1790 if (mode->CrtcVSyncStart > 2047) 1791 return MODE_BAD_VVALUE; 1792 1793 if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16) 1794 return MODE_VSYNC_WIDE; 1795 1796 if (mode->CrtcVBlankStart > 2048) 1797 return MODE_BAD_VVALUE; 1798 1799 if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257) 1800 return MODE_VBLANK_WIDE; 1801 1802 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1803 "Exiting viaIGA1ModeValid.\n")); 1804 return MODE_OK; 1805} 1806 1807static void 1808ViaSetCLE266APrimaryFIFO(ScrnInfoPtr pScrn, Bool Enable) 1809{ 1810 VIAPtr pVia = VIAPTR(pScrn); 1811 CARD32 dwGE230, dwGE298; 1812 1813 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1814 "ViaSetCLE266APrimaryFIFO: %d\n", Enable)); 1815 1816 dwGE298 = VIAGETREG(0x298); 1817 VIASETREG(0x298, dwGE298 | 0x20000000); 1818 1819 dwGE230 = VIAGETREG(0x230); 1820 if (Enable) 1821 dwGE230 |= 0x00200000; 1822 else 1823 dwGE230 &= ~0x00200000; 1824 VIASETREG(0x230, dwGE230); 1825 1826 dwGE298 = VIAGETREG(0x298); 1827 VIASETREG(0x298, dwGE298 & ~0x20000000); 1828} 1829 1830static void 1831ViaSetPrimaryExpireNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, 1832 ViaExpireNumberTable *Expire) 1833{ 1834 vgaHWPtr hwp = VGAHWPTR(pScrn); 1835 VIAPtr pVia = VIAPTR(pScrn); 1836 1837 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryExpireNumber\n")); 1838 1839 for (; Expire->X; Expire++) 1840 if ((Expire->X == mode->CrtcHDisplay) && 1841 (Expire->Y == mode->CrtcVDisplay) && 1842 (Expire->Bpp == pScrn->bitsPerPixel) && 1843 (Expire->bRamClock == pVia->MemClk)) { 1844 ViaSeqMask(hwp, 0x22, Expire->bTuningValue, 0x1F); 1845 return; 1846 } 1847} 1848 1849static void 1850ViaSetPrimaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode) 1851{ 1852 vgaHWPtr hwp = VGAHWPTR(pScrn); 1853 VIAPtr pVia = VIAPTR(pScrn); 1854 1855 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetPrimaryFIFO\n")); 1856 1857 /* Standard values. */ 1858 ViaSeqMask(hwp, 0x17, 0x1F, 0xFF); 1859 1860 if (mode->CrtcHDisplay >= 1600) { 1861 ViaSeqMask(hwp, 0x16, 0x0F, 0xBF); 1862 ViaSeqMask(hwp, 0x18, 0x4F, 0xFF); 1863 } else if (mode->CrtcHDisplay >= 1024) { 1864 ViaSeqMask(hwp, 0x16, 0x0C, 0xBF); 1865 ViaSeqMask(hwp, 0x18, 0x4C, 0xFF); 1866 } else { 1867 ViaSeqMask(hwp, 0x16, 0x08, 0xBF); 1868 ViaSeqMask(hwp, 0x18, 0x4E, 0xFF); 1869 } 1870 1871 switch (pVia->Chipset) { 1872 case VIA_CLE266: 1873 if (CLE266_REV_IS_CX(pVia->ChipRev)) { 1874 if (pVia->HasSecondary) { /* SAMM or DuoView case */ 1875 if (mode->HDisplay >= 1024) { 1876 ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ 1877 hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ 1878 hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ 1879 } 1880 } else { /* Single view or Simultaneous case */ 1881#if 0 1882 if (mode->HDisplay > 1024) { 1883 ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ 1884 hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ 1885 hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ 1886 } 1887#endif 1888 } 1889 ViaSetPrimaryExpireNumber(pScrn, mode, CLE266CExpireNumber); 1890 } else { 1891 if ((mode->HDisplay > 1024) && pVia->HasSecondary) { 1892 ViaSetCLE266APrimaryFIFO(pScrn, TRUE); 1893 1894 ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ 1895 hwp->writeSeq(hwp, 0x17, 0x2F); /* 47 */ 1896 hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ 1897 } 1898 ViaSetPrimaryExpireNumber(pScrn, mode, CLE266AExpireNumber); 1899 } 1900 break; 1901 case VIA_KM400: 1902 if (pVia->HasSecondary) { /* SAMM or DuoView case */ 1903 if ((mode->HDisplay >= 1600) && 1904 (pVia->MemClk <= VIA_MEM_DDR200)) { 1905 ViaSeqMask(hwp, 0x16, 0x09, 0x3F); /* 9 */ 1906 hwp->writeSeq(hwp, 0x17, 0x1C); /* 28 */ 1907 } else { 1908 ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ 1909 hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ 1910 } 1911 } else { 1912 if ((mode->HDisplay > 1280)) 1913 ViaSeqMask(hwp, 0x16, 0x1C, 0x3F); /* 28 */ 1914 else if (mode->HDisplay > 1024) 1915 ViaSeqMask(hwp, 0x16, 0x17, 0x3F); /* 23 */ 1916 else 1917 ViaSeqMask(hwp, 0x16, 0x10, 0x3F); /* 16 */ 1918 hwp->writeSeq(hwp, 0x17, 0x3F); /* 63 */ 1919 } 1920 hwp->writeSeq(hwp, 0x18, 0x57); /* 23 */ 1921 ViaSetPrimaryExpireNumber(pScrn, mode, KM400ExpireNumber); 1922 break; 1923 case VIA_K8M800: 1924 hwp->writeSeq(hwp, 0x17, 0xBF); /* 384/2 - 1 = 191 */ 1925 ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4 = 82 = 0x52 */ 1926 ViaSeqMask(hwp, 0x18, 0x8a, 0xBF); /* 74 */ 1927 1928 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 1929 ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */ 1930 else 1931 ViaSeqMask(hwp, 0x22, 0x00, 0x1F); /* 128/4 = overflow = 0 */ 1932 break; 1933 /* PM800/PM880/CN400 */ 1934 case VIA_PM800: 1935 hwp->writeSeq(hwp, 0x17, 0x5F); /* 95 */ 1936 ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 32 */ 1937 ViaSeqMask(hwp, 0x18, 0x10, 0xBF); /* 16 */ 1938 1939 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 1940 ViaSeqMask(hwp, 0x22, 0x10, 0x1F); /* 64/4 = 16 */ 1941 else 1942 ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 31 */ 1943 break; 1944 /* P4M800 Pro/VN800/CN700 */ 1945 case VIA_P4M800PRO: 1946 hwp->writeSeq(hwp, 0x17, 0x2F); 1947 ViaSeqMask(hwp, 0x16, 0x14, 0xBF); /* 80/4 = 20 = 0x14 */ 1948 ViaSeqMask(hwp, 0x18, 0x08, 0xBF); 1949 1950 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 1951 ViaSeqMask(hwp, 0x22, 0x10, 0x1F); 1952 else 1953 ViaSeqMask(hwp, 0x22, 0x00, 0x1F); 1954 break; 1955 case VIA_K8M890: 1956 /* depth location: {SR17,0,7} */ 1957 hwp->writeSeq(hwp, 0x17, 0xB3); /* 360/2-1 = 179 = 0xB3 */ 1958 /* Formula (x & 0x3F) | ((x & 0x40) << 1) */ 1959 /* threshold location: {SR16,0,5},{SR16,7,7} */ 1960 ViaSeqMask(hwp, 0x16, 0x92, 0xBF); /* 328/4 = 82 = 0x52 */ 1961 /* high threshold location: {SR18,0,5},{SR18,7,7} */ 1962 ViaSeqMask(hwp, 0x18, 0x8A, 0xBF); /* 296/4 = 74 = 0x4A */ 1963 /* display queue expire num location: {SR22,0,4}. */ 1964 ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 124/4 = 31 = 0x1F */ 1965 break; 1966 case VIA_P4M900: 1967 /* location: {SR17,0,7} */ 1968 hwp->writeSeq(hwp, 0x17, 0x2F); /* 96/2-1 = 47 = 0x2F */ 1969 /* location: {SR16,0,5},{SR16,7,7} */ 1970 ViaSeqMask(hwp, 0x16, 0x13, 0xBF); /* 76/4 = 19 = 0x13 */ 1971 /* location: {SR18,0,5},{SR18,7,7} */ 1972 ViaSeqMask(hwp, 0x18, 0x13, 0xBF); /* 76/4 = 19 = 0x13 */ 1973 /* location: {SR22,0,4}. */ 1974 ViaSeqMask(hwp, 0x22, 0x08, 0x1F); /* 32/4 = 8 = 0x08 */ 1975 break; 1976 case VIA_P4M890: 1977 hwp->writeSeq(hwp, 0x17, 0x2F); /* 96/2-1 = 47 = 0x2F */ 1978 ViaSeqMask(hwp, 0x16, 0x13, 0xBF); /* 76/4 = 19 = 0x13 */ 1979 ViaSeqMask(hwp, 0x18, 0x10, 0xBF); /* 64/4 = 16 = 0x10 */ 1980 ViaSeqMask(hwp, 0x22, 0x08, 0x1F); /* 32/4 = 8 = 0x08 */ 1981 break; 1982 case VIA_CX700: 1983 hwp->writeSeq(hwp, 0x17, 0x5F); 1984 ViaSeqMask(hwp, 0x16, 0x20, 0xBF); /* 128/4 = 32 = 0x20 */ 1985 ViaSeqMask(hwp, 0x18, 0x20, 0xBF); /* 128/4 = 32 = 0x20 */ 1986 ViaSeqMask(hwp, 0x22, 0x1F, 0x1F); /* 124/4 = 31 = 0x1F */ 1987 break; 1988 case VIA_VX800: 1989 hwp->writeSeq(hwp, 0x17, 0x5F); /* 192/2-1 = 95 = 0x5F */ 1990 hwp->writeSeq(hwp, 0x16, 0x26); /* 152/4 = 38 = 0x26 */ 1991 hwp->writeSeq(hwp, 0x18, 0x26); /* 152/4 = 38 */ 1992 hwp->writeSeq(hwp, 0x22, 0x10); /* 64/4 = 16 */ 1993 break; 1994 case VIA_VX855: 1995 hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199 = 0xC7 */ 1996 /* Formula for {SR16,0,5},{SR16,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ 1997 hwp->writeSeq(hwp, 0x16, 0x90); /* 320/4 = 80 = 0x50 */ 1998 /* Formula for {SR18,0,5},{SR18,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ 1999 hwp->writeSeq(hwp, 0x18, 0x90); /* 320/4 = 80 = 0x50 */ 2000 hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4 = 40 = 0x28 */ 2001 break; 2002 case VIA_VX900: 2003 hwp->writeSeq(hwp, 0x17, 0xC7); /* 400/2-1 = 199 = 0xC7 */ 2004 /* Formula for {SR16,0,5},{SR16,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ 2005 hwp->writeSeq(hwp, 0x16, 0x90); /* 320/4 = 80 = 0x50 */ 2006 /* Formula for {SR18,0,5},{SR18,7,7} is: (0x50 & 0x3F) | ((0x50 & 0x40) << 1) = 0x90 */ 2007 hwp->writeSeq(hwp, 0x18, 0x90); /* 320/4 = 80 = 0x50 */ 2008 hwp->writeSeq(hwp, 0x22, 0x28); /* 160/4 = 40 = 0x28 */ 2009 break; 2010 default: 2011 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetPrimaryFIFO: " 2012 "Chipset %d not implemented\n", pVia->Chipset); 2013 break; 2014 } 2015} 2016 2017/* 2018 * Turn off the primary FIFO only for CLE266A. 2019 */ 2020static void 2021ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn) 2022{ 2023 VIAPtr pVia = VIAPTR(pScrn); 2024 2025 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisablePrimaryFIFO\n")); 2026 2027 /* Needed because exiting from X-Window will dump back register values. 2028 * Other chipsets have no need to set extended FIFO values. */ 2029 if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev) && 2030 ((pScrn->currentMode->HDisplay > 1024) || pVia->HasSecondary)) 2031 ViaSetCLE266APrimaryFIFO(pScrn, FALSE); 2032} 2033 2034void 2035viaIGA1Save(ScrnInfoPtr pScrn) 2036{ 2037 vgaHWPtr hwp = VGAHWPTR(pScrn); 2038 VIAPtr pVia = VIAPTR(pScrn); 2039 VIARegPtr Regs = &pVia->SavedReg; 2040 2041 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2042 "Entered viaIGA1Save.\n")); 2043 2044 vgaHWProtect(pScrn, TRUE); 2045 2046 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); 2047 2048 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2049 "Saving sequencer registers.\n")); 2050 2051 /* Unlock extended registers. */ 2052 hwp->writeSeq(hwp, 0x10, 0x01); 2053 2054 Regs->SR[0x14] = hwp->readSeq(hwp, 0x14); 2055 Regs->SR[0x15] = hwp->readSeq(hwp, 0x15); 2056 Regs->SR[0x16] = hwp->readSeq(hwp, 0x16); 2057 Regs->SR[0x17] = hwp->readSeq(hwp, 0x17); 2058 Regs->SR[0x18] = hwp->readSeq(hwp, 0x18); 2059 Regs->SR[0x19] = hwp->readSeq(hwp, 0x19); 2060 2061 /* PCI Bus Control */ 2062 Regs->SR[0x1A] = hwp->readSeq(hwp, 0x1A); 2063 2064 Regs->SR[0x1B] = hwp->readSeq(hwp, 0x1B); 2065 Regs->SR[0x1C] = hwp->readSeq(hwp, 0x1C); 2066 Regs->SR[0x1D] = hwp->readSeq(hwp, 0x1D); 2067 Regs->SR[0x1E] = hwp->readSeq(hwp, 0x1E); 2068 Regs->SR[0x1F] = hwp->readSeq(hwp, 0x1F); 2069 2070 Regs->SR[0x20] = hwp->readSeq(hwp, 0x20); 2071 Regs->SR[0x21] = hwp->readSeq(hwp, 0x21); 2072 Regs->SR[0x22] = hwp->readSeq(hwp, 0x22); 2073 2074 /* Registers 3C5.23 through 3C5.25 are not used by Chrome9. 2075 * Registers 3C5.27 through 3C5.29 are not used by Chrome9. */ 2076 switch (pVia->Chipset) { 2077 case VIA_CLE266: 2078 case VIA_KM400: 2079 case VIA_PM800: 2080 case VIA_K8M800: 2081 case VIA_P4M800PRO: 2082 case VIA_CX700: 2083 case VIA_P4M890: 2084 Regs->SR[0x23] = hwp->readSeq(hwp, 0x23); 2085 Regs->SR[0x24] = hwp->readSeq(hwp, 0x24); 2086 Regs->SR[0x25] = hwp->readSeq(hwp, 0x25); 2087 2088 Regs->SR[0x27] = hwp->readSeq(hwp, 0x27); 2089 Regs->SR[0x28] = hwp->readSeq(hwp, 0x28); 2090 Regs->SR[0x29] = hwp->readSeq(hwp, 0x29); 2091 break; 2092 default: 2093 break; 2094 } 2095 2096 Regs->SR[0x26] = hwp->readSeq(hwp, 0x26); 2097 2098 Regs->SR[0x2A] = hwp->readSeq(hwp, 0x2A); 2099 Regs->SR[0x2B] = hwp->readSeq(hwp, 0x2B); 2100 Regs->SR[0x2D] = hwp->readSeq(hwp, 0x2D); 2101 Regs->SR[0x2E] = hwp->readSeq(hwp, 0x2E); 2102 2103 /* Save PCI Configuration Memory Base Shadow 0 and 1. 2104 * These registers are available only in UniChrome, UniChrome Pro, 2105 * and UniChrome Pro II. */ 2106 switch (pVia->Chipset) { 2107 case VIA_CLE266: 2108 case VIA_KM400: 2109 case VIA_PM800: 2110 case VIA_K8M800: 2111 case VIA_P4M800PRO: 2112 case VIA_CX700: 2113 case VIA_P4M890: 2114 Regs->SR[0x2F] = hwp->readSeq(hwp, 0x2F); 2115 Regs->SR[0x30] = hwp->readSeq(hwp, 0x30); 2116 break; 2117 default: 2118 break; 2119 } 2120 2121 /* Save PLL settings and several miscellaneous registers. 2122 * For UniChrome, register 3C5.44 through 3C5.4B are saved. 2123 * For UniChrome Pro and Chrome9, register 3C5.44 through 3C5.4C 2124 * are saved. */ 2125 Regs->SR[0x44] = hwp->readSeq(hwp, 0x44); 2126 Regs->SR[0x45] = hwp->readSeq(hwp, 0x45); 2127 Regs->SR[0x46] = hwp->readSeq(hwp, 0x46); 2128 Regs->SR[0x47] = hwp->readSeq(hwp, 0x47); 2129 Regs->SR[0x48] = hwp->readSeq(hwp, 0x48); 2130 Regs->SR[0x49] = hwp->readSeq(hwp, 0x49); 2131 Regs->SR[0x4A] = hwp->readSeq(hwp, 0x4A); 2132 Regs->SR[0x4B] = hwp->readSeq(hwp, 0x4B); 2133 2134 switch (pVia->Chipset) { 2135 case VIA_PM800: 2136 case VIA_K8M800: 2137 case VIA_P4M800PRO: 2138 case VIA_CX700: 2139 case VIA_P4M890: 2140 case VIA_K8M890: 2141 case VIA_P4M900: 2142 case VIA_VX800: 2143 case VIA_VX855: 2144 case VIA_VX900: 2145 Regs->SR[0x4C] = hwp->readSeq(hwp, 0x4C); 2146 2147 /* Save register 3C5.4D. 2148 * According to CX700 / VX700 (UniChrome Pro II) Open Graphics 2149 * Programming Manual Part I: Graphics Core / 2D, 2150 * this register is called Dual Channel Memory Control. 2151 * According to VX800 / VX855 / VX900 (Chrome9 HC3 / HCM / HD) 2152 * Open Graphics Programming Manual Part I: Graphics Core / 2D, 2153 * this register is called Preemptive Arbiter Control. 2154 * It is likely that this register is also supported in UniChrome Pro. */ 2155 Regs->SR[0x4D] = hwp->readSeq(hwp, 0x4D); 2156 2157 Regs->SR[0x4E] = hwp->readSeq(hwp, 0x4E); 2158 Regs->SR[0x4F] = hwp->readSeq(hwp, 0x4F); 2159 break; 2160 default: 2161 break; 2162 } 2163 2164 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2165 "Finished saving sequencer registers.\n")); 2166 2167 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2168 "Saving IGA1 registers.\n")); 2169 2170 /* UniChrome Pro or later */ 2171 switch (pVia->Chipset) { 2172 case VIA_PM800: 2173 case VIA_K8M800: 2174 case VIA_P4M800PRO: 2175 case VIA_CX700: 2176 case VIA_P4M890: 2177 case VIA_K8M890: 2178 case VIA_P4M900: 2179 case VIA_VX800: 2180 case VIA_VX855: 2181 case VIA_VX900: 2182 /* Display Fetch Blocking Control */ 2183 Regs->CR[0x30] = hwp->readCrtc(hwp, 0x30); 2184 2185 /* Half Line Position */ 2186 Regs->CR[0x31] = hwp->readCrtc(hwp, 0x31); 2187 break; 2188 default: 2189 break; 2190 } 2191 2192 Regs->CR[0x32] = hwp->readCrtc(hwp, 0x32); 2193 Regs->CR[0x33] = hwp->readCrtc(hwp, 0x33); 2194 Regs->CR[0x35] = hwp->readCrtc(hwp, 0x35); 2195 Regs->CR[0x36] = hwp->readCrtc(hwp, 0x36); 2196 2197 /* UniChrome Pro or later */ 2198 switch (pVia->Chipset) { 2199 case VIA_PM800: 2200 case VIA_K8M800: 2201 case VIA_P4M800PRO: 2202 case VIA_CX700: 2203 case VIA_P4M890: 2204 case VIA_K8M890: 2205 case VIA_P4M900: 2206 case VIA_VX800: 2207 case VIA_VX855: 2208 case VIA_VX900: 2209 /* DAC Control Register */ 2210 Regs->CR[0x37] = hwp->readCrtc(hwp, 0x37); 2211 break; 2212 default: 2213 break; 2214 } 2215 2216 Regs->CR[0x38] = hwp->readCrtc(hwp, 0x38); 2217 Regs->CR[0x39] = hwp->readCrtc(hwp, 0x39); 2218 Regs->CR[0x3A] = hwp->readCrtc(hwp, 0x3A); 2219 Regs->CR[0x3B] = hwp->readCrtc(hwp, 0x3B); 2220 Regs->CR[0x3C] = hwp->readCrtc(hwp, 0x3C); 2221 Regs->CR[0x3D] = hwp->readCrtc(hwp, 0x3D); 2222 Regs->CR[0x3E] = hwp->readCrtc(hwp, 0x3E); 2223 Regs->CR[0x3F] = hwp->readCrtc(hwp, 0x3F); 2224 2225 Regs->CR[0x40] = hwp->readCrtc(hwp, 0x40); 2226 2227 /* UniChrome Pro or later */ 2228 switch (pVia->Chipset) { 2229 case VIA_PM800: 2230 case VIA_K8M800: 2231 case VIA_P4M800PRO: 2232 case VIA_CX700: 2233 case VIA_P4M890: 2234 case VIA_K8M890: 2235 case VIA_P4M900: 2236 case VIA_VX800: 2237 case VIA_VX855: 2238 case VIA_VX900: 2239 Regs->CR[0x43] = hwp->readCrtc(hwp, 0x43); 2240 Regs->CR[0x45] = hwp->readCrtc(hwp, 0x45); 2241 break; 2242 default: 2243 break; 2244 } 2245 2246 Regs->CR[0x46] = hwp->readCrtc(hwp, 0x46); 2247 Regs->CR[0x47] = hwp->readCrtc(hwp, 0x47); 2248 2249 /* Starting Address */ 2250 /* Start Address High */ 2251 Regs->CR[0x0C] = hwp->readCrtc(hwp, 0x0C); 2252 2253 /* Start Address Low */ 2254 Regs->CR[0x0D] = hwp->readCrtc(hwp, 0x0D); 2255 2256 /* UniChrome Pro or later */ 2257 switch (pVia->Chipset) { 2258 case VIA_PM800: 2259 case VIA_K8M800: 2260 case VIA_P4M800PRO: 2261 case VIA_CX700: 2262 case VIA_P4M890: 2263 case VIA_K8M890: 2264 case VIA_P4M900: 2265 case VIA_VX800: 2266 case VIA_VX855: 2267 case VIA_VX900: 2268 /* Starting Address Overflow[28:24] */ 2269 Regs->CR[0x48] = hwp->readCrtc(hwp, 0x48); 2270 break; 2271 default: 2272 break; 2273 } 2274 2275 /* Starting Address Overflow[23:16] */ 2276 Regs->CR[0x34] = hwp->readCrtc(hwp, 0x34); 2277 2278 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2279 "Finished saving IGA1 registers.\n")); 2280 2281 vgaHWProtect(pScrn, FALSE); 2282 2283 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2284 "Exiting viaIGA1Save.\n")); 2285} 2286 2287void 2288viaIGA1Restore(ScrnInfoPtr pScrn) 2289{ 2290 vgaHWPtr hwp = VGAHWPTR(pScrn); 2291 VIAPtr pVia = VIAPTR(pScrn); 2292 VIARegPtr Regs = &pVia->SavedReg; 2293 2294 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2295 "Entered viaIGA1Restore.\n")); 2296 2297 vgaHWProtect(pScrn, TRUE); 2298 2299 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL); 2300 2301 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2302 "Restoring sequencer registers.\n")); 2303 2304 /* Unlock extended registers. */ 2305 hwp->writeSeq(hwp, 0x10, 0x01); 2306 2307 hwp->writeSeq(hwp, 0x15, Regs->SR[0x15]); 2308 hwp->writeSeq(hwp, 0x16, Regs->SR[0x16]); 2309 hwp->writeSeq(hwp, 0x17, Regs->SR[0x17]); 2310 hwp->writeSeq(hwp, 0x18, Regs->SR[0x18]); 2311 hwp->writeSeq(hwp, 0x19, Regs->SR[0x19]); 2312 hwp->writeSeq(hwp, 0x1A, Regs->SR[0x1A]); 2313 2314 hwp->writeSeq(hwp, 0x1B, Regs->SR[0x1B]); 2315 hwp->writeSeq(hwp, 0x1C, Regs->SR[0x1C]); 2316 hwp->writeSeq(hwp, 0x1D, Regs->SR[0x1D]); 2317 hwp->writeSeq(hwp, 0x1E, Regs->SR[0x1E]); 2318 hwp->writeSeq(hwp, 0x1F, Regs->SR[0x1F]); 2319 2320 hwp->writeSeq(hwp, 0x20, Regs->SR[0x20]); 2321 hwp->writeSeq(hwp, 0x21, Regs->SR[0x21]); 2322 hwp->writeSeq(hwp, 0x22, Regs->SR[0x22]); 2323 2324 /* Registers 3C5.23 through 3C5.25 are not used by Chrome9. 2325 * Registers 3C5.27 through 3C5.29 are not used by Chrome9. */ 2326 switch (pVia->Chipset) { 2327 case VIA_CLE266: 2328 case VIA_KM400: 2329 case VIA_PM800: 2330 case VIA_K8M800: 2331 case VIA_P4M800PRO: 2332 case VIA_CX700: 2333 case VIA_P4M890: 2334 hwp->writeSeq(hwp, 0x23, Regs->SR[0x23]); 2335 hwp->writeSeq(hwp, 0x24, Regs->SR[0x24]); 2336 hwp->writeSeq(hwp, 0x25, Regs->SR[0x25]); 2337 2338 hwp->writeSeq(hwp, 0x27, Regs->SR[0x27]); 2339 hwp->writeSeq(hwp, 0x28, Regs->SR[0x28]); 2340 hwp->writeSeq(hwp, 0x29, Regs->SR[0x29]); 2341 break; 2342 default: 2343 break; 2344 } 2345 2346 hwp->writeSeq(hwp, 0x26, Regs->SR[0x26]); 2347 2348 hwp->writeSeq(hwp, 0x2A, Regs->SR[0x2A]); 2349 hwp->writeSeq(hwp, 0x2B, Regs->SR[0x2B]); 2350 2351 hwp->writeSeq(hwp, 0x2D, Regs->SR[0x2D]); 2352 hwp->writeSeq(hwp, 0x2E, Regs->SR[0x2E]); 2353 2354 /* Restore PCI Configuration Memory Base Shadow 0 and 1. 2355 * These registers are available only in UniChrome, UniChrome Pro, 2356 * and UniChrome Pro II. */ 2357 switch (pVia->Chipset) { 2358 case VIA_CLE266: 2359 case VIA_KM400: 2360 case VIA_PM800: 2361 case VIA_K8M800: 2362 case VIA_P4M800PRO: 2363 case VIA_CX700: 2364 case VIA_P4M890: 2365 hwp->writeSeq(hwp, 0x2F, Regs->SR[0x2F]); 2366 hwp->writeSeq(hwp, 0x30, Regs->SR[0x30]); 2367 break; 2368 default: 2369 break; 2370 } 2371 2372 /* Restore PLL settings and several miscellaneous registers. 2373 * For UniChrome, register 3C5.44 through 3C5.4B are restored. 2374 * For UniChrome Pro and Chrome 9, register 3C5.44 through 3C5.4C 2375 * are restored. */ 2376 switch (pVia->Chipset) { 2377 case VIA_CLE266: 2378 case VIA_KM400: 2379 /* Engine Clock (ECK) PLL settings */ 2380 hwp->writeSeq(hwp, 0x48, Regs->SR[0x48]); 2381 hwp->writeSeq(hwp, 0x49, Regs->SR[0x49]); 2382 2383 /* Memory Clock (MCK) PLL settings */ 2384 hwp->writeSeq(hwp, 0x4a, Regs->SR[0x4A]); 2385 hwp->writeSeq(hwp, 0x4b, Regs->SR[0x4B]); 2386 2387 /* Primary Display Clock (VCK) PLL settings */ 2388 hwp->writeSeq(hwp, 0x46, Regs->SR[0x46]); 2389 hwp->writeSeq(hwp, 0x47, Regs->SR[0x47]); 2390 2391 /* Secondary Display Clock (LCDCK) PLL settings */ 2392 hwp->writeSeq(hwp, 0x44, Regs->SR[0x44]); 2393 hwp->writeSeq(hwp, 0x45, Regs->SR[0x45]); 2394 break; 2395 default: 2396 /* Engine Clock (ECK) PLL settings */ 2397 hwp->writeSeq(hwp, 0x47, Regs->SR[0x47]); 2398 hwp->writeSeq(hwp, 0x48, Regs->SR[0x48]); 2399 hwp->writeSeq(hwp, 0x49, Regs->SR[0x49]); 2400 2401 /* Reset ECK PLL. */ 2402 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x01); /* Set SR40[0] to 1 */ 2403 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & (~0x01)); /* Set SR40[0] to 0 */ 2404 2405 2406 /* Primary Display Clock (VCK) PLL settings */ 2407 hwp->writeSeq(hwp, 0x44, Regs->SR[0x44]); 2408 hwp->writeSeq(hwp, 0x45, Regs->SR[0x45]); 2409 hwp->writeSeq(hwp, 0x46, Regs->SR[0x46]); 2410 2411 /* Reset VCK PLL. */ 2412 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x02); /* Set SR40[1] to 1 */ 2413 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & (~0x02)); /* Set SR40[1] to 0 */ 2414 2415 2416 /* Secondary Display Clock (LCDCK) PLL settings */ 2417 hwp->writeSeq(hwp, 0x4A, Regs->SR[0x4A]); 2418 hwp->writeSeq(hwp, 0x4B, Regs->SR[0x4B]); 2419 hwp->writeSeq(hwp, 0x4C, Regs->SR[0x4C]); 2420 2421 /* Reset LCDCK PLL. */ 2422 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x04); /* Set SR40[2] to 1 */ 2423 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & (~0x04)); /* Set SR40[2] to 0 */ 2424 break; 2425 } 2426 2427 switch (pVia->Chipset) { 2428 case VIA_PM800: 2429 case VIA_K8M800: 2430 case VIA_P4M800PRO: 2431 case VIA_CX700: 2432 case VIA_P4M890: 2433 case VIA_K8M890: 2434 case VIA_P4M900: 2435 case VIA_VX800: 2436 case VIA_VX855: 2437 case VIA_VX900: 2438 /* Restore register 3C5.4D. 2439 * According to CX700 / VX700 (UniChrome Pro II) Open Graphics 2440 * Programming Manual Part I: Graphics Core / 2D, 2441 * this register is called Dual Channel Memory Control. 2442 * According to VX800 / VX855 / VX900 (Chrome9 HC3 / HCM / HD) 2443 * Open Graphics Programming Manual Part I: Graphics Core / 2D, 2444 * this register is called Preemptive Arbiter Control. 2445 * It is likely that this register is also supported in UniChrome Pro. */ 2446 hwp->writeSeq(hwp, 0x4D, Regs->SR[0x4D]); 2447 2448 hwp->writeSeq(hwp, 0x4E, Regs->SR[0x4E]); 2449 hwp->writeSeq(hwp, 0x4F, Regs->SR[0x4F]); 2450 break; 2451 default: 2452 break; 2453 } 2454 2455 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2456 "Finished restoring sequencer registers.\n")); 2457 2458 /* Reset dot clocks. */ 2459 ViaSeqMask(hwp, 0x40, 0x06, 0x06); 2460 ViaSeqMask(hwp, 0x40, 0x00, 0x06); 2461 2462 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2463 "Restoring IGA1 registers.\n")); 2464 2465 /* later */ 2466 switch (pVia->Chipset) { 2467 case VIA_PM800: 2468 case VIA_K8M800: 2469 case VIA_P4M800PRO: 2470 case VIA_CX700: 2471 case VIA_P4M890: 2472 case VIA_K8M890: 2473 case VIA_P4M900: 2474 case VIA_VX800: 2475 case VIA_VX855: 2476 case VIA_VX900: 2477 /* Display Fetch Blocking Control */ 2478 hwp->writeCrtc(hwp, 0x30, Regs->CR[0x30]); 2479 2480 /* Half Line Position */ 2481 hwp->writeCrtc(hwp, 0x31, Regs->CR[0x31]); 2482 break; 2483 default: 2484 break; 2485 } 2486 2487 /* Restore CRTC controller extended registers. */ 2488 /* Mode Control */ 2489 hwp->writeCrtc(hwp, 0x32, Regs->CR[0x32]); 2490 2491 /* HSYNCH Adjuster */ 2492 hwp->writeCrtc(hwp, 0x33, Regs->CR[0x33]); 2493 2494 /* Extended Overflow */ 2495 hwp->writeCrtc(hwp, 0x35, Regs->CR[0x35]); 2496 2497 /* Power Management 3 (Monitor Control) */ 2498 hwp->writeCrtc(hwp, 0x36, Regs->CR[0x36]); 2499 2500/* UniChrome Pro or later */ 2501 switch (pVia->Chipset) { 2502 case VIA_PM800: 2503 case VIA_K8M800: 2504 case VIA_P4M800PRO: 2505 case VIA_CX700: 2506 case VIA_P4M890: 2507 case VIA_K8M890: 2508 case VIA_P4M900: 2509 case VIA_VX800: 2510 case VIA_VX855: 2511 case VIA_VX900: 2512 /* DAC control Register */ 2513 hwp->writeCrtc(hwp, 0x37, Regs->CR[0x37]); 2514 break; 2515 default: 2516 break; 2517 } 2518 2519 hwp->writeCrtc(hwp, 0x38, Regs->CR[0x38]); 2520 hwp->writeCrtc(hwp, 0x39, Regs->CR[0x39]); 2521 hwp->writeCrtc(hwp, 0x3A, Regs->CR[0x3A]); 2522 hwp->writeCrtc(hwp, 0x3B, Regs->CR[0x3B]); 2523 hwp->writeCrtc(hwp, 0x3C, Regs->CR[0x3C]); 2524 hwp->writeCrtc(hwp, 0x3D, Regs->CR[0x3D]); 2525 hwp->writeCrtc(hwp, 0x3E, Regs->CR[0x3E]); 2526 hwp->writeCrtc(hwp, 0x3F, Regs->CR[0x3F]); 2527 2528 hwp->writeCrtc(hwp, 0x40, Regs->CR[0x40]); 2529 2530 /* UniChrome Pro or later */ 2531 switch (pVia->Chipset) { 2532 case VIA_PM800: 2533 case VIA_K8M800: 2534 case VIA_P4M800PRO: 2535 case VIA_CX700: 2536 case VIA_P4M890: 2537 case VIA_K8M890: 2538 case VIA_P4M900: 2539 case VIA_VX800: 2540 case VIA_VX855: 2541 case VIA_VX900: 2542 hwp->writeCrtc(hwp, 0x43, Regs->CR[0x43]); 2543 hwp->writeCrtc(hwp, 0x45, Regs->CR[0x45]); 2544 break; 2545 default: 2546 break; 2547 } 2548 2549 hwp->writeCrtc(hwp, 0x46, Regs->CR[0x46]); 2550 hwp->writeCrtc(hwp, 0x47, Regs->CR[0x47]); 2551 2552 /* Starting Address */ 2553 /* Start Address High */ 2554 hwp->writeCrtc(hwp, 0x0C, Regs->CR[0x0C]); 2555 2556 /* Start Address Low */ 2557 hwp->writeCrtc(hwp, 0x0D, Regs->CR[0x0D]); 2558 2559 /* UniChrome Pro or later */ 2560 switch (pVia->Chipset) { 2561 case VIA_PM800: 2562 case VIA_K8M800: 2563 case VIA_P4M800PRO: 2564 case VIA_CX700: 2565 case VIA_P4M890: 2566 case VIA_K8M890: 2567 case VIA_P4M900: 2568 case VIA_VX800: 2569 case VIA_VX855: 2570 case VIA_VX900: 2571 /* Starting Address Overflow[28:24] */ 2572 hwp->writeCrtc(hwp, 0x48, Regs->CR[0x48]); 2573 break; 2574 default: 2575 break; 2576 } 2577 2578 /* CR34 is fire bits. Must be written after CR0C, CR0D, and CR48. 2579 * Starting Address Overflow[23:16] */ 2580 hwp->writeCrtc(hwp, 0x34, Regs->CR[0x34]); 2581 2582 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2583 "Finished restoring IGA1 registers.\n")); 2584 2585 ViaDisablePrimaryFIFO(pScrn); 2586 2587 vgaHWProtect(pScrn, FALSE); 2588 2589 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2590 "Exiting viaIGA1Restore.\n")); 2591} 2592 2593/* 2594 * Initialize IGA2 (Integrated Graphics Accelerator) registers. 2595 */ 2596void 2597viaIGA2Init(ScrnInfoPtr pScrn) 2598{ 2599 vgaHWPtr hwp = VGAHWPTR(pScrn); 2600 VIAPtr pVia = VIAPTR(pScrn); 2601#ifdef HAVE_DEBUG 2602 CARD8 temp; 2603#endif 2604 2605 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2606 "Entered viaIGA2Init.\n")); 2607 2608#ifdef HAVE_DEBUG 2609 temp = hwp->readSeq(hwp, 0x1B); 2610 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2611 "SR1B: 0x%02X\n", temp)); 2612 temp = hwp->readSeq(hwp, 0x2D); 2613 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2614 "SR2D: 0x%02X\n", temp)); 2615 temp = hwp->readCrtc(hwp, 0x6A); 2616 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2617 "CR6A: 0x%02X\n", temp)); 2618 temp = hwp->readCrtc(hwp, 0x6B); 2619 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2620 "CR6B: 0x%02X\n", temp)); 2621 2622 /* For UniChrome Pro and Chrome9. */ 2623 if ((pVia->Chipset != VIA_CLE266) 2624 && (pVia->Chipset != VIA_KM400)) { 2625 temp = hwp->readCrtc(hwp, 0x6C); 2626 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2627 "CR6C: 0x%02X\n", temp)); 2628 } 2629 2630 temp = hwp->readCrtc(hwp, 0x79); 2631 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2632 "CR79: 0x%02X\n", temp)); 2633 2634#endif 2635 2636 /* 3C5.1B[7:6] - Secondary Display Engine (Gated Clock <LCK>) 2637 * 0x: Clock always off 2638 * 10: Clock always on 2639 * 11: Clock on/off according to the 2640 * Power Management Status (PMS) 2641 * 3C5.1B[5:4] - Primary Display Engine (Gated Clock <VCK>) 2642 * 0x: Clock always off 2643 * 10: Clock always on 2644 * 11: Clock on/off according to the PMS 2645 * 3C5.1B[3:1] - Reserved 2646 * 3C5.1B[0] - Primary Display’s LUT On/Off 2647 * 0: On 2648 * 1: Off */ 2649 ViaSeqMask(hwp, 0x1B, 0xC0, 0xC0); 2650 2651 /* 3C5.2D[7:6] - E3_ECK_N Selection 2652 * 00: E3_ECK_N 2653 * 01: E3_ECK 2654 * 10: delayed E3_ECK_N 2655 * 11: delayed E3_ECK 2656 * 3C5.2D[5:4] - VCK (Primary Display Clock) PLL Power Control 2657 * 0x: PLL power-off 2658 * 10: PLL always on 2659 * 11: PLL on/off according to the PMS 2660 * 3C5.2D[3:2] - LCK (Secondary Display Clock) PLL Power Control 2661 * 0x: PLL power-off 2662 * 10: PLL always on 2663 * 11: PLL on/off according to the PMS 2664 * 3C5.2D[1:0] - ECK (Engine Clock) PLL Power Control 2665 * 0x: PLL power-off 2666 * 10: PLL always on 2667 * 11: PLL on/off according to the PMS */ 2668 ViaSeqMask(hwp, 0x2D, 0x0C, 0x0C); 2669 2670 /* 3X5.6A[7] - Second Display Channel Enable 2671 * 0: Disable 2672 * 1: Enable 2673 * 3X5.6A[6] - Second Display Channel Reset 2674 * 0: Reset 2675 * 3X5.6A[5] - Second Display 8/6 Bits LUT 2676 * 0: 6-bit 2677 * 1: 8-bit 2678 * 3X5.6A[4] - Horizontal Count by 2 2679 * 0: Disable 2680 * 1: Enable 2681 * 3X5.6A[1] - LCD Gamma Enable 2682 * 0: Disable 2683 * 1: Enable 2684 * 3X5.6A[0] - LCD Pre-fetch Mode Enable 2685 * 0: Disable 2686 * 1: Enable */ 2687 ViaCrtcMask(hwp, 0x6A, 0x80, 0xC1); 2688 2689 /* TV out uses division by 2 mode. 2690 * Other devices like analog (VGA), DVI, flat panel, etc., 2691 * use normal mode. */ 2692 /* 3X5.6B[5:4] - Second Display Channel Clock Mode Selection 2693 * 0x: Normal 2694 * 1x: Division by 2 2695 * 3X5.6B[2] - IGA2 Screen Off 2696 * 0: Normal 2697 * 1: Screen off 2698 * 3X5.6B[1] - IGA2 Screen Off Selection Method 2699 * 0: IGA2 Screen off 2700 * 1: IGA1 Screen off */ 2701 ViaCrtcMask(hwp, 0x6B, 0x00, 0x36); 2702 2703 /* For UniChrome Pro and Chrome9. */ 2704 if ((pVia->Chipset != VIA_CLE266) 2705 && (pVia->Chipset != VIA_KM400)) { 2706 /* The following register fields are for UniChrome Pro and Chrome9. */ 2707 /* 3X5.6C[3:1] - LCDCK PLL Reference Clock Source Selection 2708 * 000: From XI pin 2709 * 001: From TVXI 2710 * 01x: From TVPLL 2711 * 100: DVP0TVCLKR 2712 * 101: DVP1TVCLKR 2713 * 110: CAP0 Clock 2714 * 111: CAP1 Clock 2715 * 3X5.6C[0] - LCDCK Source Selection 2716 * 0: LCDCK PLL output clock 2717 * 1: LCDCK PLL reference clock */ 2718 ViaCrtcMask(hwp, 0x6C, 0x00, 0x0F); 2719 } 2720 2721 /* Disable LCD scaling */ 2722 /* 3X5.79[0] - LCD Scaling Enable 2723 * 0: Disable 2724 * 1: Enable */ 2725 ViaCrtcMask(hwp, 0x79, 0x00, 0x01); 2726 2727 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2728 "Exiting viaIGA2Init.\n")); 2729} 2730 2731void 2732viaIGA2SetFBStartingAddress(xf86CrtcPtr crtc, int x, int y) 2733{ 2734 ScrnInfoPtr pScrn = crtc->scrn; 2735 vgaHWPtr hwp = VGAHWPTR(pScrn); 2736 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2737 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2738 CARD32 Base, tmp; 2739 CARD8 cr62, cr63, cr64, cra3; 2740 2741 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2742 "Entered viaIGA2SetFBStartingAddress.\n")); 2743 2744 Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); 2745 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2746 "Base Address: 0x%"PRIx32"\n", 2747 (uint32_t)Base)); 2748 Base = (Base + drmmode->front_bo->offset) >> 3; 2749 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2750 "DRI Base Address: 0x%"PRIx32"\n", 2751 (uint32_t)Base); 2752 2753 tmp = hwp->readCrtc(hwp, 0x62) & 0x01; 2754 tmp |= (Base & 0x7F) << 1; 2755 hwp->writeCrtc(hwp, 0x62, tmp); 2756 2757 hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7); 2758 hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15); 2759 hwp->writeCrtc(hwp, 0xA3, (Base & 0x03800000) >> 23); 2760 2761#ifdef HAVE_DEBUG 2762 cr62 = hwp->readCrtc(hwp, 0x62); 2763 cr63 = hwp->readCrtc(hwp, 0x63); 2764 cr64 = hwp->readCrtc(hwp, 0x64); 2765 cra3 = hwp->readCrtc(hwp, 0xA3); 2766 2767 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2768 "CR62: 0x%02X\n", cr62)); 2769 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2770 "CR63: 0x%02X\n", cr63)); 2771 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2772 "CR64: 0x%02X\n", cr64)); 2773 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2774 "CRA3: 0x%02X\n", cra3)); 2775#endif 2776 2777 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2778 "Exiting viaIGA2SetFBStartingAddress.\n")); 2779} 2780 2781void 2782viaIGA2SetDisplayRegister(ScrnInfoPtr pScrn, DisplayModePtr mode) 2783{ 2784 VIAPtr pVia = VIAPTR(pScrn); 2785 vgaHWPtr hwp = VGAHWPTR(pScrn); 2786 CARD16 temp; 2787 2788 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2789 "Entered viaIGA2SetDisplayRegister.\n")); 2790 2791 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2792 "Requested Screen Mode: %s\n", mode->name); 2793 2794 /* UniChrome Pro or later */ 2795 if ((pVia->Chipset != VIA_CLE266) && (pVia->Chipset != VIA_KM400)) { 2796 /* Set IGA2 to linear mode. */ 2797 /* 3X5.62[0] - IGA2 Address Mode Selection 2798 * 0: Linear 2799 * 1: Tile */ 2800 ViaCrtcMask(hwp, 0x62, 0x00, 0x01); 2801 } 2802 2803 /* Keep interlace mode off. */ 2804 /* 3X5.67[5] - Second Display Interlace Mode 2805 * 0: Off 2806 * 1: On */ 2807 ViaCrtcMask(hwp, 0x67, 0x00, 0x20); 2808 2809 2810 /* Set IGA2 horizontal total pixels.*/ 2811 /* Horizontal Total Period: 4096 - 1 (max) */ 2812 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2813 "IGA2 CrtcHTotal: %d\n", mode->CrtcHTotal)); 2814 temp = mode->CrtcHTotal - 1; 2815 2816 /* 3X5.50[7:0] - Horizontal Total Period Bits [7:0] */ 2817 hwp->writeCrtc(hwp, 0x50, temp & 0xFF); 2818 2819 /* 3X5.55[3:0] - Horizontal Total Period Bits [11:8] */ 2820 ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F); 2821 2822 2823 /* Set IGA2 horizontal display end position. */ 2824 /* Horizontal Active Data Period: 2048 - 1 (max) */ 2825 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2826 "IGA2 CrtcHDisplay: %d\n", mode->CrtcHDisplay)); 2827 temp = mode->CrtcHDisplay - 1; 2828 2829 /* 3X5.51[7:0] - Horizontal Active Data Period Bits [7:0] */ 2830 hwp->writeCrtc(hwp, 0x51, temp & 0xFF); 2831 2832 /* 3X5.55[6:4] - Horizontal Active Data Period Bits [10:8] */ 2833 ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70); 2834 2835 if (pVia->Chipset == VIA_VX900) { 2836 /* 3X5.55[7] - Horizontal Active Data Period Bits [11] */ 2837 ViaCrtcMask(hwp, 0x55, temp >> 4, 0x80); 2838 } 2839 2840 2841 /* Set IGA2 horizontal blank start. */ 2842 /* Subtracting 1 from CrtcHBlankStart appears to suppress some 2843 * monitors from reporting horizontal resolution that is 1 more 2844 * than the desired horizontal 2845 * resolution. (i.e., 1601 rather than 1600) */ 2846 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2847 "IGA2 CrtcHBlankStart: %d\n", mode->CrtcHBlankStart)); 2848 temp = mode->CrtcHBlankStart - 1; 2849 2850 /* 3X5.52[7:0] - Horizontal Blanking Start Bits [7:0] */ 2851 hwp->writeCrtc(hwp, 0x52, temp & 0xFF); 2852 2853 /* 3X5.54[2:0] - Horizontal Blanking Start Bits [10:8] */ 2854 ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07); 2855 2856 if (pVia->Chipset == VIA_VX900) { 2857 /* 3X5.6B[0] - Horizontal Blanking Start Bit [11] */ 2858 ViaCrtcMask(hwp, 0x6B, temp >> 11, 0x01); 2859 } 2860 2861 2862 /* Set IGA2 horizontal blank end. */ 2863 /* Horizontal Blanking End: 4096 - 1 (max) */ 2864 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2865 "IGA2 CrtcHBlankEnd: %d\n", mode->CrtcHBlankEnd)); 2866 temp = mode->CrtcHBlankEnd - 1; 2867 2868 /* 3X5.53[7:0] - Horizontal Blanking End Bits [7:0] */ 2869 hwp->writeCrtc(hwp, 0x53, temp & 0xFF); 2870 2871 /* 3X5.54[5:3] - Horizontal Blanking End Bits [10:8] */ 2872 ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38); 2873 2874 /* 3X5.5D[6] - Horizontal Blanking End Bit [11] */ 2875 ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40); 2876 2877 2878 /* Set IGA2 horizontal synchronization start. */ 2879 /* Horizontal Retrace Start: 2047 (max, UniChrome), 2880 * 4095 (max, UniChrome Pro and Chrome9) */ 2881 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2882 "IGA2 CrtcHSyncStart: %d\n", mode->CrtcHSyncStart)); 2883 temp = mode->CrtcHSyncStart; 2884 2885 /* 3X5.56[7:0] - Horizontal Retrace Start Bits [7:0] */ 2886 hwp->writeCrtc(hwp, 0x56, temp & 0xFF); 2887 2888 /* 3X5.54[7:6] - Horizontal Retrace Start Bits [9:8] */ 2889 ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0); 2890 2891 /* 3X5.5C[7] - Horizontal Retrace Start Bit [10] */ 2892 ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80); 2893 2894 /* For UniChrome Pro and Chrome9. */ 2895 if ((pVia->Chipset != VIA_CLE266) 2896 && (pVia->Chipset != VIA_KM400)) { 2897 2898 /* 3X5.5D[7] - Horizontal Retrace Start Bit [11] */ 2899 ViaCrtcMask(hwp, 0x5D, temp >> 4, 0x80); 2900 } 2901 2902 2903 /* Set IGA2 horizontal synchronization end. */ 2904 /* Horizontal Retrace End: 511 (max) */ 2905 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2906 "IGA2 CrtcHSyncEnd: %d\n", mode->CrtcHSyncEnd)); 2907 temp = mode->CrtcHSyncEnd - 1; 2908 2909 /* 3X5.57[7:0] - Horizontal Retrace End Bits [7:0] */ 2910 hwp->writeCrtc(hwp, 0x57, temp & 0xFF); 2911 2912 /* 3X5.5C[6] - Horizontal Retrace End Bit [8] */ 2913 ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40); 2914 2915 2916 /* Set IGA2 vertical total pixels. */ 2917 /* Vertical Total Period: 2048 - 1 (max) */ 2918 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2919 "IGA2 CrtcVTotal: %d\n", mode->CrtcVTotal)); 2920 temp = mode->CrtcVTotal - 1; 2921 2922 /* 3X5.58[7:0] - Vertical Total Period Bits [7:0] */ 2923 hwp->writeCrtc(hwp, 0x58, temp & 0xFF); 2924 2925 /* 3X5.5D[2:0] - Vertical Total Period Bits [10:8] */ 2926 ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07); 2927 2928 2929 /* Set IGA2 vertical display end position. */ 2930 /* Vertical Active Data Period: 2048 - 1 (max) */ 2931 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2932 "IGA2 CrtcVDisplay: %d\n", mode->CrtcVDisplay)); 2933 temp = mode->CrtcVDisplay - 1; 2934 2935 /* 3X5.59[7:0] - Vertical Active Data Period Bits [7:0] */ 2936 hwp->writeCrtc(hwp, 0x59, temp & 0xFF); 2937 2938 /* 3X5.5D[5:3] - Vertical Active Data Period Bits [10:8] */ 2939 ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38); 2940 2941 2942 /* Set IGA2 vertical blank start. */ 2943 /* Subtracting 1 from CrtcVBlankStart appears to suppress some 2944 * monitors from reporting vertical resolution that is 1 more 2945 * than the desired vertical resolution. (i.e., 1201 rather 2946 * than 1200) */ 2947 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2948 "IGA2 CrtcVBlankStart: %d\n", mode->CrtcVBlankStart)); 2949 temp = mode->CrtcVBlankStart - 1; 2950 2951 /* 3X5.5A[7:0] - Vertical Blanking Start Bits [7:0] */ 2952 hwp->writeCrtc(hwp, 0x5A, temp & 0xFF); 2953 2954 /* 3X5.5C[2:0] - Vertical Blanking Start Bits [10:8] */ 2955 ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07); 2956 2957 2958 /* Set IGA2 vertical blank end. */ 2959 /* Vertical Blanking End: 4096 - 1 (max) */ 2960 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2961 "IGA2 CrtcVBlankEnd: %d\n", mode->CrtcVBlankEnd)); 2962 temp = mode->CrtcVBlankEnd - 1; 2963 2964 /* 3X5.5B[7:0] - Vertical Blanking End Bits [7:0] */ 2965 hwp->writeCrtc(hwp, 0x5B, temp & 0xFF); 2966 2967 /* 3X5.5C[5:3] - Vertical Blanking End Bits [10:8] */ 2968 ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38); 2969 2970 2971 /* Set IGA2 vertical synchronization start. */ 2972 /* Horizontal Retrace Start: 2047 (max) */ 2973 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2974 "IGA2 CrtcVSyncStart: %d\n", mode->CrtcVSyncStart)); 2975 temp = mode->CrtcVSyncStart; 2976 2977 /* 3X5.5E[7:0] - Vertical Retrace Start Bits [7:0] */ 2978 hwp->writeCrtc(hwp, 0x5E, temp & 0xFF); 2979 2980 /* 3X5.5F[7:5] - Vertical Retrace Start Bits [10:8] */ 2981 ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0); 2982 2983 2984 /* Set IGA2 vertical synchronization end. */ 2985 /* Vertical Retrace End: 32 (max) */ 2986 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2987 "IGA2 CrtcVSyncEnd: %d\n", mode->CrtcVSyncEnd)); 2988 temp = mode->CrtcVSyncEnd - 1; 2989 2990 /*3X5.5F[4:0] - Vertical Retrace End Bits [4:0] */ 2991 ViaCrtcMask(hwp, 0x5F, temp & 0x1F, 0x1F); 2992 2993 2994 /* Set IGA2 horizontal offset adjustment. */ 2995 temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; 2996 2997 /* 3X5.66[7:0] - Second Display Horizontal Offset Bits [7:0] */ 2998 hwp->writeCrtc(hwp, 0x66, temp & 0xFF); 2999 3000 /* 3X5.67[1:0] - Second Display Horizontal Offset Bits [9:8] */ 3001 ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03); 3002 3003 3004 /* Set IGA2 fetch count. */ 3005 temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 4; 3006 3007 /* 3X5.65[7:0] - Second Display Horizontal 3008 * 2-Quadword Count Data Bits [7:0] */ 3009 hwp->writeCrtc(hwp, 0x65, temp & 0xFF); 3010 3011 /* 3X5.67[3:2] - Second Display Horizontal 3012 * 2-Quadword Count Data Bits [9:8] */ 3013 ViaCrtcMask(hwp, 0x67, temp >> 6, 0x0C); 3014 3015 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3016 "Exiting viaIGA2SetDisplayRegister.\n")); 3017} 3018 3019static ModeStatus 3020viaIGA2ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 3021{ 3022 VIAPtr pVia = VIAPTR(pScrn); 3023 3024 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3025 "Entered viaIGA2ModeValid.\n")); 3026 3027 if (mode->CrtcHTotal > 4096) 3028 return MODE_BAD_HVALUE; 3029 3030 if (((pVia->Chipset != VIA_VX900) 3031 && (mode->CrtcHDisplay > 2048)) 3032 || ((pVia->Chipset == VIA_VX900) 3033 && (mode->CrtcHDisplay > 4096))) 3034 return MODE_BAD_HVALUE; 3035 3036 if (((pVia->Chipset != VIA_VX900) 3037 && (mode->CrtcHBlankStart > 2048)) 3038 || ((pVia->Chipset == VIA_VX900) 3039 && (mode->CrtcHBlankStart > 4096))) 3040 return MODE_BAD_HVALUE; 3041 3042 if (mode->CrtcHBlankEnd > 4096) 3043 return MODE_HBLANK_WIDE; 3044 3045 if ((((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) 3046 && (mode->CrtcHSyncStart > 2048)) 3047 || (((pVia->Chipset != VIA_CLE266) && (pVia->Chipset != VIA_KM400)) 3048 && (mode->CrtcHSyncStart > 4096))) 3049 return MODE_BAD_HVALUE; 3050 3051 if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512) 3052 return MODE_HSYNC_WIDE; 3053 3054 if (mode->CrtcVTotal > 2048) 3055 return MODE_BAD_VVALUE; 3056 3057 if (mode->CrtcVDisplay > 2048) 3058 return MODE_BAD_VVALUE; 3059 3060 if (mode->CrtcVBlankStart > 2048) 3061 return MODE_BAD_VVALUE; 3062 3063 if (mode->CrtcVBlankEnd > 2048) 3064 return MODE_VBLANK_WIDE; 3065 3066 if (mode->CrtcVSyncStart > 2048) 3067 return MODE_BAD_VVALUE; 3068 3069 if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32) 3070 return MODE_VSYNC_WIDE; 3071 3072 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3073 "Exiting viaIGA2ModeValid.\n")); 3074 return MODE_OK; 3075} 3076 3077/* 3078 * I've thrown out the LCD requirement. Size > 1024 is not supported 3079 * by any currently known TV encoder anyway. -- Luc. 3080 * 3081 */ 3082static void 3083ViaSetSecondaryFIFO(ScrnInfoPtr pScrn, DisplayModePtr mode) 3084{ 3085 vgaHWPtr hwp = VGAHWPTR(pScrn); 3086 VIAPtr pVia = VIAPTR(pScrn); 3087 3088 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetSecondaryFIFO\n")); 3089 3090 switch (pVia->Chipset) { 3091 case VIA_CLE266: 3092 if (CLE266_REV_IS_CX(pVia->ChipRev)) { 3093 if (mode->HDisplay >= 1024) { 3094 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 3095 hwp->writeCrtc(hwp, 0x68, 0xAB);/* depth 10, threshold 11 */ 3096 } else { 3097 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 3098 hwp->writeCrtc(hwp, 0x68, 0x67);/* depth 6, threshold 7 */ 3099 } 3100 } else { 3101 if ((pScrn->bitsPerPixel >= 24) 3102 && (((mode->VDisplay > 768) 3103 && (pVia->MemClk <= VIA_MEM_DDR200)) || 3104 ((mode->HDisplay > 1280) 3105 && (pVia->MemClk <= VIA_MEM_DDR266)))) { 3106 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 3107 hwp->writeCrtc(hwp, 0x68, 0xAB);/* depth 10, threshold 11 */ 3108 } else { 3109 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 3110 hwp->writeCrtc(hwp, 0x68, 0x67);/* depth 6, threshold 7 */ 3111 } 3112 } 3113 break; 3114 case VIA_KM400: 3115 if ((mode->HDisplay >= 1600) && (pVia->MemClk <= VIA_MEM_DDR200)) { 3116 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 3117 hwp->writeCrtc(hwp, 0x68, 0xEB); /* depth 14, threshold 11 */ 3118 } else if ((pScrn->bitsPerPixel == 32) 3119 && (((mode->HDisplay > 1024) 3120 && (pVia->MemClk <= VIA_MEM_DDR333)) || 3121 ((mode->HDisplay >= 1024) 3122 && (pVia->MemClk <= VIA_MEM_DDR200)))) { 3123 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 3124 hwp->writeCrtc(hwp, 0x68, 0xCA); /* depth 12, threshold 10 */ 3125 } else if ((pScrn->bitsPerPixel == 16) 3126 && (((mode->HDisplay > 1280) 3127 && (pVia->MemClk <= VIA_MEM_DDR333)) || 3128 ((mode->HDisplay >= 1280) 3129 && (pVia->MemClk <= VIA_MEM_DDR200)))) { 3130 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 3131 hwp->writeCrtc(hwp, 0x68, 0xAB); /* depth 10, threshold 11 */ 3132 } else { 3133 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 3134 hwp->writeCrtc(hwp, 0x68, 0x67); /* depth 6, threshold 7 */ 3135 } 3136 break; 3137 case VIA_K8M800: 3138 /* depth: (384 /8 -1 -1) = 46 = 0x2E */ 3139 ViaCrtcMask(hwp, 0x68, 0xE0, 0xF0); 3140 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); 3141 ViaCrtcMask(hwp, 0x95, 0x80, 0x80); 3142 3143 /* threshold: (328/4) = 82 = 0x52 */ 3144 ViaCrtcMask(hwp, 0x68, 0x02, 0x0F); 3145 ViaCrtcMask(hwp, 0x95, 0x50, 0x70); 3146 3147 /* preq: 74 = 0x4A */ 3148 ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F); 3149 ViaCrtcMask(hwp, 0x95, 0x04, 0x07); 3150 3151 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3152 ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */ 3153 else 3154 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */ 3155 break; 3156 case VIA_PM800: 3157 /* depth: 12 - 1 = 0x0B */ 3158 ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); 3159 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); 3160 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); 3161 3162 /* threshold: 16 = 0x10 */ 3163 ViaCrtcMask(hwp, 0x68, 0x00, 0x0F); 3164 ViaCrtcMask(hwp, 0x95, 0x10, 0x70); 3165 3166 /* preq: 8 = 0x08 */ 3167 ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); 3168 ViaCrtcMask(hwp, 0x95, 0x00, 0x07); 3169 3170 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3171 ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); /* 64/4 */ 3172 else 3173 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); /* 128/4 */ 3174 break; 3175 case VIA_P4M800PRO: 3176 ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); 3177 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); 3178 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); 3179 3180 ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); 3181 ViaCrtcMask(hwp, 0x95, 0x10, 0x70); 3182 3183 ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); 3184 ViaCrtcMask(hwp, 0x95, 0x00, 0x07); 3185 3186 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3187 ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); 3188 else 3189 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); 3190 break; 3191 case VIA_P4M890: 3192 /* depth location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ 3193 ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); /* 96/8-1 = 11 = 0x0B */ 3194 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); 3195 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); 3196 3197 /* location: {CR68,0,3},{CR95,4,6} */ 3198 ViaCrtcMask(hwp, 0x68, 0x03, 0x0F); /* 76/4 = 19 = 0x13 */ 3199 ViaCrtcMask(hwp, 0x95, 0x10, 0x70); 3200 3201 /* location: {CR92,0,3},{CR95,0,2} */ 3202 ViaCrtcMask(hwp, 0x92, 0x00, 0x0F); /* 64/4 = 16 = 0x10 */ 3203 ViaCrtcMask(hwp, 0x95, 0x01, 0x07); 3204 3205 /* location: {CR94,0,6} */ 3206 ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); /* 32/4 = 8 = 0x08 */ 3207 break; 3208 case VIA_K8M890: 3209 /* Display Queue Depth, location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */ 3210 ViaCrtcMask(hwp, 0x68, 0xC0, 0xF0); /* 360/8-1 = 44 = 0x2C; 0x2C << 4 = 0xC0 */ 3211 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); /* 0x2C << 3 = 0x00 */ 3212 ViaCrtcMask(hwp, 0x95, 0x80, 0x80); /* 0x2C << 2 = 0x80 */ 3213 3214 /* Display Queue Read Threshold 1, location: {CR68,0,3},{CR95,4,6} */ 3215 ViaCrtcMask(hwp, 0x68, 0x02, 0x0F); /* 328/4 = 82 = 0x52 */ 3216 ViaCrtcMask(hwp, 0x95, 0x50, 0x70); 3217 3218 /* location: {CR92,0,3},{CR95,0,2} */ 3219 ViaCrtcMask(hwp, 0x92, 0x0A, 0x0F); /* 296/4 = 74 = 0x4A */ 3220 ViaCrtcMask(hwp, 0x95, 0x04, 0x07); /* 0x4A >> 4 = 0x04 */ 3221 3222 /* Display Expire Number Bits, location: {CR94,0,6} */ 3223 ViaCrtcMask(hwp, 0x94, 0x1F, 0x7F); /* 124/4 = 31 = 0x1F */ 3224 break; 3225 case VIA_P4M900: 3226 ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); 3227 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); 3228 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); 3229 3230 ViaCrtcMask(hwp, 0x68, 0x03, 0x0F); 3231 ViaCrtcMask(hwp, 0x95, 0x10, 0x70); 3232 ViaCrtcMask(hwp, 0x92, 0x03, 0x0F); 3233 ViaCrtcMask(hwp, 0x95, 0x01, 0x07); 3234 ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); 3235 break; 3236 case VIA_CX700: 3237 ViaCrtcMask(hwp, 0x68, 0xA0, 0xF0); 3238 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); 3239 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); 3240 3241 ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); 3242 ViaCrtcMask(hwp, 0x95, 0x10, 0x70); 3243 3244 ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); 3245 ViaCrtcMask(hwp, 0x95, 0x00, 0x07); 3246 3247 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3248 ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); 3249 else 3250 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); 3251 break; 3252 case VIA_VX800: 3253 /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 96/8-1 = 0x0B */ 3254 ViaCrtcMask(hwp, 0x68, 0xB0, 0xF0); /* ((0x0B & 0x0F) << 4)) = 0xB0 */ 3255 ViaCrtcMask(hwp, 0x94, 0x00, 0x80); /* ((0x0B & 0x10) << 3)) = 0x00 */ 3256 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); 3257 /* {CR68,0,3},{CR95,4,6} : 64/4 = 0x10 */ 3258 ViaCrtcMask(hwp, 0x68, 0x04, 0x0F); 3259 ViaCrtcMask(hwp, 0x95, 0x10, 0x70); 3260 /* {CR92,0,3},{CR95,0,2} : 32/4 = 0x08 */ 3261 ViaCrtcMask(hwp, 0x92, 0x08, 0x0F); 3262 ViaCrtcMask(hwp, 0x95, 0x00, 0x07); 3263 /* {CR94,0,6} : 128/4 = 0x20 */ 3264 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3265 ViaCrtcMask(hwp, 0x94, 0x10, 0x7F); 3266 else 3267 ViaCrtcMask(hwp, 0x94, 0x20, 0x7F); 3268 break; 3269 case VIA_VX855: 3270 /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 200/8-1 = 24 = 0x18 */ 3271 ViaCrtcMask(hwp, 0x68, 0x80, 0xF0); /* ((0x18 & 0x0F) << 4)) = 0x80 */ 3272 ViaCrtcMask(hwp, 0x94, 0x80, 0x80); /* ((0x18 & 0x10) << 3)) = 0x80 */ 3273 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); /* ((0x18 & 0x20) << 2)) = 0x00 */ 3274 /* {CR68,0,3},{CR95,4,6} : 160/4 = 0x28 */ 3275 ViaCrtcMask(hwp, 0x68, 0x08, 0x0F); /* (0x28 & 0x0F) = 0x08 */ 3276 ViaCrtcMask(hwp, 0x95, 0x20, 0x70); /* (0x28 & 0x70) = 0x20 */ 3277 /* {CR92,0,3},{CR95,0,2} : 160/4 = 0x28 */ 3278 ViaCrtcMask(hwp, 0x92, 0x08, 0x08); /* (0x28 & 0x0F) = 0x08 */ 3279 ViaCrtcMask(hwp, 0x95, 0x02, 0x07); /* ((0x28 & 0x70) >> 4)) = 0x02 */ 3280 /* {CR94,0,6} : 320/4 = 0x50 */ 3281 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3282 ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); 3283 else 3284 ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); 3285 break; 3286 case VIA_VX900: 3287 /* {CR68,4,7},{CR94,7,7},{CR95,7,7} : 192/8-1 = 23 = 0x17 */ 3288 ViaCrtcMask(hwp, 0x68, 0x70, 0xF0); /* ((0x17 & 0x0F) << 4)) = 0x70 */ 3289 ViaCrtcMask(hwp, 0x94, 0x80, 0x80); /* ((0x17 & 0x10) << 3)) = 0x80 */ 3290 ViaCrtcMask(hwp, 0x95, 0x00, 0x80); /* ((0x17 & 0x20) << 2)) = 0x00 */ 3291 /* {CR68,0,3},{CR95,4,6} : 160/4 = 0x28 */ 3292 ViaCrtcMask(hwp, 0x68, 0x08, 0x0F); /* (0x28 & 0x0F) = 0x08 */ 3293 ViaCrtcMask(hwp, 0x95, 0x20, 0x70); /* (0x28 & 0x70) = 0x20 */ 3294 /* {CR92,0,3},{CR95,0,2} : 160/4 = 0x28 */ 3295 ViaCrtcMask(hwp, 0x92, 0x08, 0x08); /* (0x28 & 0x0F) = 0x08 */ 3296 ViaCrtcMask(hwp, 0x95, 0x02, 0x07); /* ((0x28 & 0x70) >> 4)) = 0x2 */ 3297 /* {CR94,0,6} : 320/4 = 0x50 */ 3298 if ((mode->HDisplay >= 1400) && (pScrn->bitsPerPixel == 32)) 3299 ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); 3300 else 3301 ViaCrtcMask(hwp, 0x94, 0x08, 0x7F); 3302 break; 3303 default: 3304 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ViaSetSecondaryFIFO: " 3305 "Chipset %d not implemented\n", pVia->Chipset); 3306 break; 3307 } 3308} 3309 3310void 3311viaIGA2Save(ScrnInfoPtr pScrn) 3312{ 3313 vgaHWPtr hwp = VGAHWPTR(pScrn); 3314 VIAPtr pVia = VIAPTR(pScrn); 3315 VIARegPtr Regs = &pVia->SavedReg; 3316 int i; 3317 3318 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3319 "Entered viaIGA2Save.\n")); 3320 3321 vgaHWProtect(pScrn, TRUE); 3322 3323 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); 3324 3325 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3326 "Saving IGA2 registers.\n")); 3327 3328 /* Unlock extended registers. */ 3329 hwp->writeSeq(hwp, 0x10, 0x01); 3330 3331 for (i = 0; i < (0x88 - 0x50 + 1); i++) { 3332 Regs->CR[i + 0x50] = hwp->readCrtc(hwp, i + 0x50); 3333 } 3334 3335 for (i = 0; i < (0x92 - 0x8A + 1); i++) { 3336 Regs->CR[i + 0x8A] = hwp->readCrtc(hwp, i + 0x8A); 3337 } 3338 3339 for (i = 0; i < (0xA3 - 0x94 + 1); i++) { 3340 Regs->CR[i + 0x94] = hwp->readCrtc(hwp, i + 0x94); 3341 } 3342 3343 Regs->CR[0xA4] = hwp->readCrtc(hwp, 0xA4); 3344 3345 for (i = 0; i < (0xAC - 0xA5 + 1); i++) { 3346 Regs->CR[i + 0xA5] = hwp->readCrtc(hwp, i + 0xA5); 3347 } 3348 3349 /* Chrome 9 */ 3350 switch (pVia->Chipset) { 3351 case VIA_K8M890: 3352 case VIA_P4M900: 3353 case VIA_VX800: 3354 case VIA_VX855: 3355 case VIA_VX900: 3356 Regs->CR[0xAF] = hwp->readCrtc(hwp, 0xAF); 3357 break; 3358 default: 3359 break; 3360 } 3361 3362 /* Chrome 9, Chrome 9 HC, and Chrome 9 HC3 */ 3363 switch (pVia->Chipset) { 3364 case VIA_K8M890: 3365 case VIA_P4M900: 3366 case VIA_VX800: 3367 for (i = 0; i < (0xCD - 0xB0 + 1); i++) { 3368 Regs->CR[i + 0xB0] = hwp->readCrtc(hwp, i + 0xB0); 3369 } 3370 3371 break; 3372 default: 3373 break; 3374 } 3375 3376 switch (pVia->Chipset) { 3377 3378 /* UniChrome Pro and UniChrome Pro II */ 3379 case VIA_PM800: 3380 case VIA_K8M800: 3381 case VIA_P4M800PRO: 3382 case VIA_CX700: 3383 case VIA_P4M890: 3384 for (i = 0; i < (0xD7 - 0xD0 + 1); i++) { 3385 Regs->CR[i + 0xD0] = hwp->readCrtc(hwp, i + 0xD0); 3386 } 3387 3388 break; 3389 3390 /* Chrome 9 */ 3391 case VIA_K8M890: 3392 case VIA_P4M900: 3393 case VIA_VX800: 3394 case VIA_VX855: 3395 case VIA_VX900: 3396 for (i = 0; i < (0xEC - 0xD0 + 1); i++) { 3397 Regs->CR[i + 0xD0] = hwp->readCrtc(hwp, i + 0xD0); 3398 } 3399 3400 break; 3401 default: 3402 break; 3403 } 3404 3405 /* Chrome 9 */ 3406 switch (pVia->Chipset) { 3407 case VIA_K8M890: 3408 case VIA_P4M900: 3409 case VIA_VX800: 3410 case VIA_VX855: 3411 case VIA_VX900: 3412 for (i = 0; i < (0xF5 - 0xF0 + 1); i++) { 3413 Regs->CR[i + 0xF0] = hwp->readCrtc(hwp, i + 0xF0); 3414 } 3415 3416 break; 3417 default: 3418 break; 3419 } 3420 3421 /* Chrome 9 HCM and Chrome 9 HD */ 3422 if ((pVia->Chipset == VIA_VX855) || (pVia->Chipset == VIA_VX900)) { 3423 for (i = 0; i < (0xFC - 0xF6 + 1); i++) { 3424 Regs->CR[i + 0xF6] = hwp->readCrtc(hwp, i + 0xF6); 3425 } 3426 } 3427 3428 /* Chrome 9 HD */ 3429 if (pVia->Chipset == VIA_VX900) { 3430 Regs->CR[0xFD] = hwp->readCrtc(hwp, 0xFD); 3431 } 3432 3433 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3434 "Finished saving IGA2 registers.\n")); 3435 3436 vgaHWProtect(pScrn, FALSE); 3437 3438 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3439 "Exiting viaIGA2Save.\n")); 3440} 3441 3442void 3443viaIGA2Restore(ScrnInfoPtr pScrn) 3444{ 3445 vgaHWPtr hwp = VGAHWPTR(pScrn); 3446 VIAPtr pVia = VIAPTR(pScrn); 3447 VIARegPtr Regs = &pVia->SavedReg; 3448 int i; 3449 3450 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3451 "Entered viaIGA2Restore.\n")); 3452 3453 vgaHWProtect(pScrn, TRUE); 3454 3455 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL); 3456 3457 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3458 "Restoring IGA2 registers.\n")); 3459 3460 /* Unlock extended registers. */ 3461 hwp->writeSeq(hwp, 0x10, 0x01); 3462 3463 for (i = 0; i < (0x5F - 0x50 + 1); i++) { 3464 hwp->writeCrtc(hwp, i + 0x50, Regs->CR[i + 0x50]); 3465 } 3466 3467 for (i = 0; i < (0x69 - 0x62 + 1); i++) { 3468 hwp->writeCrtc(hwp, i + 0x62, Regs->CR[i + 0x62]); 3469 } 3470 3471 hwp->writeCrtc(hwp, 0x6A, Regs->CR[0x6A]); 3472 hwp->writeCrtc(hwp, 0x6B, Regs->CR[0x6B]); 3473 hwp->writeCrtc(hwp, 0x6C, Regs->CR[0x6C]); 3474 3475 for (i = 0; i < (0x88 - 0x6D + 1); i++) { 3476 hwp->writeCrtc(hwp, i + 0x6D, Regs->CR[i + 0x6D]); 3477 } 3478 3479 for (i = 0; i < (0x92 - 0x8A + 1); i++) { 3480 hwp->writeCrtc(hwp, i + 0x8A, Regs->CR[i + 0x8A]); 3481 } 3482 3483 for (i = 0; i < (0xA3 - 0x94 + 1); i++) { 3484 hwp->writeCrtc(hwp, i + 0x94, Regs->CR[i + 0x94]); 3485 } 3486 3487 /* UniChrome Pro and UniChrome Pro II */ 3488 switch (pVia->Chipset) { 3489 case VIA_PM800: 3490 case VIA_K8M800: 3491 case VIA_P4M800PRO: 3492 case VIA_CX700: 3493 case VIA_P4M890: 3494 hwp->writeCrtc(hwp, 0xA4, Regs->CR[0xA4]); 3495 break; 3496 default: 3497 break; 3498 } 3499 3500 for (i = 0; i < (0xAC - 0xA5 + 1); i++) { 3501 hwp->writeCrtc(hwp, i + 0xA5, Regs->CR[i + 0xA5]); 3502 } 3503 3504 /* Chrome 9 */ 3505 switch (pVia->Chipset) { 3506 case VIA_K8M890: 3507 case VIA_P4M900: 3508 case VIA_VX800: 3509 case VIA_VX855: 3510 case VIA_VX900: 3511 hwp->writeCrtc(hwp, 0xAF, Regs->CR[0xAF]); 3512 break; 3513 default: 3514 break; 3515 } 3516 3517 /* Chrome 9, Chrome 9 HC, and Chrome 9 HC3 */ 3518 switch (pVia->Chipset) { 3519 case VIA_K8M890: 3520 case VIA_P4M900: 3521 case VIA_VX800: 3522 for (i = 0; i < (0xCD - 0xB0 + 1); i++) { 3523 hwp->writeCrtc(hwp, i + 0xB0, Regs->CR[i + 0xB0]); 3524 } 3525 3526 break; 3527 default: 3528 break; 3529 } 3530 3531 switch (pVia->Chipset) { 3532 /* UniChrome Pro and UniChrome Pro II */ 3533 case VIA_PM800: 3534 case VIA_K8M800: 3535 case VIA_P4M800PRO: 3536 case VIA_CX700: 3537 case VIA_P4M890: 3538 for (i = 0; i < (0xD7 - 0xD0 + 1); i++) { 3539 hwp->writeCrtc(hwp, i + 0xD0, Regs->CR[i + 0xD0]); 3540 } 3541 3542 break; 3543 3544 /* Chrome 9 */ 3545 case VIA_K8M890: 3546 case VIA_P4M900: 3547 case VIA_VX800: 3548 case VIA_VX855: 3549 case VIA_VX900: 3550 for (i = 0; i < (0xEC - 0xD0 + 1); i++) { 3551 hwp->writeCrtc(hwp, i + 0xD0, Regs->CR[i + 0xD0]); 3552 } 3553 3554 break; 3555 default: 3556 break; 3557 } 3558 3559 /* Chrome 9 */ 3560 switch (pVia->Chipset) { 3561 case VIA_K8M890: 3562 case VIA_P4M900: 3563 case VIA_VX800: 3564 case VIA_VX855: 3565 case VIA_VX900: 3566 for (i = 0; i < (0xF5 - 0xF0 + 1); i++) { 3567 hwp->writeCrtc(hwp, i + 0xF0, Regs->CR[i + 0xF0]); 3568 } 3569 3570 break; 3571 default: 3572 break; 3573 } 3574 3575 /* Chrome 9 HCM and Chrome 9 HD */ 3576 if ((pVia->Chipset == VIA_VX855) || (pVia->Chipset == VIA_VX900)) { 3577 for (i = 0; i < (0xFC - 0xF6 + 1); i++) { 3578 hwp->writeCrtc(hwp, i + 0xF6, Regs->CR[i + 0xF6]); 3579 } 3580 } 3581 3582 /* Chrome 9 HD */ 3583 if (pVia->Chipset == VIA_VX900) { 3584 hwp->writeCrtc(hwp, 0xFD, Regs->CR[0xFD]); 3585 } 3586 3587 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3588 "Finished restoring IGA2 registers.\n")); 3589 3590 vgaHWProtect(pScrn, FALSE); 3591 3592 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3593 "Exiting viaIGA2Restore.\n")); 3594} 3595 3596/* 3597 * Not tested yet 3598 */ 3599void 3600ViaShadowCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 3601{ 3602 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaShadowCRTCSetMode\n")); 3603 3604 vgaHWPtr hwp = VGAHWPTR(pScrn); 3605 CARD16 temp; 3606 3607 temp = (mode->CrtcHTotal >> 3) - 5; 3608 hwp->writeCrtc(hwp, 0x6D, temp & 0xFF); 3609 ViaCrtcMask(hwp, 0x71, temp >> 5, 0x08); 3610 3611 temp = (mode->CrtcHBlankEnd >> 3) - 1; 3612 hwp->writeCrtc(hwp, 0x6E, temp & 0xFF); 3613 3614 temp = mode->CrtcVTotal - 2; 3615 hwp->writeCrtc(hwp, 0x6F, temp & 0xFF); 3616 ViaCrtcMask(hwp, 0x71, temp >> 8, 0x07); 3617 3618 temp = mode->CrtcVDisplay - 1; 3619 hwp->writeCrtc(hwp, 0x70, temp & 0xFF); 3620 ViaCrtcMask(hwp, 0x71, temp >> 4, 0x70); 3621 3622 temp = mode->CrtcVBlankStart - 1; 3623 hwp->writeCrtc(hwp, 0x72, temp & 0xFF); 3624 ViaCrtcMask(hwp, 0x74, temp >> 4, 0x70); 3625 3626 temp = mode->CrtcVTotal - 1; 3627 hwp->writeCrtc(hwp, 0x73, temp & 0xFF); 3628 ViaCrtcMask(hwp, 0x74, temp >> 8, 0x07); 3629 3630 ViaCrtcMask(hwp, 0x76, mode->CrtcVSyncEnd, 0x0F); 3631 3632 temp = mode->CrtcVSyncStart; 3633 hwp->writeCrtc(hwp, 0x75, temp & 0xFF); 3634 ViaCrtcMask(hwp, 0x76, temp >> 4, 0x70); 3635} 3636 3637static void 3638iga1_crtc_dpms(xf86CrtcPtr crtc, int mode) 3639{ 3640 ScrnInfoPtr pScrn = crtc->scrn; 3641 3642 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3643 "Entered iga1_crtc_dpms.\n")); 3644 3645 switch (mode) { 3646 case DPMSModeOn: 3647 viaIGA1DPMSControl(pScrn, 0x00); 3648 break; 3649 3650 case DPMSModeStandby: 3651 viaIGA1DPMSControl(pScrn, 0x01); 3652 break; 3653 3654 case DPMSModeSuspend: 3655 viaIGA1DPMSControl(pScrn, 0x02); 3656 break; 3657 3658 case DPMSModeOff: 3659 viaIGA1DPMSControl(pScrn, 0x03); 3660 break; 3661 3662 default: 3663 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS Mode: %d\n", 3664 mode); 3665 break; 3666 } 3667 //vgaHWSaveScreen(pScrn->pScreen, mode); 3668 3669 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3670 "Exiting iga1_crtc_dpms.\n")); 3671} 3672 3673static void 3674iga1_crtc_save(xf86CrtcPtr crtc) 3675{ 3676 ScrnInfoPtr pScrn = crtc->scrn; 3677 3678 viaIGA1Save(pScrn); 3679} 3680 3681static void 3682iga1_crtc_restore(xf86CrtcPtr crtc) 3683{ 3684 ScrnInfoPtr pScrn = crtc->scrn; 3685 3686 viaIGA1Restore(pScrn); 3687} 3688 3689static Bool 3690iga1_crtc_lock(xf86CrtcPtr crtc) 3691{ 3692 return FALSE; 3693} 3694 3695static void 3696iga1_crtc_unlock(xf86CrtcPtr crtc) 3697{ 3698} 3699 3700static Bool 3701iga1_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 3702 DisplayModePtr adjusted_mode) 3703{ 3704 ScrnInfoPtr pScrn = crtc->scrn; 3705 VIAPtr pVia = VIAPTR(pScrn); 3706 CARD32 temp; 3707 ModeStatus modestatus; 3708 3709 if ((mode->Clock < pScrn->clockRanges->minClock) || 3710 (mode->Clock > pScrn->clockRanges->maxClock)) { 3711 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3712 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 3713 mode->name, mode->Clock, pScrn->clockRanges->minClock, 3714 pScrn->clockRanges->maxClock); 3715 return FALSE; 3716 } 3717 3718 modestatus = viaIGA1ModeValid(pScrn, mode); 3719 if (modestatus != MODE_OK) { 3720 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 3721 mode->name, xf86ModeStatusToString(modestatus)); 3722 return FALSE; 3723 } 3724 3725 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 3726 (pScrn->bitsPerPixel >> 3); 3727 if (pVia->pBIOSInfo->Bandwidth < temp) { 3728 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3729 "Required bandwidth is not available. (%u > %u)\n", 3730 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 3731 return FALSE; 3732 } 3733 3734 if (!pScrn->bitsPerPixel) { 3735 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3736 "Invalid bpp information.\n"); 3737 return FALSE; 3738 } 3739 3740 /* 16 is the Chrome IGP display controller memory alignment. */ 3741 if (crtc->x % (16 / ((pScrn->bitsPerPixel + 7) >> 3))) { 3742 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3743 "The X location specified is not properly aligned " 3744 "to Chrome IGP's memory alignment.\n"); 3745 return FALSE; 3746 } 3747 3748 return TRUE; 3749} 3750 3751static void 3752iga1_crtc_prepare(xf86CrtcPtr crtc) 3753{ 3754 ScrnInfoPtr pScrn = crtc->scrn; 3755 3756 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3757 "Entered iga1_crtc_prepare.\n")); 3758 3759 /* Turn off IGA1. */ 3760 viaIGA1DPMSControl(pScrn, 0x03); 3761 3762 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3763 "Exiting iga1_crtc_prepare.\n")); 3764} 3765 3766static void 3767iga1_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 3768{ 3769 ScrnInfoPtr pScrn = crtc->scrn; 3770 3771 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3772 "Entered iga1_crtc_set_origin.\n")); 3773 3774 viaIGA1SetFBStartingAddress(crtc, x, y); 3775 VIAVidAdjustFrame(pScrn, x, y); 3776 3777 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3778 "Exiting iga1_crtc_set_origin.\n")); 3779} 3780 3781static void 3782iga1_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 3783 DisplayModePtr adjusted_mode, 3784 int x, int y) 3785{ 3786 ScrnInfoPtr pScrn = crtc->scrn; 3787 vgaHWPtr hwp = VGAHWPTR(pScrn); 3788 VIAPtr pVia = VIAPTR(pScrn); 3789 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 3790 3791 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3792 "Entered iga1_crtc_mode_set.\n")); 3793 3794 /* Put IGA1 into a reset state. */ 3795 viaIGA1HWReset(pScrn, 0x00); 3796 3797 if (!vgaHWInit(pScrn, adjusted_mode)) { 3798 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3799 "vgaHWInit failed.\n")); 3800 goto exit; 3801 } 3802 3803 viaIGAInitCommon(pScrn); 3804 viaIGA1Init(pScrn); 3805 3806 /* Disable IGA1 */ 3807 ViaSeqMask(hwp, 0x59, 0x00, 0x80); 3808 3809 ViaPrintMode(pScrn, adjusted_mode); 3810 3811 /* Set color depth. */ 3812 viaIGA1SetColorDepth(pScrn, pScrn->bitsPerPixel); 3813 3814 /* Set display controller screen parameters. */ 3815 viaIGA1SetDisplayRegister(pScrn, adjusted_mode); 3816 3817 ViaSetPrimaryFIFO(pScrn, adjusted_mode); 3818 3819 pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, adjusted_mode); 3820 pBIOSInfo->ClockExternal = FALSE; 3821 ViaSetPrimaryDotclock(pScrn, pBIOSInfo->Clock); 3822 ViaSetUseExternalClock(hwp); 3823 ViaCrtcMask(hwp, 0x6B, 0x00, 0x01); 3824 3825 /* Enable IGA1 */ 3826 ViaSeqMask(hwp, 0x59, 0x80, 0x80); 3827 3828 viaIGA1SetFBStartingAddress(crtc, x, y); 3829 VIAVidAdjustFrame(pScrn, x, y); 3830 3831exit: 3832 /* Put IGA1 back into a normal operating state. */ 3833 viaIGA1HWReset(pScrn, 0x01); 3834 3835 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3836 "Exiting iga1_crtc_mode_set.\n")); 3837} 3838 3839static void 3840iga1_crtc_commit(xf86CrtcPtr crtc) 3841{ 3842 ScrnInfoPtr pScrn = crtc->scrn; 3843 VIAPtr pVia = VIAPTR(pScrn); 3844 3845 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3846 "Entering iga1_crtc_commit.\n")); 3847 3848 if (crtc->scrn->pScreen != NULL && pVia->drmmode.hwcursor) 3849#ifdef HAVE_XF86_CURSOR_RESET_CURSOR 3850 xf86CursorResetCursor(crtc->scrn->pScreen); 3851#else 3852 xf86_reload_cursors(crtc->scrn->pScreen); 3853#endif 3854 3855 /* Turn on IGA1. */ 3856 viaIGA1DPMSControl(pScrn, 0x00); 3857 3858 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3859 "Exiting iga1_crtc_commit.\n")); 3860} 3861 3862static void 3863iga1_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 3864 int size) 3865{ 3866 ScrnInfoPtr pScrn = crtc->scrn; 3867 LOCO colors[size]; 3868 int i; 3869 3870 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3871 "Entering iga1_crtc_gamma_set.\n")); 3872 3873 for (i = 0; i < size; i++) { 3874 colors[i].red = red[i] >> 8; 3875 colors[i].green = green[i] >> 8; 3876 colors[i].blue = blue[i] >> 8; 3877 } 3878 3879 /* Set palette LUT to 8-bit mode. */ 3880 viaIGA1SetPaletteLUTResolution(pScrn, 0x01); 3881 3882 switch (pScrn->bitsPerPixel) { 3883 case 8: 3884 /* IGA1 will access the palette LUT. */ 3885 viaSetPaletteLUTAccess(pScrn, 0x00); 3886 3887 VIALoadRgbLut(pScrn, 0, size, colors); 3888 3889 /* Turn gamma correction off. */ 3890 viaIGA1SetGamma(pScrn, FALSE); 3891 break; 3892 case 16: 3893 /* IGA1 will access the palette LUT. */ 3894 viaSetPaletteLUTAccess(pScrn, 0x00); 3895 3896 VIALoadRgbLut(pScrn, 0, size, colors); 3897 3898 /* Turn gamma correction off. */ 3899 viaIGA1SetGamma(pScrn, FALSE); 3900 break; 3901 case 24: 3902 case 32: 3903 /* IGA1 will access the palette LUT. */ 3904 viaSetPaletteLUTAccess(pScrn, 0x00); 3905 3906 VIALoadRgbLut(pScrn, 0, size, colors); 3907 3908 /* Turn gamma correction off. */ 3909 viaIGA1SetGamma(pScrn, FALSE); 3910 break; 3911 default: 3912 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3913 "Unsupported color depth: %d\n", 3914 pScrn->bitsPerPixel); 3915 break; 3916 } 3917 3918 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3919 "Exiting iga1_crtc_gamma_set.\n")); 3920} 3921 3922static void * 3923iga1_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 3924{ 3925 return NULL; 3926} 3927 3928static PixmapPtr 3929iga1_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 3930{ 3931 return NULL; 3932} 3933 3934static void 3935iga1_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 3936{ 3937} 3938 3939/* 3940 Set the cursor foreground and background colors. In 8bpp, fg and 3941 bg are indices into the current colormap unless the 3942 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 3943 and in all other bpps the fg and bg are in 8-8-8 RGB format. 3944*/ 3945static void 3946iga1_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 3947{ 3948 ScrnInfoPtr pScrn = crtc->scrn; 3949 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 3950 3951 if (xf86_config->cursor_fg) 3952 return; 3953 3954 /* Don't recolour the image if we don't have to. */ 3955 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 3956 return; 3957 3958 viaIGA1DisplayHI(pScrn, FALSE); 3959 3960 xf86_config->cursor_fg = fg; 3961 xf86_config->cursor_bg = bg; 3962} 3963 3964static void 3965iga1_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 3966{ 3967 ScrnInfoPtr pScrn = crtc->scrn; 3968 unsigned xoff, yoff; 3969 3970 if (x < 0) { 3971 xoff = ((-x) & 0xFE); 3972 x = 0; 3973 } else { 3974 xoff = 0; 3975 } 3976 3977 if (y < 0) { 3978 yoff = ((-y) & 0xFE); 3979 y = 0; 3980 } else { 3981 yoff = 0; 3982 } 3983 3984 viaIGA1SetHIDisplayLocation(pScrn, x, xoff, y, yoff); 3985} 3986 3987static void 3988iga1_crtc_show_cursor(xf86CrtcPtr crtc) 3989{ 3990 ScrnInfoPtr pScrn = crtc->scrn; 3991 3992 viaIGA1DisplayHI(pScrn, TRUE); 3993} 3994 3995static void 3996iga1_crtc_hide_cursor(xf86CrtcPtr crtc) 3997{ 3998 ScrnInfoPtr pScrn = crtc->scrn; 3999 4000 viaIGA1DisplayHI(pScrn, FALSE); 4001} 4002 4003static void 4004iga1_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) 4005{ 4006 drmmode_crtc_private_ptr iga = crtc->driver_private; 4007 ScrnInfoPtr pScrn = crtc->scrn; 4008 void *dst; 4009 4010 dst = drm_bo_map(pScrn, iga->cursor_bo); 4011 memset(dst, 0x00, iga->cursor_bo->size); 4012 memcpy(dst, image, iga->cursor_bo->size); 4013 drm_bo_unmap(pScrn, iga->cursor_bo); 4014 4015 viaIGA1InitHI(pScrn); 4016 viaIGA1SetHIStartingAddress(crtc); 4017} 4018 4019static void 4020iga_crtc_destroy(xf86CrtcPtr crtc) 4021{ 4022 if (crtc->driver_private) 4023 free(crtc->driver_private); 4024} 4025 4026const xf86CrtcFuncsRec iga1_crtc_funcs = { 4027 .dpms = iga1_crtc_dpms, 4028 .save = iga1_crtc_save, 4029 .restore = iga1_crtc_restore, 4030 .lock = iga1_crtc_lock, 4031 .unlock = iga1_crtc_unlock, 4032 .mode_fixup = iga1_crtc_mode_fixup, 4033 .prepare = iga1_crtc_prepare, 4034 .mode_set = iga1_crtc_mode_set, 4035 .commit = iga1_crtc_commit, 4036 .gamma_set = iga1_crtc_gamma_set, 4037 .shadow_create = iga1_crtc_shadow_create, 4038 .shadow_allocate = iga1_crtc_shadow_allocate, 4039 .shadow_destroy = iga1_crtc_shadow_destroy, 4040 .set_cursor_colors = iga1_crtc_set_cursor_colors, 4041 .set_cursor_position = iga1_crtc_set_cursor_position, 4042 .show_cursor = iga1_crtc_show_cursor, 4043 .hide_cursor = iga1_crtc_hide_cursor, 4044 .load_cursor_argb = iga1_crtc_load_cursor_argb, 4045#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 2 4046 .set_origin = iga1_crtc_set_origin, 4047#endif 4048 .destroy = iga_crtc_destroy, 4049}; 4050 4051static void 4052iga2_crtc_dpms(xf86CrtcPtr crtc, int mode) 4053{ 4054 ScrnInfoPtr pScrn = crtc->scrn; 4055 4056 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4057 "Entered iga2_crtc_dpms.\n")); 4058 4059 switch (mode) { 4060 case DPMSModeOn: 4061 viaIGA2DisplayOutput(pScrn, TRUE); 4062 break; 4063 4064 case DPMSModeStandby: 4065 case DPMSModeSuspend: 4066 case DPMSModeOff: 4067 viaIGA2DisplayOutput(pScrn, FALSE); 4068 break; 4069 4070 default: 4071 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode: %d\n", 4072 mode); 4073 break; 4074 } 4075 //vgaHWSaveScreen(pScrn->pScreen, mode); 4076 4077 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4078 "Exiting iga2_crtc_dpms.\n")); 4079} 4080 4081static void 4082iga2_crtc_save(xf86CrtcPtr crtc) 4083{ 4084 ScrnInfoPtr pScrn = crtc->scrn; 4085 4086 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4087 "Entered iga2_crtc_save.\n")); 4088 4089 viaIGA2Save(pScrn); 4090 4091 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4092 "Exiting iga2_crtc_save.\n")); 4093} 4094 4095static void 4096iga2_crtc_restore(xf86CrtcPtr crtc) 4097{ 4098 ScrnInfoPtr pScrn = crtc->scrn; 4099 4100 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4101 "Entered iga2_crtc_restore.\n")); 4102 4103 viaIGA2Restore(pScrn); 4104 4105 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4106 "Exiting iga2_crtc_restore.\n")); 4107} 4108 4109static Bool 4110iga2_crtc_lock(xf86CrtcPtr crtc) 4111{ 4112 return FALSE; 4113} 4114 4115static void 4116iga2_crtc_unlock(xf86CrtcPtr crtc) 4117{ 4118} 4119 4120static Bool 4121iga2_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 4122 DisplayModePtr adjusted_mode) 4123{ 4124 ScrnInfoPtr pScrn = crtc->scrn; 4125 VIAPtr pVia = VIAPTR(pScrn); 4126 CARD32 temp; 4127 ModeStatus modestatus; 4128 4129 if ((mode->Clock < pScrn->clockRanges->minClock) || 4130 (mode->Clock > pScrn->clockRanges->maxClock)) { 4131 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4132 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 4133 mode->name, mode->Clock, pScrn->clockRanges->minClock, 4134 pScrn->clockRanges->maxClock); 4135 return FALSE; 4136 } 4137 4138 modestatus = viaIGA2ModeValid(pScrn, mode); 4139 if (modestatus != MODE_OK) { 4140 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 4141 mode->name, xf86ModeStatusToString(modestatus)); 4142 return FALSE; 4143 } 4144 4145 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 4146 (pScrn->bitsPerPixel >> 3); 4147 if (pVia->pBIOSInfo->Bandwidth < temp) { 4148 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4149 "Required bandwidth is not available. (%u > %u)\n", 4150 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 4151 return FALSE; 4152 } 4153 4154 if (!pScrn->bitsPerPixel) { 4155 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4156 "Invalid bpp information.\n"); 4157 return FALSE; 4158 } 4159 4160 /* 16 is the Chrome IGP display controller memory alignment. */ 4161 if (crtc->x % (16 / ((pScrn->bitsPerPixel + 7) >> 3))) { 4162 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4163 "The X location specified is not properly aligned " 4164 "to Chrome IGP's memory alignment.\n"); 4165 return FALSE; 4166 } 4167 4168 return TRUE; 4169} 4170 4171static void 4172iga2_crtc_prepare(xf86CrtcPtr crtc) 4173{ 4174 ScrnInfoPtr pScrn = crtc->scrn; 4175 4176 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4177 "Entered iga2_crtc_prepare.\n")); 4178 4179 /* Turn off IGA2. */ 4180 viaIGA2DisplayOutput(pScrn, FALSE); 4181 4182 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4183 "Exiting iga2_crtc_prepare.\n")); 4184} 4185 4186static void 4187iga2_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 4188{ 4189 ScrnInfoPtr pScrn = crtc->scrn; 4190 4191 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4192 "Entered iga2_crtc_set_origin.\n")); 4193 4194 viaIGA2SetFBStartingAddress(crtc, x, y); 4195 VIAVidAdjustFrame(pScrn, x, y); 4196 4197 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4198 "Exiting iga2_crtc_set_origin.\n")); 4199} 4200 4201static void 4202iga2_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 4203 DisplayModePtr adjusted_mode, int x, int y) 4204{ 4205 ScrnInfoPtr pScrn = crtc->scrn; 4206 vgaHWPtr hwp = VGAHWPTR(pScrn); 4207 VIAPtr pVia = VIAPTR(pScrn); 4208 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 4209 4210 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4211 "Entered iga2_crtc_mode_set.\n")); 4212 4213 /* Put IGA2 into a reset state. */ 4214 viaIGA2HWReset(pScrn, 0x00); 4215 4216 /* Disable IGA2 display channel. */ 4217 viaIGA2DisplayChannel(pScrn, FALSE); 4218 4219 viaIGAInitCommon(pScrn); 4220 viaIGA2Init(pScrn); 4221 4222 ViaPrintMode(pScrn, adjusted_mode); 4223 4224 /* Set color depth. */ 4225 viaIGA2SetColorDepth(pScrn, pScrn->bitsPerPixel); 4226 4227 /* Set display controller screen parameters. */ 4228 viaIGA2SetDisplayRegister(pScrn, adjusted_mode); 4229 4230 ViaSetSecondaryFIFO(pScrn, adjusted_mode); 4231 pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, adjusted_mode); 4232 pBIOSInfo->ClockExternal = FALSE; 4233 ViaSetSecondaryDotclock(pScrn, pBIOSInfo->Clock); 4234 ViaSetUseExternalClock(hwp); 4235 4236 viaIGA2SetFBStartingAddress(crtc, x, y); 4237 VIAVidAdjustFrame(pScrn, x, y); 4238 4239 /* Enable IGA2 display channel. */ 4240 viaIGA2DisplayChannel(pScrn, TRUE); 4241 4242 /* Put IGA2 back into a normal operating state. */ 4243 viaIGA2HWReset(pScrn, 0x01); 4244 4245 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4246 "Exiting iga2_crtc_mode_set.\n")); 4247} 4248 4249static void 4250iga2_crtc_commit(xf86CrtcPtr crtc) 4251{ 4252 ScrnInfoPtr pScrn = crtc->scrn; 4253 VIAPtr pVia = VIAPTR(pScrn); 4254 4255 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4256 "Entering iga2_crtc_commit.\n")); 4257 4258 if (crtc->scrn->pScreen != NULL && pVia->drmmode.hwcursor) 4259#ifdef HAVE_XF86_CURSOR_RESET_CURSOR 4260 xf86CursorResetCursor(crtc->scrn->pScreen); 4261#else 4262 xf86_reload_cursors(crtc->scrn->pScreen); 4263#endif 4264 4265 /* Turn on IGA2. */ 4266 viaIGA2DisplayOutput(pScrn, TRUE); 4267 4268 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4269 "Exiting iga2_crtc_commit.\n")); 4270} 4271 4272static void 4273iga2_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 4274 int size) 4275{ 4276 ScrnInfoPtr pScrn = crtc->scrn; 4277 LOCO colors[size]; 4278 int i; 4279 4280 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4281 "Entering iga2_crtc_gamma_set.\n")); 4282 4283 for (i = 0; i < size; i++) { 4284 colors[i].red = red[i] >> 8; 4285 colors[i].green = green[i] >> 8; 4286 colors[i].blue = blue[i] >> 8; 4287 } 4288 4289 /* Set palette LUT to 8-bit mode. */ 4290 viaIGA2SetPaletteLUTResolution(pScrn, 0x01); 4291 4292 switch (pScrn->bitsPerPixel) { 4293 case 8: 4294 /* IGA2 will access the palette LUT. */ 4295 viaSetPaletteLUTAccess(pScrn, 0x01); 4296 4297 VIALoadRgbLut(pScrn, 0, size, colors); 4298 4299 /* Turn gamma correction off. */ 4300 viaIGA2SetGamma(pScrn, FALSE); 4301 break; 4302 case 16: 4303 /* IGA2 will access the palette LUT. */ 4304 viaSetPaletteLUTAccess(pScrn, 0x01); 4305 4306 VIALoadRgbLut(pScrn, 0, size, colors); 4307 4308 /* Turn gamma correction off. */ 4309 viaIGA2SetGamma(pScrn, FALSE); 4310 break; 4311 case 24: 4312 case 32: 4313 /* IGA2 will access the palette LUT. */ 4314 viaSetPaletteLUTAccess(pScrn, 0x01); 4315 4316 VIALoadRgbLut(pScrn, 0, size, colors); 4317 4318 /* Turn gamma correction off. */ 4319 viaIGA2SetGamma(pScrn, FALSE); 4320 break; 4321 default: 4322 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4323 "Unsupported color depth: %d\n", 4324 pScrn->bitsPerPixel); 4325 break; 4326 } 4327 4328 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4329 "Exiting iga2_crtc_gamma_set.\n")); 4330} 4331 4332static void * 4333iga2_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 4334{ 4335 return NULL; 4336} 4337 4338static PixmapPtr 4339iga2_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 4340{ 4341 return NULL; 4342} 4343 4344static void 4345iga2_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 4346{ 4347} 4348 4349/* 4350 Set the cursor foreground and background colors. In 8bpp, fg and 4351 bg are indices into the current colormap unless the 4352 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 4353 and in all other bpps the fg and bg are in 8-8-8 RGB format. 4354*/ 4355static void 4356iga2_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 4357{ 4358 drmmode_crtc_private_ptr iga = crtc->driver_private; 4359 ScrnInfoPtr pScrn = crtc->scrn; 4360 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 4361 int height = 64, width = 64, i; 4362 CARD32 pixel, *dst; 4363 4364 if (xf86_config->cursor_fg) 4365 return; 4366 4367 fg |= 0xff000000; 4368 bg |= 0xff000000; 4369 4370 /* Don't recolour the image if we don't have to. */ 4371 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 4372 return; 4373 4374 viaIGA2DisplayHI(pScrn, FALSE); 4375 4376 dst = drm_bo_map(pScrn, iga->cursor_bo); 4377 for (i = 0; i < width * height; i++, dst++) 4378 if ((pixel = *dst)) 4379 *dst = (pixel == xf86_config->cursor_fg) ? fg : bg; 4380 drm_bo_unmap(pScrn, iga->cursor_bo); 4381 4382 xf86_config->cursor_fg = fg; 4383 xf86_config->cursor_bg = bg; 4384} 4385 4386static void 4387iga2_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 4388{ 4389 ScrnInfoPtr pScrn = crtc->scrn; 4390 unsigned xoff, yoff; 4391 4392 if (x < 0) { 4393 xoff = ((-x) & 0xFE); 4394 x = 0; 4395 } else { 4396 xoff = 0; 4397 } 4398 4399 if (y < 0) { 4400 yoff = ((-y) & 0xFE); 4401 y = 0; 4402 } else { 4403 yoff = 0; 4404 } 4405 4406 viaIGA2SetHIDisplayLocation(pScrn, x, xoff, y, yoff); 4407} 4408 4409static void 4410iga2_crtc_show_cursor(xf86CrtcPtr crtc) 4411{ 4412 ScrnInfoPtr pScrn = crtc->scrn; 4413 4414 viaIGA2DisplayHI(pScrn, TRUE); 4415} 4416 4417static void 4418iga2_crtc_hide_cursor(xf86CrtcPtr crtc) 4419{ 4420 ScrnInfoPtr pScrn = crtc->scrn; 4421 4422 viaIGA2DisplayHI(pScrn, FALSE); 4423} 4424 4425static void 4426iga2_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) 4427{ 4428 drmmode_crtc_private_ptr iga = crtc->driver_private; 4429 ScrnInfoPtr pScrn = crtc->scrn; 4430 void *dst; 4431 4432 dst = drm_bo_map(pScrn, iga->cursor_bo); 4433 memset(dst, 0x00, iga->cursor_bo->size); 4434 memcpy(dst, image, iga->cursor_bo->size); 4435 drm_bo_unmap(pScrn, iga->cursor_bo); 4436 4437 viaIGA2InitHI(pScrn); 4438 viaIGA2SetHIStartingAddress(crtc); 4439} 4440 4441const xf86CrtcFuncsRec iga2_crtc_funcs = { 4442 .dpms = iga2_crtc_dpms, 4443 .save = iga2_crtc_save, 4444 .restore = iga2_crtc_restore, 4445 .lock = iga2_crtc_lock, 4446 .unlock = iga2_crtc_unlock, 4447 .mode_fixup = iga2_crtc_mode_fixup, 4448 .prepare = iga2_crtc_prepare, 4449 .mode_set = iga2_crtc_mode_set, 4450 .commit = iga2_crtc_commit, 4451 .gamma_set = iga2_crtc_gamma_set, 4452 .shadow_create = iga2_crtc_shadow_create, 4453 .shadow_allocate = iga2_crtc_shadow_allocate, 4454 .shadow_destroy = iga2_crtc_shadow_destroy, 4455 .set_cursor_colors = iga2_crtc_set_cursor_colors, 4456 .set_cursor_position = iga2_crtc_set_cursor_position, 4457 .show_cursor = iga2_crtc_show_cursor, 4458 .hide_cursor = iga2_crtc_hide_cursor, 4459 .load_cursor_argb = iga2_crtc_load_cursor_argb, 4460#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 2 4461 .set_origin = iga2_crtc_set_origin, 4462#endif 4463 .destroy = iga_crtc_destroy, 4464}; 4465