via_display.c revision 90b17f1b
1/* 2 * Copyright 2005-2011 The Openchrome Project [openchrome.org] 3 * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] 4 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 5 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sub license, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 */ 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "via_driver.h" 31 32/* 33 * Enables the second display channel. 34 */ 35void 36ViaSecondDisplayChannelEnable(ScrnInfoPtr pScrn) 37{ 38 vgaHWPtr hwp = VGAHWPTR(pScrn); 39 40 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 41 "ViaSecondDisplayChannelEnable\n")); 42 ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 6); 43 ViaCrtcMask(hwp, 0x6A, 1 << 7, 1 << 7); 44 ViaCrtcMask(hwp, 0x6A, 1 << 6, 1 << 6); 45} 46 47/* 48 * Disables the second display channel. 49 */ 50void 51ViaSecondDisplayChannelDisable(ScrnInfoPtr pScrn) 52{ 53 vgaHWPtr hwp = VGAHWPTR(pScrn); 54 55 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 56 "ViaSecondDisplayChannelDisable\n")); 57 58 ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 6); 59 ViaCrtcMask(hwp, 0x6A, 0x00, 1 << 7); 60 ViaCrtcMask(hwp, 0x6A, 1 << 6, 1 << 6); 61} 62 63/* 64 * Initial settings for displays. 65 */ 66void 67ViaDisplayInit(ScrnInfoPtr pScrn) 68{ 69 VIAPtr pVia = VIAPTR(pScrn); 70 vgaHWPtr hwp = VGAHWPTR(pScrn); 71 72 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayInit\n")); 73 74 ViaSecondDisplayChannelDisable(pScrn); 75 ViaCrtcMask(hwp, 0x6A, 0x00, 0x3D); 76 77 hwp->writeCrtc(hwp, 0x6B, 0x00); 78 hwp->writeCrtc(hwp, 0x6C, 0x00); 79 hwp->writeCrtc(hwp, 0x79, 0x00); 80 81 /* (IGA1 Timing Plus 2, added in VT3259 A3 or later) */ 82 if (pVia->Chipset != VIA_CLE266 && pVia->Chipset != VIA_KM400) 83 ViaCrtcMask(hwp, 0x47, 0x00, 0xC8); 84} 85 86/* 87 * Enables simultaneous mode. 88 */ 89void 90ViaDisplayEnableSimultaneous(ScrnInfoPtr pScrn) 91{ 92 vgaHWPtr hwp = VGAHWPTR(pScrn); 93 94 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 95 "ViaDisplayEnableSimultaneous\n")); 96 ViaCrtcMask(hwp, 0x6B, 0x08, 0x08); 97} 98 99/* 100 * Disables simultaneous mode. 101 */ 102void 103ViaDisplayDisableSimultaneous(ScrnInfoPtr pScrn) 104{ 105 vgaHWPtr hwp = VGAHWPTR(pScrn); 106 107 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 108 "ViaDisplayDisableSimultaneous\n")); 109 ViaCrtcMask(hwp, 0x6B, 0x00, 0x08); 110} 111 112/* 113 * Sets the primary or secondary display stream on internal TMDS. 114 */ 115void 116ViaDisplaySetStreamOnDFP(ScrnInfoPtr pScrn, Bool primary) 117{ 118 vgaHWPtr hwp = VGAHWPTR(pScrn); 119 120 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnDFP\n")); 121 122 if (primary) 123 ViaCrtcMask(hwp, 0x99, 0x00, 0x10); 124 else 125 ViaCrtcMask(hwp, 0x99, 0x10, 0x10); 126} 127 128static void 129ViaCRTCSetGraphicsRegisters(ScrnInfoPtr pScrn) 130{ 131 vgaHWPtr hwp = VGAHWPTR(pScrn); 132 133 /* graphics registers */ 134 hwp->writeGr(hwp, 0x00, 0x00); 135 hwp->writeGr(hwp, 0x01, 0x00); 136 hwp->writeGr(hwp, 0x02, 0x00); 137 hwp->writeGr(hwp, 0x03, 0x00); 138 hwp->writeGr(hwp, 0x04, 0x00); 139 hwp->writeGr(hwp, 0x05, 0x40); 140 hwp->writeGr(hwp, 0x06, 0x05); 141 hwp->writeGr(hwp, 0x07, 0x0F); 142 hwp->writeGr(hwp, 0x08, 0xFF); 143 144 ViaGrMask(hwp, 0x20, 0, 0xFF); 145 ViaGrMask(hwp, 0x21, 0, 0xFF); 146 ViaGrMask(hwp, 0x22, 0, 0xFF); 147} 148 149static void 150ViaCRTCSetAttributeRegisters(ScrnInfoPtr pScrn) 151{ 152 vgaHWPtr hwp = VGAHWPTR(pScrn); 153 CARD8 i; 154 155 /* attribute registers */ 156 for (i = 0; i <= 0xF; i++) { 157 hwp->writeAttr(hwp, i, i); 158 } 159 hwp->writeAttr(hwp, 0x10, 0x41); 160 hwp->writeAttr(hwp, 0x11, 0xFF); 161 hwp->writeAttr(hwp, 0x12, 0x0F); 162 hwp->writeAttr(hwp, 0x13, 0x00); 163 hwp->writeAttr(hwp, 0x14, 0x00); 164} 165 166void 167VIALoadRgbLut(ScrnInfoPtr pScrn, int start, int numColors, LOCO *colors) 168{ 169 vgaHWPtr hwp = VGAHWPTR(pScrn); 170 int i, j; 171 172 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadRgbLut\n")); 173 174 hwp->enablePalette(hwp); 175 hwp->writeDacMask(hwp, 0xFF); 176 177 /* We need the same palette contents for both 16 and 24 bits, but X doesn't 178 * play: X's colormap handling is hopelessly intertwined with almost every 179 * X subsystem. So we just space out RGB values over the 256*3. */ 180 181 switch (pScrn->bitsPerPixel) { 182 case 16: 183 for (i = start; i < numColors; i++) { 184 hwp->writeDacWriteAddr(hwp, i * 4); 185 for (j = 0; j < 4; j++) { 186 hwp->writeDacData(hwp, colors[i / 2].red); 187 hwp->writeDacData(hwp, colors[i].green); 188 hwp->writeDacData(hwp, colors[i / 2].blue); 189 } 190 } 191 break; 192 case 8: 193 case 24: 194 case 32: 195 for (i = start; i < numColors; i++) { 196 hwp->writeDacWriteAddr(hwp, i); 197 hwp->writeDacData(hwp, colors[i].red); 198 hwp->writeDacData(hwp, colors[i].green); 199 hwp->writeDacData(hwp, colors[i].blue); 200 } 201 break; 202 default: 203 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 204 "Unsupported bitdepth: %d\n", pScrn->bitsPerPixel); 205 break; 206 } 207 hwp->disablePalette(hwp); 208} 209 210void 211ViaGammaDisable(ScrnInfoPtr pScrn) 212{ 213 VIAPtr pVia = VIAPTR(pScrn); 214 vgaHWPtr hwp = VGAHWPTR(pScrn); 215 216 switch (pVia->Chipset) { 217 case VIA_CLE266: 218 case VIA_KM400: 219 ViaSeqMask(hwp, 0x16, 0x00, 0x80); 220 break; 221 default: 222 ViaCrtcMask(hwp, 0x33, 0x00, 0x80); 223 break; 224 } 225 226 /* Disable gamma on secondary */ 227 /* This is needed or the hardware will lockup */ 228 ViaSeqMask(hwp, 0x1A, 0x00, 0x01); 229 ViaCrtcMask(hwp, 0x6A, 0x00, 0x02); 230 switch (pVia->Chipset) { 231 case VIA_CLE266: 232 case VIA_KM400: 233 case VIA_K8M800: 234 case VIA_PM800: 235 break; 236 default: 237 ViaCrtcMask(hwp, 0x6A, 0x00, 0x20); 238 break; 239 } 240} 241 242void 243ViaCRTCInit(ScrnInfoPtr pScrn) 244{ 245 vgaHWPtr hwp = VGAHWPTR(pScrn); 246 247 hwp->writeSeq(hwp, 0x10, 0x01); /* unlock extended registers */ 248 ViaCrtcMask(hwp, 0x47, 0x00, 0x01); /* unlock CRT registers */ 249 ViaCRTCSetGraphicsRegisters(pScrn); 250 ViaCRTCSetAttributeRegisters(pScrn); 251} 252 253void 254ViaFirstCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 255{ 256 vgaHWPtr hwp = VGAHWPTR(pScrn); 257 VIAPtr pVia = VIAPTR(pScrn); 258 CARD16 temp; 259 260 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetMode\n")); 261 262 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up %s\n", mode->name)); 263 264 ViaCrtcMask(hwp, 0x11, 0x00, 0x80); /* modify starting address */ 265 ViaCrtcMask(hwp, 0x03, 0x80, 0x80); /* enable vertical retrace access */ 266 267 /* Set Misc Register */ 268 temp = 0x23; 269 if (mode->Flags & V_NHSYNC) 270 temp |= 0x40; 271 if (mode->Flags & V_NVSYNC) 272 temp |= 0x80; 273 temp |= 0x0C; /* Undefined/external clock */ 274 hwp->writeMiscOut(hwp, temp); 275 276 /* Sequence registers */ 277 hwp->writeSeq(hwp, 0x00, 0x00); 278 279#if 0 280 if (mode->Flags & V_CLKDIV2) 281 hwp->writeSeq(hwp, 0x01, 0x09); 282 else 283#endif 284 hwp->writeSeq(hwp, 0x01, 0x01); 285 286 hwp->writeSeq(hwp, 0x02, 0x0F); 287 hwp->writeSeq(hwp, 0x03, 0x00); 288 hwp->writeSeq(hwp, 0x04, 0x0E); 289 290 ViaSeqMask(hwp, 0x15, 0x02, 0x02); 291 292 /* bpp */ 293 switch (pScrn->bitsPerPixel) { 294 case 8: 295 /* Only CLE266.AX use 6bits LUT. */ 296 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev < 15) 297 ViaSeqMask(hwp, 0x15, 0x22, 0xFE); 298 else 299 ViaSeqMask(hwp, 0x15, 0xA2, 0xFE); 300 break; 301 case 16: 302 ViaSeqMask(hwp, 0x15, 0xB6, 0xFE); 303 break; 304 case 24: 305 case 32: 306 ViaSeqMask(hwp, 0x15, 0xAE, 0xFE); 307 break; 308 default: 309 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n", 310 pScrn->bitsPerPixel); 311 break; 312 } 313 314 switch (pVia->ChipId) { 315 case VIA_K8M890: 316 case VIA_CX700: 317 case VIA_P4M900: 318 case VIA_VX800: 319 case VIA_VX855: 320 case VIA_VX900: 321 break; 322 default: 323 ViaSeqMask(hwp, 0x16, 0x08, 0xBF); 324 ViaSeqMask(hwp, 0x17, 0x1F, 0xFF); 325 ViaSeqMask(hwp, 0x18, 0x4E, 0xFF); 326 ViaSeqMask(hwp, 0x1A, 0x08, 0xFD); 327 break; 328 } 329 330 /* Crtc registers */ 331 /* horizontal total : 4100 */ 332 temp = (mode->CrtcHTotal >> 3) - 5; 333 hwp->writeCrtc(hwp, 0x00, temp & 0xFF); 334 ViaCrtcMask(hwp, 0x36, temp >> 5, 0x08); 335 336 /* horizontal address : 2048 */ 337 temp = (mode->CrtcHDisplay >> 3) - 1; 338 hwp->writeCrtc(hwp, 0x01, temp & 0xFF); 339 340 /* horizontal blanking start : 2048 */ 341 /* temp = (mode->CrtcHDisplay >> 3) - 1; */ 342 temp = (mode->CrtcHBlankStart >> 3) - 1; 343 hwp->writeCrtc(hwp, 0x02, temp & 0xFF); 344 /* If HblankStart has more bits anywhere, add them here */ 345 346 /* horizontal blanking end : start + 1025 */ 347 /* temp = (mode->CrtcHTotal >> 3) - 1; */ 348 temp = (mode->CrtcHBlankEnd >> 3) - 1; 349 ViaCrtcMask(hwp, 0x03, temp, 0x1F); 350 ViaCrtcMask(hwp, 0x05, temp << 2, 0x80); 351 ViaCrtcMask(hwp, 0x33, temp >> 1, 0x20); 352 353 /* CrtcHSkew ??? */ 354 355 /* horizontal sync start : 4095 */ 356 temp = mode->CrtcHSyncStart >> 3; 357 hwp->writeCrtc(hwp, 0x04, temp & 0xFF); 358 ViaCrtcMask(hwp, 0x33, temp >> 4, 0x10); 359 360 /* horizontal sync end : start + 256 */ 361 temp = mode->CrtcHSyncEnd >> 3; 362 ViaCrtcMask(hwp, 0x05, temp, 0x1F); 363 364 /* vertical total : 2049 */ 365 temp = mode->CrtcVTotal - 2; 366 hwp->writeCrtc(hwp, 0x06, temp & 0xFF); 367 ViaCrtcMask(hwp, 0x07, temp >> 8, 0x01); 368 ViaCrtcMask(hwp, 0x07, temp >> 4, 0x20); 369 ViaCrtcMask(hwp, 0x35, temp >> 10, 0x01); 370 371 /* vertical address : 2048 */ 372 temp = mode->CrtcVDisplay - 1; 373 hwp->writeCrtc(hwp, 0x12, temp & 0xFF); 374 ViaCrtcMask(hwp, 0x07, temp >> 7, 0x02); 375 ViaCrtcMask(hwp, 0x07, temp >> 3, 0x40); 376 ViaCrtcMask(hwp, 0x35, temp >> 8, 0x04); 377 378 /* Primary starting address -> 0x00, adjustframe does the rest */ 379 hwp->writeCrtc(hwp, 0x0C, 0x00); 380 hwp->writeCrtc(hwp, 0x0D, 0x00); 381 ViaCrtcMask(hwp, 0x48, 0x00, 0x03); /* is this even possible on CLE266A ? */ 382 hwp->writeCrtc(hwp, 0x34, 0x00); 383 384 /* vertical sync start : 2047 */ 385 temp = mode->CrtcVSyncStart; 386 hwp->writeCrtc(hwp, 0x10, temp & 0xFF); 387 ViaCrtcMask(hwp, 0x07, temp >> 6, 0x04); 388 ViaCrtcMask(hwp, 0x07, temp >> 2, 0x80); 389 ViaCrtcMask(hwp, 0x35, temp >> 9, 0x02); 390 391 /* vertical sync end : start + 16 -- other bits someplace? */ 392 ViaCrtcMask(hwp, 0x11, mode->CrtcVSyncEnd, 0x0F); 393 394 /* line compare: We are not doing splitscreen so 0x3FFF */ 395 hwp->writeCrtc(hwp, 0x18, 0xFF); 396 ViaCrtcMask(hwp, 0x07, 0x10, 0x10); 397 ViaCrtcMask(hwp, 0x09, 0x40, 0x40); 398 ViaCrtcMask(hwp, 0x33, 0x06, 0x07); 399 ViaCrtcMask(hwp, 0x35, 0x10, 0x10); 400 401 /* zero Maximum scan line */ 402 ViaCrtcMask(hwp, 0x09, 0x00, 0x1F); 403 hwp->writeCrtc(hwp, 0x14, 0x00); 404 405 /* vertical blanking start : 2048 */ 406 /* temp = mode->CrtcVDisplay - 1; */ 407 temp = mode->CrtcVBlankStart - 1; 408 hwp->writeCrtc(hwp, 0x15, temp & 0xFF); 409 ViaCrtcMask(hwp, 0x07, temp >> 5, 0x08); 410 ViaCrtcMask(hwp, 0x09, temp >> 4, 0x20); 411 ViaCrtcMask(hwp, 0x35, temp >> 7, 0x08); 412 413 /* vertical blanking end : start + 257 */ 414 /* temp = mode->CrtcVTotal - 1; */ 415 temp = mode->CrtcVBlankEnd - 1; 416 hwp->writeCrtc(hwp, 0x16, temp); 417 418 /* FIXME: check if this is really necessary here */ 419 switch (pVia->ChipId) { 420 case VIA_K8M890: 421 case VIA_CX700: 422 case VIA_P4M900: 423 case VIA_VX800: 424 case VIA_VX855: 425 case VIA_VX900: 426 break; 427 default: 428 /* some leftovers */ 429 hwp->writeCrtc(hwp, 0x08, 0x00); 430 ViaCrtcMask(hwp, 0x32, 0, 0xFF); /* ? */ 431 ViaCrtcMask(hwp, 0x33, 0, 0xC8); 432 break; 433 } 434 435 /* offset */ 436 temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; 437 /* Make sure that this is 32-byte aligned. */ 438 if (temp & 0x03) { 439 temp += 0x03; 440 temp &= ~0x03; 441 } 442 hwp->writeCrtc(hwp, 0x13, temp & 0xFF); 443 ViaCrtcMask(hwp, 0x35, temp >> 3, 0xE0); 444 445 /* fetch count */ 446 temp = (mode->CrtcHDisplay * (pScrn->bitsPerPixel >> 3)) >> 3; 447 /* Make sure that this is 32-byte aligned. */ 448 if (temp & 0x03) { 449 temp += 0x03; 450 temp &= ~0x03; 451 } 452 453 hwp->writeSeq(hwp, 0x1C, ((temp >> 1)+1) & 0xFF); 454 ViaSeqMask(hwp, 0x1D, temp >> 9, 0x03); 455 456 switch (pVia->ChipId) { 457 case VIA_K8M890: 458 case VIA_CX700: 459 case VIA_P4M900: 460 case VIA_VX800: 461 case VIA_VX855: 462 case VIA_VX900: 463 break; 464 default: 465 /* some leftovers */ 466 ViaCrtcMask(hwp, 0x32, 0, 0xFF); 467 ViaCrtcMask(hwp, 0x33, 0, 0xC8); 468 break; 469 } 470} 471 472void 473ViaFirstCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y) 474{ 475 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 476 drmmode_ptr drmmode = drmmode_crtc->drmmode; 477 ScrnInfoPtr pScrn = crtc->scrn; 478 VIAPtr pVia = VIAPTR(pScrn); 479 vgaHWPtr hwp = VGAHWPTR(pScrn); 480 CARD32 Base; 481 482 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCSetStartingAddress\n")); 483 484 Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); 485 Base = (Base + drmmode->front_bo->offset) >> 1; 486 487 hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8); 488 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 489 /* FIXME The proper starting address for CR48 is 0x1F - Bits[28:24] */ 490 if (!(pVia->Chipset == VIA_CLE266 && CLE266_REV_IS_AX(pVia->ChipRev))) 491 ViaCrtcMask(hwp, 0x48, Base >> 24, 0x0F); 492 /* CR34 are fire bits. Must be written after CR0C CR0D CR48. */ 493 hwp->writeCrtc(hwp, 0x34, (Base & 0xFF0000) >> 16); 494} 495 496void 497ViaSecondCRTCSetStartingAddress(xf86CrtcPtr crtc, int x, int y) 498{ 499 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 500 drmmode_ptr drmmode = drmmode_crtc->drmmode; 501 ScrnInfoPtr pScrn = crtc->scrn; 502 vgaHWPtr hwp = VGAHWPTR(pScrn); 503 CARD32 Base, tmp; 504 505 Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); 506 Base = (Base + drmmode->front_bo->offset) >> 3; 507 508 tmp = hwp->readCrtc(hwp, 0x62) & 0x01; 509 tmp |= (Base & 0x7F) << 1; 510 hwp->writeCrtc(hwp, 0x62, tmp); 511 512 hwp->writeCrtc(hwp, 0x63, (Base & 0x7F80) >> 7); 513 hwp->writeCrtc(hwp, 0x64, (Base & 0x7F8000) >> 15); 514 hwp->writeCrtc(hwp, 0xA3, (Base & 0x03800000) >> 23); 515} 516 517void 518ViaSecondCRTCHorizontalQWCount(ScrnInfoPtr pScrn, int width) 519{ 520 vgaHWPtr hwp = VGAHWPTR(pScrn); 521 CARD16 temp; 522 523 /* fetch count */ 524 temp = (width * (pScrn->bitsPerPixel >> 3)) >> 3; 525 /* Make sure that this is 32-byte aligned. */ 526 if (temp & 0x03) { 527 temp += 0x03; 528 temp &= ~0x03; 529 } 530 hwp->writeCrtc(hwp, 0x65, (temp >> 1) & 0xFF); 531 ViaCrtcMask(hwp, 0x67, temp >> 7, 0x0C); 532} 533 534void 535ViaSecondCRTCHorizontalOffset(ScrnInfoPtr pScrn) 536{ 537 vgaHWPtr hwp = VGAHWPTR(pScrn); 538 CARD16 temp; 539 540 /* offset */ 541 temp = (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)) >> 3; 542 /* Make sure that this is 32-byte aligned. */ 543 if (temp & 0x03) { 544 temp += 0x03; 545 temp &= ~0x03; 546 } 547 548 hwp->writeCrtc(hwp, 0x66, temp & 0xFF); 549 ViaCrtcMask(hwp, 0x67, temp >> 8, 0x03); 550} 551 552void 553ViaSecondCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 554{ 555 VIAPtr pVia = VIAPTR(pScrn); 556 vgaHWPtr hwp = VGAHWPTR(pScrn); 557 CARD16 temp; 558 559 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode: %p\n", mode); 560 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode->name: %p\n", mode->name); 561 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "mode->name: %s\n", mode->name); 562 563 564 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSecondCRTCSetMode\n")); 565 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up %s\n", mode->name)); 566 /* bpp */ 567 switch (pScrn->bitsPerPixel) { 568 case 8: 569 ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); 570 break; 571 case 16: 572 ViaCrtcMask(hwp, 0x67, 0x40, 0xC0); 573 break; 574 case 24: 575 case 32: 576 ViaCrtcMask(hwp, 0x67, 0xC0, 0xC0); 577 break; 578 default: 579 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled bitdepth: %d\n", 580 pScrn->bitsPerPixel); 581 break; 582 } 583 584 switch (pVia->ChipId) { 585 case VIA_K8M890: 586 case VIA_CX700: 587 case VIA_P4M900: 588 case VIA_VX800: 589 case VIA_VX855: 590 case VIA_VX900: 591 break; 592 default: 593 ViaSeqMask(hwp, 0x16, 0x08, 0xBF); 594 ViaSeqMask(hwp, 0x17, 0x1F, 0xFF); 595 ViaSeqMask(hwp, 0x18, 0x4E, 0xFF); 596 ViaSeqMask(hwp, 0x1A, 0x08, 0xFD); 597 break; 598 } 599 600 /* Crtc registers */ 601 /* horizontal total : 4096 */ 602 temp = mode->CrtcHTotal - 1; 603 hwp->writeCrtc(hwp, 0x50, temp & 0xFF); 604 ViaCrtcMask(hwp, 0x55, temp >> 8, 0x0F); 605 606 /* horizontal address : 2048 */ 607 temp = mode->CrtcHDisplay - 1; 608 hwp->writeCrtc(hwp, 0x51, temp & 0xFF); 609 ViaCrtcMask(hwp, 0x55, temp >> 4, 0x70); 610 611 /* horizontal blanking start : 2048 */ 612 /* temp = mode->CrtcHDisplay - 1; */ 613 temp = mode->CrtcHBlankStart - 1; 614 hwp->writeCrtc(hwp, 0x52, temp & 0xFF); 615 ViaCrtcMask(hwp, 0x54, temp >> 8, 0x07); 616 617 /* horizontal blanking end : 4096 */ 618 /* temp = mode->CrtcHTotal - 1; */ 619 temp = mode->CrtcHBlankEnd - 1; 620 hwp->writeCrtc(hwp, 0x53, temp & 0xFF); 621 ViaCrtcMask(hwp, 0x54, temp >> 5, 0x38); 622 ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x40); 623 624 /* horizontal sync start : 2047 */ 625 temp = mode->CrtcHSyncStart; 626 hwp->writeCrtc(hwp, 0x56, temp & 0xFF); 627 ViaCrtcMask(hwp, 0x54, temp >> 2, 0xC0); 628 ViaCrtcMask(hwp, 0x5C, temp >> 3, 0x80); 629 630 if (pVia->ChipId != VIA_CLE266 && pVia->ChipId != VIA_KM400) 631 ViaCrtcMask(hwp, 0x5D, temp >> 4, 0x80); 632 633 /* horizontal sync end : sync start + 512 */ 634 temp = mode->CrtcHSyncEnd; 635 hwp->writeCrtc(hwp, 0x57, temp & 0xFF); 636 ViaCrtcMask(hwp, 0x5C, temp >> 2, 0x40); 637 638 /* vertical total : 2048 */ 639 temp = mode->CrtcVTotal - 1; 640 hwp->writeCrtc(hwp, 0x58, temp & 0xFF); 641 ViaCrtcMask(hwp, 0x5D, temp >> 8, 0x07); 642 643 644 /* vertical address : 2048 */ 645 temp = mode->CrtcVDisplay - 1; 646 hwp->writeCrtc(hwp, 0x59, temp & 0xFF); 647 ViaCrtcMask(hwp, 0x5D, temp >> 5, 0x38); 648 649 /* vertical blanking start : 2048 */ 650 /* temp = mode->CrtcVDisplay - 1; */ 651 temp = mode->CrtcVBlankStart - 1; 652 hwp->writeCrtc(hwp, 0x5A, temp & 0xFF); 653 ViaCrtcMask(hwp, 0x5C, temp >> 8, 0x07); 654 655 /* vertical blanking end : 2048 */ 656 /* temp = mode->CrtcVTotal - 1; */ 657 temp = mode->CrtcVBlankEnd - 1; 658 hwp->writeCrtc(hwp, 0x5B, temp & 0xFF); 659 ViaCrtcMask(hwp, 0x5C, temp >> 5, 0x38); 660 661 /* vertical sync start : 2047 */ 662 temp = mode->CrtcVSyncStart; 663 hwp->writeCrtc(hwp, 0x5E, temp & 0xFF); 664 ViaCrtcMask(hwp, 0x5F, temp >> 3, 0xE0); 665 666 /* vertical sync end : start + 32 */ 667 temp = mode->CrtcVSyncEnd; 668 ViaCrtcMask(hwp, 0x5F, temp, 0x1F); 669 670 switch (pVia->ChipId) { 671 case VIA_K8M890: 672 case VIA_CX700: 673 case VIA_P4M900: 674 case VIA_VX800: 675 case VIA_VX855: 676 case VIA_VX900: 677 break; 678 default: 679 /* some leftovers */ 680 hwp->writeCrtc(hwp, 0x08, 0x00); 681 ViaCrtcMask(hwp, 0x32, 0, 0xFF); /* ? */ 682 ViaCrtcMask(hwp, 0x33, 0, 0xC8); 683 break; 684 } 685 686 ViaSecondCRTCHorizontalOffset(pScrn); 687 ViaSecondCRTCHorizontalQWCount(pScrn, mode->CrtcHDisplay); 688} 689 690/* 691 * Checks for limitations imposed by the available VGA timing registers. 692 */ 693static ModeStatus 694ViaFirstCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 695{ 696 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaFirstCRTCModeValid\n")); 697 698 if (mode->CrtcHTotal > 4100) 699 return MODE_BAD_HVALUE; 700 701 if (mode->CrtcHDisplay > 2048) 702 return MODE_BAD_HVALUE; 703 704 if (mode->CrtcHBlankStart > 2048) 705 return MODE_BAD_HVALUE; 706 707 if ((mode->CrtcHBlankEnd - mode->CrtcHBlankStart) > 1025) 708 return MODE_HBLANK_WIDE; 709 710 if (mode->CrtcHSyncStart > 4095) 711 return MODE_BAD_HVALUE; 712 713 if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 256) 714 return MODE_HSYNC_WIDE; 715 716 if (mode->CrtcVTotal > 2049) 717 return MODE_BAD_VVALUE; 718 719 if (mode->CrtcVDisplay > 2048) 720 return MODE_BAD_VVALUE; 721 722 if (mode->CrtcVSyncStart > 2047) 723 return MODE_BAD_VVALUE; 724 725 if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 16) 726 return MODE_VSYNC_WIDE; 727 728 if (mode->CrtcVBlankStart > 2048) 729 return MODE_BAD_VVALUE; 730 731 if ((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) > 257) 732 return MODE_VBLANK_WIDE; 733 734 return MODE_OK; 735} 736 737static ModeStatus 738ViaSecondCRTCModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) 739{ 740 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSecondCRTCModeValid\n")); 741 742 if (mode->CrtcHTotal > 4096) 743 return MODE_BAD_HVALUE; 744 745 if (mode->CrtcHDisplay > 2048) 746 return MODE_BAD_HVALUE; 747 748 if (mode->CrtcHBlankStart > 2048) 749 return MODE_BAD_HVALUE; 750 751 if (mode->CrtcHBlankEnd > 4096) 752 return MODE_HBLANK_WIDE; 753 754 if (mode->CrtcHSyncStart > 2047) 755 return MODE_BAD_HVALUE; 756 757 if ((mode->CrtcHSyncEnd - mode->CrtcHSyncStart) > 512) 758 return MODE_HSYNC_WIDE; 759 760 if (mode->CrtcVTotal > 2048) 761 return MODE_BAD_VVALUE; 762 763 if (mode->CrtcVDisplay > 2048) 764 return MODE_BAD_VVALUE; 765 766 if (mode->CrtcVBlankStart > 2048) 767 return MODE_BAD_VVALUE; 768 769 if (mode->CrtcVBlankEnd > 2048) 770 return MODE_VBLANK_WIDE; 771 772 if (mode->CrtcVSyncStart > 2047) 773 return MODE_BAD_VVALUE; 774 775 if ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) > 32) 776 return MODE_VSYNC_WIDE; 777 778 return MODE_OK; 779} 780 781/* 782 * Not tested yet 783 */ 784void 785ViaShadowCRTCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 786{ 787 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaShadowCRTCSetMode\n")); 788 789 vgaHWPtr hwp = VGAHWPTR(pScrn); 790 CARD16 temp; 791 792 temp = (mode->CrtcHTotal >> 3) - 5; 793 hwp->writeCrtc(hwp, 0x6D, temp & 0xFF); 794 ViaCrtcMask(hwp, 0x71, temp >> 5, 0x08); 795 796 temp = (mode->CrtcHBlankEnd >> 3) - 1; 797 hwp->writeCrtc(hwp, 0x6E, temp & 0xFF); 798 799 temp = mode->CrtcVTotal - 2; 800 hwp->writeCrtc(hwp, 0x6F, temp & 0xFF); 801 ViaCrtcMask(hwp, 0x71, temp >> 8, 0x07); 802 803 temp = mode->CrtcVDisplay - 1; 804 hwp->writeCrtc(hwp, 0x70, temp & 0xFF); 805 ViaCrtcMask(hwp, 0x71, temp >> 4, 0x70); 806 807 temp = mode->CrtcVBlankStart - 1; 808 hwp->writeCrtc(hwp, 0x72, temp & 0xFF); 809 ViaCrtcMask(hwp, 0x74, temp >> 4, 0x70); 810 811 temp = mode->CrtcVTotal - 1; 812 hwp->writeCrtc(hwp, 0x73, temp & 0xFF); 813 ViaCrtcMask(hwp, 0x74, temp >> 8, 0x07); 814 815 ViaCrtcMask(hwp, 0x76, mode->CrtcVSyncEnd, 0x0F); 816 817 temp = mode->CrtcVSyncStart; 818 hwp->writeCrtc(hwp, 0x75, temp & 0xFF); 819 ViaCrtcMask(hwp, 0x76, temp >> 4, 0x70); 820} 821 822static void 823iga1_crtc_dpms(xf86CrtcPtr crtc, int mode) 824{ 825 ScrnInfoPtr pScrn = crtc->scrn; 826 VIAPtr pVia = VIAPTR(pScrn); 827 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 828 829 if (pVia->pVbe) { 830 ViaVbeDPMS(pScrn, mode); 831 } else { 832 switch (mode) { 833 case DPMSModeOn: 834 if (pBIOSInfo->SimultaneousEnabled) 835 ViaDisplayEnableSimultaneous(pScrn); 836 break; 837 838 case DPMSModeStandby: 839 case DPMSModeSuspend: 840 case DPMSModeOff: 841 if (pBIOSInfo->SimultaneousEnabled) 842 ViaDisplayDisableSimultaneous(pScrn); 843 break; 844 845 default: 846 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", 847 mode); 848 break; 849 } 850 //vgaHWSaveScreen(pScrn->pScreen, mode); 851 } 852} 853 854static void 855iga1_crtc_save(xf86CrtcPtr crtc) 856{ 857 ScrnInfoPtr pScrn = crtc->scrn; 858 vgaHWPtr hwp = VGAHWPTR(pScrn); 859 VIAPtr pVia = VIAPTR(pScrn); 860 861 if (pVia->pVbe && pVia->vbeSR) { 862 ViaVbeSaveRestore(pScrn, MODE_SAVE); 863 } else { 864 VIASave(pScrn); 865 } 866 867 vgaHWUnlock(hwp); 868} 869 870static void 871iga1_crtc_restore(xf86CrtcPtr crtc) 872{ 873 ScrnInfoPtr pScrn = crtc->scrn; 874 vgaHWPtr hwp = VGAHWPTR(pScrn); 875 VIAPtr pVia = VIAPTR(pScrn); 876 877 if (pVia->pVbe && pVia->vbeSR) 878 ViaVbeSaveRestore(pScrn, MODE_RESTORE); 879 else 880 VIARestore(pScrn); 881 882 /* A soft reset helps to avoid a 3D hang on VT switch. */ 883 switch (pVia->Chipset) { 884 case VIA_K8M890: 885 case VIA_P4M900: 886 case VIA_VX800: 887 case VIA_VX855: 888 case VIA_VX900: 889 break; 890 891 default: 892 hwp->writeSeq(hwp, 0x1A, pVia->SavedReg.SR1A | 0x40); 893 break; 894 } 895 vgaHWLock(hwp); 896} 897 898static Bool 899iga1_crtc_lock(xf86CrtcPtr crtc) 900{ 901 return FALSE; 902} 903 904static void 905iga1_crtc_unlock(xf86CrtcPtr crtc) 906{ 907} 908 909static Bool 910iga1_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 911 DisplayModePtr adjusted_mode) 912{ 913 ScrnInfoPtr pScrn = crtc->scrn; 914 VIAPtr pVia = VIAPTR(pScrn); 915 CARD32 temp; 916 ModeStatus modestatus; 917 918 if (pVia->pVbe) 919 return TRUE; 920 921 if ((mode->Clock < pScrn->clockRanges->minClock) || 922 (mode->Clock > pScrn->clockRanges->maxClock)) { 923 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 924 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 925 mode->name, mode->Clock, pScrn->clockRanges->minClock, 926 pScrn->clockRanges->maxClock); 927 return FALSE; 928 } 929 930 modestatus = ViaFirstCRTCModeValid(pScrn, mode); 931 if (modestatus != MODE_OK) { 932 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 933 mode->name, xf86ModeStatusToString(modestatus)); 934 return FALSE; 935 } 936 937 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 938 (pScrn->bitsPerPixel >> 3); 939 if (pVia->pBIOSInfo->Bandwidth < temp) { 940 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 941 "Required bandwidth is not available. (%u > %u)\n", 942 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 943 return FALSE; 944 } 945 return TRUE; 946} 947 948static void 949iga1_crtc_prepare (xf86CrtcPtr crtc) 950{ 951} 952 953static void 954iga1_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 955{ 956 ScrnInfoPtr pScrn = crtc->scrn; 957 VIAPtr pVia = VIAPTR(pScrn); 958 959 if (pVia->pVbe) { 960 ViaVbeAdjustFrame(pScrn, x, y); 961 } else { 962 ViaFirstCRTCSetStartingAddress(crtc, x, y); 963 } 964 VIAVidAdjustFrame(pScrn, x, y); 965} 966 967static void 968iga1_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 969 DisplayModePtr adjusted_mode, 970 int x, int y) 971{ 972 ScrnInfoPtr pScrn = crtc->scrn; 973 VIAPtr pVia = VIAPTR(pScrn); 974 975 if (!pVia->pVbe) { 976 if (!vgaHWInit(pScrn, adjusted_mode)) 977 return; 978 979 if (pVia->UseLegacyModeSwitch) { 980 ViaModePrimaryLegacy(crtc, adjusted_mode); 981 } else { 982 ViaCRTCInit(pScrn); 983 ViaModeFirstCRTC(pScrn, adjusted_mode); 984 985 if (pVia->pBIOSInfo->SimultaneousEnabled) 986 ViaDisplayEnableSimultaneous(pScrn); 987 else 988 ViaDisplayDisableSimultaneous(pScrn); 989 } 990 } else { 991 if (!ViaVbeSetMode(pScrn, adjusted_mode)) 992 return; 993 } 994 iga1_crtc_set_origin(crtc, crtc->x, crtc->y); 995} 996 997static void 998iga1_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 999 int size) 1000{ 1001 ScrnInfoPtr pScrn = crtc->scrn; 1002 vgaHWPtr hwp = VGAHWPTR(pScrn); 1003 VIAPtr pVia = VIAPTR(pScrn); 1004 int SR1A, SR1B, CR67, CR6A; 1005 LOCO colors[size]; 1006 int i; 1007 1008 for (i = 0; i < size; i++) { 1009 colors[i].red = red[i] >> 8; 1010 colors[i].green = green[i] >> 8; 1011 colors[i].blue = blue[i] >> 8; 1012 } 1013 1014 if (pScrn->bitsPerPixel != 8) { 1015 switch (pVia->Chipset) { 1016 case VIA_CLE266: 1017 case VIA_KM400: 1018 ViaSeqMask(hwp, 0x16, 0x80, 0x80); 1019 break; 1020 default: 1021 ViaCrtcMask(hwp, 0x33, 0x80, 0x80); 1022 break; 1023 } 1024 1025 ViaSeqMask(hwp, 0x1A, 0x00, 0x01); 1026 VIALoadRgbLut(pScrn, 0, size, colors); 1027 1028 } else { 1029 1030 SR1A = hwp->readSeq(hwp, 0x1A); 1031 SR1B = hwp->readSeq(hwp, 0x1B); 1032 CR67 = hwp->readCrtc(hwp, 0x67); 1033 CR6A = hwp->readCrtc(hwp, 0x6A); 1034 1035 for (i = 0; i < size; i++) { 1036 hwp->writeDacWriteAddr(hwp, i); 1037 hwp->writeDacData(hwp, colors[i].red); 1038 hwp->writeDacData(hwp, colors[i].green); 1039 hwp->writeDacData(hwp, colors[i].blue); 1040 } 1041 } 1042} 1043 1044static void * 1045iga1_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 1046{ 1047 return NULL; 1048} 1049 1050static PixmapPtr 1051iga1_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 1052{ 1053 return NULL; 1054} 1055 1056static void 1057iga1_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 1058{ 1059} 1060 1061/* 1062 Set the cursor foreground and background colors. In 8bpp, fg and 1063 bg are indices into the current colormap unless the 1064 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 1065 and in all other bpps the fg and bg are in 8-8-8 RGB format. 1066*/ 1067static void 1068iga1_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) 1069{ 1070 ScrnInfoPtr pScrn = crtc->scrn; 1071 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1072 VIAPtr pVia = VIAPTR(pScrn); 1073 CARD32 temp; 1074 1075 if (xf86_config->cursor_fg) 1076 return; 1077 1078 /* Don't recolour the image if we don't have to. */ 1079 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 1080 return; 1081 1082 switch(pVia->Chipset) { 1083 case VIA_CX700: 1084 case VIA_P4M890: 1085 case VIA_P4M900: 1086 case VIA_VX800: 1087 case VIA_VX855: 1088 case VIA_VX900: 1089 temp = VIAGETREG(PRIM_HI_CTRL); 1090 VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFE); 1091 break; 1092 1093 default: 1094 temp = VIAGETREG(HI_CONTROL); 1095 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 1096 break; 1097 } 1098 1099 xf86_config->cursor_fg = fg; 1100 xf86_config->cursor_bg = bg; 1101} 1102 1103static void 1104iga1_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) 1105{ 1106 ScrnInfoPtr pScrn = crtc->scrn; 1107 VIAPtr pVia = VIAPTR(pScrn); 1108 unsigned xoff, yoff; 1109 1110 if (x < 0) { 1111 xoff = ((-x) & 0xFE); 1112 x = 0; 1113 } else { 1114 xoff = 0; 1115 } 1116 1117 if (y < 0) { 1118 yoff = ((-y) & 0xFE); 1119 y = 0; 1120 } else { 1121 yoff = 0; 1122 } 1123 1124 switch(pVia->Chipset) { 1125 case VIA_CX700: 1126 case VIA_P4M890: 1127 case VIA_P4M900: 1128 case VIA_VX800: 1129 case VIA_VX855: 1130 case VIA_VX900: 1131 VIASETREG(PRIM_HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1132 VIASETREG(PRIM_HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1133 break; 1134 1135 default: 1136 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1137 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1138 break; 1139 } 1140} 1141 1142static void 1143iga1_crtc_show_cursor (xf86CrtcPtr crtc) 1144{ 1145 drmmode_crtc_private_ptr iga = crtc->driver_private; 1146 ScrnInfoPtr pScrn = crtc->scrn; 1147 VIAPtr pVia = VIAPTR(pScrn); 1148 1149 switch(pVia->Chipset) { 1150 case VIA_CX700: 1151 case VIA_P4M890: 1152 case VIA_P4M900: 1153 case VIA_VX800: 1154 case VIA_VX855: 1155 case VIA_VX900: 1156 VIASETREG(PRIM_HI_FBOFFSET, iga->cursor_bo->offset); 1157 VIASETREG(PRIM_HI_CTRL, 0x36000005); 1158 break; 1159 1160 default: 1161 /* Mono Cursor Display Path [bit31]: Primary */ 1162 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 1163 VIASETREG(HI_CONTROL, 0x76000005); 1164 break; 1165 } 1166} 1167 1168static void 1169iga1_crtc_hide_cursor (xf86CrtcPtr crtc) 1170{ 1171 ScrnInfoPtr pScrn = crtc->scrn; 1172 VIAPtr pVia = VIAPTR(pScrn); 1173 CARD32 temp; 1174 1175 switch(pVia->Chipset) { 1176 case VIA_CX700: 1177 case VIA_P4M890: 1178 case VIA_P4M900: 1179 case VIA_VX800: 1180 case VIA_VX855: 1181 case VIA_VX900: 1182 temp = VIAGETREG(PRIM_HI_CTRL); 1183 VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFA); 1184 break; 1185 1186 default: 1187 temp = VIAGETREG(HI_CONTROL); 1188 /* Hardware cursor disable [bit0] */ 1189 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 1190 break; 1191 } 1192} 1193 1194static void 1195iga_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) 1196{ 1197 drmmode_crtc_private_ptr iga = crtc->driver_private; 1198 ScrnInfoPtr pScrn = crtc->scrn; 1199 void *dst; 1200 1201 dst = drm_bo_map(pScrn, iga->cursor_bo); 1202 memset(dst, 0x00, iga->cursor_bo->size); 1203 memcpy(dst, image, iga->cursor_bo->size); 1204 drm_bo_unmap(pScrn, iga->cursor_bo); 1205} 1206 1207static void 1208iga_crtc_commit(xf86CrtcPtr crtc) 1209{ 1210 ScrnInfoPtr pScrn = crtc->scrn; 1211 VIAPtr pVia = VIAPTR(pScrn); 1212 1213 if (crtc->scrn->pScreen != NULL && pVia->drmmode.hwcursor) 1214 xf86_reload_cursors(crtc->scrn->pScreen); 1215} 1216 1217static void 1218iga_crtc_destroy(xf86CrtcPtr crtc) 1219{ 1220 if (crtc->driver_private) 1221 free(crtc->driver_private); 1222} 1223 1224static const xf86CrtcFuncsRec iga1_crtc_funcs = { 1225 .dpms = iga1_crtc_dpms, 1226 .save = iga1_crtc_save, 1227 .restore = iga1_crtc_restore, 1228 .lock = iga1_crtc_lock, 1229 .unlock = iga1_crtc_unlock, 1230 .mode_fixup = iga1_crtc_mode_fixup, 1231 .prepare = iga1_crtc_prepare, 1232 .mode_set = iga1_crtc_mode_set, 1233 .commit = iga_crtc_commit, 1234 .gamma_set = iga1_crtc_gamma_set, 1235 .shadow_create = iga1_crtc_shadow_create, 1236 .shadow_allocate = iga1_crtc_shadow_allocate, 1237 .shadow_destroy = iga1_crtc_shadow_destroy, 1238 .set_cursor_colors = iga1_crtc_set_cursor_colors, 1239 .set_cursor_position = iga1_crtc_set_cursor_position, 1240 .show_cursor = iga1_crtc_show_cursor, 1241 .hide_cursor = iga1_crtc_hide_cursor, 1242 .load_cursor_argb = iga_crtc_load_cursor_argb, 1243#ifdef RANDR_12_INTERFACE 1244 .set_origin = iga1_crtc_set_origin, 1245#endif 1246 .destroy = iga_crtc_destroy, 1247}; 1248 1249static void 1250iga2_crtc_dpms(xf86CrtcPtr crtc, int mode) 1251{ 1252 ScrnInfoPtr pScrn = crtc->scrn; 1253 VIAPtr pVia = VIAPTR(pScrn); 1254 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 1255 1256 if (pVia->pVbe) { 1257 ViaVbeDPMS(pScrn, mode); 1258 } else { 1259 switch (mode) { 1260 case DPMSModeOn: 1261 if (pBIOSInfo->SimultaneousEnabled) 1262 ViaDisplayEnableSimultaneous(pScrn); 1263 break; 1264 1265 case DPMSModeStandby: 1266 case DPMSModeSuspend: 1267 case DPMSModeOff: 1268 if (pBIOSInfo->SimultaneousEnabled) 1269 ViaDisplayDisableSimultaneous(pScrn); 1270 break; 1271 1272 default: 1273 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", 1274 mode); 1275 break; 1276 } 1277 //vgaHWSaveScreen(pScrn->pScreen, mode); 1278 } 1279} 1280 1281static void 1282iga2_crtc_save(xf86CrtcPtr crtc) 1283{ 1284 ScrnInfoPtr pScrn = crtc->scrn; 1285 vgaHWPtr hwp = VGAHWPTR(pScrn); 1286 VIAPtr pVia = VIAPTR(pScrn); 1287 1288 if (pVia->pVbe && pVia->vbeSR) 1289 ViaVbeSaveRestore(pScrn, MODE_SAVE); 1290 else 1291 VIASave(pScrn); 1292 vgaHWUnlock(hwp); 1293} 1294 1295static void 1296iga2_crtc_restore(xf86CrtcPtr crtc) 1297{ 1298 ScrnInfoPtr pScrn = crtc->scrn; 1299 vgaHWPtr hwp = VGAHWPTR(pScrn); 1300 VIAPtr pVia = VIAPTR(pScrn); 1301 1302 if (pVia->pVbe && pVia->vbeSR) 1303 ViaVbeSaveRestore(pScrn, MODE_RESTORE); 1304 else 1305 VIARestore(pScrn); 1306 vgaHWLock(hwp); 1307} 1308 1309static Bool 1310iga2_crtc_lock(xf86CrtcPtr crtc) 1311{ 1312 return FALSE; 1313} 1314 1315static void 1316iga2_crtc_unlock(xf86CrtcPtr crtc) 1317{ 1318} 1319 1320static Bool 1321iga2_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 1322 DisplayModePtr adjusted_mode) 1323{ 1324 ScrnInfoPtr pScrn = crtc->scrn; 1325 VIAPtr pVia = VIAPTR(pScrn); 1326 CARD32 temp; 1327 ModeStatus modestatus; 1328 1329 if (pVia->pVbe) 1330 return TRUE; 1331 1332 if ((mode->Clock < pScrn->clockRanges->minClock) || 1333 (mode->Clock > pScrn->clockRanges->maxClock)) { 1334 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1335 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 1336 mode->name, mode->Clock, pScrn->clockRanges->minClock, 1337 pScrn->clockRanges->maxClock); 1338 return FALSE; 1339 } 1340 1341 modestatus = ViaFirstCRTCModeValid(pScrn, mode); 1342 if (modestatus != MODE_OK) { 1343 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 1344 mode->name, xf86ModeStatusToString(modestatus)); 1345 return FALSE; 1346 } 1347 1348 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 1349 (pScrn->bitsPerPixel >> 3); 1350 if (pVia->pBIOSInfo->Bandwidth < temp) { 1351 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1352 "Required bandwidth is not available. (%u > %u)\n", 1353 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 1354 return FALSE; 1355 } 1356 return TRUE; 1357} 1358 1359static void 1360iga2_crtc_prepare (xf86CrtcPtr crtc) 1361{ 1362} 1363 1364static void 1365iga2_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 1366{ 1367 ScrnInfoPtr pScrn = crtc->scrn; 1368 VIAPtr pVia = VIAPTR(pScrn); 1369 1370 if (pVia->pVbe) { 1371 ViaVbeAdjustFrame(pScrn, x, y); 1372 } else { 1373 ViaSecondCRTCSetStartingAddress(crtc, x, y); 1374 } 1375 VIAVidAdjustFrame(pScrn, x, y); 1376} 1377 1378static void 1379iga2_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 1380 DisplayModePtr adjusted_mode, int x, int y) 1381{ 1382 ScrnInfoPtr pScrn = crtc->scrn; 1383 VIAPtr pVia = VIAPTR(pScrn); 1384 1385 if (pVia->pVbe) { 1386 if (!ViaVbeSetMode(pScrn, adjusted_mode)) 1387 return; 1388 } else { 1389 if (!vgaHWInit(pScrn, adjusted_mode)) 1390 return; 1391 1392 if (pVia->UseLegacyModeSwitch) { 1393 ViaModeSecondaryLegacy(crtc, adjusted_mode); 1394 } else { 1395 ViaCRTCInit(pScrn); 1396 ViaModeSecondCRTC(pScrn, adjusted_mode); 1397 ViaSecondDisplayChannelEnable(pScrn); 1398 1399 if (pVia->pBIOSInfo->SimultaneousEnabled) 1400 ViaDisplayEnableSimultaneous(pScrn); 1401 else 1402 ViaDisplayDisableSimultaneous(pScrn); 1403 } 1404 } 1405 iga2_crtc_set_origin(crtc, crtc->x, crtc->y); 1406} 1407 1408static void 1409iga2_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 1410 int size) 1411{ 1412 ScrnInfoPtr pScrn = crtc->scrn; 1413 vgaHWPtr hwp = VGAHWPTR(pScrn); 1414 VIAPtr pVia = VIAPTR(pScrn); 1415 int SR1A, SR1B, CR67, CR6A; 1416 LOCO colors[size]; 1417 int i; 1418 1419 for (i = 0; i < size; i++) { 1420 colors[i].red = red[i] >> 8; 1421 colors[i].green = green[i] >> 8; 1422 colors[i].blue = blue[i] >> 8; 1423 } 1424 1425 if (pScrn->bitsPerPixel != 8) { 1426 if (!(pVia->Chipset == VIA_CLE266 && 1427 CLE266_REV_IS_AX(pVia->ChipRev))) { 1428 ViaSeqMask(hwp, 0x1A, 0x01, 0x01); 1429 ViaCrtcMask(hwp, 0x6A, 0x02, 0x02); 1430 1431 switch (pVia->Chipset) { 1432 case VIA_CLE266: 1433 case VIA_KM400: 1434 case VIA_K8M800: 1435 case VIA_PM800: 1436 break; 1437 1438 default: 1439 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 1440 break; 1441 } 1442 VIALoadRgbLut(pScrn, 0, size, colors); 1443 } 1444 } else { 1445 SR1A = hwp->readSeq(hwp, 0x1A); 1446 SR1B = hwp->readSeq(hwp, 0x1B); 1447 CR67 = hwp->readCrtc(hwp, 0x67); 1448 CR6A = hwp->readCrtc(hwp, 0x6A); 1449 1450 ViaSeqMask(hwp, 0x1A, 0x01, 0x01); 1451 ViaSeqMask(hwp, 0x1B, 0x80, 0x80); 1452 ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); 1453 ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0); 1454 1455 for (i = 0; i < size; i++) { 1456 hwp->writeDacWriteAddr(hwp, i); 1457 hwp->writeDacData(hwp, colors[i].red); 1458 hwp->writeDacData(hwp, colors[i].green); 1459 hwp->writeDacData(hwp, colors[i].blue); 1460 } 1461 1462 hwp->writeSeq(hwp, 0x1A, SR1A); 1463 hwp->writeSeq(hwp, 0x1B, SR1B); 1464 hwp->writeCrtc(hwp, 0x67, CR67); 1465 hwp->writeCrtc(hwp, 0x6A, CR6A); 1466 1467 /* Screen 0 palette was changed by mode setting of Screen 1, 1468 * so load it again. */ 1469 for (i = 0; i < size; i++) { 1470 hwp->writeDacWriteAddr(hwp, i); 1471 hwp->writeDacData(hwp, colors[i].red); 1472 hwp->writeDacData(hwp, colors[i].green); 1473 hwp->writeDacData(hwp, colors[i].blue); 1474 } 1475 } 1476} 1477 1478static void * 1479iga2_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 1480{ 1481 return NULL; 1482} 1483 1484static PixmapPtr 1485iga2_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 1486{ 1487 return NULL; 1488} 1489 1490static void 1491iga2_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 1492{ 1493} 1494 1495/* 1496 Set the cursor foreground and background colors. In 8bpp, fg and 1497 bg are indices into the current colormap unless the 1498 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 1499 and in all other bpps the fg and bg are in 8-8-8 RGB format. 1500*/ 1501static void 1502iga2_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 1503{ 1504 drmmode_crtc_private_ptr iga = crtc->driver_private; 1505 ScrnInfoPtr pScrn = crtc->scrn; 1506 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1507 int height = 64, width = 64, i; 1508 VIAPtr pVia = VIAPTR(pScrn); 1509 CARD32 pixel, temp, *dst; 1510 1511 if (xf86_config->cursor_fg) 1512 return; 1513 1514 fg |= 0xff000000; 1515 bg |= 0xff000000; 1516 1517 /* Don't recolour the image if we don't have to. */ 1518 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 1519 return; 1520 1521 switch(pVia->Chipset) { 1522 case VIA_CX700: 1523 case VIA_P4M890: 1524 case VIA_P4M900: 1525 case VIA_VX800: 1526 case VIA_VX855: 1527 case VIA_VX900: 1528 temp = VIAGETREG(HI_CONTROL); 1529 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 1530 break; 1531 1532 default: 1533 temp = VIAGETREG(HI_CONTROL); 1534 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 1535 height = width = 32; 1536 break; 1537 } 1538 1539 dst = drm_bo_map(pScrn, iga->cursor_bo); 1540 for (i = 0; i < width * height; i++, dst++) 1541 if ((pixel = *dst)) 1542 *dst = (pixel == xf86_config->cursor_fg) ? fg : bg; 1543 drm_bo_unmap(pScrn, iga->cursor_bo); 1544 1545 xf86_config->cursor_fg = fg; 1546 xf86_config->cursor_bg = bg; 1547} 1548 1549static void 1550iga2_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 1551{ 1552 ScrnInfoPtr pScrn = crtc->scrn; 1553 VIAPtr pVia = VIAPTR(pScrn); 1554 unsigned xoff, yoff; 1555 1556 if (x < 0) { 1557 xoff = ((-x) & 0xFE); 1558 x = 0; 1559 } else { 1560 xoff = 0; 1561 } 1562 1563 if (y < 0) { 1564 yoff = ((-y) & 0xFE); 1565 y = 0; 1566 } else { 1567 yoff = 0; 1568 } 1569 1570 switch(pVia->Chipset) { 1571 case VIA_CX700: 1572 case VIA_P4M890: 1573 case VIA_P4M900: 1574 case VIA_VX800: 1575 case VIA_VX855: 1576 case VIA_VX900: 1577 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1578 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1579 break; 1580 1581 default: 1582 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1583 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1584 break; 1585 } 1586} 1587 1588static void 1589iga2_crtc_show_cursor(xf86CrtcPtr crtc) 1590{ 1591 drmmode_crtc_private_ptr iga = crtc->driver_private; 1592 ScrnInfoPtr pScrn = crtc->scrn; 1593 VIAPtr pVia = VIAPTR(pScrn); 1594 1595 switch(pVia->Chipset) { 1596 case VIA_CX700: 1597 case VIA_P4M890: 1598 case VIA_P4M900: 1599 case VIA_VX800: 1600 case VIA_VX855: 1601 case VIA_VX900: 1602 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 1603 VIASETREG(HI_CONTROL, 0xB6000005); 1604 break; 1605 1606 default: 1607 /* Mono Cursor Display Path [bit31]: Secondary */ 1608 /* FIXME For CLE266 and KM400 try to enable 32x32 cursor size [bit1] */ 1609 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 1610 VIASETREG(HI_CONTROL, 0xF6000005); 1611 break; 1612 } 1613} 1614 1615static void 1616iga2_crtc_hide_cursor(xf86CrtcPtr crtc) 1617{ 1618 ScrnInfoPtr pScrn = crtc->scrn; 1619 VIAPtr pVia = VIAPTR(pScrn); 1620 CARD32 temp; 1621 1622 switch(pVia->Chipset) { 1623 case VIA_CX700: 1624 case VIA_P4M890: 1625 case VIA_P4M900: 1626 case VIA_VX800: 1627 case VIA_VX855: 1628 case VIA_VX900: 1629 temp = VIAGETREG(HI_CONTROL); 1630 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 1631 break; 1632 1633 default: 1634 temp = VIAGETREG(HI_CONTROL); 1635 /* Hardware cursor disable [bit0] */ 1636 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 1637 break; 1638 } 1639} 1640 1641static const xf86CrtcFuncsRec iga2_crtc_funcs = { 1642 .dpms = iga2_crtc_dpms, 1643 .save = iga2_crtc_save, 1644 .restore = iga2_crtc_restore, 1645 .lock = iga2_crtc_lock, 1646 .unlock = iga2_crtc_unlock, 1647 .mode_fixup = iga2_crtc_mode_fixup, 1648 .prepare = iga2_crtc_prepare, 1649 .mode_set = iga2_crtc_mode_set, 1650 .commit = iga_crtc_commit, 1651 .gamma_set = iga2_crtc_gamma_set, 1652 .shadow_create = iga2_crtc_shadow_create, 1653 .shadow_allocate = iga2_crtc_shadow_allocate, 1654 .shadow_destroy = iga2_crtc_shadow_destroy, 1655 .set_cursor_colors = iga2_crtc_set_cursor_colors, 1656 .set_cursor_position = iga2_crtc_set_cursor_position, 1657 .show_cursor = iga2_crtc_show_cursor, 1658 .hide_cursor = iga2_crtc_hide_cursor, 1659 .load_cursor_argb = iga_crtc_load_cursor_argb, 1660#ifdef RANDR_12_INTERFACE 1661 .set_origin = iga2_crtc_set_origin, 1662#endif 1663 .destroy = iga_crtc_destroy, 1664}; 1665 1666Bool 1667UMSCrtcInit(ScrnInfoPtr pScrn) 1668{ 1669 drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL; 1670 vgaHWPtr hwp = VGAHWPTR(pScrn); 1671 VIAPtr pVia = VIAPTR(pScrn); 1672 ClockRangePtr clockRanges; 1673 int max_pitch, max_height; 1674 VIABIOSInfoPtr pBIOSInfo; 1675 xf86CrtcPtr iga1, iga2; 1676 1677 /* Read memory bandwidth from registers. */ 1678 pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; 1679 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1680 "Detected MemClk %d\n", pVia->MemClk)); 1681 if (pVia->MemClk >= VIA_MEM_END) { 1682 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1683 "Unknown Memory clock: %d\n", pVia->MemClk); 1684 pVia->MemClk = VIA_MEM_END - 1; 1685 } 1686 pBIOSInfo = pVia->pBIOSInfo; 1687 pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); 1688 1689 if (pBIOSInfo->TVType == TVTYPE_NONE) { 1690 /* Use jumper to determine TV type. */ 1691 if (hwp->readCrtc(hwp, 0x3B) & 0x02) { 1692 pBIOSInfo->TVType = TVTYPE_PAL; 1693 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1694 "Detected TV standard: PAL.\n")); 1695 } else { 1696 pBIOSInfo->TVType = TVTYPE_NTSC; 1697 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1698 "Detected TV standard: NTSC.\n")); 1699 } 1700 } 1701 1702 if (pVia->drmmode.hwcursor) { 1703 if (!xf86LoadSubModule(pScrn, "ramdac")) 1704 return FALSE; 1705 } 1706 1707 if (!xf86LoadSubModule(pScrn, "i2c")) 1708 return FALSE; 1709 else 1710 ViaI2CInit(pScrn); 1711 1712 if (!xf86LoadSubModule(pScrn, "ddc")) 1713 return FALSE; 1714 1715 pVia->pVbe = NULL; 1716 if (pVia->useVBEModes) { 1717 /* VBE doesn't properly initialise int10 itself. */ 1718 if (xf86LoadSubModule(pScrn, "int10") && 1719 xf86LoadSubModule(pScrn, "vbe")) { 1720 pVia->pVbe = VBEExtendedInit(NULL, pVia->EntityIndex, 1721 SET_BIOS_SCRATCH | 1722 RESTORE_BIOS_SCRATCH); 1723 } 1724 1725 if (!pVia->pVbe) 1726 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialisation failed." 1727 " Using builtin code to set modes.\n"); 1728 else 1729 ConfiguredMonitor = vbeDoEDID(pVia->pVbe, NULL); 1730 } 1731 1732 /* 1733 * Set up ClockRanges, which describe what clock ranges are 1734 * available, and what sort of modes they can be used for. 1735 */ 1736 clockRanges = xnfalloc(sizeof(ClockRange)); 1737 clockRanges->next = NULL; 1738 clockRanges->minClock = 20000; 1739 clockRanges->maxClock = 230000; 1740 1741 clockRanges->clockIndex = -1; 1742 clockRanges->interlaceAllowed = TRUE; 1743 clockRanges->doubleScanAllowed = FALSE; 1744 pScrn->clockRanges = clockRanges; 1745 1746 /* 1747 * Now handle the outputs 1748 */ 1749 iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1750 if (!iga1_rec) { 1751 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 1752 return FALSE; 1753 } 1754 1755 iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs); 1756 if (!iga1) { 1757 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1758 free(iga1_rec); 1759 return FALSE; 1760 } 1761 iga1_rec->drmmode = &pVia->drmmode; 1762 iga1_rec->index = 0; 1763 iga1->driver_private = iga1_rec; 1764 1765 iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1766 if (!iga2_rec) { 1767 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 1768 xf86CrtcDestroy(iga1); 1769 return FALSE; 1770 } 1771 1772 iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs); 1773 if (!iga2) { 1774 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1775 xf86CrtcDestroy(iga1); 1776 free(iga2_rec); 1777 return FALSE; 1778 } 1779 iga2_rec->drmmode = &pVia->drmmode; 1780 iga2_rec->index = 1; 1781 iga2->driver_private = iga2_rec; 1782 1783 /* 1784 * CLE266A: 1785 * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) 1786 * Max Height: 4096 (and beyond) 1787 * 1788 * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited 1789 * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). 1790 * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. 1791 * 1792 * We should be able to limit the memory available for a mode to 32 MB, 1793 * but miScanLineWidth fails to catch this properly (apertureSize). 1794 */ 1795 switch (pVia->Chipset) { 1796 case VIA_CLE266: 1797 case VIA_KM400: 1798 case VIA_K8M800: 1799 case VIA_PM800: 1800 case VIA_VM800: 1801 max_pitch = 3344; 1802 max_height = 2508; 1803 break; 1804 1805 case VIA_CX700: 1806 case VIA_K8M890: 1807 case VIA_P4M890: 1808 case VIA_P4M900: 1809 max_pitch = 8192/(pScrn->bitsPerPixel >> 3)-1; 1810 max_height = max_pitch; 1811 break; 1812 1813 default: 1814 max_pitch = 16384/(pScrn->bitsPerPixel >> 3)-1; 1815 max_height = max_pitch; 1816 break; 1817 } 1818 1819 /* Init HI_X0 for cursor */ 1820 switch (pVia->Chipset) { 1821 case VIA_CX700: 1822 /* case VIA_CN750: */ 1823 case VIA_P4M890: 1824 case VIA_P4M900: 1825 case VIA_VX800: 1826 case VIA_VX855: 1827 case VIA_VX900: 1828 /* set 0 as transparent color key for IGA 2 */ 1829 VIASETREG(HI_TRANSPARENT_COLOR, 0); 1830 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 1831 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 1832 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 1833 1834 /* set 0 as transparent color key for IGA 1 */ 1835 VIASETREG(PRIM_HI_TRANSCOLOR, 0); 1836 VIASETREG(PRIM_HI_FIFO, 0x0D000D0F); 1837 VIASETREG(PRIM_HI_INVTCOLOR, 0x00FFFFFF); 1838 VIASETREG(V327_HI_INVTCOLOR, 0x00FFFFFF); 1839 break; 1840 1841 default: 1842 VIASETREG(HI_TRANSPARENT_COLOR, 0); 1843 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 1844 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 1845 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 1846 break; 1847 } 1848 1849 xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height); 1850 1851 ViaOutputsDetect(pScrn); 1852 1853 if (pVia->pVbe) { 1854 if (!ViaVbeModePreInit(pScrn)) 1855 return FALSE; 1856 } 1857 return TRUE; 1858} 1859