via_display.c revision 5b405e1a
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; 1006 int i; 1007 1008 colors = malloc(size * sizeof(*colors)); 1009 if (colors == NULL) 1010 return; 1011 1012 for (i = 0; i < size; i++) { 1013 colors[i].red = red[i] >> 8; 1014 colors[i].green = green[i] >> 8; 1015 colors[i].blue = blue[i] >> 8; 1016 } 1017 1018 if (pScrn->bitsPerPixel != 8) { 1019 switch (pVia->Chipset) { 1020 case VIA_CLE266: 1021 case VIA_KM400: 1022 ViaSeqMask(hwp, 0x16, 0x80, 0x80); 1023 break; 1024 default: 1025 ViaCrtcMask(hwp, 0x33, 0x80, 0x80); 1026 break; 1027 } 1028 1029 ViaSeqMask(hwp, 0x1A, 0x00, 0x01); 1030 VIALoadRgbLut(pScrn, 0, size, colors); 1031 1032 } else { 1033 1034 SR1A = hwp->readSeq(hwp, 0x1A); 1035 SR1B = hwp->readSeq(hwp, 0x1B); 1036 CR67 = hwp->readCrtc(hwp, 0x67); 1037 CR6A = hwp->readCrtc(hwp, 0x6A); 1038 1039 for (i = 0; i < size; i++) { 1040 hwp->writeDacWriteAddr(hwp, i); 1041 hwp->writeDacData(hwp, colors[i].red); 1042 hwp->writeDacData(hwp, colors[i].green); 1043 hwp->writeDacData(hwp, colors[i].blue); 1044 } 1045 } 1046 free(colors); 1047} 1048 1049static void * 1050iga1_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 1051{ 1052 return NULL; 1053} 1054 1055static PixmapPtr 1056iga1_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 1057{ 1058 return NULL; 1059} 1060 1061static void 1062iga1_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 1063{ 1064} 1065 1066/* 1067 Set the cursor foreground and background colors. In 8bpp, fg and 1068 bg are indices into the current colormap unless the 1069 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 1070 and in all other bpps the fg and bg are in 8-8-8 RGB format. 1071*/ 1072static void 1073iga1_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) 1074{ 1075 ScrnInfoPtr pScrn = crtc->scrn; 1076 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1077 VIAPtr pVia = VIAPTR(pScrn); 1078 CARD32 temp; 1079 1080 if (xf86_config->cursor_fg) 1081 return; 1082 1083 /* Don't recolour the image if we don't have to. */ 1084 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 1085 return; 1086 1087 switch(pVia->Chipset) { 1088 case VIA_CX700: 1089 case VIA_P4M890: 1090 case VIA_P4M900: 1091 case VIA_VX800: 1092 case VIA_VX855: 1093 case VIA_VX900: 1094 temp = VIAGETREG(PRIM_HI_CTRL); 1095 VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFE); 1096 break; 1097 1098 default: 1099 temp = VIAGETREG(HI_CONTROL); 1100 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 1101 break; 1102 } 1103 1104 xf86_config->cursor_fg = fg; 1105 xf86_config->cursor_bg = bg; 1106} 1107 1108static void 1109iga1_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) 1110{ 1111 ScrnInfoPtr pScrn = crtc->scrn; 1112 VIAPtr pVia = VIAPTR(pScrn); 1113 unsigned xoff, yoff; 1114 1115 if (x < 0) { 1116 xoff = ((-x) & 0xFE); 1117 x = 0; 1118 } else { 1119 xoff = 0; 1120 } 1121 1122 if (y < 0) { 1123 yoff = ((-y) & 0xFE); 1124 y = 0; 1125 } else { 1126 yoff = 0; 1127 } 1128 1129 switch(pVia->Chipset) { 1130 case VIA_CX700: 1131 case VIA_P4M890: 1132 case VIA_P4M900: 1133 case VIA_VX800: 1134 case VIA_VX855: 1135 case VIA_VX900: 1136 VIASETREG(PRIM_HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1137 VIASETREG(PRIM_HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1138 break; 1139 1140 default: 1141 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1142 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1143 break; 1144 } 1145} 1146 1147static void 1148iga1_crtc_show_cursor (xf86CrtcPtr crtc) 1149{ 1150 drmmode_crtc_private_ptr iga = crtc->driver_private; 1151 ScrnInfoPtr pScrn = crtc->scrn; 1152 VIAPtr pVia = VIAPTR(pScrn); 1153 1154 switch(pVia->Chipset) { 1155 case VIA_CX700: 1156 case VIA_P4M890: 1157 case VIA_P4M900: 1158 case VIA_VX800: 1159 case VIA_VX855: 1160 case VIA_VX900: 1161 VIASETREG(PRIM_HI_FBOFFSET, iga->cursor_bo->offset); 1162 VIASETREG(PRIM_HI_CTRL, 0x36000005); 1163 break; 1164 1165 default: 1166 /* Mono Cursor Display Path [bit31]: Primary */ 1167 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 1168 VIASETREG(HI_CONTROL, 0x76000005); 1169 break; 1170 } 1171} 1172 1173static void 1174iga1_crtc_hide_cursor (xf86CrtcPtr crtc) 1175{ 1176 ScrnInfoPtr pScrn = crtc->scrn; 1177 VIAPtr pVia = VIAPTR(pScrn); 1178 CARD32 temp; 1179 1180 switch(pVia->Chipset) { 1181 case VIA_CX700: 1182 case VIA_P4M890: 1183 case VIA_P4M900: 1184 case VIA_VX800: 1185 case VIA_VX855: 1186 case VIA_VX900: 1187 temp = VIAGETREG(PRIM_HI_CTRL); 1188 VIASETREG(PRIM_HI_CTRL, temp & 0xFFFFFFFA); 1189 break; 1190 1191 default: 1192 temp = VIAGETREG(HI_CONTROL); 1193 /* Hardware cursor disable [bit0] */ 1194 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 1195 break; 1196 } 1197} 1198 1199static void 1200iga_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) 1201{ 1202 drmmode_crtc_private_ptr iga = crtc->driver_private; 1203 ScrnInfoPtr pScrn = crtc->scrn; 1204 void *dst; 1205 1206 dst = drm_bo_map(pScrn, iga->cursor_bo); 1207 memset(dst, 0x00, iga->cursor_bo->size); 1208 memcpy(dst, image, iga->cursor_bo->size); 1209 drm_bo_unmap(pScrn, iga->cursor_bo); 1210} 1211 1212static void 1213iga_crtc_commit(xf86CrtcPtr crtc) 1214{ 1215 ScrnInfoPtr pScrn = crtc->scrn; 1216 VIAPtr pVia = VIAPTR(pScrn); 1217 1218 if (crtc->scrn->pScreen != NULL && pVia->drmmode.hwcursor) 1219 xf86_reload_cursors(crtc->scrn->pScreen); 1220} 1221 1222static void 1223iga_crtc_destroy(xf86CrtcPtr crtc) 1224{ 1225 if (crtc->driver_private) 1226 free(crtc->driver_private); 1227} 1228 1229static const xf86CrtcFuncsRec iga1_crtc_funcs = { 1230 .dpms = iga1_crtc_dpms, 1231 .save = iga1_crtc_save, 1232 .restore = iga1_crtc_restore, 1233 .lock = iga1_crtc_lock, 1234 .unlock = iga1_crtc_unlock, 1235 .mode_fixup = iga1_crtc_mode_fixup, 1236 .prepare = iga1_crtc_prepare, 1237 .mode_set = iga1_crtc_mode_set, 1238 .commit = iga_crtc_commit, 1239 .gamma_set = iga1_crtc_gamma_set, 1240 .shadow_create = iga1_crtc_shadow_create, 1241 .shadow_allocate = iga1_crtc_shadow_allocate, 1242 .shadow_destroy = iga1_crtc_shadow_destroy, 1243 .set_cursor_colors = iga1_crtc_set_cursor_colors, 1244 .set_cursor_position = iga1_crtc_set_cursor_position, 1245 .show_cursor = iga1_crtc_show_cursor, 1246 .hide_cursor = iga1_crtc_hide_cursor, 1247 .load_cursor_argb = iga_crtc_load_cursor_argb, 1248#ifdef RANDR_12_INTERFACE 1249 .set_origin = iga1_crtc_set_origin, 1250#endif 1251 .destroy = iga_crtc_destroy, 1252}; 1253 1254static void 1255iga2_crtc_dpms(xf86CrtcPtr crtc, int mode) 1256{ 1257 ScrnInfoPtr pScrn = crtc->scrn; 1258 VIAPtr pVia = VIAPTR(pScrn); 1259 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 1260 1261 if (pVia->pVbe) { 1262 ViaVbeDPMS(pScrn, mode); 1263 } else { 1264 switch (mode) { 1265 case DPMSModeOn: 1266 if (pBIOSInfo->SimultaneousEnabled) 1267 ViaDisplayEnableSimultaneous(pScrn); 1268 break; 1269 1270 case DPMSModeStandby: 1271 case DPMSModeSuspend: 1272 case DPMSModeOff: 1273 if (pBIOSInfo->SimultaneousEnabled) 1274 ViaDisplayDisableSimultaneous(pScrn); 1275 break; 1276 1277 default: 1278 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", 1279 mode); 1280 break; 1281 } 1282 //vgaHWSaveScreen(pScrn->pScreen, mode); 1283 } 1284} 1285 1286static void 1287iga2_crtc_save(xf86CrtcPtr crtc) 1288{ 1289 ScrnInfoPtr pScrn = crtc->scrn; 1290 vgaHWPtr hwp = VGAHWPTR(pScrn); 1291 VIAPtr pVia = VIAPTR(pScrn); 1292 1293 if (pVia->pVbe && pVia->vbeSR) 1294 ViaVbeSaveRestore(pScrn, MODE_SAVE); 1295 else 1296 VIASave(pScrn); 1297 vgaHWUnlock(hwp); 1298} 1299 1300static void 1301iga2_crtc_restore(xf86CrtcPtr crtc) 1302{ 1303 ScrnInfoPtr pScrn = crtc->scrn; 1304 vgaHWPtr hwp = VGAHWPTR(pScrn); 1305 VIAPtr pVia = VIAPTR(pScrn); 1306 1307 if (pVia->pVbe && pVia->vbeSR) 1308 ViaVbeSaveRestore(pScrn, MODE_RESTORE); 1309 else 1310 VIARestore(pScrn); 1311 vgaHWLock(hwp); 1312} 1313 1314static Bool 1315iga2_crtc_lock(xf86CrtcPtr crtc) 1316{ 1317 return FALSE; 1318} 1319 1320static void 1321iga2_crtc_unlock(xf86CrtcPtr crtc) 1322{ 1323} 1324 1325static Bool 1326iga2_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 1327 DisplayModePtr adjusted_mode) 1328{ 1329 ScrnInfoPtr pScrn = crtc->scrn; 1330 VIAPtr pVia = VIAPTR(pScrn); 1331 CARD32 temp; 1332 ModeStatus modestatus; 1333 1334 if (pVia->pVbe) 1335 return TRUE; 1336 1337 if ((mode->Clock < pScrn->clockRanges->minClock) || 1338 (mode->Clock > pScrn->clockRanges->maxClock)) { 1339 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1340 "Clock for mode \"%s\" outside of allowed range (%u (%u - %u))\n", 1341 mode->name, mode->Clock, pScrn->clockRanges->minClock, 1342 pScrn->clockRanges->maxClock); 1343 return FALSE; 1344 } 1345 1346 modestatus = ViaFirstCRTCModeValid(pScrn, mode); 1347 if (modestatus != MODE_OK) { 1348 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" : %s.\n", 1349 mode->name, xf86ModeStatusToString(modestatus)); 1350 return FALSE; 1351 } 1352 1353 temp = mode->CrtcHDisplay * mode->CrtcVDisplay * mode->VRefresh * 1354 (pScrn->bitsPerPixel >> 3); 1355 if (pVia->pBIOSInfo->Bandwidth < temp) { 1356 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1357 "Required bandwidth is not available. (%u > %u)\n", 1358 (unsigned)temp, (unsigned)pVia->pBIOSInfo->Bandwidth); 1359 return FALSE; 1360 } 1361 return TRUE; 1362} 1363 1364static void 1365iga2_crtc_prepare (xf86CrtcPtr crtc) 1366{ 1367} 1368 1369static void 1370iga2_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 1371{ 1372 ScrnInfoPtr pScrn = crtc->scrn; 1373 VIAPtr pVia = VIAPTR(pScrn); 1374 1375 if (pVia->pVbe) { 1376 ViaVbeAdjustFrame(pScrn, x, y); 1377 } else { 1378 ViaSecondCRTCSetStartingAddress(crtc, x, y); 1379 } 1380 VIAVidAdjustFrame(pScrn, x, y); 1381} 1382 1383static void 1384iga2_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 1385 DisplayModePtr adjusted_mode, int x, int y) 1386{ 1387 ScrnInfoPtr pScrn = crtc->scrn; 1388 VIAPtr pVia = VIAPTR(pScrn); 1389 1390 if (pVia->pVbe) { 1391 if (!ViaVbeSetMode(pScrn, adjusted_mode)) 1392 return; 1393 } else { 1394 if (!vgaHWInit(pScrn, adjusted_mode)) 1395 return; 1396 1397 if (pVia->UseLegacyModeSwitch) { 1398 ViaModeSecondaryLegacy(crtc, adjusted_mode); 1399 } else { 1400 ViaCRTCInit(pScrn); 1401 ViaModeSecondCRTC(pScrn, adjusted_mode); 1402 ViaSecondDisplayChannelEnable(pScrn); 1403 1404 if (pVia->pBIOSInfo->SimultaneousEnabled) 1405 ViaDisplayEnableSimultaneous(pScrn); 1406 else 1407 ViaDisplayDisableSimultaneous(pScrn); 1408 } 1409 } 1410 iga2_crtc_set_origin(crtc, crtc->x, crtc->y); 1411} 1412 1413static void 1414iga2_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 1415 int size) 1416{ 1417 ScrnInfoPtr pScrn = crtc->scrn; 1418 vgaHWPtr hwp = VGAHWPTR(pScrn); 1419 VIAPtr pVia = VIAPTR(pScrn); 1420 int SR1A, SR1B, CR67, CR6A; 1421 int i; 1422 LOCO *colors; 1423 1424 colors = malloc(size * sizeof(*colors)); 1425 if (colors == NULL) 1426 return; 1427 1428 for (i = 0; i < size; i++) { 1429 colors[i].red = red[i] >> 8; 1430 colors[i].green = green[i] >> 8; 1431 colors[i].blue = blue[i] >> 8; 1432 } 1433 1434 if (pScrn->bitsPerPixel != 8) { 1435 if (!(pVia->Chipset == VIA_CLE266 && 1436 CLE266_REV_IS_AX(pVia->ChipRev))) { 1437 ViaSeqMask(hwp, 0x1A, 0x01, 0x01); 1438 ViaCrtcMask(hwp, 0x6A, 0x02, 0x02); 1439 1440 switch (pVia->Chipset) { 1441 case VIA_CLE266: 1442 case VIA_KM400: 1443 case VIA_K8M800: 1444 case VIA_PM800: 1445 break; 1446 1447 default: 1448 ViaCrtcMask(hwp, 0x6A, 0x20, 0x20); 1449 break; 1450 } 1451 VIALoadRgbLut(pScrn, 0, size, colors); 1452 } 1453 } else { 1454 SR1A = hwp->readSeq(hwp, 0x1A); 1455 SR1B = hwp->readSeq(hwp, 0x1B); 1456 CR67 = hwp->readCrtc(hwp, 0x67); 1457 CR6A = hwp->readCrtc(hwp, 0x6A); 1458 1459 ViaSeqMask(hwp, 0x1A, 0x01, 0x01); 1460 ViaSeqMask(hwp, 0x1B, 0x80, 0x80); 1461 ViaCrtcMask(hwp, 0x67, 0x00, 0xC0); 1462 ViaCrtcMask(hwp, 0x6A, 0xC0, 0xC0); 1463 1464 for (i = 0; i < size; i++) { 1465 hwp->writeDacWriteAddr(hwp, i); 1466 hwp->writeDacData(hwp, colors[i].red); 1467 hwp->writeDacData(hwp, colors[i].green); 1468 hwp->writeDacData(hwp, colors[i].blue); 1469 } 1470 1471 hwp->writeSeq(hwp, 0x1A, SR1A); 1472 hwp->writeSeq(hwp, 0x1B, SR1B); 1473 hwp->writeCrtc(hwp, 0x67, CR67); 1474 hwp->writeCrtc(hwp, 0x6A, CR6A); 1475 1476 /* Screen 0 palette was changed by mode setting of Screen 1, 1477 * so load it again. */ 1478 for (i = 0; i < size; i++) { 1479 hwp->writeDacWriteAddr(hwp, i); 1480 hwp->writeDacData(hwp, colors[i].red); 1481 hwp->writeDacData(hwp, colors[i].green); 1482 hwp->writeDacData(hwp, colors[i].blue); 1483 } 1484 } 1485 free(colors); 1486} 1487 1488static void * 1489iga2_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 1490{ 1491 return NULL; 1492} 1493 1494static PixmapPtr 1495iga2_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 1496{ 1497 return NULL; 1498} 1499 1500static void 1501iga2_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 1502{ 1503} 1504 1505/* 1506 Set the cursor foreground and background colors. In 8bpp, fg and 1507 bg are indices into the current colormap unless the 1508 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case 1509 and in all other bpps the fg and bg are in 8-8-8 RGB format. 1510*/ 1511static void 1512iga2_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 1513{ 1514 drmmode_crtc_private_ptr iga = crtc->driver_private; 1515 ScrnInfoPtr pScrn = crtc->scrn; 1516 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1517 int height = 64, width = 64, i; 1518 VIAPtr pVia = VIAPTR(pScrn); 1519 CARD32 pixel, temp, *dst; 1520 1521 if (xf86_config->cursor_fg) 1522 return; 1523 1524 fg |= 0xff000000; 1525 bg |= 0xff000000; 1526 1527 /* Don't recolour the image if we don't have to. */ 1528 if (fg == xf86_config->cursor_fg && bg == xf86_config->cursor_bg) 1529 return; 1530 1531 switch(pVia->Chipset) { 1532 case VIA_CX700: 1533 case VIA_P4M890: 1534 case VIA_P4M900: 1535 case VIA_VX800: 1536 case VIA_VX855: 1537 case VIA_VX900: 1538 temp = VIAGETREG(HI_CONTROL); 1539 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 1540 break; 1541 1542 default: 1543 temp = VIAGETREG(HI_CONTROL); 1544 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFE); 1545 height = width = 32; 1546 break; 1547 } 1548 1549 dst = drm_bo_map(pScrn, iga->cursor_bo); 1550 for (i = 0; i < width * height; i++, dst++) 1551 if ((pixel = *dst)) 1552 *dst = (pixel == xf86_config->cursor_fg) ? fg : bg; 1553 drm_bo_unmap(pScrn, iga->cursor_bo); 1554 1555 xf86_config->cursor_fg = fg; 1556 xf86_config->cursor_bg = bg; 1557} 1558 1559static void 1560iga2_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 1561{ 1562 ScrnInfoPtr pScrn = crtc->scrn; 1563 VIAPtr pVia = VIAPTR(pScrn); 1564 unsigned xoff, yoff; 1565 1566 if (x < 0) { 1567 xoff = ((-x) & 0xFE); 1568 x = 0; 1569 } else { 1570 xoff = 0; 1571 } 1572 1573 if (y < 0) { 1574 yoff = ((-y) & 0xFE); 1575 y = 0; 1576 } else { 1577 yoff = 0; 1578 } 1579 1580 switch(pVia->Chipset) { 1581 case VIA_CX700: 1582 case VIA_P4M890: 1583 case VIA_P4M900: 1584 case VIA_VX800: 1585 case VIA_VX855: 1586 case VIA_VX900: 1587 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1588 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1589 break; 1590 1591 default: 1592 VIASETREG(HI_POSSTART, ((x << 16) | (y & 0x07ff))); 1593 VIASETREG(HI_CENTEROFFSET, ((xoff << 16) | (yoff & 0x07ff))); 1594 break; 1595 } 1596} 1597 1598static void 1599iga2_crtc_show_cursor(xf86CrtcPtr crtc) 1600{ 1601 drmmode_crtc_private_ptr iga = crtc->driver_private; 1602 ScrnInfoPtr pScrn = crtc->scrn; 1603 VIAPtr pVia = VIAPTR(pScrn); 1604 1605 switch(pVia->Chipset) { 1606 case VIA_CX700: 1607 case VIA_P4M890: 1608 case VIA_P4M900: 1609 case VIA_VX800: 1610 case VIA_VX855: 1611 case VIA_VX900: 1612 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 1613 VIASETREG(HI_CONTROL, 0xB6000005); 1614 break; 1615 1616 default: 1617 /* Mono Cursor Display Path [bit31]: Secondary */ 1618 /* FIXME For CLE266 and KM400 try to enable 32x32 cursor size [bit1] */ 1619 VIASETREG(HI_FBOFFSET, iga->cursor_bo->offset); 1620 VIASETREG(HI_CONTROL, 0xF6000005); 1621 break; 1622 } 1623} 1624 1625static void 1626iga2_crtc_hide_cursor(xf86CrtcPtr crtc) 1627{ 1628 ScrnInfoPtr pScrn = crtc->scrn; 1629 VIAPtr pVia = VIAPTR(pScrn); 1630 CARD32 temp; 1631 1632 switch(pVia->Chipset) { 1633 case VIA_CX700: 1634 case VIA_P4M890: 1635 case VIA_P4M900: 1636 case VIA_VX800: 1637 case VIA_VX855: 1638 case VIA_VX900: 1639 temp = VIAGETREG(HI_CONTROL); 1640 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 1641 break; 1642 1643 default: 1644 temp = VIAGETREG(HI_CONTROL); 1645 /* Hardware cursor disable [bit0] */ 1646 VIASETREG(HI_CONTROL, temp & 0xFFFFFFFA); 1647 break; 1648 } 1649} 1650 1651static const xf86CrtcFuncsRec iga2_crtc_funcs = { 1652 .dpms = iga2_crtc_dpms, 1653 .save = iga2_crtc_save, 1654 .restore = iga2_crtc_restore, 1655 .lock = iga2_crtc_lock, 1656 .unlock = iga2_crtc_unlock, 1657 .mode_fixup = iga2_crtc_mode_fixup, 1658 .prepare = iga2_crtc_prepare, 1659 .mode_set = iga2_crtc_mode_set, 1660 .commit = iga_crtc_commit, 1661 .gamma_set = iga2_crtc_gamma_set, 1662 .shadow_create = iga2_crtc_shadow_create, 1663 .shadow_allocate = iga2_crtc_shadow_allocate, 1664 .shadow_destroy = iga2_crtc_shadow_destroy, 1665 .set_cursor_colors = iga2_crtc_set_cursor_colors, 1666 .set_cursor_position = iga2_crtc_set_cursor_position, 1667 .show_cursor = iga2_crtc_show_cursor, 1668 .hide_cursor = iga2_crtc_hide_cursor, 1669 .load_cursor_argb = iga_crtc_load_cursor_argb, 1670#ifdef RANDR_12_INTERFACE 1671 .set_origin = iga2_crtc_set_origin, 1672#endif 1673 .destroy = iga_crtc_destroy, 1674}; 1675 1676Bool 1677UMSCrtcInit(ScrnInfoPtr pScrn) 1678{ 1679 drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL; 1680 vgaHWPtr hwp = VGAHWPTR(pScrn); 1681 VIAPtr pVia = VIAPTR(pScrn); 1682 ClockRangePtr clockRanges; 1683 int max_pitch, max_height; 1684 VIABIOSInfoPtr pBIOSInfo; 1685 xf86CrtcPtr iga1, iga2; 1686 1687 /* Read memory bandwidth from registers. */ 1688 pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; 1689 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1690 "Detected MemClk %d\n", pVia->MemClk)); 1691 if (pVia->MemClk >= VIA_MEM_END) { 1692 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1693 "Unknown Memory clock: %d\n", pVia->MemClk); 1694 pVia->MemClk = VIA_MEM_END - 1; 1695 } 1696 pBIOSInfo = pVia->pBIOSInfo; 1697 pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); 1698 1699 if (pBIOSInfo->TVType == TVTYPE_NONE) { 1700 /* Use jumper to determine TV type. */ 1701 if (hwp->readCrtc(hwp, 0x3B) & 0x02) { 1702 pBIOSInfo->TVType = TVTYPE_PAL; 1703 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1704 "Detected TV standard: PAL.\n")); 1705 } else { 1706 pBIOSInfo->TVType = TVTYPE_NTSC; 1707 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1708 "Detected TV standard: NTSC.\n")); 1709 } 1710 } 1711 1712 if (pVia->drmmode.hwcursor) { 1713 if (!xf86LoadSubModule(pScrn, "ramdac")) 1714 return FALSE; 1715 } 1716 1717 if (!xf86LoadSubModule(pScrn, "i2c")) 1718 return FALSE; 1719 else 1720 ViaI2CInit(pScrn); 1721 1722 if (!xf86LoadSubModule(pScrn, "ddc")) 1723 return FALSE; 1724 1725 pVia->pVbe = NULL; 1726 if (pVia->useVBEModes) { 1727 /* VBE doesn't properly initialise int10 itself. */ 1728 if (xf86LoadSubModule(pScrn, "int10") && 1729 xf86LoadSubModule(pScrn, "vbe")) { 1730 pVia->pVbe = VBEExtendedInit(NULL, pVia->EntityIndex, 1731 SET_BIOS_SCRATCH | 1732 RESTORE_BIOS_SCRATCH); 1733 } 1734 1735 if (!pVia->pVbe) 1736 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VBE initialisation failed." 1737 " Using builtin code to set modes.\n"); 1738 else 1739 ConfiguredMonitor = vbeDoEDID(pVia->pVbe, NULL); 1740 } 1741 1742 /* 1743 * Set up ClockRanges, which describe what clock ranges are 1744 * available, and what sort of modes they can be used for. 1745 */ 1746 clockRanges = xnfalloc(sizeof(ClockRange)); 1747 clockRanges->next = NULL; 1748 clockRanges->minClock = 20000; 1749 clockRanges->maxClock = 230000; 1750 1751 clockRanges->clockIndex = -1; 1752 clockRanges->interlaceAllowed = TRUE; 1753 clockRanges->doubleScanAllowed = FALSE; 1754 pScrn->clockRanges = clockRanges; 1755 1756 /* 1757 * Now handle the outputs 1758 */ 1759 iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1760 if (!iga1_rec) { 1761 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 1762 return FALSE; 1763 } 1764 1765 iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs); 1766 if (!iga1) { 1767 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1768 free(iga1_rec); 1769 return FALSE; 1770 } 1771 iga1_rec->drmmode = &pVia->drmmode; 1772 iga1_rec->index = 0; 1773 iga1->driver_private = iga1_rec; 1774 1775 iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1776 if (!iga2_rec) { 1777 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 1778 xf86CrtcDestroy(iga1); 1779 return FALSE; 1780 } 1781 1782 iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs); 1783 if (!iga2) { 1784 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1785 xf86CrtcDestroy(iga1); 1786 free(iga2_rec); 1787 return FALSE; 1788 } 1789 iga2_rec->drmmode = &pVia->drmmode; 1790 iga2_rec->index = 1; 1791 iga2->driver_private = iga2_rec; 1792 1793 /* 1794 * CLE266A: 1795 * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) 1796 * Max Height: 4096 (and beyond) 1797 * 1798 * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited 1799 * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). 1800 * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. 1801 * 1802 * We should be able to limit the memory available for a mode to 32 MB, 1803 * but miScanLineWidth fails to catch this properly (apertureSize). 1804 */ 1805 switch (pVia->Chipset) { 1806 case VIA_CLE266: 1807 case VIA_KM400: 1808 case VIA_K8M800: 1809 case VIA_PM800: 1810 case VIA_VM800: 1811 max_pitch = 3344; 1812 max_height = 2508; 1813 break; 1814 1815 case VIA_CX700: 1816 case VIA_K8M890: 1817 case VIA_P4M890: 1818 case VIA_P4M900: 1819 max_pitch = 8192/(pScrn->bitsPerPixel >> 3)-1; 1820 max_height = max_pitch; 1821 break; 1822 1823 default: 1824 max_pitch = 16384/(pScrn->bitsPerPixel >> 3)-1; 1825 max_height = max_pitch; 1826 break; 1827 } 1828 1829 /* Init HI_X0 for cursor */ 1830 switch (pVia->Chipset) { 1831 case VIA_CX700: 1832 /* case VIA_CN750: */ 1833 case VIA_P4M890: 1834 case VIA_P4M900: 1835 case VIA_VX800: 1836 case VIA_VX855: 1837 case VIA_VX900: 1838 /* set 0 as transparent color key for IGA 2 */ 1839 VIASETREG(HI_TRANSPARENT_COLOR, 0); 1840 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 1841 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 1842 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 1843 1844 /* set 0 as transparent color key for IGA 1 */ 1845 VIASETREG(PRIM_HI_TRANSCOLOR, 0); 1846 VIASETREG(PRIM_HI_FIFO, 0x0D000D0F); 1847 VIASETREG(PRIM_HI_INVTCOLOR, 0x00FFFFFF); 1848 VIASETREG(V327_HI_INVTCOLOR, 0x00FFFFFF); 1849 break; 1850 1851 default: 1852 VIASETREG(HI_TRANSPARENT_COLOR, 0); 1853 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 1854 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 1855 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 1856 break; 1857 } 1858 1859 xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height); 1860 1861 ViaOutputsDetect(pScrn); 1862 1863 if (pVia->pVbe) { 1864 if (!ViaVbeModePreInit(pScrn)) 1865 return FALSE; 1866 } 1867 return TRUE; 1868} 1869