via_display.c revision 03bd066f
1/* 2 * Copyright 2015-2016 Kevin Brace 3 * Copyright 2005-2016 The OpenChrome Project 4 * [http://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 "via_driver.h" 33 34/* 35 * Controls IGA1 DPMS State. 36 */ 37void 38viaIGA1DPMSControl(ScrnInfoPtr pScrn, CARD8 dpmsControl) 39{ 40 vgaHWPtr hwp = VGAHWPTR(pScrn); 41 42 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 43 "Entered viaIGA1DPMSControl.\n")); 44 45 /* 3X5.36[5:4] - DPMS Control 46 * 00: On 47 * 01: Stand-by 48 * 10: Suspend 49 * 11: Off */ 50 ViaCrtcMask(hwp, 0x36, dpmsControl << 4, 0x30); 51 52 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 53 "Exiting viaIGA1DPMSControl.\n")); 54} 55 56/* 57 * Controls IGA2 display output on or off state. 58 */ 59void 60viaIGA2DisplayOutput(ScrnInfoPtr pScrn, Bool outputState) 61{ 62 vgaHWPtr hwp = VGAHWPTR(pScrn); 63 64 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65 "Entered viaIGA2DisplayOutput.\n")); 66 67 /* 3X5.6B[2] - IGA2 Screen Off 68 * 0: Screen on 69 * 1: Screen off */ 70 ViaCrtcMask(hwp, 0x6B, outputState ? 0x00 : 0x04, 0x04); 71 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 72 "IGA2 Display Output: %s\n", 73 outputState ? "On" : "Off"); 74 75 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 76 "Exiting viaIGA2DisplayOutput.\n")); 77} 78 79/* 80 * Controls IGA2 display channel state. 81 */ 82void 83viaIGA2DisplayChannel(ScrnInfoPtr pScrn, Bool channelState) 84{ 85 vgaHWPtr hwp = VGAHWPTR(pScrn); 86 87 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 88 "Entered viaIGA2DisplayChannel.\n")); 89 90 /* 3X5.6A[7] - Second Display Channel Enable 91 * 3X5.6A[6] - Second Display Channel Reset (0 for reset) */ 92 ViaCrtcMask(hwp, 0x6A, 0x00, 0x40); 93 ViaCrtcMask(hwp, 0x6A, channelState ? 0x80 : 0x00, 0x80); 94 ViaCrtcMask(hwp, 0x6A, 0x40, 0x40); 95 96 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 97 "IGA2 Display Channel: %s\n", 98 channelState ? "On" : "Off"); 99 100 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 101 "Exiting viaIGA2DisplayChannel.\n")); 102} 103 104/* 105 * Initial settings for displays. 106 */ 107void 108viaDisplayInit(ScrnInfoPtr pScrn) 109{ 110 VIAPtr pVia = VIAPTR(pScrn); 111 vgaHWPtr hwp = VGAHWPTR(pScrn); 112 113 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 114 "Entered viaDisplayInit.\n")); 115 116 ViaCrtcMask(hwp, 0x6A, 0x00, 0x3D); 117 hwp->writeCrtc(hwp, 0x6B, 0x00); 118 hwp->writeCrtc(hwp, 0x6C, 0x00); 119 hwp->writeCrtc(hwp, 0x79, 0x00); 120 121 /* (IGA1 Timing Plus 2, added in VT3259 A3 or later) */ 122 if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) 123 ViaCrtcMask(hwp, 0x47, 0x00, 0xC8); 124 125 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 126 "Exiting viaDisplayInit.\n")); 127} 128 129/* 130 * Sets the primary or secondary display stream on internal TMDS. 131 */ 132void 133ViaDisplaySetStreamOnDFP(ScrnInfoPtr pScrn, Bool primary) 134{ 135 vgaHWPtr hwp = VGAHWPTR(pScrn); 136 137 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnDFP\n")); 138 139 if (primary) 140 ViaCrtcMask(hwp, 0x99, 0x00, 0x10); 141 else 142 ViaCrtcMask(hwp, 0x99, 0x10, 0x10); 143} 144 145static void 146ViaCRTCSetGraphicsRegisters(ScrnInfoPtr pScrn) 147{ 148 vgaHWPtr hwp = VGAHWPTR(pScrn); 149 150 /* graphics registers */ 151 hwp->writeGr(hwp, 0x00, 0x00); 152 hwp->writeGr(hwp, 0x01, 0x00); 153 hwp->writeGr(hwp, 0x02, 0x00); 154 hwp->writeGr(hwp, 0x03, 0x00); 155 hwp->writeGr(hwp, 0x04, 0x00); 156 hwp->writeGr(hwp, 0x05, 0x40); 157 hwp->writeGr(hwp, 0x06, 0x05); 158 hwp->writeGr(hwp, 0x07, 0x0F); 159 hwp->writeGr(hwp, 0x08, 0xFF); 160 161 ViaGrMask(hwp, 0x20, 0, 0xFF); 162 ViaGrMask(hwp, 0x21, 0, 0xFF); 163 ViaGrMask(hwp, 0x22, 0, 0xFF); 164} 165 166static void 167ViaCRTCSetAttributeRegisters(ScrnInfoPtr pScrn) 168{ 169 vgaHWPtr hwp = VGAHWPTR(pScrn); 170 CARD8 i; 171 172 /* attribute registers */ 173 for (i = 0; i <= 0xF; i++) { 174 hwp->writeAttr(hwp, i, i); 175 } 176 hwp->writeAttr(hwp, 0x10, 0x41); 177 hwp->writeAttr(hwp, 0x11, 0xFF); 178 hwp->writeAttr(hwp, 0x12, 0x0F); 179 hwp->writeAttr(hwp, 0x13, 0x00); 180 hwp->writeAttr(hwp, 0x14, 0x00); 181} 182 183void 184VIALoadRgbLut(ScrnInfoPtr pScrn, int start, int numColors, LOCO *colors) 185{ 186 vgaHWPtr hwp = VGAHWPTR(pScrn); 187 int i, j; 188 189 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadRgbLut\n")); 190 191 hwp->enablePalette(hwp); 192 hwp->writeDacMask(hwp, 0xFF); 193 194 /* We need the same palette contents for both 16 and 24 bits, but X doesn't 195 * play: X's colormap handling is hopelessly intertwined with almost every 196 * X subsystem. So we just space out RGB values over the 256*3. */ 197 198 switch (pScrn->bitsPerPixel) { 199 case 16: 200 for (i = start; i < numColors; i++) { 201 hwp->writeDacWriteAddr(hwp, i * 4); 202 for (j = 0; j < 4; j++) { 203 hwp->writeDacData(hwp, colors[i / 2].red); 204 hwp->writeDacData(hwp, colors[i].green); 205 hwp->writeDacData(hwp, colors[i / 2].blue); 206 } 207 } 208 break; 209 case 8: 210 case 24: 211 case 32: 212 for (i = start; i < numColors; i++) { 213 hwp->writeDacWriteAddr(hwp, i); 214 hwp->writeDacData(hwp, colors[i].red); 215 hwp->writeDacData(hwp, colors[i].green); 216 hwp->writeDacData(hwp, colors[i].blue); 217 } 218 break; 219 default: 220 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 221 "Unsupported bitdepth: %d\n", pScrn->bitsPerPixel); 222 break; 223 } 224 hwp->disablePalette(hwp); 225} 226 227void 228ViaGammaDisable(ScrnInfoPtr pScrn) 229{ 230 VIAPtr pVia = VIAPTR(pScrn); 231 vgaHWPtr hwp = VGAHWPTR(pScrn); 232 233 switch (pVia->Chipset) { 234 case VIA_CLE266: 235 case VIA_KM400: 236 ViaSeqMask(hwp, 0x16, 0x00, 0x80); 237 break; 238 default: 239 ViaCrtcMask(hwp, 0x33, 0x00, 0x80); 240 break; 241 } 242 243 /* Disable gamma on secondary */ 244 /* This is needed or the hardware will lockup */ 245 ViaSeqMask(hwp, 0x1A, 0x00, 0x01); 246 ViaCrtcMask(hwp, 0x6A, 0x00, 0x02); 247 switch (pVia->Chipset) { 248 case VIA_CLE266: 249 case VIA_KM400: 250 case VIA_K8M800: 251 case VIA_PM800: 252 break; 253 default: 254 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 255 break; 256 } 257} 258 259void 260ViaCRTCInit(ScrnInfoPtr pScrn) 261{ 262 vgaHWPtr hwp = VGAHWPTR(pScrn); 263 264 hwp->writeSeq(hwp, 0x10, 0x01); /* unlock extended registers */ 265 ViaCrtcMask(hwp, 0x47, 0x00, 0x01); /* unlock CRT registers */ 266 ViaCRTCSetGraphicsRegisters(pScrn); 267 ViaCRTCSetAttributeRegisters(pScrn); 268} 269 270/* 271 * Initialize common IGA (Integrated Graphics Accelerator) registers. 272 */ 273void 274viaIGAInitCommon(ScrnInfoPtr pScrn) 275{ 276 vgaHWPtr hwp = VGAHWPTR(pScrn); 277 VIAPtr pVia = VIAPTR(pScrn); 278#ifdef HAVE_DEBUG 279 CARD8 temp; 280#endif 281 282 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 283 "Entered viaIGAInitCommon.\n")); 284 285 /* Unlock VIA Technologies extended VGA registers. */ 286 /* 3C5.10[0] - Unlock Accessing of I/O Space 287 * 0: Disable 288 * 1: Enable */ 289 ViaSeqMask(hwp, 0x10, 0x01, 0x01); 290 291 ViaCRTCSetGraphicsRegisters(pScrn); 292 ViaCRTCSetAttributeRegisters(pScrn); 293 294#ifdef HAVE_DEBUG 295 temp = hwp->readSeq(hwp, 0x15); 296 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 297 "SR15: 0x%02X\n", temp)); 298 temp = hwp->readSeq(hwp, 0x19); 299 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 300 "SR19: 0x%02X\n", temp)); 301 temp = hwp->readSeq(hwp, 0x1A); 302 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 303 "SR1A: 0x%02X\n", temp)); 304 temp = hwp->readSeq(hwp, 0x1B); 305 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 306 "SR1B: 0x%02X\n", temp)); 307 temp = hwp->readSeq(hwp, 0x1E); 308 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 309 "SR1E: 0x%02X\n", temp)); 310 temp = hwp->readSeq(hwp, 0x2A); 311 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 312 "SR2A: 0x%02X\n", temp)); 313 temp = hwp->readSeq(hwp, 0x2D); 314 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 315 "SR2D: 0x%02X\n", temp)); 316 temp = hwp->readSeq(hwp, 0x2E); 317 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 318 "SR2E: 0x%02X\n", temp)); 319 temp = hwp->readSeq(hwp, 0x3F); 320 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 321 "SR3F: 0x%02X\n", temp)); 322 temp = hwp->readSeq(hwp, 0x65); 323 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 324 "SR65: 0x%02X\n", temp)); 325 temp = hwp->readCrtc(hwp, 0x36); 326 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 327 "CR36: 0x%02X\n", temp)); 328 329 /* For UniChrome Pro and Chrome9. */ 330 if ((pVia->Chipset != VIA_CLE266) 331 && (pVia->Chipset != VIA_KM400)) { 332 temp = hwp->readCrtc(hwp, 0x47); 333 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 334 "CR47: 0x%02X\n", temp)); 335 } 336 337 temp = hwp->readCrtc(hwp, 0x6B); 338 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 339 "CR6B: 0x%02X\n", temp)); 340 341 if (pVia->Chipset == VIA_CLE266) { 342 temp = hwp->readCrtc(hwp, 0x6C); 343 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 344 "CR6C: 0x%02X\n", temp)); 345 } 346 347#endif 348 349 /* Be careful with 3C5.15[5] - Wrap Around Disable. 350 * It must be set to 1 for correct operation. */ 351 /* 3C5.15[7] - 8/6 Bits LUT 352 * 0: 6-bit 353 * 1: 8-bit 354 * 3C5.15[6] - Text Column Control 355 * 0: 80 column 356 * 1: 132 column 357 * 3C5.15[5] - Wrap Around Disable 358 * 0: Disable (For Mode 0-13) 359 * 1: Enable 360 * 3C5.15[4] - Hi Color Mode Select 361 * 0: 555 362 * 1: 565 363 * 3C5.15[3:2] - Display Color Depth Select 364 * 00: 8bpp 365 * 01: 16bpp 366 * 10: 30bpp 367 * 11: 32bpp 368 * 3C5.15[1] - Extended Display Mode Enable 369 * 0: Disable 370 * 1: Enable 371 * 3C5.15[0] - Reserved */ 372 ViaSeqMask(hwp, 0x15, 0x22, 0x62); 373 374 /* 3C5.19[7] - Reserved 375 * 3C5.19[6] - MIU/AGP Interface Clock Control 376 * 0: Clocks always on 377 * 1: Enable clock gating 378 * 3C5.19[5] - P-Arbiter Interface Clock Control 379 * 0: Clocks always on 380 * 1: Enable clock gating 381 * 3C5.19[4] - AGP Interface Clock Control 382 * 0: Clocks always on 383 * 1: Enable clock gating 384 * 3C5.19[3] - Typical Arbiter Interface Clock Control 385 * 0: Clocks always on 386 * 1: Enable clock gating 387 * 3C5.19[2] - MC Interface Clock Control 388 * 0: Clocks always on 389 * 1: Enable clock gating 390 * 3C5.19[1] - Display Interface Clock Control 391 * 0: Clocks always on 392 * 1: Enable clock gating 393 * 3C5.19[0] - CPU Interface Clock Control 394 * 0: Clocks always on 395 * 1: Enable clock gating */ 396 ViaSeqMask(hwp, 0x19, 0x7F, 0x7F); 397 398 /* 3C5.1A[7] - Read Cache Enable 399 * 0: Disable 400 * 1: Enable 401 * 3C5.1A[6] - Software Reset 402 * 0: Default value 403 * 1: Reset 404 * 3C5.1A[5] - DVI Sense 405 * 0: No connect 406 * 1: Connected 407 * 3C5.1A[4] - Second DVI Sense 408 * 0: No connect 409 * 1: Connected 410 * 3C5.1A[3] - Extended Mode Memory Access Enable 411 * 0: Disable 412 * 1: Enable 413 * 3C5.1A[2] - PCI Burst Write Wait State Select 414 * 0: 0 Wait state 415 * 1: 1 Wait state 416 * 3C5.1A[1] - Reserved 417 * 3C5.1A[0] - LUT Shadow Access 418 * 0: 3C6/3C7/3C8/3C9 addresses map to 419 * Primary Display’s LUT 420 * 1: 3C6/3C7/3C8/3C9 addresses map to 421 * Secondary Display’s LUT */ 422 ViaSeqMask(hwp, 0x1A, 0x88, 0xC8); 423 424 /* Set DVP0 data drive strength to 0b11 (highest). */ 425 /* 3C5.1B[1] - DVP0 Data Drive Strength Bit [0] 426 * (It could be for DIP0 (Digital Interface Port 0) for 427 * CLE266. Reserved for CX700 / VX700 / VX800 / VX855 / 428 * VX900. These newer devices do not have DVP0.) */ 429 ViaSeqMask(hwp, 0x1B, 0x02, 0x02); 430 431 /* Set DVP0 clock drive strength to 0b11 (highest). */ 432 /* 3C5.1E[7:6] - Video Capture Port Power Control 433 * 0x: Pad always off 434 * 10: Depend on the other control signal 435 * 11: Pad on/off according to the PMS 436 * 3C5.1E[5:4] - Digital Video Port 1 Power Control 437 * 0x: Pad always off 438 * 10: Depend on the other control signal 439 * 11: Pad on/off according to the PMS 440 * 3C5.1E[3] - Spread Spectrum On/Off 441 * 0: Off 442 * 1: On 443 * 3C5.1E[2] - DVP0 Clock Drive Strength Bit [0] 444 * (It could be for DIP0 (Digital Interface Port 0) for 445 * CLE266. Reserved for CX700 / VX700 / VX800 / VX855 / 446 * VX900. These newer devices do not have DVP0.) 447 * 3C5.1E[1] - Replace ECK by MCK 448 * For BIST purpose. 449 * 3C5.1E[0] - On/Off ROC ECK 450 * 0: Off 451 * 1: On */ 452 ViaSeqMask(hwp, 0x1E, 0xF4, 0xF4); 453 454 /* Set DVP0 data drive strength to 0b11 (highest). */ 455 /* Set DVP0 clock drive strength to 0b11 (highest). */ 456 /* 3C5.2A[7] - Reserved 457 * 3C5.2A[6] - The Spread Spectrum Type Control 458 * 0: Original Type 459 * 1: FIFO Type 460 * 3C5.2A[5] - DVP0 Data Drive Strength Bit [1] 461 * (Reserved for CX700 / VX700 / VX800 / VX855 / 462 * VX900. These devices do not have DVP0.) 463 * 3C5.2A[4] - DVP0 Clock Drive Strength Bit [1] 464 * (Reserved for CX700 / VX700 / VX800 / VX855 / 465 * VX900. These devices do not have DVP0.) 466 * 3C5.2A[3:2] - LVDS Channel 2 I/O Pad Control 467 * 0x: Pad always off 468 * 10: Depend on the other control signal 469 * 11: Pad on/off according to the PMS 470 * 3C5.2A[1:0] - LVDS Channel 1 and DVI I/O Pad Control 471 * 0x: Pad always off 472 * 10: Depend on the other control signal 473 * 11: Pad on/off according to the PMS */ 474 ViaSeqMask(hwp, 0x2A, 0x3F, 0x3F); 475 476 /* 3C5.2D[7:6] - E3_ECK_N Selection 477 * 00: E3_ECK_N 478 * 01: E3_ECK 479 * 10: delayed E3_ECK_N 480 * 11: delayed E3_ECK 481 * 3C5.2D[5:4] - VCK (Primary Display Clock) PLL Power Control 482 * 0x: PLL power-off 483 * 10: PLL always on 484 * 11: PLL on/off according to the PMS 485 * 3C5.2D[3:2] - LCK (Secondary Display Clock) PLL Power Control 486 * 0x: PLL power-off 487 * 10: PLL always on 488 * 11: PLL on/off according to the PMS 489 * 3C5.2D[1:0] - ECK (Engine Clock) PLL Power Control 490 * 0x: PLL power-off 491 * 10: PLL always on 492 * 11: PLL on/off according to the PMS */ 493 ViaSeqMask(hwp, 0x2D, 0x03, 0xC3); 494 495 /* In Wyse X class mobile thin client, it was observed that setting 496 * SR2E[3:2] (3C5.2E[3:2]; PCI Master / DMA) to 0b11 (clock on / off 497 * according to the engine IDLE status) causes an X.Org Server boot 498 * failure. Setting this register to 0b10 (clock always on) corrects 499 * the problem. */ 500 /* 3C5.2E[7:6] - Capturer (Gated Clock <ECK>) 501 * 0x: Clock off 502 * 10: Clock always on 503 * 11: Clock on/off according to the engine IDLE status 504 * 3C5.2E[5:4] - Video Processor (Gated Clock <ECK>) 505 * 0x: Clock off 506 * 10: Clock always on 507 * 11: Clock on/off according to the engine IDLE status 508 * 3C5.2E[3:2] - PCI Master/DMA (Gated Clock <ECK/CPUCK>) 509 * 0x: Clock off 510 * 10: Clock always on 511 * 11: Clock on/off according to the engine IDLE status 512 * 3C5.2E[1:0] - Video Playback Engine (V3/V4 Gated Clock <VCK>) 513 * 0x: Clock off 514 * 10: Clock always on 515 * 11: Clock on/off according to the engine IDLE status */ 516 ViaSeqMask(hwp, 0x2E, 0xFB, 0xFF); 517 518 /* 3C5.3F[7:6] - CR Clock Control (Gated Clock <ECK>) 519 * 0x: Clock off 520 * 10: Clock always on 521 * 11: Clock on/off according to the engine IDLE status 522 * 3C5.3F[5:4] - 3D Clock Control (Gated Clock <ECK>) 523 * 0x: Clock off 524 * 10: Clock always on 525 * 11: Clock on/off according to the engine IDLE status 526 * 3C5.3F[3:2] - 2D Clock Control (Gated Clock <ECK/CPUCK>) 527 * 0x: Clock off 528 * 10: Clock always on 529 * 11: Clock on/off according to the engine IDLE status 530 * 3C5.3F[1:0] - Video Clock Control (Gated Clock <ECK>) 531 * 0x: Clock off 532 * 10: Clock always on 533 * 11: Clock on/off according to each engine IDLE status */ 534 ViaSeqMask(hwp, 0x3F, 0xFF, 0xFF); 535 536 /* Set DVP1 data drive strength to 0b11 (highest). */ 537 /* Set DVP1 clock drive strength to 0b11 (highest). */ 538 /* 3C5.65[3:2] - DVP1 Clock Pads Driving Select 539 * 00: lowest 540 * 01: low 541 * 10: high 542 * 11: highest 543 * 3C5.65[1:0] - DVP1 Data Pads Driving Select 544 * 00: lowest 545 * 01: low 546 * 10: high 547 * 11: highest */ 548 ViaSeqMask(hwp, 0x65, 0x0F, 0x0F); 549 550 /* 3X5.36[7] - DPMS VSYNC Output 551 * 3X5.36[6] - DPMS HSYNC Output 552 * 3X5.36[5:4] - DPMS Control 553 * 00: On 554 * 01: Stand-by 555 * 10: Suspend 556 * 11: Off 557 * When the DPMS state is off, both HSYNC and VSYNC 558 * are grounded, saving monitor power consumption. 559 * 3X5.36[3] - Horizontal Total Bit [8] 560 * 3X5.36[2:1] - Reserved 561 * 3X5.36[0] - PCI Power Management Control 562 * 0: Disable 563 * 1: Enable */ 564 ViaCrtcMask(hwp, 0x36, 0x01, 0x01); 565 566 /* For UniChrome Pro and Chrome9. */ 567 if ((pVia->Chipset != VIA_CLE266) 568 && (pVia->Chipset != VIA_KM400)) { 569 /* 3X5.47[7] - IGA1 Timing Plus 2 VCK 570 * 3X5.47[6] - IGA1 Timing Plus 4 VCK 571 * 3X5.47[5] - Peep at the PCI-bus 572 * 0: Disable 573 * 1: Enable 574 * 3X5.47[4] - Reserved 575 * 3X5.47[3] - IGA1 Timing Plus 6 VCK 576 * 3X5.47[2] - DACOFF Backdoor Register 577 * 3X5.47[1] - LCD Simultaneous Mode Backdoor Register for 578 * 8/9 Dot Clocks 579 * 3X5.47[0] - LCD Simultaneous Mode Backdoor Register for 580 * Clock Select and CRTC Register Protect 581 * 582 */ 583 ViaCrtcMask(hwp, 0x47, 0x00, 0x23); 584 } 585 586 /* 3X5.6B[3] - Simultaneous Display Enable 587 * 0: Disable 588 * 1: Enable */ 589 ViaCrtcMask(hwp, 0x6B, 0x00, 0x08); 590 591 /* CLE266 only. */ 592 if (pVia->Chipset == VIA_CLE266) { 593 /* The following register fields are for CLE266 only. */ 594 /* 3X5.6C - Digital Interface Port 0 (DIP0) Control 595 * 3X5.6C[7] - DIP0 Source 596 * 0: IGA1 597 * 1: IGA2 598 * 3X5.6C[4:2] - Appears to be related to DIP0 signal polarity 599 * control. Used by CLE266A2 to workaround a bug when 600 * it is utilizing an external TV encoder. 601 * 3X5.6C[1] - Appears to be utilized when CLE266 is utilizing an 602 * external TV encoder. 603 * 3X5.6C[0] - Appears to be a bit to control internal / external 604 * clock source or whether or not the VCK (IGA1 clock 605 * source) comes from VCK PLL or from an external 606 * source. This bit should be set to 1 when TV encoder 607 * is in use. */ 608 ViaCrtcMask(hwp, 0x6C, 0x00, 0x01); 609 } 610 611 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 612 "Exiting viaIGAInitCommon.\n")); 613} 614 615/* 616 * Initialize IGA1 (Integrated Graphics Accelerator) registers. 617 */ 618void 619viaIGA1Init(ScrnInfoPtr pScrn) 620{ 621 vgaHWPtr hwp = VGAHWPTR(pScrn); 622 VIAPtr pVia = VIAPTR(pScrn); 623#ifdef HAVE_DEBUG 624 CARD8 temp; 625#endif 626 627 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 628 "Entered viaIGA1Init.\n")); 629 630#ifdef HAVE_DEBUG 631 temp = hwp->readSeq(hwp, 0x1B); 632 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 633 "SR1B: 0x%02X\n", temp)); 634 temp = hwp->readSeq(hwp, 0x2D); 635 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 636 "SR2D: 0x%02X\n", temp)); 637 temp = hwp->readCrtc(hwp, 0x32); 638 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 639 "CR32: 0x%02X\n", temp)); 640 temp = hwp->readCrtc(hwp, 0x33); 641 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 642 "CR33: 0x%02X\n", temp)); 643 644 /* For UniChrome Pro and Chrome9. */ 645 if ((pVia->Chipset != VIA_CLE266) 646 && (pVia->Chipset != VIA_KM400)) { 647 temp = hwp->readCrtc(hwp, 0x47); 648 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 649 "CR47: 0x%02X\n", temp)); 650 } 651 652 temp = hwp->readCrtc(hwp, 0x6B); 653 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 654 "CR6B: 0x%02X\n", temp)); 655 656 /* For UniChrome Pro and Chrome9. */ 657 if ((pVia->Chipset != VIA_CLE266) 658 && (pVia->Chipset != VIA_KM400)) { 659 temp = hwp->readCrtc(hwp, 0x6C); 660 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 661 "CR6C: 0x%02X\n", temp)); 662 } 663 664#endif 665 666 /* 3C5.1B[7:6] - Secondary Display Engine (Gated Clock <LCK>) 667 * 0x: Clock always off 668 * 10: Clock always on 669 * 11: Clock on/off according to the 670 * Power Management Status (PMS) 671 * 3C5.1B[5:4] - Primary Display Engine (Gated Clock <VCK>) 672 * 0x: Clock always off 673 * 10: Clock always on 674 * 11: Clock on/off according to the PMS 675 * 3C5.1B[3:1] - Reserved 676 * 3C5.1B[0] - Primary Display’s LUT On/Off 677 * 0: On 678 * 1: Off */ 679 ViaSeqMask(hwp, 0x1B, 0x30, 0x31); 680 681 /* 3C5.2D[7:6] - E3_ECK_N Selection 682 * 00: E3_ECK_N 683 * 01: E3_ECK 684 * 10: delayed E3_ECK_N 685 * 11: delayed E3_ECK 686 * 3C5.2D[5:4] - VCK (Primary Display Clock) PLL Power Control 687 * 0x: PLL power-off 688 * 10: PLL always on 689 * 11: PLL on/off according to the PMS 690 * 3C5.2D[3:2] - LCK (Secondary Display Clock) PLL Power Control 691 * 0x: PLL power-off 692 * 10: PLL always on 693 * 11: PLL on/off according to the PMS 694 * 3C5.2D[1:0] - ECK (Engine Clock) PLL Power Control 695 * 0x: PLL power-off 696 * 10: PLL always on 697 * 11: PLL on/off according to the PMS */ 698 ViaSeqMask(hwp, 0x2D, 0x30, 0x30); 699 700 /* 3X5.32[7:5] - HSYNC Delay Number by VCLK 701 * 000: No delay 702 * 001: Delay + 4 VCKs 703 * 010: Delay + 8 VCKs 704 * 011: Delay + 12 VCKs 705 * 100: Delay + 16 VCKs 706 * 101: Delay + 20 VCKs 707 * Others: Undefined 708 * 3X5.32[4] - Reserved 709 * 3X5.32[3] - CRT SYNC Driving Selection 710 * 0: Low 711 * 1: High 712 * 3X5.32[2] - Display End Blanking Enable 713 * 0: Disable 714 * 1: Enable 715 * 3X5.32[1] - Digital Video Port (DVP) Gamma Correction 716 * If the gamma correction of primary display is 717 * turned on, the gamma correction in DVP can be 718 * enabled / disabled by this bit. 719 * 0: Disable 720 * 1: Enable 721 * 3X5.32[0] - Real-Time Flipping 722 * 0: Flip by the frame 723 * 1: Flip by each scan line */ 724 ViaCrtcMask(hwp, 0x32, 0x04, 0xEF); 725 726 /* Keep interlace mode off. 727 * No shift for HSYNC.*/ 728 /* 3X5.33[7] - Primary Display Gamma Correction 729 * 0: Disable 730 * 1: Enable 731 * 3X5.33[6] - Primary Display Interlace Mode 732 * 0: Disable 733 * 1: Enable 734 * 3X5.33[5] - Horizontal Blanking End Bit [6] 735 * 3X5.33[4] - Horizontal Synchronization Start Bit [8] 736 * 3X5.33[3] - Prefetch Mode 737 * 0: Disable 738 * 1: Enable 739 * 3X5.33[2:0] - The Value will Shift the HSYNC to be Early than Planned 740 * 000: Shift to early time by 3 characters 741 * (VGA mode suggested value; default value) 742 * 001: Shift to early time by 4 characters 743 * 010: Shift to early time by 5 characters 744 * 011: Shift to early time by 6 characters 745 * 100: Shift to early time by 7 characters 746 * 101: Shift to early time by 0 character 747 * (Non-VGA mode suggested value) 748 * 110: Shift to early time by 1 character 749 * 111: Shift to early time by 2 characters */ 750 ViaCrtcMask(hwp, 0x33, 0x05, 0xCF); 751 752 /* For UniChrome Pro and Chrome9. */ 753 if ((pVia->Chipset != VIA_CLE266) 754 && (pVia->Chipset != VIA_KM400)) { 755 /* 3X5.47[7] - IGA1 Timing Plus 2 VCK 756 * 3X5.47[6] - IGA1 Timing Plus 4 VCK 757 * 3X5.47[5] - Peep at the PCI-bus 758 * 0: Disable 759 * 1: Enable 760 * 3X5.47[4] - Reserved 761 * 3X5.47[3] - IGA1 Timing Plus 6 VCK 762 * 3X5.47[2] - DACOFF Backdoor Register 763 * 3X5.47[1] - LCD Simultaneous Mode Backdoor Register for 764 * 8/9 Dot Clocks 765 * 3X5.47[0] - LCD Simultaneous Mode Backdoor Register for 766 * Clock Select and CRTC Register Protect */ 767 ViaCrtcMask(hwp, 0x47, 0x00, 0xCC); 768 } 769 770 /* TV out uses division by 2 mode. 771 * Other devices like analog (VGA), DVI, flat panel, etc., 772 * use normal mode. */ 773 /* 3X5.6B[7:6] - First Display Channel Clock Mode Selection 774 * 0x: Normal 775 * 1x: Division by 2 */ 776 ViaCrtcMask(hwp, 0x6B, 0x00, 0xC0); 777 778 /* For UniChrome Pro and Chrome9. */ 779 if ((pVia->Chipset != VIA_CLE266) 780 && (pVia->Chipset != VIA_KM400)) { 781 /* The following register fields are for UniChrome Pro and Chrome9. */ 782 /* 3X5.6C[7:5] - VCK PLL Reference Clock Source Selection 783 * 000: From XI pin 784 * 001: From TVXI 785 * 01x: From TVPLL 786 * 100: DVP0TVCLKR 787 * 101: DVP1TVCLKR 788 * 110: CAP0 Clock 789 * 111: CAP1 Clock 790 * 3X5.6C[4] - VCK Source Selection 791 * 0: VCK PLL output clock 792 * 1: VCK PLL reference clock */ 793 ViaCrtcMask(hwp, 0x6C, 0x00, 0xF0); 794 } 795 796 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 797 "Exiting viaIGA1Init.\n")); 798} 799 800void 801viaIGA1SetFBStartingAddress(xf86CrtcPtr crtc, int x, int y) 802{ 803 ScrnInfoPtr pScrn = crtc->scrn; 804 VIAPtr pVia = VIAPTR(pScrn); 805 vgaHWPtr hwp = VGAHWPTR(pScrn); 806 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 807 drmmode_ptr drmmode = drmmode_crtc->drmmode; 808 CARD32 Base; 809 CARD8 cr0c, cr0d, cr34, cr48; 810 811 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 812 "Entered viaIGA1SetFBStartingAddress.\n")); 813 814 Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); 815 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 816 "Base Address: 0x%lx\n", 817 Base)); 818 Base = (Base + drmmode->front_bo->offset) >> 1; 819 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 820 "DRI Base Address: 0x%lx\n", 821 Base); 822 823 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 824 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 825 826 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) { 827 ViaCrtcMask(hwp, 0x48, Base >> 24, 0x1F); 828 } 829 830 /* CR34 are fire bits. Must be written after CR0C, CR0D, and CR48. */ 831 hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16); 832 833#ifdef HAVE_DEBUG 834 cr0d = hwp->readCrtc(hwp, 0x0D); 835 cr0c = hwp->readCrtc(hwp, 0x0C); 836 cr34 = hwp->readCrtc(hwp, 0x34); 837 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) { 838 cr48 = hwp->readCrtc(hwp, 0x48); 839 } 840 841 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 842 "CR0D: 0x%02X\n", cr0d)); 843 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 844 "CR0C: 0x%02X\n", cr0c)); 845 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 846 "CR34: 0x%02X\n", cr34)); 847 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) { 848 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 849 "CR48: 0x%02X\n", cr48)); 850 } 851 852#endif 853 854 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 855 "Exiting viaIGA1SetFBStartingAddress.\n")); 856} 857 858void 859viaIGA1SetDisplayRegister(ScrnInfoPtr pScrn, DisplayModePtr mode) 860{ 861 vgaHWPtr hwp = VGAHWPTR(pScrn); 862 VIAPtr pVia = VIAPTR(pScrn); 863 CARD16 temp; 864 865 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 866 "Entered viaIGA1SetDisplayRegister.\n")); 867 868 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 869 "IGA1 Requested Screen Mode: %s\n", mode->name); 870 871 ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */ 872 ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */ 873 874 /* Set Misc Register */ 875 temp = 0x23; 876 if (mode->Flags & V_NHSYNC) 877 temp |= 0x40; 878 if (mode->Flags & V_NVSYNC) 879 temp |= 0x80; 880 temp |= 0x0C; /* Undefined/external clock */ 881 hwp->writeMiscOut(hwp, temp); 882 883 /* Sequence registers */ 884 hwp->writeSeq(hwp, 0x00, 0x00); 885 886#if 0 887 if (mode->Flags & V_CLKDIV2) 888 hwp->writeSeq(hwp, 0x01, 0x09); 889 else 890#endif 891 hwp->writeSeq(hwp, 0x01, 0x01); 892 893 hwp->writeSeq(hwp, 0x02, 0x0F); 894 hwp->writeSeq(hwp, 0x03, 0x00); 895 hwp->writeSeq(hwp, 0x04, 0x0E); 896 897 898 /* Setting maximum scan line to 0. */ 899 /* 3X5.09[4:0] - Maximum Scan Line */ 900 ViaCrtcMask(hwp, 0x09, 0x00, 0x1F); 901 902 903 /* 3X5.14[6] - Double Word Mode 904 * Allows normal addressing or double-word addressing. 905 * 0: Normal word addressing 906 * 1: Double word addressing 907 * 3X5.14[4:0] - Underline Location */ 908 ViaCrtcMask(hwp, 0x14, 0x00, 0x5F); 909 910 911 /* We are not using the split screen feature so line compare register 912 * should be set to 0x7FF. */ 913 temp = 0x7FF; 914 915 /* 3X5.18[7:0] - Line Compare Bits [7:0] */ 916 hwp->writeCrtc(hwp, 0x18, temp & 0xFF); 917 918 /* 3X5.07[4] - Line Compare Bit [8] */ 919 ViaCrtcMask(hwp, 0x07, temp >> 4, 0x10); 920 921 /* 3X5.09[6] - Line Compare Bit [9] */ 922 ViaCrtcMask(hwp, 0x09, temp >> 3, 0x40); 923 924 /* 3X5.35[4] - Line Compare Bit [10] */ 925 ViaCrtcMask(hwp, 0x35, temp >> 6, 0x10); 926 927 928 /* Set the color depth for IGA1. */ 929 switch (pScrn->bitsPerPixel) { 930 case 8: 931 /* Only CLE266.AX uses 6-bit LUT. */ 932 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15) { 933 /* 6-bit LUT */ 934 /* 3C5.15[7] - 8/6 Bits LUT 935 * 0: 6-bit 936 * 1: 8-bit 937 * 3C5.15[4] - Hi Color Mode Select 938 * 0: 555 939 * 1: 565 940 * 3C5.15[3:2] - Display Color Depth Select 941 * 00: 8bpp 942 * 01: 16bpp 943 * 10: 30bpp 944 * 11: 32bpp */ 945 ViaSeqMask(hwp, 0x15, 0x00, 0x9C); 946 } else { 947 /* 8-bit LUT */ 948 ViaSeqMask(hwp, 0x15, 0x80, 0x9C); 949 } 950 951 break; 952 case 16: 953 ViaSeqMask(hwp, 0x15, 0x94, 0x9C); 954 break; 955 case 24: 956 case 32: 957 ViaSeqMask(hwp, 0x15, 0x9C, 0x9C); 958 break; 959 default: 960 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 961 "Unsupported color depth: %d\n", 962 pScrn->bitsPerPixel); 963 break; 964 } 965 966 967 /* 3X5.32[7:5] - HSYNC Delay Number by VCLK 968 * 000: No delay 969 * 001: Delay + 4 VCKs 970 * 010: Delay + 8 VCKs 971 * 011: Delay + 12 VCKs 972 * 100: Delay + 16 VCKs 973 * 101: Delay + 20 VCKs 974 * Others: Undefined 975 * 3X5.32[4] - Reserved 976 * 3X5.32[3] - CRT SYNC Driving Selection 977 * 0: Low 978 * 1: High 979 * 3X5.32[2] - Display End Blanking Enable 980 * 0: Disable 981 * 1: Enable 982 * 3X5.32[1] - Digital Video Port (DVP) Gamma Correction 983 * If the gamma correction of primary display is 984 * turned on, the gamma correction in DVP can be 985 * enabled / disabled by this bit. 986 * 0: Disable 987 * 1: Enable 988 * 3X5.32[0] - Real-Time Flipping 989 * 0: Flip by the frame 990 * 1: Flip by each scan line */ 991 ViaCrtcMask(hwp, 0x32, 0x04, 0xEC); 992 993 /* Keep interlace mode off. 994 * No shift for HSYNC.*/ 995 /* 3X5.33[7] - Primary Display Gamma Correction 996 * 0: Disable 997 * 1: Enable 998 * 3X5.33[6] - Primary Display Interlace Mode 999 * 0: Disable 1000 * 1: Enable 1001 * 3X5.33[5] - Horizontal Blanking End Bit [6] 1002 * 3X5.33[4] - Horizontal Synchronization Start Bit [8] 1003 * 3X5.33[3] - Prefetch Mode 1004 * 0: Disable 1005 * 1: Enable 1006 * 3X5.33[2:0] - The Value will Shift the HSYNC to be Early than Planned 1007 * 000: Shift to early time by 3 characters 1008 * (VGA mode suggested value; default value) 1009 * 001: Shift to early time by 4 characters 1010 * 010: Shift to early time by 5 characters 1011 * 011: Shift to early time by 6 characters 1012 * 100: Shift to early time by 7 characters 1013 * 101: Shift to early time by 0 character 1014 * (Non-VGA mode suggested value) 1015 * 110: Shift to early time by 1 character 1016 * 111: Shift to early time by 2 characters */ 1017 ViaCrtcMask(hwp, 0x33, 0x05, 0x4F); 1018 1019 /* Set IGA1 to linear mode */ 1020 /* 3X5.43[2] - IGA1 Address Mode Selection 1021 * 0: Linear 1022 * 1: Tile */ 1023 ViaCrtcMask(hwp, 0x43, 0x00, 0x04); 1024 1025 1026 /* Set IGA1 horizontal total.*/ 1027 /* Due to IGA1 horizontal total being only 9 bits wide, 1028 * the adjusted horizontal total needs to be shifted by 1029 * 3 bit positions to the right. 1030 * In addition to that, this particular register requires the 1031 * value to be 5 less than the actual value being written. */ 1032 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1033 "IGA1 CrtcHTotal: %d\n", mode->CrtcHTotal)); 1034 temp = (mode->CrtcHTotal >> 3) - 5; 1035 1036 /* 3X5.00[7:0] - Horizontal Total Bits [7:0] */ 1037 hwp->writeCrtc(hwp, 0x00, temp & 0xFF); 1038 1039 /* 3X5.36[3] - Horizontal Total Bit [8] */ 1040 ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08); 1041 1042 1043 /* Set IGA1 horizontal display end. */ 1044 /* Due to IGA1 horizontal display end being only 8 bits wide, 1045 * the adjusted horizontal display end needs to be shifted by 1046 * 3 bit positions to the right. 1047 * In addition to that, this particular register requires the 1048 * value to be 1 less than the actual value being written. */ 1049 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1050 "IGA1 CrtcHDisplay: %d\n", mode->CrtcHDisplay)); 1051 temp = (mode->CrtcHDisplay >> 3) - 1; 1052 1053 /* 3X5.01[7:0] - Horizontal Display End Bits [7:0] */ 1054 hwp->writeCrtc(hwp, 0x01, temp & 0xFF); 1055 1056 1057 /* Set IGA1 horizontal blank start. */ 1058 /* Due to IGA1 horizontal blank start being only 8 bits wide, 1059 * the adjusted horizontal blank start needs to be shifted by 1060 * 3 bit positions to the right. */ 1061 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1062 "IGA1 CrtcHBlankStart: %d\n", mode->CrtcHBlankStart)); 1063 temp = mode->CrtcHBlankStart >> 3; 1064 1065 /* 3X5.02[7:0] - Horizontal Blanking Start Bits [7:0] */ 1066 hwp->writeCrtc(hwp, 0x02, temp & 0xFF); 1067 1068 1069 /* Set IGA1 horizontal blank end. */ 1070 /* After shifting horizontal blank end by 3 bit positions to the 1071 * right, the 7 least significant bits are actually used. 1072 * In addition to that, this particular register requires the 1073 * value to be 1 less than the actual value being written. */ 1074 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1075 "IGA1 CrtcHBlankEnd: %d\n", mode->CrtcHBlankEnd)); 1076 temp = (mode->CrtcHBlankEnd >> 3) - 1; 1077 1078 /* 3X5.03[4:0] - Horizontal Blanking End Bits [4:0] */ 1079 ViaCrtcMask(hwp, 0x03, temp, 0x1F); 1080 1081 /* 3X5.05[7] - Horizontal Blanking End Bit [5] */ 1082 ViaCrtcMask(hwp, 0x05, temp << 2, 0x80); 1083 1084 /* 3X5.33[5] - Horizontal Blanking End Bit [6] */ 1085 ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20); 1086 1087 1088 /* Set IGA1 horizontal synchronization start. */ 1089 /* Due to IGA1 horizontal synchronization start being only 9 bits wide, 1090 * the adjusted horizontal synchronization start needs to be shifted by 1091 * 3 bit positions to the right. */ 1092 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1093 "IGA1 CrtcHSyncStart: %d\n", mode->CrtcHSyncStart)); 1094 temp = mode->CrtcHSyncStart >> 3; 1095 1096 /* 3X5.04[7:0] - Horizontal Retrace Start Bits [7:0] */ 1097 hwp->writeCrtc(hwp, 0x04, temp & 0xFF); 1098 1099 /* 3X5.33[4] - Horizontal Retrace Start Bit [8] */ 1100 ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10); 1101 1102 1103 /* Set IGA1 horizontal synchronization end. */ 1104 /* After shifting horizontal synchronization end by 3 bit positions 1105 * to the right, the 5 least significant bits are actually used. 1106 * In addition to that, this particular register requires the 1107 * value to be 1 less than the actual value being written. */ 1108 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1109 "IGA1 CrtcHSyncEnd: %d\n", mode->CrtcHSyncEnd)); 1110 temp = (mode->CrtcHSyncEnd >> 3) - 1; 1111 1112 /* 3X5.05[4:0] - Horizontal Retrace End Bits [4:0] */ 1113 ViaCrtcMask(hwp, 0x05, temp, 0x1F); 1114 1115 1116 /* Set IGA1 vertical total. */ 1117 /* Vertical total requires the value to be 2 less 1118 * than the actual value being written. */ 1119 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1120 "IGA1 CrtcVTotal: %d\n", mode->CrtcVTotal)); 1121 temp = mode->CrtcVTotal - 2; 1122 1123 /* 3X5.06[7:0] - Vertical Total Period Bits [7:0] */ 1124 hwp->writeCrtc(hwp, 0x06, temp & 0xFF); 1125 1126 /* 3X5.07[0] - Vertical Total Period Bit [8] */ 1127 ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01); 1128 1129 /* 3X5.07[5] - Vertical Total Period Bit [9] */ 1130 ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20); 1131 1132 /* 3X5.35[0] - Vertical Total Period Bit [10] */ 1133 ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01); 1134 1135 1136 /* Set IGA1 vertical display end. */ 1137 /* Vertical display end requires the value to be 1 less 1138 * than the actual value being written. */ 1139 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1140 "IGA1 CrtcVDisplay: %d\n", mode->CrtcVDisplay)); 1141 temp = mode->CrtcVDisplay - 1; 1142 1143 /* 3X5.12[7:0] - Vertical Active Data Period Bits [7:0] */ 1144 hwp->writeCrtc(hwp, 0x12, temp & 0xFF); 1145 1146 /* 3X5.07[1] - Vertical Active Data Period Bit [8] */ 1147 ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02); 1148 1149 /* 3X5.07[6] - Vertical Active Data Period Bit [9] */ 1150 ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40); 1151 1152 /* 3X5.35[2] - Vertical Active Data Period Bit [10] */ 1153 ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04); 1154 1155 1156 /* Set IGA1 vertical blank start. */ 1157 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1158 "IGA1 CrtcVBlankStart: %d\n", mode->CrtcVBlankStart)); 1159 temp = mode->CrtcVBlankStart; 1160 1161 /* 3X5.15[7:0] - Vertical Blanking Start Bits [7:0] */ 1162 hwp->writeCrtc(hwp, 0x15, temp & 0xFF); 1163 1164 /* 3X5.07[3] - Vertical Blanking Start Bit [8] */ 1165 ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08); 1166 1167 /* 3X5.09[5] - Vertical Blanking Start Bit [9] */ 1168 ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20); 1169 1170 /* 3X5.35[3] - Vertical Blanking Start Bit [10] */ 1171 ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08); 1172 1173 1174 /* Set IGA1 vertical blank end. */ 1175 /* Vertical blank end requires the value to be 1 less 1176 * than the actual value being written, and 8 LSB 1177 * (Least Significant Bits) are written straight into the 1178 * relevant register. */ 1179 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1180 "IGA1 CrtcVBlankEnd: %d\n", mode->CrtcVBlankEnd)); 1181 temp = mode->CrtcVBlankEnd - 1; 1182 1183 /* 3X5.16[7:0] - Vertical Blanking End Bits [7:0] */ 1184 hwp->writeCrtc(hwp, 0x16, temp & 0xFF); 1185 1186 1187 /* Set IGA1 vertical synchronization start. */ 1188 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1189 "IGA1 CrtcVSyncStart: %d\n", mode->CrtcVSyncStart)); 1190 temp = mode->CrtcVSyncStart; 1191 1192 /* 3X5.10[7:0] - Vertical Retrace Start Bits [7:0] */ 1193 hwp->writeCrtc(hwp, 0x10, temp & 0xFF); 1194 1195 /* 3X5.07[2] - Vertical Retrace Start Bit [8] */ 1196 ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04); 1197 1198 /* 3X5.07[7] - Vertical Retrace Start Bit [9] */ 1199 ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80); 1200 1201 /* 3X5.35[1] - Vertical Retrace Start Bit [10] */ 1202 ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02); 1203 1204 1205 /* Set IGA1 vertical synchronization end. */ 1206 /* Vertical synchronization end requires the value to be 1 less 1207 * than the actual value being written, and 4 LSB 1208 * (Least Significant Bits) are written straight into the 1209 * relevant register. */ 1210 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1211 "IGA1 CrtcVSyncEnd: %d\n", mode->CrtcVSyncEnd)); 1212 temp = mode->CrtcVSyncEnd - 1; 1213 1214 /*3X5.11[3:0] - Vertical Retrace End Bits [3:0] */ 1215 ViaCrtcMask(hwp, 0x11, temp & 0x0F, 0x0F); 1216 1217 1218 /* Set IGA1 horizontal offset adjustment. */ 1219 temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; 1220 1221 /* Make sure that this is 32-byte aligned. */ 1222 if (temp & 0x03) { 1223 temp += 0x03; 1224 temp &= ~0x03; 1225 } 1226 1227 /* 3X5.13[7:0] - Primary Display Horizontal Offset Bits [7:0] */ 1228 hwp->writeCrtc(hwp, 0x13, temp & 0xFF); 1229 1230 /* 3X5.35[7:5] - Primary Display Horizontal Offset Bits [10:8] */ 1231 ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0); 1232 1233 1234 /* Set IGA1 horizontal display fetch (read) count. */ 1235 temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3; 1236 1237 /* Make sure that this is 32-byte aligned. */ 1238 if (temp & 0x03) { 1239 temp += 0x03; 1240 temp &= ~0x03; 1241 } 1242 1243 /* Primary Display Horizontal Display Fetch Count Data needs to be 1244 * 16-byte aligned. */ 1245 temp = temp >> 1; 1246 1247 /* 3C5.1C[7:0] - Primary Display Horizontal Display 1248 * Fetch Count Data Bits [7:0] */ 1249 hwp->writeSeq(hwp, 0x1C, temp & 0xFF); 1250 1251 /* 3C5.1D[1:0] - Primary Display Horizontal Display 1252 * Fetch Count Data Bits [9:8] */ 1253 ViaSeqMask(hwp, 0x1D, temp >> 8, 0x03); 1254 1255 1256 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1257 "Exiting viaIGA1SetDisplayRegister.\n")); 1258} 1259 1260/* 1261 * Checks for limitations imposed by the available VGA timing registers. 1262 */ 1263static ModeStatus 1264viaIGA1ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 1265{ 1266 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1267 "Entered viaIGA1ModeValid.\n")); 1268 1269 /* Note that horizontal total being written to VGA registers is 1270 * shifted to the right by 3 bit positions since only 9 bits are 1271 * available, and then 5 is subtracted from it. Hence, to check if 1272 * the screen can even be valid, opposite of that needs to happen. 1273 * That being said, to check if the number is within an acceptable range, 1274 * 1 is subtracted from 5, hence, 4 (5 - 1) is multiplied with 8 (i.e., 1275 * 1 is shifted 3 bit positions to the left), and the resulting 32 is 1276 * added to 4096 (9 + 3 bits) to calculate the maximum horizontal total 1277 * IGA1 can handle. Ultimately, 4128 is the largest number VIA IGP's 1278 * IGA1 can handle. */ 1279 if (mode->CrtcHTotal > (4096 + ((1 << 3) * (5 - 1)))) 1280 return MODE_BAD_HVALUE; 1281 1282 if (mode->CrtcHDisplay > 2048) 1283 return MODE_BAD_HVALUE; 1284 1285 if (mode->CrtcHBlankStart > 2048) 1286 return MODE_BAD_HVALUE; 1287 1288 if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025) 1289 return MODE_HBLANK_WIDE; 1290 1291 if (mode->CrtcHSyncStart > 4095) 1292 return MODE_BAD_HVALUE; 1293 1294 if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256) 1295 return MODE_HSYNC_WIDE; 1296 1297 if (mode->CrtcVTotal > 2049) 1298 return MODE_BAD_VVALUE; 1299 1300 if (mode->CrtcVDisplay > 2048) 1301 return MODE_BAD_VVALUE; 1302 1303 if (mode->CrtcVSyncStart > 2047) 1304 return MODE_BAD_VVALUE; 1305 1306 if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16) 1307 return MODE_VSYNC_WIDE; 1308 1309 if (mode->CrtcVBlankStart > 2048) 1310 return MODE_BAD_VVALUE; 1311 1312 if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257) 1313 return MODE_VBLANK_WIDE; 1314 1315 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1316 "Exiting viaIGA1ModeValid.\n")); 1317 return MODE_OK; 1318} 1319 1320void 1321viaIGA1Save(ScrnInfoPtr pScrn) 1322{ 1323 vgaHWPtr hwp = VGAHWPTR(pScrn); 1324 VIAPtr pVia = VIAPTR(pScrn); 1325 VIARegPtr Regs = &pVia->SavedReg; 1326 1327 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1328 "Entered viaIGA1Save.\n")); 1329 1330 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1331 "Saving sequencer registers.\n")); 1332 1333 /* Unlock extended registers. */ 1334 hwp->writeSeq(hwp, 0x10, 0x01); 1335 1336 Regs->SR14 = hwp->readSeq(hwp, 0x14); 1337 Regs->SR15 = hwp->readSeq(hwp, 0x15); 1338 Regs->SR16 = hwp->readSeq(hwp, 0x16); 1339 Regs->SR17 = hwp->readSeq(hwp, 0x17); 1340 Regs->SR18 = hwp->readSeq(hwp, 0x18); 1341 Regs->SR19 = hwp->readSeq(hwp, 0x19); 1342 1343 /* PCI Bus Control */ 1344 Regs->SR1A = hwp->readSeq(hwp, 0x1A); 1345 1346 Regs->SR1B = hwp->readSeq(hwp, 0x1B); 1347 Regs->SR1C = hwp->readSeq(hwp, 0x1C); 1348 Regs->SR1D = hwp->readSeq(hwp, 0x1D); 1349 Regs->SR1E = hwp->readSeq(hwp, 0x1E); 1350 Regs->SR1F = hwp->readSeq(hwp, 0x1F); 1351 1352 Regs->SR22 = hwp->readSeq(hwp, 0x22); 1353 1354 /* Registers 3C5.23 through 3C5.25 are not used by Chrome9. 1355 * Registers 3C5.27 through 3C5.29 are not used by Chrome9. */ 1356 switch (pVia->Chipset) { 1357 case VIA_CLE266: 1358 case VIA_KM400: 1359 case VIA_PM800: 1360 case VIA_K8M800: 1361 case VIA_P4M800PRO: 1362 case VIA_CX700: 1363 case VIA_P4M890: 1364 Regs->SR23 = hwp->readSeq(hwp, 0x23); 1365 Regs->SR24 = hwp->readSeq(hwp, 0x24); 1366 Regs->SR25 = hwp->readSeq(hwp, 0x25); 1367 1368 Regs->SR27 = hwp->readSeq(hwp, 0x27); 1369 Regs->SR28 = hwp->readSeq(hwp, 0x28); 1370 Regs->SR29 = hwp->readSeq(hwp, 0x29); 1371 break; 1372 default: 1373 break; 1374 } 1375 1376 Regs->SR26 = hwp->readSeq(hwp, 0x26); 1377 1378 Regs->SR2A = hwp->readSeq(hwp, 0x2A); 1379 Regs->SR2B = hwp->readSeq(hwp, 0x2B); 1380 Regs->SR2D = hwp->readSeq(hwp, 0x2D); 1381 Regs->SR2E = hwp->readSeq(hwp, 0x2E); 1382 1383 /* Save PCI Configuration Memory Base Shadow 0 and 1. 1384 * These registers are available only in UniChrome, UniChrome Pro, 1385 * and UniChrome Pro II. */ 1386 switch (pVia->Chipset) { 1387 case VIA_CLE266: 1388 case VIA_KM400: 1389 case VIA_PM800: 1390 case VIA_K8M800: 1391 case VIA_P4M800PRO: 1392 case VIA_CX700: 1393 case VIA_P4M890: 1394 Regs->SR2F = hwp->readSeq(hwp, 0x2F); 1395 Regs->SR30 = hwp->readSeq(hwp, 0x30); 1396 break; 1397 default: 1398 break; 1399 } 1400 1401 /* Save PLL settings and several miscellaneous registers. 1402 * For UniChrome, register 3C5.44 through 3C5.4B are saved. 1403 * For UniChrome Pro and Chrome9, register 3C5.44 through 3C5.4C 1404 * are saved. */ 1405 Regs->SR44 = hwp->readSeq(hwp, 0x44); 1406 Regs->SR45 = hwp->readSeq(hwp, 0x45); 1407 Regs->SR46 = hwp->readSeq(hwp, 0x46); 1408 Regs->SR47 = hwp->readSeq(hwp, 0x47); 1409 Regs->SR48 = hwp->readSeq(hwp, 0x48); 1410 Regs->SR49 = hwp->readSeq(hwp, 0x49); 1411 Regs->SR4A = hwp->readSeq(hwp, 0x4A); 1412 Regs->SR4B = hwp->readSeq(hwp, 0x4B); 1413 1414 switch (pVia->Chipset) { 1415 case VIA_PM800: 1416 case VIA_K8M800: 1417 case VIA_P4M800PRO: 1418 case VIA_CX700: 1419 case VIA_P4M890: 1420 case VIA_K8M890: 1421 case VIA_P4M900: 1422 case VIA_VX800: 1423 case VIA_VX855: 1424 case VIA_VX900: 1425 1426 Regs->SR4C = hwp->readSeq(hwp, 0x4C); 1427 1428 /* Save register 3C5.4D. 1429 * According to CX700 / VX700 (UniChrome Pro II) Open Graphics 1430 * Programming Manual Part I: Graphics Core / 2D, 1431 * this register is called Dual Channel Memory Control. 1432 * According to VX800 / VX855 / VX900 (Chrome9 HC3 / HCM / HD) 1433 * Open Graphics Programming Manual Part I: Graphics Core / 2D, 1434 * this register is called Preemptive Arbiter Control. 1435 * It is likely that this register is also supported in UniChrome Pro. */ 1436 Regs->SR4D = hwp->readSeq(hwp, 0x4D); 1437 1438 Regs->SR4E = hwp->readSeq(hwp, 0x4E); 1439 Regs->SR4F = hwp->readSeq(hwp, 0x4F); 1440 break; 1441 default: 1442 break; 1443 } 1444 1445 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1446 "Finished saving sequencer registers.\n")); 1447 1448 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1449 "Saving IGA1 registers.\n")); 1450 1451 /* UniChrome Pro or later */ 1452 switch (pVia->Chipset) { 1453 case VIA_PM800: 1454 case VIA_K8M800: 1455 case VIA_P4M800PRO: 1456 case VIA_CX700: 1457 case VIA_P4M890: 1458 case VIA_K8M890: 1459 case VIA_P4M900: 1460 case VIA_VX800: 1461 case VIA_VX855: 1462 case VIA_VX900: 1463 1464 /* Display Fetch Blocking Control */ 1465 Regs->CR30 = hwp->readCrtc(hwp, 0x30); 1466 1467 /* Half Line Position */ 1468 Regs->CR31 = hwp->readCrtc(hwp, 0x31); 1469 break; 1470 default: 1471 break; 1472 } 1473 1474 Regs->CR32 = hwp->readCrtc(hwp, 0x32); 1475 Regs->CR33 = hwp->readCrtc(hwp, 0x33); 1476 Regs->CR35 = hwp->readCrtc(hwp, 0x35); 1477 Regs->CR36 = hwp->readCrtc(hwp, 0x36); 1478 1479 /* UniChrome Pro or later */ 1480 switch (pVia->Chipset) { 1481 case VIA_PM800: 1482 case VIA_K8M800: 1483 case VIA_P4M800PRO: 1484 case VIA_CX700: 1485 case VIA_P4M890: 1486 case VIA_K8M890: 1487 case VIA_P4M900: 1488 case VIA_VX800: 1489 case VIA_VX855: 1490 case VIA_VX900: 1491 1492 /* DAC Control Register */ 1493 Regs->CR37 = hwp->readCrtc(hwp, 0x37); 1494 break; 1495 default: 1496 break; 1497 } 1498 1499 Regs->CR38 = hwp->readCrtc(hwp, 0x38); 1500 Regs->CR39 = hwp->readCrtc(hwp, 0x39); 1501 Regs->CR3A = hwp->readCrtc(hwp, 0x3A); 1502 Regs->CR3B = hwp->readCrtc(hwp, 0x3B); 1503 Regs->CR3C = hwp->readCrtc(hwp, 0x3C); 1504 Regs->CR3D = hwp->readCrtc(hwp, 0x3D); 1505 Regs->CR3E = hwp->readCrtc(hwp, 0x3E); 1506 Regs->CR3F = hwp->readCrtc(hwp, 0x3F); 1507 1508 Regs->CR40 = hwp->readCrtc(hwp, 0x40); 1509 1510 /* UniChrome Pro or later */ 1511 switch (pVia->Chipset) { 1512 case VIA_PM800: 1513 case VIA_K8M800: 1514 case VIA_P4M800PRO: 1515 case VIA_CX700: 1516 case VIA_P4M890: 1517 case VIA_K8M890: 1518 case VIA_P4M900: 1519 case VIA_VX800: 1520 case VIA_VX855: 1521 case VIA_VX900: 1522 1523 Regs->CR43 = hwp->readCrtc(hwp, 0x43); 1524 Regs->CR45 = hwp->readCrtc(hwp, 0x45); 1525 break; 1526 default: 1527 break; 1528 } 1529 1530 Regs->CR46 = hwp->readCrtc(hwp, 0x46); 1531 Regs->CR47 = hwp->readCrtc(hwp, 0x47); 1532 1533 /* Starting Address */ 1534 /* Start Address High */ 1535 Regs->CR0C = hwp->readCrtc(hwp, 0x0C); 1536 1537 /* Start Address Low */ 1538 Regs->CR0D = hwp->readCrtc(hwp, 0x0D); 1539 1540 /* UniChrome Pro or later */ 1541 switch (pVia->Chipset) { 1542 case VIA_PM800: 1543 case VIA_K8M800: 1544 case VIA_P4M800PRO: 1545 case VIA_CX700: 1546 case VIA_P4M890: 1547 case VIA_K8M890: 1548 case VIA_P4M900: 1549 case VIA_VX800: 1550 case VIA_VX855: 1551 case VIA_VX900: 1552 1553 /* Starting Address Overflow[28:24] */ 1554 Regs->CR48 = hwp->readCrtc(hwp, 0x48); 1555 break; 1556 default: 1557 break; 1558 } 1559 1560 /* Starting Address Overflow[23:16] */ 1561 Regs->CR34 = hwp->readCrtc(hwp, 0x34); 1562 1563 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1564 "Finished saving IGA1 registers.\n")); 1565 1566 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1567 "Exiting viaIGA1Save.\n")); 1568} 1569 1570void 1571viaIGA1Restore(ScrnInfoPtr pScrn) 1572{ 1573 vgaHWPtr hwp = VGAHWPTR(pScrn); 1574 VIAPtr pVia = VIAPTR(pScrn); 1575 VIARegPtr Regs = &pVia->SavedReg; 1576 1577 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1578 "Entered viaIGA1Restore.\n")); 1579 1580 /* Unlock extended registers. */ 1581 hwp->writeSeq(hwp, 0x10, 0x01); 1582 1583 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1584 "Restoring sequencer registers.\n")); 1585 1586 hwp->writeSeq(hwp, 0x14, Regs->SR14); 1587 hwp->writeSeq(hwp, 0x15, Regs->SR15); 1588 hwp->writeSeq(hwp, 0x16, Regs->SR16); 1589 hwp->writeSeq(hwp, 0x17, Regs->SR17); 1590 hwp->writeSeq(hwp, 0x18, Regs->SR18); 1591 hwp->writeSeq(hwp, 0x19, Regs->SR19); 1592 1593 /* PCI Bus Control */ 1594 hwp->writeSeq(hwp, 0x1A, Regs->SR1A); 1595 1596 hwp->writeSeq(hwp, 0x1B, Regs->SR1B); 1597 hwp->writeSeq(hwp, 0x1C, Regs->SR1C); 1598 hwp->writeSeq(hwp, 0x1D, Regs->SR1D); 1599 hwp->writeSeq(hwp, 0x1E, Regs->SR1E); 1600 hwp->writeSeq(hwp, 0x1F, Regs->SR1F); 1601 1602 hwp->writeSeq(hwp, 0x22, Regs->SR22); 1603 1604 /* Registers 3C5.23 through 3C5.25 are not used by Chrome9. 1605 * Registers 3C5.27 through 3C5.29 are not used by Chrome9. */ 1606 switch (pVia->Chipset) { 1607 case VIA_CLE266: 1608 case VIA_KM400: 1609 case VIA_PM800: 1610 case VIA_K8M800: 1611 case VIA_P4M800PRO: 1612 case VIA_CX700: 1613 case VIA_P4M890: 1614 1615 hwp->writeSeq(hwp, 0x23, Regs->SR23); 1616 hwp->writeSeq(hwp, 0x24, Regs->SR24); 1617 hwp->writeSeq(hwp, 0x25, Regs->SR25); 1618 1619 hwp->writeSeq(hwp, 0x27, Regs->SR27); 1620 hwp->writeSeq(hwp, 0x28, Regs->SR28); 1621 hwp->writeSeq(hwp, 0x29, Regs->SR29); 1622 break; 1623 default: 1624 break; 1625 } 1626 1627 hwp->writeSeq(hwp, 0x26, Regs->SR26); 1628 1629 hwp->writeSeq(hwp, 0x2A, Regs->SR2A); 1630 hwp->writeSeq(hwp, 0x2B, Regs->SR2B); 1631 1632 hwp->writeSeq(hwp, 0x2D, Regs->SR2D); 1633 hwp->writeSeq(hwp, 0x2E, Regs->SR2E); 1634 1635 /* Restore PCI Configuration Memory Base Shadow 0 and 1. 1636 * These registers are available only in UniChrome, UniChrome Pro, 1637 * and UniChrome Pro II. */ 1638 switch (pVia->Chipset) { 1639 case VIA_CLE266: 1640 case VIA_KM400: 1641 case VIA_PM800: 1642 case VIA_K8M800: 1643 case VIA_P4M800PRO: 1644 case VIA_CX700: 1645 case VIA_P4M890: 1646 1647 hwp->writeSeq(hwp, 0x2F, Regs->SR2F); 1648 hwp->writeSeq(hwp, 0x30, Regs->SR30); 1649 break; 1650 default: 1651 break; 1652 } 1653 1654 /* Restore PLL settings and several miscellaneous registers. 1655 * For UniChrome, register 3C5.44 through 3C5.4B are restored. 1656 * For UniChrome Pro and Chrome 9, register 3C5.44 through 3C5.4C 1657 * are restored. */ 1658 switch (pVia->Chipset) { 1659 case VIA_CLE266: 1660 case VIA_KM400: 1661 /* Engine Clock (ECK) PLL settings */ 1662 hwp->writeSeq(hwp, 0x48, Regs->SR48); 1663 hwp->writeSeq(hwp, 0x49, Regs->SR49); 1664 1665 /* Memory Clock (MCK) PLL settings */ 1666 hwp->writeSeq(hwp, 0x4a, Regs->SR4A); 1667 hwp->writeSeq(hwp, 0x4b, Regs->SR4B); 1668 1669 /* Primary Display Clock (VCK) PLL settings */ 1670 hwp->writeSeq(hwp, 0x46, Regs->SR46); 1671 hwp->writeSeq(hwp, 0x47, Regs->SR47); 1672 1673 /* Secondary Display Clock (LCDCK) PLL settings */ 1674 hwp->writeSeq(hwp, 0x44, Regs->SR44); 1675 hwp->writeSeq(hwp, 0x45, Regs->SR45); 1676 break; 1677 default: 1678 /* Engine Clock (ECK) PLL settings */ 1679 hwp->writeSeq(hwp, 0x47, Regs->SR47); 1680 hwp->writeSeq(hwp, 0x48, Regs->SR48); 1681 hwp->writeSeq(hwp, 0x49, Regs->SR49); 1682 1683 /* Reset ECK PLL. */ 1684 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x01); /* Set SR40[0] to 1 */ 1685 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & (~0x01)); /* Set SR40[0] to 0 */ 1686 1687 1688 /* Primary Display Clock (VCK) PLL settings */ 1689 hwp->writeSeq(hwp, 0x44, Regs->SR44); 1690 hwp->writeSeq(hwp, 0x45, Regs->SR45); 1691 hwp->writeSeq(hwp, 0x46, Regs->SR46); 1692 1693 /* Reset VCK PLL. */ 1694 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x02); /* Set SR40[1] to 1 */ 1695 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & (~0x02)); /* Set SR40[1] to 0 */ 1696 1697 1698 /* Secondary Display Clock (LCDCK) PLL settings */ 1699 hwp->writeSeq(hwp, 0x4A, Regs->SR4A); 1700 hwp->writeSeq(hwp, 0x4B, Regs->SR4B); 1701 hwp->writeSeq(hwp, 0x4C, Regs->SR4C); 1702 1703 /* Reset LCDCK PLL. */ 1704 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) | 0x04); /* Set SR40[2] to 1 */ 1705 hwp->writeSeq(hwp, 0x40, hwp->readSeq(hwp, 0x40) & (~0x04)); /* Set SR40[2] to 0 */ 1706 break; 1707 } 1708 1709 switch (pVia->Chipset) { 1710 case VIA_PM800: 1711 case VIA_K8M800: 1712 case VIA_P4M800PRO: 1713 case VIA_CX700: 1714 case VIA_P4M890: 1715 case VIA_K8M890: 1716 case VIA_P4M900: 1717 case VIA_VX800: 1718 case VIA_VX855: 1719 case VIA_VX900: 1720 1721 /* Restore register 3C5.4D. 1722 * According to CX700 / VX700 (UniChrome Pro II) Open Graphics 1723 * Programming Manual Part I: Graphics Core / 2D, 1724 * this register is called Dual Channel Memory Control. 1725 * According to VX800 / VX855 / VX900 (Chrome9 HC3 / HCM / HD) 1726 * Open Graphics Programming Manual Part I: Graphics Core / 2D, 1727 * this register is called Preemptive Arbiter Control. 1728 * It is likely that this register is also supported in UniChrome Pro. */ 1729 hwp->writeSeq(hwp, 0x4D, Regs->SR4D); 1730 1731 hwp->writeSeq(hwp, 0x4E, Regs->SR4E); 1732 hwp->writeSeq(hwp, 0x4F, Regs->SR4F); 1733 break; 1734 default: 1735 break; 1736 } 1737 1738 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1739 "Finished restoring sequencer registers.\n")); 1740 1741/* Reset dot clocks. */ 1742 ViaSeqMask(hwp, 0x40, 0x06, 0x06); 1743 ViaSeqMask(hwp, 0x40, 0x00, 0x06); 1744 1745 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1746 "Restoring IGA1 registers.\n")); 1747 1748/* UniChrome Pro or later */ 1749 switch (pVia->Chipset) { 1750 case VIA_PM800: 1751 case VIA_K8M800: 1752 case VIA_P4M800PRO: 1753 case VIA_CX700: 1754 case VIA_P4M890: 1755 case VIA_K8M890: 1756 case VIA_P4M900: 1757 case VIA_VX800: 1758 case VIA_VX855: 1759 case VIA_VX900: 1760 1761 /* Display Fetch Blocking Control */ 1762 hwp->writeCrtc(hwp, 0x30, Regs->CR30); 1763 1764 /* Half Line Position */ 1765 hwp->writeCrtc(hwp, 0x31, Regs->CR31); 1766 break; 1767 default: 1768 break; 1769 } 1770 1771 /* Restore CRTC controller extended registers. */ 1772 /* Mode Control */ 1773 hwp->writeCrtc(hwp, 0x32, Regs->CR32); 1774 1775 /* HSYNCH Adjuster */ 1776 hwp->writeCrtc(hwp, 0x33, Regs->CR33); 1777 1778 /* Extended Overflow */ 1779 hwp->writeCrtc(hwp, 0x35, Regs->CR35); 1780 1781 /* Power Management 3 (Monitor Control) */ 1782 hwp->writeCrtc(hwp, 0x36, Regs->CR36); 1783 1784/* UniChrome Pro or later */ 1785 switch (pVia->Chipset) { 1786 case VIA_PM800: 1787 case VIA_K8M800: 1788 case VIA_P4M800PRO: 1789 case VIA_CX700: 1790 case VIA_P4M890: 1791 case VIA_K8M890: 1792 case VIA_P4M900: 1793 case VIA_VX800: 1794 case VIA_VX855: 1795 case VIA_VX900: 1796 1797 /* DAC control Register */ 1798 hwp->writeCrtc(hwp, 0x37, Regs->CR37); 1799 break; 1800 default: 1801 break; 1802 } 1803 1804 hwp->writeCrtc(hwp, 0x38, Regs->CR38); 1805 hwp->writeCrtc(hwp, 0x39, Regs->CR39); 1806 hwp->writeCrtc(hwp, 0x3A, Regs->CR3A); 1807 hwp->writeCrtc(hwp, 0x3B, Regs->CR3B); 1808 hwp->writeCrtc(hwp, 0x3C, Regs->CR3C); 1809 hwp->writeCrtc(hwp, 0x3D, Regs->CR3D); 1810 hwp->writeCrtc(hwp, 0x3E, Regs->CR3E); 1811 hwp->writeCrtc(hwp, 0x3F, Regs->CR3F); 1812 1813 hwp->writeCrtc(hwp, 0x40, Regs->CR40); 1814 1815 /* UniChrome Pro or later */ 1816 switch (pVia->Chipset) { 1817 case VIA_PM800: 1818 case VIA_K8M800: 1819 case VIA_P4M800PRO: 1820 case VIA_CX700: 1821 case VIA_P4M890: 1822 case VIA_K8M890: 1823 case VIA_P4M900: 1824 case VIA_VX800: 1825 case VIA_VX855: 1826 case VIA_VX900: 1827 1828 hwp->writeCrtc(hwp, 0x43, Regs->CR43); 1829 hwp->writeCrtc(hwp, 0x45, Regs->CR45); 1830 break; 1831 default: 1832 break; 1833 } 1834 1835 hwp->writeCrtc(hwp, 0x46, Regs->CR46); 1836 hwp->writeCrtc(hwp, 0x47, Regs->CR47); 1837 1838 /* Starting Address */ 1839 /* Start Address High */ 1840 hwp->writeCrtc(hwp, 0x0C, Regs->CR0C); 1841 1842 /* Start Address Low */ 1843 hwp->writeCrtc(hwp, 0x0D, Regs->CR0D); 1844 1845 /* UniChrome Pro or later */ 1846 switch (pVia->Chipset) { 1847 case VIA_PM800: 1848 case VIA_K8M800: 1849 case VIA_P4M800PRO: 1850 case VIA_CX700: 1851 case VIA_P4M890: 1852 case VIA_K8M890: 1853 case VIA_P4M900: 1854 case VIA_VX800: 1855 case VIA_VX855: 1856 case VIA_VX900: 1857 1858 /* Starting Address Overflow[28:24] */ 1859 hwp->writeCrtc(hwp, 0x48, Regs->CR48); 1860 break; 1861 default: 1862 break; 1863 } 1864 1865 /* CR34 is fire bits. Must be written after CR0C, CR0D, and CR48. 1866 * Starting Address Overflow[23:16] */ 1867 hwp->writeCrtc(hwp, 0x34, Regs->CR34); 1868 1869 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1870 "Finished restoring IGA1 registers.\n")); 1871 1872 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1873 "Exiting viaIGA1Restore.\n")); 1874} 1875 1876/* 1877 * Initialize IGA2 (Integrated Graphics Accelerator) registers. 1878 */ 1879void 1880viaIGA2Init(ScrnInfoPtr pScrn) 1881{ 1882 vgaHWPtr hwp = VGAHWPTR(pScrn); 1883 VIAPtr pVia = VIAPTR(pScrn); 1884#ifdef HAVE_DEBUG 1885 CARD8 temp; 1886#endif 1887 1888 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1889 "Entered viaIGA2Init.\n")); 1890 1891#ifdef HAVE_DEBUG 1892 temp = hwp->readSeq(hwp, 0x1B); 1893 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1894 "SR1B: 0x%02X\n", temp)); 1895 temp = hwp->readSeq(hwp, 0x2D); 1896 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1897 "SR2D: 0x%02X\n", temp)); 1898 temp = hwp->readCrtc(hwp, 0x6A); 1899 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1900 "CR6A: 0x%02X\n", temp)); 1901 temp = hwp->readCrtc(hwp, 0x6B); 1902 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1903 "CR6B: 0x%02X\n", temp)); 1904 1905 /* For UniChrome Pro and Chrome9. */ 1906 if ((pVia->Chipset != VIA_CLE266) 1907 && (pVia->Chipset != VIA_KM400)) { 1908 temp = hwp->readCrtc(hwp, 0x6C); 1909 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1910 "CR6C: 0x%02X\n", temp)); 1911 } 1912 1913 temp = hwp->readCrtc(hwp, 0x79); 1914 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1915 "CR79: 0x%02X\n", temp)); 1916 1917#endif 1918 1919 /* 3C5.1B[7:6] - Secondary Display Engine (Gated Clock <LCK>) 1920 * 0x: Clock always off 1921 * 10: Clock always on 1922 * 11: Clock on/off according to the 1923 * Power Management Status (PMS) 1924 * 3C5.1B[5:4] - Primary Display Engine (Gated Clock <VCK>) 1925 * 0x: Clock always off 1926 * 10: Clock always on 1927 * 11: Clock on/off according to the PMS 1928 * 3C5.1B[3:1] - Reserved 1929 * 3C5.1B[0] - Primary Display’s LUT On/Off 1930 * 0: On 1931 * 1: Off */ 1932 ViaSeqMask(hwp, 0x1B, 0xC0, 0xC0); 1933 1934 /* 3C5.2D[7:6] - E3_ECK_N Selection 1935 * 00: E3_ECK_N 1936 * 01: E3_ECK 1937 * 10: delayed E3_ECK_N 1938 * 11: delayed E3_ECK 1939 * 3C5.2D[5:4] - VCK (Primary Display Clock) PLL Power Control 1940 * 0x: PLL power-off 1941 * 10: PLL always on 1942 * 11: PLL on/off according to the PMS 1943 * 3C5.2D[3:2] - LCK (Secondary Display Clock) PLL Power Control 1944 * 0x: PLL power-off 1945 * 10: PLL always on 1946 * 11: PLL on/off according to the PMS 1947 * 3C5.2D[1:0] - ECK (Engine Clock) PLL Power Control 1948 * 0x: PLL power-off 1949 * 10: PLL always on 1950 * 11: PLL on/off according to the PMS */ 1951 ViaSeqMask(hwp, 0x2D, 0x0C, 0x0C); 1952 1953 /* 3X5.6A[7] - Second Display Channel Enable 1954 * 0: Disable 1955 * 1: Enable 1956 * 3X5.6A[6] - Second Display Channel Reset 1957 * 0: Reset 1958 * 3X5.6A[5] - Second Display 8/6 Bits LUT 1959 * 0: 6-bit 1960 * 1: 8-bit 1961 * 3X5.6A[4] - Horizontal Count by 2 1962 * 0: Disable 1963 * 1: Enable 1964 * 3X5.6A[1] - LCD Gamma Enable 1965 * 0: Disable 1966 * 1: Enable 1967 * 3X5.6A[0] - LCD Pre-fetch Mode Enable 1968 * 0: Disable 1969 * 1: Enable */ 1970 ViaCrtcMask(hwp, 0x6A, 0x80, 0xB3); 1971 1972 /* TV out uses division by 2 mode. 1973 * Other devices like analog (VGA), DVI, flat panel, etc., 1974 * use normal mode. */ 1975 /* 3X5.6B[5:4] - Second Display Channel Clock Mode Selection 1976 * 0x: Normal 1977 * 1x: Division by 2 1978 * 3X5.6B[2] - IGA2 Screen Off 1979 * 0: Normal 1980 * 1: Screen off 1981 * 3X5.6B[1] - IGA2 Screen Off Selection Method 1982 * 0: IGA2 Screen off 1983 * 1: IGA1 Screen off */ 1984 ViaCrtcMask(hwp, 0x6B, 0x00, 0x36); 1985 1986 /* For UniChrome Pro and Chrome9. */ 1987 if ((pVia->Chipset != VIA_CLE266) 1988 && (pVia->Chipset != VIA_KM400)) { 1989 /* The following register fields are for UniChrome Pro and Chrome9. */ 1990 /* 3X5.6C[3:1] - LCDCK PLL Reference Clock Source Selection 1991 * 000: From XI pin 1992 * 001: From TVXI 1993 * 01x: From TVPLL 1994 * 100: DVP0TVCLKR 1995 * 101: DVP1TVCLKR 1996 * 110: CAP0 Clock 1997 * 111: CAP1 Clock 1998 * 3X5.6C[0] - LCDCK Source Selection 1999 * 0: LCDCK PLL output clock 2000 * 1: LCDCK PLL reference clock */ 2001 ViaCrtcMask(hwp, 0x6C, 0x00, 0x0F); 2002 } 2003 2004 /* Disable LCD scaling */ 2005 /* 3X5.79[0] - LCD Scaling Enable 2006 * 0: Disable 2007 * 1: Enable */ 2008 ViaCrtcMask(hwp, 0x79, 0x00, 0x01); 2009 2010 /* Set DVP0 (Digital Video Port 0) source to IGA2. */ 2011 /* 3X5.96[7] - DVP0 ALPHA Enable 2012 * 0: Disable 2013 * 1: Enable 2014 * 3X5.96[6] - DVP0 VSYNC Polarity 2015 * 0: Positive 2016 * 1: Negative 2017 * 3X5.96[5] - DVP0 HSYNC Polarity 2018 * 0: Positive 2019 * 1: Negative 2020 * 3X5.96[4] - DVP0 Data Source Selection 0 2021 * 0: Primary Display 2022 * 1: Secondary Display 2023 * 3X5.96[3] - DVP0 Clock Polarity 2024 * 3X5.96[2:0] - DVP0 Clock Adjust 2025 * Valid Value: 0 through 7 */ 2026 ViaCrtcMask(hwp, 0x96, 0x10, 0x10); 2027 2028 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2029 "Exiting viaIGA2Init.\n")); 2030} 2031 2032void 2033viaIGA2SetFBStartingAddress(xf86CrtcPtr crtc, int x, int y) 2034{ 2035 ScrnInfoPtr pScrn = crtc->scrn; 2036 vgaHWPtr hwp = VGAHWPTR(pScrn); 2037 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2038 drmmode_ptr drmmode = drmmode_crtc->drmmode; 2039 CARD32 Base, tmp; 2040 CARD8 cr62, cr63, cr64, cra3; 2041 2042 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2043 "Entered viaIGA2SetFBStartingAddress.\n")); 2044 2045 Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); 2046 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2047 "Base Address: 0x%lx\n", 2048 Base)); 2049 Base = (Base + drmmode->front_bo->offset) >> 3; 2050 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2051 "DRI Base Address: 0x%lx\n", 2052 Base); 2053 2054 tmp = hwp->readCrtc(hwp, 0x62) & 0x01; 2055 tmp |= (Base & 0x7F) << 1; 2056 hwp->writeCrtc(hwp, 0x62, tmp); 2057 2058 hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7); 2059 hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15); 2060 hwp->writeCrtc(hwp, 0xA3, (Base & 0x03800000) >> 23); 2061 2062#ifdef HAVE_DEBUG 2063 cr62 = hwp->readCrtc(hwp, 0x62); 2064 cr63 = hwp->readCrtc(hwp, 0x63); 2065 cr64 = hwp->readCrtc(hwp, 0x64); 2066 cra3 = hwp->readCrtc(hwp, 0xA3); 2067 2068 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2069 "CR62: 0x%02X\n", cr62)); 2070 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2071 "CR63: 0x%02X\n", cr63)); 2072 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2073 "CR64: 0x%02X\n", cr64)); 2074 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2075 "CRA3: 0x%02X\n", cra3)); 2076#endif 2077 2078 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2079 "Exiting viaIGA2SetFBStartingAddress.\n")); 2080} 2081 2082void 2083viaIGA2SetDisplayRegister(ScrnInfoPtr pScrn, DisplayModePtr mode) 2084{ 2085 VIAPtr pVia = VIAPTR(pScrn); 2086 vgaHWPtr hwp = VGAHWPTR(pScrn); 2087 CARD16 temp; 2088 2089 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2090 "Entered viaIGA2SetDisplayRegister.\n")); 2091 2092 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2093 "Requested Screen Mode: %s\n", mode->name); 2094 2095 /* Set the color depth for IGA2. */ 2096 switch (pScrn->bitsPerPixel) { 2097 case 8: 2098 /* Only CLE266.AX uses 6-bit LUT. */ 2099 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15) { 2100 /* 6-bit LUT */ 2101 /* 3X5.6A[5] - Second Display 8/6 Bits LUT 2102 * 0: 6-bit 2103 * 1: 8-bit */ 2104 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 2105 } else { 2106 /* Set IGA2 display LUT to 8-bit */ 2107 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 2108 } 2109 2110 ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); 2111 break; 2112 case 16: 2113 ViaCrtcMask(hwp, 0x67, 0x40, 0xC0); 2114 break; 2115 case 24: 2116 case 32: 2117 ViaCrtcMask(hwp, 0x67, 0xC0, 0xC0); 2118 break; 2119 default: 2120 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2121 "Unsupported color depth: %d\n", 2122 pScrn->bitsPerPixel); 2123 break; 2124 } 2125 2126 /* LVDS Channel 1 and 2 should be controlled by PMS 2127 * (Power Management Status). */ 2128 ViaSeqMask(hwp, 0x2A, 0x0F, 0x0F); 2129 2130 /* 3X5.99[3:0] appears to be a register to adjust an LCD panel 2131 * (the official name of the register is unknown). */ 2132 if (pVia->Chipset == VIA_P4M900) { 2133 ViaCrtcMask(hwp, 0x99, 0x08, 0x0F); 2134 } 2135 2136 /* IGA2 for DFP Low. */ 2137 ViaCrtcMask(hwp, 0x99, 0x10, 0x10); 2138 2139 /* Use IGA2 for DVP1 Data Source Selection 0. */ 2140 ViaCrtcMask(hwp, 0x9B, 0x10, 0x10); 2141 2142 /* Linear Mode */ 2143 ViaCrtcMask(hwp, 0x62, 0x00, 0x01); 2144 2145 2146 /* Set IGA2 horizontal total pixels.*/ 2147 /* Horizontal Total Period: 4096 - 1 (max) */ 2148 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2149 "IGA2 CrtcHTotal: %d\n", mode->CrtcHTotal)); 2150 temp = mode->CrtcHTotal - 1; 2151 2152 /* 3X5.50[7:0] - Horizontal Total Period Bits [7:0] */ 2153 hwp->writeCrtc(hwp, 0x50, temp & 0xFF); 2154 2155 /* 3X5.55[3:0] - Horizontal Total Period Bits [11:8] */ 2156 ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F); 2157 2158 2159 /* Set IGA2 horizontal display end position. */ 2160 /* Horizontal Active Data Period: 2048 - 1 (max) */ 2161 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2162 "IGA2 CrtcHDisplay: %d\n", mode->CrtcHDisplay)); 2163 temp = mode->CrtcHDisplay - 1; 2164 2165 /* 3X5.51[7:0] - Horizontal Active Data Period Bits [7:0] */ 2166 hwp->writeCrtc(hwp, 0x51, temp & 0xFF); 2167 2168 /* 3X5.55[6:4] - Horizontal Active Data Period Bits [10:8] */ 2169 ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70); 2170 2171 2172 /* Set IGA2 horizontal blank start. */ 2173 /* Horizontal Blanking Start: 2048 - 1 (max) */ 2174 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2175 "IGA2 CrtcHBlankStart: %d\n", mode->CrtcHBlankStart)); 2176 temp = mode->CrtcHBlankStart; 2177 2178 /* 3X5.52[7:0] - Horizontal Blanking Start Bits [7:0] */ 2179 hwp->writeCrtc(hwp, 0x52, temp & 0xFF); 2180 2181 /* 3X5.54[2:0] - Horizontal Blanking Start Bits [10:8] */ 2182 ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07); 2183 2184 2185 /* Set IGA2 horizontal blank end. */ 2186 /* Horizontal Blanking End: 4096 - 1 (max) */ 2187 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2188 "IGA2 CrtcHBlankEnd: %d\n", mode->CrtcHBlankEnd)); 2189 temp = mode->CrtcHBlankEnd - 1; 2190 2191 /* 3X5.53[7:0] - Horizontal Blanking End Bits [7:0] */ 2192 hwp->writeCrtc(hwp, 0x53, temp & 0xFF); 2193 2194 /* 3X5.54[5:3] - Horizontal Blanking End Bits [10:8] */ 2195 ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38); 2196 2197 /* 3X5.5D[6] - Horizontal Blanking End Bit [11] */ 2198 ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40); 2199 2200 2201 /* Set IGA2 horizontal synchronization start. */ 2202 /* Horizontal Retrace Start: 2047 (max, UniChrome), 2203 * 4095 (max, UniChrome Pro and Chrome9) */ 2204 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2205 "IGA2 CrtcHSyncStart: %d\n", mode->CrtcHSyncStart)); 2206 temp = mode->CrtcHSyncStart; 2207 2208 /* 3X5.56[7:0] - Horizontal Retrace Start Bits [7:0] */ 2209 hwp->writeCrtc(hwp, 0x56, temp & 0xFF); 2210 2211 /* 3X5.54[7:6] - Horizontal Retrace Start Bits [9:8] */ 2212 ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0); 2213 2214 /* 3X5.5C[7] - Horizontal Retrace Start Bit [10] */ 2215 ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80); 2216 2217 /* For UniChrome Pro and Chrome9. */ 2218 if ((pVia->Chipset != VIA_CLE266) 2219 && (pVia->Chipset != VIA_KM400)) { 2220 2221 /* 3X5.5D[7] - Horizontal Retrace Start Bit [11] */ 2222 ViaCrtcMask(hwp, 0x5D, temp >> 4, 0x80); 2223 } 2224 2225 2226 /* Set IGA2 horizontal synchronization end. */ 2227 /* Horizontal Retrace End: 511 (max) */ 2228 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2229 "IGA2 CrtcHSyncEnd: %d\n", mode->CrtcHSyncEnd)); 2230 temp = mode->CrtcHSyncEnd - 1; 2231 2232 /* 3X5.57[7:0] - Horizontal Retrace End Bits [7:0] */ 2233 hwp->writeCrtc(hwp, 0x57, temp & 0xFF); 2234 2235 /* 3X5.5C[6] - Horizontal Retrace End Bit [8] */ 2236 ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40); 2237 2238 2239 /* Set IGA2 vertical total pixels. */ 2240 /* Vertical Total Period: 2048 - 1 (max) */ 2241 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2242 "IGA2 CrtcVTotal: %d\n", mode->CrtcVTotal)); 2243 temp = mode->CrtcVTotal - 1; 2244 2245 /* 3X5.58[7:0] - Vertical Total Period Bits [7:0] */ 2246 hwp->writeCrtc(hwp, 0x58, temp & 0xFF); 2247 2248 /* 3X5.5D[2:0] - Vertical Total Period Bits [10:8] */ 2249 ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07); 2250 2251 2252 /* Set IGA2 vertical display end position. */ 2253 /* Vertical Active Data Period: 2048 - 1 (max) */ 2254 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2255 "IGA2 CrtcVDisplay: %d\n", mode->CrtcVDisplay)); 2256 temp = mode->CrtcVDisplay - 1; 2257 2258 /* 3X5.59[7:0] - Vertical Active Data Period Bits [7:0] */ 2259 hwp->writeCrtc(hwp, 0x59, temp & 0xFF); 2260 2261 /* 3X5.5D[5:3] - Vertical Active Data Period Bits [10:8] */ 2262 ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38); 2263 2264 2265 /* Set IGA2 vertical blank start. */ 2266 /* Vertical Blanking Start: 2048 - 1 (max) */ 2267 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2268 "IGA2 CrtcVBlankStart: %d\n", mode->CrtcVBlankStart)); 2269 temp = mode->CrtcVBlankStart; 2270 2271 /* 3X5.5A[7:0] - Vertical Blanking Start Bits [7:0] */ 2272 hwp->writeCrtc(hwp, 0x5A, temp & 0xFF); 2273 2274 /* 3X5.5C[2:0] - Vertical Blanking Start Bits [10:8] */ 2275 ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07); 2276 2277 2278 /* Set IGA2 vertical blank end. */ 2279 /* Vertical Blanking End: 4096 - 1 (max) */ 2280 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2281 "IGA2 CrtcVBlankEnd: %d\n", mode->CrtcVBlankEnd)); 2282 temp = mode->CrtcVBlankEnd - 1; 2283 2284 /* 3X5.5B[7:0] - Vertical Blanking End Bits [7:0] */ 2285 hwp->writeCrtc(hwp, 0x5B, temp & 0xFF); 2286 2287 /* 3X5.5C[5:3] - Vertical Blanking End Bits [10:8] */ 2288 ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38); 2289 2290 2291 /* Set IGA2 vertical synchronization start. */ 2292 /* Horizontal Retrace Start: 2047 (max) */ 2293 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2294 "IGA2 CrtcVSyncStart: %d\n", mode->CrtcVSyncStart)); 2295 temp = mode->CrtcVSyncStart; 2296 2297 /* 3X5.5E[7:0] - Vertical Retrace Start Bits [7:0] */ 2298 hwp->writeCrtc(hwp, 0x5E, temp & 0xFF); 2299 2300 /* 3X5.5F[7:5] - Vertical Retrace Start Bits [10:8] */ 2301 ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0); 2302 2303 2304 /* Set IGA2 vertical synchronization end. */ 2305 /* Vertical Retrace End: 32 (max) */ 2306 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2307 "IGA2 CrtcVSyncEnd: %d\n", mode->CrtcVSyncEnd)); 2308 temp = mode->CrtcVSyncEnd - 1; 2309 2310 /*3X5.5F[4:0] - Vertical Retrace End Bits [4:0] */ 2311 ViaCrtcMask(hwp, 0x5F, temp & 0x1F, 0x1F); 2312 2313 2314 /* Set IGA2 horizontal offset adjustment. */ 2315 temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; 2316 2317 /* Make sure that this is 32-byte aligned. */ 2318 if (temp & 0x03) { 2319 temp += 0x03; 2320 temp &= ~0x03; 2321 } 2322 2323 /* 3X5.66[7:0] - Second Display Horizontal Offset Bits [7:0] */ 2324 hwp->writeCrtc(hwp, 0x66, temp & 0xFF); 2325 2326 /* 3X5.67[1:0] - Second Display Horizontal Offset Bits [9:8] */ 2327 ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03); 2328 2329 2330 /* Set IGA2 alignment. */ 2331 temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3; 2332 2333 /* Make sure that this is 32-byte aligned. */ 2334 if (temp & 0x03) { 2335 temp += 0x03; 2336 temp &= ~0x03; 2337 } 2338 2339 /* 3X5.65[7:0] - Second Display Horizontal 2340 * 2-Quadword Count Data Bits [7:0] */ 2341 hwp->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF); 2342 2343 /* 3X5.67[3:2] - Second Display Horizontal 2344 * 2-Quadword Count Data Bits [9:8] */ 2345 ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C); 2346 2347 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2348 "Exiting viaIGA2SetDisplayRegister.\n")); 2349} 2350 2351static ModeStatus 2352viaIGA2ModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 2353{ 2354 VIAPtr pVia = VIAPTR(pScrn); 2355 2356 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2357 "Entered viaIGA2ModeValid.\n")); 2358 2359 if (mode->CrtcHTotal > 4096) 2360 return MODE_BAD_HVALUE; 2361 2362 if (mode->CrtcHDisplay > 2048) 2363 return MODE_BAD_HVALUE; 2364 2365 if (mode->CrtcHBlankStart > 2048) 2366 return MODE_BAD_HVALUE; 2367 2368 if (mode->CrtcHBlankEnd > 4096) 2369 return MODE_HBLANK_WIDE; 2370 2371 if ((((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) 2372 && (mode->CrtcHSyncStart > 2048)) 2373 || (((pVia->Chipset != VIA_CLE266) && (pVia->Chipset != VIA_KM400)) 2374 && (mode->CrtcHSyncStart > 4096))) 2375 return MODE_BAD_HVALUE; 2376 2377 if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512) 2378 return MODE_HSYNC_WIDE; 2379 2380 if (mode->CrtcVTotal > 2048) 2381 return MODE_BAD_VVALUE; 2382 2383 if (mode->CrtcVDisplay > 2048) 2384 return MODE_BAD_VVALUE; 2385 2386 if (mode->CrtcVBlankStart > 2048) 2387 return MODE_BAD_VVALUE; 2388 2389 if (mode->CrtcVBlankEnd > 2048) 2390 return MODE_VBLANK_WIDE; 2391 2392 if (mode->CrtcVSyncStart > 2048) 2393 return MODE_BAD_VVALUE; 2394 2395 if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32) 2396 return MODE_VSYNC_WIDE; 2397 2398 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2399 "Exiting viaIGA2ModeValid.\n")); 2400 return MODE_OK; 2401} 2402 2403void 2404viaIGA2Save(ScrnInfoPtr pScrn) 2405{ 2406 vgaHWPtr hwp = VGAHWPTR(pScrn); 2407 VIAPtr pVia = VIAPTR(pScrn); 2408 VIARegPtr Regs = &pVia->SavedReg; 2409 int i; 2410 2411 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2412 "Entered viaIGA2Save.\n")); 2413 2414 /* Unlock extended registers. */ 2415 hwp->writeSeq(hwp, 0x10, 0x01); 2416 2417 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2418 "Saving IGA2 registers.\n")); 2419 2420 for (i = 0; i < (0x88 - 0x50 + 1); i++) { 2421 Regs->EXCR[i + (0x50 - 0x50)] = hwp->readCrtc(hwp, i + 0x50); 2422 2423 } 2424 2425 for (i = 0; i < (0x92 - 0x8A + 1); i++) { 2426 Regs->EXCR[i + (0x8A - 0x50)] = hwp->readCrtc(hwp, i + 0x8A); 2427 2428 } 2429 2430 for (i = 0; i < (0xA3 - 0x94 + 1); i++) { 2431 Regs->EXCR[i + (0x94 - 0x50)] = hwp->readCrtc(hwp, i + 0x94); 2432 2433 } 2434 2435 Regs->EXCR[0xA4 - 0x50] = hwp->readCrtc(hwp, 0xA4); 2436 2437 for (i = 0; i < (0xAC - 0xA5 + 1); i++) { 2438 Regs->EXCR[i + (0xA5 - 0x50)] = hwp->readCrtc(hwp, i + 0xA5); 2439 2440 } 2441 2442 /* Chrome 9 */ 2443 switch (pVia->Chipset) { 2444 case VIA_K8M890: 2445 case VIA_P4M900: 2446 case VIA_VX800: 2447 case VIA_VX855: 2448 case VIA_VX900: 2449 Regs->EXCR[0xAF - 0x50] = hwp->readCrtc(hwp, 0xAF); 2450 break; 2451 default: 2452 break; 2453 } 2454 2455 /* Chrome 9, Chrome 9 HC, and Chrome 9 HC3 */ 2456 switch (pVia->Chipset) { 2457 case VIA_K8M890: 2458 case VIA_P4M900: 2459 case VIA_VX800: 2460 for (i = 0; i < (0xCD - 0xB0 + 1); i++) { 2461 Regs->EXCR[i + (0xB0 - 0x50)] = hwp->readCrtc(hwp, i + 0xB0); 2462 2463 } 2464 2465 break; 2466 default: 2467 break; 2468 } 2469 2470 switch (pVia->Chipset) { 2471 2472 /* UniChrome Pro and UniChrome Pro II */ 2473 case VIA_PM800: 2474 case VIA_K8M800: 2475 case VIA_P4M800PRO: 2476 case VIA_CX700: 2477 case VIA_P4M890: 2478 for (i = 0; i < (0xD7 - 0xD0 + 1); i++) { 2479 Regs->EXCR[i + (0xD0 - 0x50)] = hwp->readCrtc(hwp, i + 0xD0); 2480 2481 } 2482 2483 break; 2484 2485 /* Chrome 9 */ 2486 case VIA_K8M890: 2487 case VIA_P4M900: 2488 case VIA_VX800: 2489 case VIA_VX855: 2490 case VIA_VX900: 2491 for (i = 0; i < (0xEC - 0xD0 + 1); i++) { 2492 Regs->EXCR[i + (0xD0 - 0x50)] = hwp->readCrtc(hwp, i + 0xD0); 2493 2494 } 2495 2496 break; 2497 default: 2498 break; 2499 } 2500 2501 /* Chrome 9 */ 2502 switch (pVia->Chipset) { 2503 case VIA_K8M890: 2504 case VIA_P4M900: 2505 case VIA_VX800: 2506 case VIA_VX855: 2507 case VIA_VX900: 2508 for (i = 0; i < (0xF5 - 0xF0 + 1); i++) { 2509 Regs->EXCR[i + (0xF0 - 0x50)] = hwp->readCrtc(hwp, i + 0xF0); 2510 2511 } 2512 2513 break; 2514 default: 2515 break; 2516 } 2517 2518 /* Chrome 9 HCM and Chrome 9 HD */ 2519 if ((pVia->Chipset == VIA_VX855) || (pVia->Chipset == VIA_VX900)) { 2520 for (i = 0; i < (0xFC - 0xF6 + 1); i++) { 2521 Regs->EXCR[i + (0xF6 - 0x50)] = hwp->readCrtc(hwp, i + 0xF6); 2522 2523 } 2524 } 2525 2526 /* Chrome 9 HD */ 2527 if (pVia->Chipset == VIA_VX900) { 2528 Regs->EXCR[0xFD - 0x50] = hwp->readCrtc(hwp, 0xFD); 2529 2530 } 2531 2532 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2533 "Finished saving IGA2 registers.\n")); 2534 2535 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2536 "Exiting viaIGA2Save.\n")); 2537} 2538 2539void 2540viaIGA2Restore(ScrnInfoPtr pScrn) 2541{ 2542 vgaHWPtr hwp = VGAHWPTR(pScrn); 2543 VIAPtr pVia = VIAPTR(pScrn); 2544 VIARegPtr Regs = &pVia->SavedReg; 2545 int i; 2546 2547 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2548 "Entered viaIGA2Restore.\n")); 2549 2550 /* Unlock extended registers. */ 2551 hwp->writeSeq(hwp, 0x10, 0x01); 2552 2553 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2554 "Restoring IGA2 registers.\n")); 2555 2556 for (i = 0; i < (0x5F - 0x50 + 1); i++) { 2557 hwp->writeCrtc(hwp, i + 0x50, Regs->EXCR[i + (0x50 - 0x50)]); 2558 2559 } 2560 2561 for (i = 0; i < (0x69 - 0x62 + 1); i++) { 2562 hwp->writeCrtc(hwp, i + 0x62, Regs->EXCR[i + (0x62 - 0x50)]); 2563 2564 } 2565 2566 for (i = 0; i < (0x88 - 0x6D + 1); i++) { 2567 hwp->writeCrtc(hwp, i + 0x6D, Regs->EXCR[i + (0x6D - 0x50)]); 2568 2569 } 2570 2571 for (i = 0; i < (0x92 - 0x8A + 1); i++) { 2572 hwp->writeCrtc(hwp, i + 0x8A, Regs->EXCR[i + (0x8A - 0x50)]); 2573 2574 } 2575 2576 for (i = 0; i < (0xA3 - 0x94 + 1); i++) { 2577 hwp->writeCrtc(hwp, i + 0x94, Regs->EXCR[i + (0x94 - 0x50)]); 2578 2579 } 2580 2581 /* UniChrome Pro and UniChrome Pro II */ 2582 switch (pVia->Chipset) { 2583 case VIA_PM800: 2584 case VIA_K8M800: 2585 case VIA_P4M800PRO: 2586 case VIA_CX700: 2587 case VIA_P4M890: 2588 hwp->writeCrtc(hwp, 0xA4, Regs->EXCR[0xA4 - 0x50]); 2589 break; 2590 default: 2591 break; 2592 } 2593 2594 for (i = 0; i < (0xAC - 0xA5 + 1); i++) { 2595 hwp->writeCrtc(hwp, i + 0xA5, Regs->EXCR[i + (0xA5 - 0x50)]); 2596 2597 } 2598 2599 /* Chrome 9 */ 2600 switch (pVia->Chipset) { 2601 case VIA_K8M890: 2602 case VIA_P4M900: 2603 case VIA_VX800: 2604 case VIA_VX855: 2605 case VIA_VX900: 2606 hwp->writeCrtc(hwp, 0xAF, Regs->EXCR[0xAF - 0x50]); 2607 break; 2608 default: 2609 break; 2610 } 2611 2612 /* Chrome 9, Chrome 9 HC, and Chrome 9 HC3 */ 2613 switch (pVia->Chipset) { 2614 case VIA_K8M890: 2615 case VIA_P4M900: 2616 case VIA_VX800: 2617 for (i = 0; i < (0xCD - 0xB0 + 1); i++) { 2618 hwp->writeCrtc(hwp, i + 0xB0, Regs->EXCR[i + (0xB0 - 0x50)]); 2619 2620 } 2621 2622 break; 2623 default: 2624 break; 2625 } 2626 2627 switch (pVia->Chipset) { 2628 /* UniChrome Pro and UniChrome Pro II */ 2629 case VIA_PM800: 2630 case VIA_K8M800: 2631 case VIA_P4M800PRO: 2632 case VIA_CX700: 2633 case VIA_P4M890: 2634 for (i = 0; i < (0xD7 - 0xD0 + 1); i++) { 2635 hwp->writeCrtc(hwp, i + 0xD0, Regs->EXCR[i + (0xD0 - 0x50)]); 2636 2637 } 2638 2639 break; 2640 2641 /* Chrome 9 */ 2642 case VIA_K8M890: 2643 case VIA_P4M900: 2644 case VIA_VX800: 2645 case VIA_VX855: 2646 case VIA_VX900: 2647 for (i = 0; i < (0xEC - 0xD0 + 1); i++) { 2648 hwp->writeCrtc(hwp, i + 0xD0, Regs->EXCR[i + (0xD0 - 0x50)]); 2649 2650 } 2651 2652 break; 2653 default: 2654 break; 2655 } 2656 2657 /* Chrome 9 */ 2658 switch (pVia->Chipset) { 2659 case VIA_K8M890: 2660 case VIA_P4M900: 2661 case VIA_VX800: 2662 case VIA_VX855: 2663 case VIA_VX900: 2664 for (i = 0; i < (0xF5 - 0xF0 + 1); i++) { 2665 hwp->writeCrtc(hwp, i + 0xF0, Regs->EXCR[i + (0xF0 - 0x50)]); 2666 2667 } 2668 2669 break; 2670 default: 2671 break; 2672 } 2673 2674 /* Chrome 9 HCM and Chrome 9 HD */ 2675 if ((pVia->Chipset == VIA_VX855) || (pVia->Chipset == VIA_VX900)) { 2676 for (i = 0; i < (0xFC - 0xF6 + 1); i++) { 2677 hwp->writeCrtc(hwp, i + 0xF6, Regs->EXCR[i + (0xF6 - 0x50)]); 2678 2679 } 2680 } 2681 2682 /* Chrome 9 HD */ 2683 if (pVia->Chipset == VIA_VX900) { 2684 hwp->writeCrtc(hwp, 0xFD, Regs->EXCR[0xFD - 0x50]); 2685 2686 } 2687 2688 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2689 "Finished restoring IGA2 registers.\n")); 2690 2691 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2692 "Exiting viaIGA2Restore.\n")); 2693} 2694 2695/* 2696 * Not tested yet 2697 */ 2698void 2699ViaShadowCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 2700{ 2701 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaShadowCRTCSetMode\n")); 2702 2703 vgaHWPtr hwp = VGAHWPTR(pScrn); 2704 CARD16 temp; 2705 2706 temp = (mode->CrtcHTotal >> 3) - 5; 2707 hwp->writeCrtc(hwp, 0x6D, temp & 0xFF); 2708 ViaCrtcMask(hwp, 0x71, temp >> 5, 0x08); 2709 2710 temp = (mode->CrtcHBlankEnd >> 3) - 1; 2711 hwp->writeCrtc(hwp, 0x6E, temp & 0xFF); 2712 2713 temp = mode->CrtcVTotal - 2; 2714 hwp->writeCrtc(hwp, 0x6F, temp & 0xFF); 2715 ViaCrtcMask(hwp, 0x71, temp >> 8, 0x07); 2716 2717 temp = mode->CrtcVDisplay - 1; 2718 hwp->writeCrtc(hwp, 0x70, temp & 0xFF); 2719 ViaCrtcMask(hwp, 0x71, temp >> 4, 0x70); 2720 2721 temp = mode->CrtcVBlankStart - 1; 2722 hwp->writeCrtc(hwp, 0x72, temp & 0xFF); 2723 ViaCrtcMask(hwp, 0x74, temp >> 4, 0x70); 2724 2725 temp = mode->CrtcVTotal - 1; 2726 hwp->writeCrtc(hwp, 0x73, temp & 0xFF); 2727 ViaCrtcMask(hwp, 0x74, temp >> 8, 0x07); 2728 2729 ViaCrtcMask(hwp, 0x76, mode->CrtcVSyncEnd, 0x0F); 2730 2731 temp = mode->CrtcVSyncStart; 2732 hwp->writeCrtc(hwp, 0x75, temp & 0xFF); 2733 ViaCrtcMask(hwp, 0x76, temp >> 4, 0x70); 2734} 2735 2736static void 2737iga1_crtc_dpms(xf86CrtcPtr crtc, int mode) 2738{ 2739 ScrnInfoPtr pScrn = crtc->scrn; 2740 VIAPtr pVia = VIAPTR(pScrn); 2741 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 2742 2743 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2744 "Entered iga1_crtc_dpms.\n")); 2745 2746 switch (mode) { 2747 case DPMSModeOn: 2748 viaIGA1DPMSControl(pScrn, 0x00); 2749 break; 2750 2751 case DPMSModeStandby: 2752 viaIGA1DPMSControl(pScrn, 0x01); 2753 break; 2754 2755 case DPMSModeSuspend: 2756 viaIGA1DPMSControl(pScrn, 0x02); 2757 break; 2758 2759 case DPMSModeOff: 2760 viaIGA1DPMSControl(pScrn, 0x03); 2761 break; 2762 2763 default: 2764 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS Mode: %d\n", 2765 mode); 2766 break; 2767 } 2768 //vgaHWSaveScreen(pScrn->pScreen, mode); 2769 2770 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2771 "Exiting iga1_crtc_dpms.\n")); 2772} 2773 2774static void 2775iga1_crtc_save(xf86CrtcPtr crtc) 2776{ 2777 ScrnInfoPtr pScrn = crtc->scrn; 2778 vgaHWPtr hwp = VGAHWPTR(pScrn); 2779 VIAPtr pVia = VIAPTR(pScrn); 2780 2781 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2782 "Entered iga1_crtc_save.\n")); 2783 2784 vgaHWProtect(pScrn, TRUE); 2785 2786 /* Save the standard VGA registers. */ 2787 if (xf86IsPrimaryPci(pVia->PciInfo)) { 2788 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); 2789 } else { 2790 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); 2791 } 2792 2793 viaIGA1Save(pScrn); 2794 2795 vgaHWProtect(pScrn, FALSE); 2796 vgaHWUnlock(hwp); 2797 2798 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2799 "Exiting iga1_crtc_save.\n")); 2800} 2801 2802static void 2803iga1_crtc_restore(xf86CrtcPtr crtc) 2804{ 2805 ScrnInfoPtr pScrn = crtc->scrn; 2806 vgaHWPtr hwp = VGAHWPTR(pScrn); 2807 VIAPtr pVia = VIAPTR(pScrn); 2808 CARD8 tmp; 2809 2810 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2811 "Entered iga1_crtc_restore.\n")); 2812 2813 vgaHWProtect(pScrn, TRUE); 2814 2815 /* Restore the standard VGA registers. */ 2816 if (xf86IsPrimaryPci(pVia->PciInfo)) { 2817 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL); 2818 } else { 2819 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE); 2820 } 2821 2822 /* Gamma must be disabled before restoring palette. */ 2823 ViaGammaDisable(pScrn); 2824 2825 viaIGA1Restore(pScrn); 2826 2827 ViaDisablePrimaryFIFO(pScrn); 2828 2829 vgaHWProtect(pScrn, FALSE); 2830 vgaHWLock(hwp); 2831 2832 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2833 "Exiting iga1_crtc_restore.\n")); 2834} 2835 2836static Bool 2837iga1_crtc_lock(xf86CrtcPtr crtc) 2838{ 2839 return FALSE; 2840} 2841 2842static void 2843iga1_crtc_unlock(xf86CrtcPtr crtc) 2844{ 2845} 2846 2847static Bool 2848iga1_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 2849 DisplayModePtr adjusted_mode) 2850{ 2851 ScrnInfoPtr pScrn = crtc->scrn; 2852 VIAPtr pVia = VIAPTR(pScrn); 2853 CARD32 temp; 2854 ModeStatus modestatus; 2855 2856 if ((mode->Clock < pScrn->clockRanges->minClock) || 2857 (mode->Clock > pScrn->clockRanges->maxClock)) { 2858 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2859 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 2860 mode->name, mode->Clock, pScrn->clockRanges->minClock, 2861 pScrn->clockRanges->maxClock); 2862 return FALSE; 2863 } 2864 2865 modestatus = viaIGA1ModeValid(pScrn, mode); 2866 if (modestatus != MODE_OK) { 2867 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 2868 mode->name, xf86ModeStatusToString(modestatus)); 2869 return FALSE; 2870 } 2871 2872 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 2873 (pScrn->bitsPerPixel >> 3); 2874 if (pVia->pBIOSInfo->Bandwidth < temp) { 2875 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2876 "Required bandwidth is not available. (%u > %u)\n", 2877 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 2878 return FALSE; 2879 } 2880 return TRUE; 2881} 2882 2883static void 2884iga1_crtc_prepare (xf86CrtcPtr crtc) 2885{ 2886} 2887 2888static void 2889iga1_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 2890{ 2891 ScrnInfoPtr pScrn = crtc->scrn; 2892 VIAPtr pVia = VIAPTR(pScrn); 2893 2894 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2895 "Entered iga1_crtc_set_origin.\n")); 2896 2897 viaIGA1SetFBStartingAddress(crtc, x, y); 2898 VIAVidAdjustFrame(pScrn, x, y); 2899 2900 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2901 "Exiting iga1_crtc_set_origin.\n")); 2902} 2903 2904static void 2905iga1_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 2906 DisplayModePtr adjusted_mode, 2907 int x, int y) 2908{ 2909 ScrnInfoPtr pScrn = crtc->scrn; 2910 vgaHWPtr hwp = VGAHWPTR(pScrn); 2911 VIAPtr pVia = VIAPTR(pScrn); 2912 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 2913 2914 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2915 "Entered iga1_crtc_mode_set.\n")); 2916 2917 if (!vgaHWInit(pScrn, adjusted_mode)) { 2918 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2919 "vgaHWInit failed.\n")); 2920 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2921 "Exiting iga1_crtc_mode_set.\n")); 2922 return; 2923 } 2924 2925 /* Turn off IGA1 during mode setting. */ 2926 viaIGA1DPMSControl(pScrn, 0x03); 2927 2928 viaIGAInitCommon(pScrn); 2929 viaIGA1Init(pScrn); 2930 ViaCRTCInit(pScrn); 2931 2932 /* Turn off Screen */ 2933 ViaCrtcMask(hwp, 0x17, 0x00, 0x80); 2934 2935 /* Disable IGA1 */ 2936 ViaSeqMask(hwp, 0x59, 0x00, 0x80); 2937 2938 viaIGA1SetDisplayRegister(pScrn, adjusted_mode); 2939 ViaSetPrimaryFIFO(pScrn, adjusted_mode); 2940 2941 pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, adjusted_mode); 2942 pBIOSInfo->ClockExternal = FALSE; 2943 ViaSetPrimaryDotclock(pScrn, pBIOSInfo->Clock); 2944 ViaSetUseExternalClock(hwp); 2945 ViaCrtcMask(hwp, 0x6B, 0x00, 0x01); 2946 2947 hwp->disablePalette(hwp); 2948 2949 /* Enable IGA1 */ 2950 ViaSeqMask(hwp, 0x59, 0x80, 0x80); 2951 2952 /* Turn on Screen */ 2953 ViaCrtcMask(hwp, 0x17, 0x80, 0x80); 2954 2955 viaIGA1SetFBStartingAddress(crtc, x, y); 2956 VIAVidAdjustFrame(pScrn, x, y); 2957 2958 /* Turn on IGA1 now that mode setting is done. */ 2959 viaIGA1DPMSControl(pScrn, 0x00); 2960 2961 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2962 "Exiting iga1_crtc_mode_set.\n")); 2963} 2964 2965static void 2966iga1_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 2967 int size) 2968{ 2969 ScrnInfoPtr pScrn = crtc->scrn; 2970 vgaHWPtr hwp = VGAHWPTR(pScrn); 2971 VIAPtr pVia = VIAPTR(pScrn); 2972 int SR1A, SR1B, CR67, CR6A; 2973 LOCO *colors; 2974 int i; 2975 2976 colors = malloc(size * sizeof(*colors)); 2977 if (colors == NULL) 2978 return; 2979 2980 for (i = 0; i < size; i++) { 2981 colors[i].red = red[i] >> 8; 2982 colors[i].green = green[i] >> 8; 2983 colors[i].blue = blue[i] >> 8; 2984 } 2985 2986 if (pScrn->bitsPerPixel != 8) { 2987 switch (pVia->Chipset) { 2988 case VIA_CLE266: 2989 case VIA_KM400: 2990 ViaSeqMask(hwp, 0x16, 0x80, 0x80); 2991 break; 2992 default: 2993 ViaCrtcMask(hwp, 0x33, 0x80, 0x80); 2994 break; 2995 } 2996 2997 ViaSeqMask(hwp, 0x1A, 0x00, 0x01); 2998 VIALoadRgbLut(pScrn, 0, size, colors); 2999 3000 } else { 3001 3002 SR1A = hwp->readSeq(hwp, 0x1A); 3003 SR1B = hwp->readSeq(hwp, 0x1B); 3004 CR67 = hwp->readCrtc(hwp, 0x67); 3005 CR6A = hwp->readCrtc(hwp, 0x6A); 3006 3007 for (i = 0; i < size; i++) { 3008 hwp->writeDacWriteAddr(hwp, i); 3009 hwp->writeDacData(hwp, colors[i].red); 3010 hwp->writeDacData(hwp, colors[i].green); 3011 hwp->writeDacData(hwp, colors[i].blue); 3012 } 3013 } 3014 free(colors); 3015} 3016 3017static void * 3018iga1_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 3019{ 3020 return NULL; 3021} 3022 3023static PixmapPtr 3024iga1_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 3025{ 3026 return NULL; 3027} 3028 3029static void 3030iga1_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 3031{ 3032} 3033 3034/* 3035 Set the cursor foreground and background colors. In 8bpp, fg and 3036 bg are indices into the current colormap unless the 3037 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 3038 and in all other bpps the fg and bg are in 8-8-8 RGB format. 3039*/ 3040static void 3041iga1_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) 3042{ 3043 ScrnInfoPtr pScrn = crtc->scrn; 3044 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 3045 VIAPtr pVia = VIAPTR(pScrn); 3046 CARD32 temp; 3047 3048 if (xf86_config->cursor_fg) 3049 return; 3050 3051 /* Don't recolour the image if we don't have to. */ 3052 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 3053 return; 3054 3055 switch(pVia->Chipset) { 3056 case VIA_PM800: 3057 case VIA_CX700: 3058 case VIA_P4M890: 3059 case VIA_P4M900: 3060 case VIA_VX800: 3061 case VIA_VX855: 3062 case VIA_VX900: 3063 temp = VIAGETREG(PRIM_HI_CTRL); 3064 VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFE); 3065 break; 3066 3067 default: 3068 temp = VIAGETREG(HI_CONTROL); 3069 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 3070 break; 3071 } 3072 3073 xf86_config->cursor_fg = fg; 3074 xf86_config->cursor_bg = bg; 3075} 3076 3077static void 3078iga1_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) 3079{ 3080 ScrnInfoPtr pScrn = crtc->scrn; 3081 VIAPtr pVia = VIAPTR(pScrn); 3082 unsigned xoff, yoff; 3083 3084 if (x < 0) { 3085 xoff = ((-x) & 0xFE); 3086 x = 0; 3087 } else { 3088 xoff = 0; 3089 } 3090 3091 if (y < 0) { 3092 yoff = ((-y) & 0xFE); 3093 y = 0; 3094 } else { 3095 yoff = 0; 3096 } 3097 3098 switch(pVia->Chipset) { 3099 case VIA_PM800: 3100 case VIA_CX700: 3101 case VIA_P4M890: 3102 case VIA_P4M900: 3103 case VIA_VX800: 3104 case VIA_VX855: 3105 case VIA_VX900: 3106 VIASETREG(PRIM_HI_POSSTART, ((x << 16) | (y & 0x07ff))); 3107 VIASETREG(PRIM_HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 3108 break; 3109 3110 default: 3111 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 3112 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 3113 break; 3114 } 3115} 3116 3117static void 3118iga1_crtc_show_cursor (xf86CrtcPtr crtc) 3119{ 3120 drmmode_crtc_private_ptr iga = crtc->driver_private; 3121 ScrnInfoPtr pScrn = crtc->scrn; 3122 VIAPtr pVia = VIAPTR(pScrn); 3123 3124 switch(pVia->Chipset) { 3125 case VIA_PM800: 3126 case VIA_CX700: 3127 case VIA_P4M890: 3128 case VIA_P4M900: 3129 case VIA_VX800: 3130 case VIA_VX855: 3131 case VIA_VX900: 3132 VIASETREG(PRIM_HI_FBOFFSET, iga->cursor_bo->offset); 3133 VIASETREG(PRIM_HI_CTRL, 0x36000005); 3134 break; 3135 3136 default: 3137 /* Mono Cursor Display Path [bit31]: Primary */ 3138 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 3139 VIASETREG(HI_CONTROL, 0x76000005); 3140 break; 3141 } 3142} 3143 3144static void 3145iga1_crtc_hide_cursor (xf86CrtcPtr crtc) 3146{ 3147 ScrnInfoPtr pScrn = crtc->scrn; 3148 VIAPtr pVia = VIAPTR(pScrn); 3149 CARD32 temp; 3150 3151 switch(pVia->Chipset) { 3152 case VIA_PM800: 3153 case VIA_CX700: 3154 case VIA_P4M890: 3155 case VIA_P4M900: 3156 case VIA_VX800: 3157 case VIA_VX855: 3158 case VIA_VX900: 3159 temp = VIAGETREG(PRIM_HI_CTRL); 3160 VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFA); 3161 break; 3162 3163 default: 3164 temp = VIAGETREG(HI_CONTROL); 3165 /* Hardware cursor disable [bit0] */ 3166 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 3167 break; 3168 } 3169} 3170 3171static void 3172iga_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) 3173{ 3174 drmmode_crtc_private_ptr iga = crtc->driver_private; 3175 ScrnInfoPtr pScrn = crtc->scrn; 3176 void *dst; 3177 3178 dst = drm_bo_map(pScrn, iga->cursor_bo); 3179 memset(dst, 0x00, iga->cursor_bo->size); 3180 memcpy(dst, image, iga->cursor_bo->size); 3181 drm_bo_unmap(pScrn, iga->cursor_bo); 3182} 3183 3184static void 3185iga_crtc_commit(xf86CrtcPtr crtc) 3186{ 3187 ScrnInfoPtr pScrn = crtc->scrn; 3188 VIAPtr pVia = VIAPTR(pScrn); 3189 3190 if (crtc->scrn->pScreen != NULL && pVia->drmmode.hwcursor) 3191 xf86_reload_cursors(crtc->scrn->pScreen); 3192} 3193 3194static void 3195iga_crtc_destroy(xf86CrtcPtr crtc) 3196{ 3197 if (crtc->driver_private) 3198 free(crtc->driver_private); 3199} 3200 3201const xf86CrtcFuncsRec iga1_crtc_funcs = { 3202 .dpms = iga1_crtc_dpms, 3203 .save = iga1_crtc_save, 3204 .restore = iga1_crtc_restore, 3205 .lock = iga1_crtc_lock, 3206 .unlock = iga1_crtc_unlock, 3207 .mode_fixup = iga1_crtc_mode_fixup, 3208 .prepare = iga1_crtc_prepare, 3209 .mode_set = iga1_crtc_mode_set, 3210 .commit = iga_crtc_commit, 3211 .gamma_set = iga1_crtc_gamma_set, 3212 .shadow_create = iga1_crtc_shadow_create, 3213 .shadow_allocate = iga1_crtc_shadow_allocate, 3214 .shadow_destroy = iga1_crtc_shadow_destroy, 3215 .set_cursor_colors = iga1_crtc_set_cursor_colors, 3216 .set_cursor_position = iga1_crtc_set_cursor_position, 3217 .show_cursor = iga1_crtc_show_cursor, 3218 .hide_cursor = iga1_crtc_hide_cursor, 3219 .load_cursor_argb = iga_crtc_load_cursor_argb, 3220#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 2 3221 .set_origin = iga1_crtc_set_origin, 3222#endif 3223 .destroy = iga_crtc_destroy, 3224}; 3225 3226static void 3227iga2_crtc_dpms(xf86CrtcPtr crtc, int mode) 3228{ 3229 ScrnInfoPtr pScrn = crtc->scrn; 3230 VIAPtr pVia = VIAPTR(pScrn); 3231 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 3232 3233 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3234 "Entered iga2_crtc_dpms.\n")); 3235 3236 switch (mode) { 3237 case DPMSModeOn: 3238 viaIGA2DisplayOutput(pScrn, TRUE); 3239 break; 3240 3241 case DPMSModeStandby: 3242 case DPMSModeSuspend: 3243 case DPMSModeOff: 3244 viaIGA2DisplayOutput(pScrn, FALSE); 3245 break; 3246 3247 default: 3248 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode: %d\n", 3249 mode); 3250 break; 3251 } 3252 //vgaHWSaveScreen(pScrn->pScreen, mode); 3253 3254 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3255 "Exiting iga2_crtc_dpms.\n")); 3256} 3257 3258static void 3259iga2_crtc_save(xf86CrtcPtr crtc) 3260{ 3261 ScrnInfoPtr pScrn = crtc->scrn; 3262 vgaHWPtr hwp = VGAHWPTR(pScrn); 3263 VIAPtr pVia = VIAPTR(pScrn); 3264 3265 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3266 "Entered iga2_crtc_save.\n")); 3267 3268 viaIGA2Save(pScrn); 3269 3270 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3271 "Exiting iga2_crtc_save.\n")); 3272} 3273 3274static void 3275iga2_crtc_restore(xf86CrtcPtr crtc) 3276{ 3277 ScrnInfoPtr pScrn = crtc->scrn; 3278 vgaHWPtr hwp = VGAHWPTR(pScrn); 3279 VIAPtr pVia = VIAPTR(pScrn); 3280 CARD8 tmp; 3281 3282 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3283 "Entered iga2_crtc_restore.\n")); 3284 3285 viaIGA2Restore(pScrn); 3286 3287 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3288 "Exiting iga2_crtc_restore.\n")); 3289} 3290 3291static Bool 3292iga2_crtc_lock(xf86CrtcPtr crtc) 3293{ 3294 return FALSE; 3295} 3296 3297static void 3298iga2_crtc_unlock(xf86CrtcPtr crtc) 3299{ 3300} 3301 3302static Bool 3303iga2_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 3304 DisplayModePtr adjusted_mode) 3305{ 3306 ScrnInfoPtr pScrn = crtc->scrn; 3307 VIAPtr pVia = VIAPTR(pScrn); 3308 CARD32 temp; 3309 ModeStatus modestatus; 3310 3311 if ((mode->Clock < pScrn->clockRanges->minClock) || 3312 (mode->Clock > pScrn->clockRanges->maxClock)) { 3313 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3314 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 3315 mode->name, mode->Clock, pScrn->clockRanges->minClock, 3316 pScrn->clockRanges->maxClock); 3317 return FALSE; 3318 } 3319 3320 modestatus = viaIGA2ModeValid(pScrn, mode); 3321 if (modestatus != MODE_OK) { 3322 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 3323 mode->name, xf86ModeStatusToString(modestatus)); 3324 return FALSE; 3325 } 3326 3327 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 3328 (pScrn->bitsPerPixel >> 3); 3329 if (pVia->pBIOSInfo->Bandwidth < temp) { 3330 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3331 "Required bandwidth is not available. (%u > %u)\n", 3332 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 3333 return FALSE; 3334 } 3335 return TRUE; 3336} 3337 3338static void 3339iga2_crtc_prepare (xf86CrtcPtr crtc) 3340{ 3341} 3342 3343static void 3344iga2_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 3345{ 3346 ScrnInfoPtr pScrn = crtc->scrn; 3347 VIAPtr pVia = VIAPTR(pScrn); 3348 3349 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3350 "Entered iga2_crtc_set_origin.\n")); 3351 3352 viaIGA2SetFBStartingAddress(crtc, x, y); 3353 VIAVidAdjustFrame(pScrn, x, y); 3354 3355 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3356 "Exiting iga2_crtc_set_origin.\n")); 3357} 3358 3359static void 3360iga2_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 3361 DisplayModePtr adjusted_mode, int x, int y) 3362{ 3363 ScrnInfoPtr pScrn = crtc->scrn; 3364 vgaHWPtr hwp = VGAHWPTR(pScrn); 3365 VIAPtr pVia = VIAPTR(pScrn); 3366 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 3367 3368 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3369 "Entered iga2_crtc_mode_set.\n")); 3370 3371 if (!vgaHWInit(pScrn, adjusted_mode)) { 3372 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3373 "vgaHWInit failed.\n")); 3374 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3375 "Exiting iga2_crtc_mode_set.\n")); 3376 return; 3377 } 3378 3379 /* Turn off IGA2 during mode setting. */ 3380 viaIGA2DisplayOutput(pScrn, FALSE); 3381 3382 viaIGAInitCommon(pScrn); 3383 viaIGA2Init(pScrn); 3384 ViaCRTCInit(pScrn); 3385 3386 viaIGA2SetDisplayRegister(pScrn, adjusted_mode); 3387 ViaSetSecondaryFIFO(pScrn, adjusted_mode); 3388 pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, adjusted_mode); 3389 pBIOSInfo->ClockExternal = FALSE; 3390 ViaSetSecondaryDotclock(pScrn, pBIOSInfo->Clock); 3391 ViaSetUseExternalClock(hwp); 3392 3393 hwp->disablePalette(hwp); 3394 3395 viaIGA2DisplayChannel(pScrn, TRUE); 3396 3397 viaIGA2SetFBStartingAddress(crtc, x, y); 3398 VIAVidAdjustFrame(pScrn, x, y); 3399 3400 /* Turn on IGA2 now that mode setting is done. */ 3401 viaIGA2DisplayOutput(pScrn, TRUE); 3402 3403 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3404 "Exiting iga2_crtc_mode_set.\n")); 3405} 3406 3407static void 3408iga2_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 3409 int size) 3410{ 3411 ScrnInfoPtr pScrn = crtc->scrn; 3412 vgaHWPtr hwp = VGAHWPTR(pScrn); 3413 VIAPtr pVia = VIAPTR(pScrn); 3414 int SR1A, SR1B, CR67, CR6A; 3415 int i; 3416 LOCO *colors; 3417 3418 colors = malloc(size * sizeof(*colors)); 3419 if (colors == NULL) 3420 return; 3421 3422 for (i = 0; i < size; i++) { 3423 colors[i].red = red[i] >> 8; 3424 colors[i].green = green[i] >> 8; 3425 colors[i].blue = blue[i] >> 8; 3426 } 3427 3428 if (pScrn->bitsPerPixel != 8) { 3429 if (!(pVia->Chipset == VIA_CLE266 && 3430 CLE266_REV_IS_AX(pVia->ChipRev))) { 3431 ViaSeqMask(hwp, 0x1A, 0x01, 0x01); 3432 ViaCrtcMask(hwp, 0x6A, 0x02, 0x02); 3433 3434 switch (pVia->Chipset) { 3435 case VIA_CLE266: 3436 case VIA_KM400: 3437 case VIA_K8M800: 3438 case VIA_PM800: 3439 break; 3440 3441 default: 3442 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 3443 break; 3444 } 3445 VIALoadRgbLut(pScrn, 0, size, colors); 3446 } 3447 } else { 3448 SR1A = hwp->readSeq(hwp, 0x1A); 3449 SR1B = hwp->readSeq(hwp, 0x1B); 3450 CR67 = hwp->readCrtc(hwp, 0x67); 3451 CR6A = hwp->readCrtc(hwp, 0x6A); 3452 3453 ViaSeqMask(hwp, 0x1A, 0x01, 0x01); 3454 ViaSeqMask(hwp, 0x1B, 0x80, 0x80); 3455 ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); 3456 ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0); 3457 3458 for (i = 0; i < size; i++) { 3459 hwp->writeDacWriteAddr(hwp, i); 3460 hwp->writeDacData(hwp, colors[i].red); 3461 hwp->writeDacData(hwp, colors[i].green); 3462 hwp->writeDacData(hwp, colors[i].blue); 3463 } 3464 3465 hwp->writeSeq(hwp, 0x1A, SR1A); 3466 hwp->writeSeq(hwp, 0x1B, SR1B); 3467 hwp->writeCrtc(hwp, 0x67, CR67); 3468 hwp->writeCrtc(hwp, 0x6A, CR6A); 3469 3470 /* Screen 0 palette was changed by mode setting of Screen 1, 3471 * so load it again. */ 3472 for (i = 0; i < size; i++) { 3473 hwp->writeDacWriteAddr(hwp, i); 3474 hwp->writeDacData(hwp, colors[i].red); 3475 hwp->writeDacData(hwp, colors[i].green); 3476 hwp->writeDacData(hwp, colors[i].blue); 3477 } 3478 } 3479 free(colors); 3480} 3481 3482static void * 3483iga2_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 3484{ 3485 return NULL; 3486} 3487 3488static PixmapPtr 3489iga2_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 3490{ 3491 return NULL; 3492} 3493 3494static void 3495iga2_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 3496{ 3497} 3498 3499/* 3500 Set the cursor foreground and background colors. In 8bpp, fg and 3501 bg are indices into the current colormap unless the 3502 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 3503 and in all other bpps the fg and bg are in 8-8-8 RGB format. 3504*/ 3505static void 3506iga2_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 3507{ 3508 drmmode_crtc_private_ptr iga = crtc->driver_private; 3509 ScrnInfoPtr pScrn = crtc->scrn; 3510 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 3511 int height = 64, width = 64, i; 3512 VIAPtr pVia = VIAPTR(pScrn); 3513 CARD32 pixel, temp, *dst; 3514 3515 if (xf86_config->cursor_fg) 3516 return; 3517 3518 fg |= 0xff000000; 3519 bg |= 0xff000000; 3520 3521 /* Don't recolour the image if we don't have to. */ 3522 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 3523 return; 3524 3525 switch(pVia->Chipset) { 3526 case VIA_PM800: 3527 case VIA_CX700: 3528 case VIA_P4M890: 3529 case VIA_P4M900: 3530 case VIA_VX800: 3531 case VIA_VX855: 3532 case VIA_VX900: 3533 temp = VIAGETREG(HI_CONTROL); 3534 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 3535 break; 3536 3537 default: 3538 temp = VIAGETREG(HI_CONTROL); 3539 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 3540 height = width = 32; 3541 break; 3542 } 3543 3544 dst = drm_bo_map(pScrn, iga->cursor_bo); 3545 for (i = 0; i < width * height; i++, dst++) 3546 if ((pixel = *dst)) 3547 *dst = (pixel == xf86_config->cursor_fg) ? fg : bg; 3548 drm_bo_unmap(pScrn, iga->cursor_bo); 3549 3550 xf86_config->cursor_fg = fg; 3551 xf86_config->cursor_bg = bg; 3552} 3553 3554static void 3555iga2_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 3556{ 3557 ScrnInfoPtr pScrn = crtc->scrn; 3558 VIAPtr pVia = VIAPTR(pScrn); 3559 unsigned xoff, yoff; 3560 3561 if (x < 0) { 3562 xoff = ((-x) & 0xFE); 3563 x = 0; 3564 } else { 3565 xoff = 0; 3566 } 3567 3568 if (y < 0) { 3569 yoff = ((-y) & 0xFE); 3570 y = 0; 3571 } else { 3572 yoff = 0; 3573 } 3574 3575 switch(pVia->Chipset) { 3576 case VIA_PM800: 3577 case VIA_CX700: 3578 case VIA_P4M890: 3579 case VIA_P4M900: 3580 case VIA_VX800: 3581 case VIA_VX855: 3582 case VIA_VX900: 3583 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 3584 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 3585 break; 3586 3587 default: 3588 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 3589 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 3590 break; 3591 } 3592} 3593 3594static void 3595iga2_crtc_show_cursor(xf86CrtcPtr crtc) 3596{ 3597 drmmode_crtc_private_ptr iga = crtc->driver_private; 3598 ScrnInfoPtr pScrn = crtc->scrn; 3599 VIAPtr pVia = VIAPTR(pScrn); 3600 3601 switch(pVia->Chipset) { 3602 case VIA_PM800: 3603 case VIA_CX700: 3604 case VIA_P4M890: 3605 case VIA_P4M900: 3606 case VIA_VX800: 3607 case VIA_VX855: 3608 case VIA_VX900: 3609 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 3610 VIASETREG(HI_CONTROL, 0xB6000005); 3611 break; 3612 3613 default: 3614 /* Mono Cursor Display Path [bit31]: Secondary */ 3615 /* FIXME For CLE266 and KM400 try to enable 32x32 cursor size [bit1] */ 3616 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 3617 VIASETREG(HI_CONTROL, 0xF6000005); 3618 break; 3619 } 3620} 3621 3622static void 3623iga2_crtc_hide_cursor(xf86CrtcPtr crtc) 3624{ 3625 ScrnInfoPtr pScrn = crtc->scrn; 3626 VIAPtr pVia = VIAPTR(pScrn); 3627 CARD32 temp; 3628 3629 switch(pVia->Chipset) { 3630 case VIA_PM800: 3631 case VIA_CX700: 3632 case VIA_P4M890: 3633 case VIA_P4M900: 3634 case VIA_VX800: 3635 case VIA_VX855: 3636 case VIA_VX900: 3637 temp = VIAGETREG(HI_CONTROL); 3638 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 3639 break; 3640 3641 default: 3642 temp = VIAGETREG(HI_CONTROL); 3643 /* Hardware cursor disable [bit0] */ 3644 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 3645 break; 3646 } 3647} 3648 3649const xf86CrtcFuncsRec iga2_crtc_funcs = { 3650 .dpms = iga2_crtc_dpms, 3651 .save = iga2_crtc_save, 3652 .restore = iga2_crtc_restore, 3653 .lock = iga2_crtc_lock, 3654 .unlock = iga2_crtc_unlock, 3655 .mode_fixup = iga2_crtc_mode_fixup, 3656 .prepare = iga2_crtc_prepare, 3657 .mode_set = iga2_crtc_mode_set, 3658 .commit = iga_crtc_commit, 3659 .gamma_set = iga2_crtc_gamma_set, 3660 .shadow_create = iga2_crtc_shadow_create, 3661 .shadow_allocate = iga2_crtc_shadow_allocate, 3662 .shadow_destroy = iga2_crtc_shadow_destroy, 3663 .set_cursor_colors = iga2_crtc_set_cursor_colors, 3664 .set_cursor_position = iga2_crtc_set_cursor_position, 3665 .show_cursor = iga2_crtc_show_cursor, 3666 .hide_cursor = iga2_crtc_hide_cursor, 3667 .load_cursor_argb = iga_crtc_load_cursor_argb, 3668#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) > 2 3669 .set_origin = iga2_crtc_set_origin, 3670#endif 3671 .destroy = iga_crtc_destroy, 3672}; 3673