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