1/* 2 * Copyright 2011-2016 The OpenChrome Project 3 * [https://www.freedesktop.org/wiki/Openchrome] 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include "globals.h" 30#include "via_driver.h" 31#include "xf86fbman.h" 32 33static void 34viaMMIOEnable(ScrnInfoPtr pScrn) 35{ 36 VIAPtr pVia = VIAPTR(pScrn); 37 vgaHWPtr hwp = VGAHWPTR(pScrn); 38 39 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 40 "Entered viaMMIOEnable.\n")); 41 42 switch (pVia->Chipset) { 43 case VIA_CX700: 44 case VIA_K8M890: 45 case VIA_P4M900: 46 case VIA_VX800: 47 case VIA_VX855: 48 case VIA_VX900: 49 ViaSeqMask(hwp, 0x1A, 0x08, 0x08); 50 break; 51 default: 52 if (pVia->IsSecondary) 53 ViaSeqMask(hwp, 0x1A, 0x38, 0x38); 54 else 55 ViaSeqMask(hwp, 0x1A, 0x68, 0x68); 56 break; 57 } 58 59 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 60 "Exiting viaMMIOEnable.\n")); 61} 62 63static void 64viaMMIODisable(ScrnInfoPtr pScrn) 65{ 66 VIAPtr pVia = VIAPTR(pScrn); 67 vgaHWPtr hwp = VGAHWPTR(pScrn); 68 69 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 70 "Entered viaMMIODisable.\n")); 71 72 switch (pVia->Chipset) { 73 case VIA_CX700: 74 case VIA_K8M890: 75 case VIA_P4M900: 76 case VIA_VX800: 77 case VIA_VX855: 78 case VIA_VX900: 79 ViaSeqMask(hwp, 0x1A, 0x00, 0x08); 80 break; 81 default: 82 ViaSeqMask(hwp, 0x1A, 0x00, 0x60); 83 break; 84 } 85 86 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 87 "Exiting viaMMIODisable.\n")); 88} 89 90static Bool 91viaMapMMIO(ScrnInfoPtr pScrn) 92{ 93 VIAPtr pVia = VIAPTR(pScrn); 94 vgaHWPtr hwp = VGAHWPTR(pScrn); 95 CARD8 val; 96#ifdef HAVE_PCIACCESS 97 int err; 98#else 99 unsigned char *tmp; 100#endif 101 102 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 103 "Entered viaMapMMIO.\n")); 104 105#ifdef HAVE_PCIACCESS 106 pVia->MmioBase = pVia->PciInfo->regions[1].base_addr; 107#else 108 pVia->MmioBase = pVia->PciInfo->memBase[1]; 109#endif 110 111 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 112 "Mapping MMIO at address 0x%lX with " 113 "size %u KB.\n", 114 pVia->MmioBase, VIA_MMIO_REGSIZE / 1024); 115 116#ifdef HAVE_PCIACCESS 117 err = pci_device_map_range(pVia->PciInfo, 118 pVia->MmioBase, 119 VIA_MMIO_REGSIZE, PCI_DEV_MAP_FLAG_WRITABLE, 120 (void **)&pVia->MapBase); 121 122 if (err) { 123 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 124 "Unable to map MMIO.\n" 125 "Error: %s (%u)\n", 126 strerror(err), err); 127 goto fail; 128 } 129#else 130 pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, 131 VIDMEM_MMIO, pVia->PciTag, 132 pVia->MmioBase, VIA_MMIO_REGSIZE); 133 if (!pVia->MapBase) { 134 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 135 "Unable to map MMIO.\n"); 136 goto fail; 137 } 138#endif 139 140 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 141 "Mapping 2D Host BitBLT space at address 0x%lX with " 142 "size %u KB.\n", 143 pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE / 1024); 144 145#ifdef HAVE_PCIACCESS 146 err = pci_device_map_range(pVia->PciInfo, 147 pVia->MmioBase + VIA_MMIO_BLTBASE, 148 VIA_MMIO_BLTSIZE, PCI_DEV_MAP_FLAG_WRITABLE, 149 (void **)&pVia->BltBase); 150 151 if (err) { 152 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 153 "Unable to map 2D Host BitBLT space.\n" 154 "Error: %s (%u)\n", 155 strerror(err), err); 156 goto fail; 157 } 158#else 159 pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, 160 VIDMEM_MMIO, pVia->PciTag, 161 pVia->MmioBase + VIA_MMIO_BLTBASE, 162 VIA_MMIO_BLTSIZE); 163 if (!pVia->BltBase) { 164 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 165 "Unable to map 2D Host BitBLT space.\n"); 166 goto fail; 167 } 168#endif 169 170 if (!(pVia->videoRambytes)) { 171 goto fail; 172 } 173 174#ifdef HAVE_PCIACCESS 175 if (pVia->Chipset == VIA_VX900) { 176 pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr; 177 } else { 178 pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr; 179 } 180#else 181 if (pVia->Chipset == VIA_VX900) { 182 pVia->FrameBufferBase = pVia->PciInfo->memBase[2]; 183 } else { 184 pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; 185 } 186#endif 187 188 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 189 "Mapping the frame buffer at address 0x%lX with " 190 "size %lu KB.\n", 191 pVia->FrameBufferBase, pVia->videoRambytes / 1024); 192 193#ifdef HAVE_PCIACCESS 194 err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase, 195 pVia->videoRambytes, 196 (PCI_DEV_MAP_FLAG_WRITABLE | 197 PCI_DEV_MAP_FLAG_WRITE_COMBINE), 198 (void **)&pVia->FBBase); 199 if (err) { 200 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 201 "Unable to map the frame buffer.\n" 202 "Error: %s (%u)\n", 203 strerror(err), err); 204 goto fail; 205 } 206#else 207 /* 208 * FIXME: This is a hack to get rid of offending wrongly sized 209 * MTRR regions set up by the VIA BIOS. Should be taken care of 210 * in the OS support layer. 211 */ 212 tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 213 pVia->FrameBufferBase, pVia->videoRambytes); 214 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes); 215 216 /* 217 * And, as if this wasn't enough, 2.6 series kernels don't 218 * remove MTRR regions on the first attempt. So try again. 219 */ 220 tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 221 pVia->FrameBufferBase, pVia->videoRambytes); 222 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes); 223 /* 224 * End of hack. 225 */ 226 227 pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 228 pVia->PciTag, pVia->FrameBufferBase, 229 pVia->videoRambytes); 230 231 if (!pVia->FBBase) { 232 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 233 "Unable to map the frame buffer.\n"); 234 goto fail; 235 } 236#endif 237 238 pVia->FBFreeStart = 0; 239 pVia->FBFreeEnd = pVia->videoRambytes; 240 241 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 242 "Frame buffer start address: %p, free start: 0x%X end: 0x%X\n", 243 pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd); 244 245#ifdef HAVE_PCIACCESS 246 if (pVia->Chipset == VIA_VX900) { 247 pScrn->memPhysBase = pVia->PciInfo->regions[2].base_addr; 248 } else { 249 pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr; 250 } 251#else 252 if (pVia->Chipset == VIA_VX900) { 253 pScrn->memPhysBase = pVia->PciInfo->memBase[2]; 254 } else { 255 pScrn->memPhysBase = pVia->PciInfo->memBase[0]; 256 } 257#endif 258 259 pScrn->fbOffset = 0; 260 if (pVia->IsSecondary) { 261 pScrn->fbOffset = pScrn->videoRam << 10; 262 } 263 264 /* MMIO for MPEG engine. */ 265 pVia->MpegMapBase = pVia->MapBase + 0xc00; 266 267 /* Set up MMIO vgaHW. */ 268 vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); 269 270 val = hwp->readEnable(hwp); 271 hwp->writeEnable(hwp, val | 0x01); 272 273 val = hwp->readMiscOut(hwp); 274 hwp->writeMiscOut(hwp, val | 0x01); 275 276 /* Unlock extended I/O space. */ 277 ViaSeqMask(hwp, 0x10, 0x01, 0x01); 278 279 viaMMIOEnable(pScrn); 280 281 vgaHWGetIOBase(hwp); 282 283 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 284 "Exiting viaMapMMIO.\n")); 285 return TRUE; 286 287fail: 288 289#ifdef HAVE_PCIACCESS 290 if (pVia->FBBase) { 291 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 292 pVia->videoRambytes); 293 } 294 295 if (pVia->BltBase) { 296 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 297 VIA_MMIO_BLTSIZE); 298 } 299 300 if (pVia->MapBase) { 301 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 302 VIA_MMIO_REGSIZE); 303 } 304#else 305 if (pVia->FBBase) { 306 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 307 pVia->videoRambytes); 308 } 309 310 if (pVia->BltBase) { 311 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 312 VIA_MMIO_BLTSIZE); 313 } 314 315 if (pVia->MapBase) { 316 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 317 VIA_MMIO_REGSIZE); 318 } 319#endif 320 321 pVia->FBBase = NULL; 322 pVia->BltBase = NULL; 323 pVia->MapBase = NULL; 324 325 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 326 "Exiting viaMapMMIO.\n")); 327 return FALSE; 328} 329 330void 331viaUnmapMMIO(ScrnInfoPtr pScrn) 332{ 333 VIAPtr pVia = VIAPTR(pScrn); 334 335 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 336 "Entered viaUnmapMMIO.\n")); 337 338 viaMMIODisable(pScrn); 339 340#ifdef HAVE_PCIACCESS 341 if (pVia->FBBase) { 342 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 343 pVia->videoRambytes); 344 } 345 346 if (pVia->BltBase) { 347 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 348 VIA_MMIO_BLTSIZE); 349 } 350 351 if (pVia->MapBase) { 352 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 353 VIA_MMIO_REGSIZE); 354 } 355#else 356 if (pVia->FBBase) { 357 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 358 pVia->videoRambytes); 359 } 360 361 if (pVia->BltBase) { 362 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 363 VIA_MMIO_BLTSIZE); 364 } 365 366 if (pVia->MapBase) { 367 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 368 VIA_MMIO_REGSIZE); 369 } 370#endif 371 372 pVia->FBBase = NULL; 373 pVia->BltBase = NULL; 374 pVia->MapBase = NULL; 375 376 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 377 "Exiting viaUnmapMMIO.\n")); 378} 379 380/* 381 * Leftover from VIA's code. 382 */ 383static void 384viaInitPCIe(VIAPtr pVia) 385{ 386 VIASETREG(0x41c, 0x00100000); 387 VIASETREG(0x420, 0x680A0000); 388 VIASETREG(0x420, 0x02000000); 389} 390 391static void 392viaInitAGP(VIAPtr pVia) 393{ 394 VIASETREG(VIA_REG_TRANSET, 0x00100000); 395 VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 396 VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 397 VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 398 VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 399 VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 400 VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 401 VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 402 VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); 403 404 VIASETREG(VIA_REG_TRANSET, 0xfe020000); 405 VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 406} 407 408/* 409 * Initialize the virtual command queue. Header-2 commands can be put 410 * in this queue for buffering. AFAIK it doesn't handle Header-1 411 * commands, which is really a pity, since it has to be idled before 412 * issuing a Header-1 command. 413 */ 414static void 415viaEnableAGPVQ(VIAPtr pVia) 416{ 417 CARD32 418 vqStartAddr = pVia->VQStart, 419 vqEndAddr = pVia->VQEnd, 420 vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), 421 vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), 422 vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | 423 ((vqEndAddr & 0xFF000000) >> 16), 424 vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); 425 426 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 427 VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); 428 VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); 429 VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); 430 VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); 431 VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); 432 VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); 433 VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); 434 VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); 435 VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); 436 VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); 437 VIASETREG(VIA_REG_TRANSPACE, 0x00000006); 438 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 439 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 440 VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 441 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 442 443 VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); 444 VIASETREG(VIA_REG_TRANSPACE, vqStartL); 445 VIASETREG(VIA_REG_TRANSPACE, vqEndL); 446 VIASETREG(VIA_REG_TRANSPACE, vqLen); 447} 448 449static void 450viaEnablePCIeVQ(VIAPtr pVia) 451{ 452 CARD32 453 vqStartAddr = pVia->VQStart, 454 vqEndAddr = pVia->VQEnd, 455 vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), 456 vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), 457 vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | 458 ((vqEndAddr & 0xFF000000) >> 16), 459 vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); 460 461 VIASETREG(0x41c, 0x00100000); 462 VIASETREG(0x420, vqStartEndH); 463 VIASETREG(0x420, vqStartL); 464 VIASETREG(0x420, vqEndL); 465 VIASETREG(0x420, vqLen); 466 VIASETREG(0x420, 0x74301001); 467 VIASETREG(0x420, 0x00000000); 468} 469 470/* 471 * Disable the virtual command queue. 472 */ 473void 474viaDisableVQ(ScrnInfoPtr pScrn) 475{ 476 VIAPtr pVia = VIAPTR(pScrn); 477 478 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 479 "Entered viaDisableVQ.\n")); 480 481 switch (pVia->Chipset) { 482 case VIA_K8M890: 483 case VIA_P4M900: 484 case VIA_VX800: 485 case VIA_VX855: 486 case VIA_VX900: 487 VIASETREG(0x41c, 0x00100000); 488 VIASETREG(0x420, 0x74301000); 489 break; 490 default: 491 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 492 VIASETREG(VIA_REG_TRANSPACE, 0x00000004); 493 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 494 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 495 VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 496 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 497 break; 498 } 499 500 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 501 "Exiting viaDisableVQ.\n")); 502} 503 504/* 505 * Initialize the 2D engine and set the 2D context mode to the 506 * current screen depth. Also enable the virtual queue. 507 */ 508static void 509viaInitialize2DEngine(ScrnInfoPtr pScrn) 510{ 511 VIAPtr pVia = VIAPTR(pScrn); 512 ViaTwodContext *tdc = &pVia->td; 513 int i; 514 515 /* Initialize the 2D engine registers to reset the 2D engine. */ 516 for (i = 0x04; i <= 0x40; i += 4) { 517 VIASETREG(i, 0x0); 518 } 519 520 if (pVia->Chipset == VIA_VX800 || 521 pVia->Chipset == VIA_VX855 || 522 pVia->Chipset == VIA_VX900) { 523 for (i = 0x44; i <= 0x5c; i += 4) { 524 VIASETREG(i, 0x0); 525 } 526 } 527 528 if (pVia->Chipset == VIA_VX900) 529 { 530 /*410 redefine 0x30 34 38*/ 531 VIASETREG(0x60, 0x0); /*already useable here*/ 532 } 533 534 switch (pVia->Chipset) { 535 case VIA_K8M890: 536 case VIA_P4M900: 537 case VIA_VX800: 538 case VIA_VX855: 539 case VIA_VX900: 540 viaInitPCIe(pVia); 541 break; 542 default: 543 viaInitAGP(pVia); 544 break; 545 } 546 547 if (pVia->VQStart != 0) { 548 switch (pVia->Chipset) { 549 case VIA_K8M890: 550 case VIA_P4M900: 551 case VIA_VX800: 552 case VIA_VX855: 553 case VIA_VX900: 554 viaEnablePCIeVQ(pVia); 555 break; 556 default: 557 viaEnableAGPVQ(pVia); 558 break; 559 } 560 } else { 561 viaDisableVQ(pScrn); 562 } 563 564 viaAccelSetMode(pScrn->bitsPerPixel, tdc); 565} 566 567static void 568viaInitialize3DEngine(ScrnInfoPtr pScrn) 569{ 570 VIAPtr pVia = VIAPTR(pScrn); 571 int i; 572 573 VIASETREG(VIA_REG_TRANSET, 0x00010000); 574 for (i = 0; i <= 0x7D; i++) 575 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 576 577 VIASETREG(VIA_REG_TRANSET, 0x00020000); 578 for (i = 0; i <= 0x94; i++) 579 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 580 VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 581 582 VIASETREG(VIA_REG_TRANSET, 0x01020000); 583 for (i = 0; i <= 0x94; i++) 584 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 585 VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 586 587 VIASETREG(VIA_REG_TRANSET, 0xfe020000); 588 for (i = 0; i <= 0x03; i++) 589 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 590 591 VIASETREG(VIA_REG_TRANSET, 0x00030000); 592 for (i = 0; i <= 0xff; i++) 593 VIASETREG(VIA_REG_TRANSPACE, 0); 594 595 VIASETREG(VIA_REG_TRANSET, 0x00100000); 596 VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 597 VIASETREG(VIA_REG_TRANSPACE, 0x10000002); 598 VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 599 VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 600 VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 601 VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 602 VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 603 604 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 605 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3) 606 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 607 else 608 VIASETREG(VIA_REG_TRANSPACE, 0x4000800f); 609 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 610 VIASETREG(VIA_REG_TRANSPACE, 0x45080C04); 611 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 612 VIASETREG(VIA_REG_TRANSPACE, 0x50000000); 613 VIASETREG(VIA_REG_TRANSPACE, 0x51000000); 614 VIASETREG(VIA_REG_TRANSPACE, 0x52000000); 615 VIASETREG(VIA_REG_TRANSPACE, 0x53000000); 616 617 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 618 VIASETREG(VIA_REG_TRANSPACE, 0x08000001); 619 VIASETREG(VIA_REG_TRANSPACE, 0x0A000183); 620 VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F); 621 VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B); 622 VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B); 623 VIASETREG(VIA_REG_TRANSPACE, 0x0E000000); 624 VIASETREG(VIA_REG_TRANSPACE, 0x0F000000); 625 VIASETREG(VIA_REG_TRANSPACE, 0x10000000); 626 VIASETREG(VIA_REG_TRANSPACE, 0x11000000); 627 VIASETREG(VIA_REG_TRANSPACE, 0x20000000); 628} 629 630/* 631 * Acceleration initialization function. Sets up offscreen memory disposition, 632 * and initializes engines and acceleration method. 633 */ 634Bool 635umsAccelInit(ScreenPtr pScreen) 636{ 637 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 638 VIAPtr pVia = VIAPTR(pScrn); 639 Bool ret = FALSE; 640 641 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 642 "Entered umsAccelInit.\n")); 643 644 pVia->VQStart = 0; 645 pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM); 646 if (!pVia->vq_bo) 647 goto err; 648 649 pVia->VQStart = pVia->vq_bo->offset; 650 pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size; 651 652 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 653 "Initializing the 2D engine.\n")); 654 viaInitialize2DEngine(pScrn); 655 656 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 657 "Initializing the 3D engine.\n")); 658 viaInitialize3DEngine(pScrn); 659 660 pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 661 if (!pVia->exa_sync_bo) 662 goto err; 663 664 /* Sync marker space. */ 665 pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 666 if (!pVia->exa_sync_bo) 667 goto err; 668 669 pVia->markerOffset = pVia->exa_sync_bo->offset; 670 pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo); 671 if (!pVia->markerBuf) 672 goto err; 673 pVia->curMarker = 0; 674 pVia->lastMarkerRead = 0; 675 676#ifdef HAVE_DRI 677 pVia->dBounce = NULL; 678 pVia->scratchAddr = NULL; 679#endif /* HAVE_DRI */ 680 ret = TRUE; 681err: 682 if (!ret) { 683 if (pVia->markerBuf) { 684 drm_bo_unmap(pScrn, pVia->exa_sync_bo); 685 pVia->markerBuf = NULL; 686 } 687 if (pVia->exa_sync_bo) 688 drm_bo_free(pScrn, pVia->exa_sync_bo); 689 if (pVia->vq_bo) 690 drm_bo_free(pScrn, pVia->vq_bo); 691 } 692 693 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 694 "Exiting umsAccelInit.\n")); 695 return ret; 696} 697 698Bool 699umsCreate(ScrnInfoPtr pScrn) 700{ 701 ScreenPtr pScreen = pScrn->pScreen; 702 VIAPtr pVia = VIAPTR(pScrn); 703 unsigned long offset; 704 BoxRec AvailFBArea; 705 Bool ret = TRUE; 706 long size; 707 int maxY; 708 709#ifdef HAVE_DRI 710 if (pVia->directRenderingType == DRI_1) { 711 pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2; 712 if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) 713 pVia->driSize = pVia->maxDriSize * 1024; 714 715 /* In the case of DRI we handle all VRAM by the DRI ioctls */ 716 if (pVia->useEXA) 717 return TRUE; 718 719 /* XAA has to use FBManager so we have to split the space with DRI */ 720 maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); 721 } else 722#endif 723 maxY = pVia->FBFreeEnd / pVia->Bpl; 724 725 /* FBManager can't handle more than 32767 scan lines */ 726 if (maxY > 32767) 727 maxY = 32767; 728 729 AvailFBArea.x1 = 0; 730 AvailFBArea.y1 = 0; 731 AvailFBArea.x2 = pScrn->displayWidth; 732 AvailFBArea.y2 = maxY; 733 pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; 734 735 /* 736 * Initialization of the XFree86 framebuffer manager is done via 737 * Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox) 738 * FullBox represents the area of the framebuffer that the manager 739 * is allowed to manage. This is typically a box with a width 740 * of pScrn->displayWidth and a height of as many lines as can be fit 741 * within the total video memory 742 */ 743 ret = xf86InitFBManager(pScreen, &AvailFBArea); 744 if (ret != TRUE) 745 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n"); 746 747 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 748 "Frame Buffer From (%d,%d) To (%d,%d)\n", 749 AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2)); 750 751 offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp; 752 size = pVia->FBFreeEnd / pVia->Bpp - offset; 753 if (size > 0) 754 xf86InitFBManagerLinear(pScreen, offset, size); 755 756 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 757 "Using %d lines for offscreen memory.\n", 758 AvailFBArea.y2 - pScrn->virtualY)); 759 return TRUE; 760} 761 762Bool 763umsPreInit(ScrnInfoPtr pScrn) 764{ 765 MessageType from = X_PROBED; 766 VIAPtr pVia = VIAPTR(pScrn); 767 CARD8 videoRam; 768 vgaHWPtr hwp; 769#ifdef HAVE_PCIACCESS 770 struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3); 771 struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0); 772#endif 773 int bMemSize = 0; 774 775 if (!xf86LoadSubModule(pScrn, "vgahw")) 776 return FALSE; 777 778 if (!vgaHWGetHWRec(pScrn)) 779 return FALSE; 780 781#if 0 782 /* Here we can alter the number of registers saved and restored by the 783 * standard vgaHWSave and Restore routines. 784 */ 785 vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, 786 VGA_NUM_ATTR); 787#endif 788 hwp = VGAHWPTR(pScrn); 789 790 switch (pVia->Chipset) { 791 case VIA_CLE266: 792#ifdef HAVE_PCIACCESS 793 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 794#else 795 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 796#endif 797 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 798 break; 799 case VIA_KM400: 800#ifdef HAVE_PCIACCESS 801 /* P4M800 Host Bridge PCI Device ID */ 802 if (DEVICE_ID(bridge) == 0x0296) { 803 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 804 } else { 805 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 806 } 807#else 808 /* P4M800 Host Bridge PCI Device ID */ 809 if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) { 810 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 811 } else { 812 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 813 } 814#endif 815 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 816 break; 817 case VIA_PM800: 818 case VIA_P4M800PRO: 819 case VIA_K8M800: 820#ifdef HAVE_PCIACCESS 821 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 822#else 823 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 824#endif 825 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 826 break; 827 case VIA_P4M890: 828 case VIA_K8M890: 829 case VIA_P4M900: 830 case VIA_CX700: 831 case VIA_VX800: 832 case VIA_VX855: 833 case VIA_VX900: 834#ifdef HAVE_PCIACCESS 835 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 836#else 837 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 838#endif 839 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12; 840 break; 841 default: 842 if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { 843 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 844 "Using old memory-detection method.\n"); 845 bMemSize = hwp->readSeq(hwp, 0x39); 846 if (bMemSize > 16 && bMemSize <= 128) 847 pScrn->videoRam = (bMemSize + 1) << 9; 848 else if (bMemSize > 0 && bMemSize < 31) 849 pScrn->videoRam = bMemSize << 12; 850 else { 851 from = X_DEFAULT; 852 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 853 "Memory size detection failed: using 16 MB.\n"); 854 pScrn->videoRam = 16 << 10; 855 } 856 } else { 857 from = X_DEFAULT; 858 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 859 "No memory-detection done. Use VideoRAM option.\n"); 860 } 861 } 862 863 /* 864 * PCI BAR are limited to 256 MB. 865 */ 866 if (pScrn->videoRam > (256 << 10)) { 867 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 868 "Cannot use more than 256 MB of VRAM.\n"); 869 pScrn->videoRam = (256 << 10); 870 } 871 872 if (from == X_PROBED) { 873 xf86DrvMsg(pScrn->scrnIndex, from, 874 "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); 875 } 876 877 /* Split the FB for SAMM. */ 878 /* FIXME: For now, split the FB into two equal sections. 879 * This should be user-adjustable via a config option. */ 880 if (pVia->IsSecondary) { 881 DevUnion *pPriv; 882 VIAEntPtr pVIAEnt; 883 VIAPtr pVia1; 884 885 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); 886 pVIAEnt = pPriv->ptr; 887 pScrn->videoRam = pScrn->videoRam >> 1; 888 pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; 889 pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); 890 pVia1->videoRambytes = pScrn->videoRam << 10; 891 pVia->FrameBufferBase += (pScrn->videoRam << 10); 892 } 893 894 pVia->videoRambytes = pScrn->videoRam << 10; 895 896 /* maybe throw in some more sanity checks here */ 897#ifndef HAVE_PCIACCESS 898 pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, 899 pVia->PciInfo->func); 900#endif 901 902 /* Map PCI hardware resources to the memory map. */ 903 if (!viaMapMMIO(pScrn)) { 904 return FALSE; 905 } 906 907 return TRUE; 908} 909 910Bool 911umsCrtcInit(ScrnInfoPtr pScrn) 912{ 913 drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL; 914 vgaHWPtr hwp = VGAHWPTR(pScrn); 915 VIAPtr pVia = VIAPTR(pScrn); 916#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 917 ClockRangePtr clockRanges; 918#else 919 ClockRangesPtr clockRanges; 920#endif 921 int max_pitch, max_height; 922 VIABIOSInfoPtr pBIOSInfo; 923 xf86CrtcPtr iga1, iga2; 924 925 /* 3X5.3B through 3X5.3F are scratch pad registers. */ 926 pVia->originalCR3B = hwp->readCrtc(hwp, 0x3B); 927 pVia->originalCR3C = hwp->readCrtc(hwp, 0x3C); 928 pVia->originalCR3D = hwp->readCrtc(hwp, 0x3D); 929 pVia->originalCR3E = hwp->readCrtc(hwp, 0x3E); 930 pVia->originalCR3F = hwp->readCrtc(hwp, 0x3F); 931 932 /* Read memory bandwidth from registers. */ 933 pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; 934 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 935 "Detected MemClk %d\n", pVia->MemClk)); 936 if (pVia->MemClk >= VIA_MEM_END) { 937 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 938 "Unknown Memory clock: %d\n", pVia->MemClk); 939 pVia->MemClk = VIA_MEM_END - 1; 940 } 941 pBIOSInfo = pVia->pBIOSInfo; 942 pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); 943 944 if (pBIOSInfo->TVType == TVTYPE_NONE) { 945 /* Use jumper to determine TV type. */ 946 if (hwp->readCrtc(hwp, 0x3B) & 0x02) { 947 pBIOSInfo->TVType = TVTYPE_PAL; 948 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 949 "Detected TV standard: PAL.\n")); 950 } else { 951 pBIOSInfo->TVType = TVTYPE_NTSC; 952 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 953 "Detected TV standard: NTSC.\n")); 954 } 955 } 956 957 if (pVia->drmmode.hwcursor) { 958 if (!xf86LoadSubModule(pScrn, "ramdac")) 959 return FALSE; 960 } 961 962 if (!xf86LoadSubModule(pScrn, "i2c")) 963 return FALSE; 964 else 965 ViaI2CInit(pScrn); 966 967 if (!xf86LoadSubModule(pScrn, "ddc")) 968 return FALSE; 969 970 /* 971 * Set up ClockRanges, which describe what clock ranges are 972 * available, and what sort of modes they can be used for. 973 */ 974 975#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 976 clockRanges = xnfalloc(sizeof(ClockRange)); 977#else 978 clockRanges = xnfalloc(sizeof(ClockRanges)); 979#endif 980 clockRanges->next = NULL; 981 clockRanges->minClock = 20000; 982 clockRanges->maxClock = 230000; 983 984 clockRanges->clockIndex = -1; 985 clockRanges->interlaceAllowed = TRUE; 986 clockRanges->doubleScanAllowed = FALSE; 987 pScrn->clockRanges = clockRanges; 988 989 /* 990 * Now handle the outputs 991 */ 992 iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 993 if (!iga1_rec) { 994 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 995 return FALSE; 996 } 997 998 iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs); 999 if (!iga1) { 1000 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1001 free(iga1_rec); 1002 return FALSE; 1003 } 1004 iga1_rec->drmmode = &pVia->drmmode; 1005 iga1_rec->index = 0; 1006 iga1->driver_private = iga1_rec; 1007 1008 iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1009 if (!iga2_rec) { 1010 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 1011 xf86CrtcDestroy(iga1); 1012 return FALSE; 1013 } 1014 1015 iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs); 1016 if (!iga2) { 1017 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1018 xf86CrtcDestroy(iga1); 1019 free(iga2_rec); 1020 return FALSE; 1021 } 1022 iga2_rec->drmmode = &pVia->drmmode; 1023 iga2_rec->index = 1; 1024 iga2->driver_private = iga2_rec; 1025 1026 if (!pScrn->bitsPerPixel) { 1027 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1028 "Detected bitsPerPixel to be 0 bit.\n"); 1029 xf86CrtcDestroy(iga2); 1030 xf86CrtcDestroy(iga1); 1031 return FALSE; 1032 } 1033 1034 /* 1035 * CLE266A: 1036 * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) 1037 * Max Height: 4096 (and beyond) 1038 * 1039 * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited 1040 * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). 1041 * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. 1042 * 1043 * We should be able to limit the memory available for a mode to 32 MB, 1044 * but miScanLineWidth fails to catch this properly (apertureSize). 1045 */ 1046 max_pitch = (8192 / ((pScrn->bitsPerPixel + 7) >> 3)) - (16 / ((pScrn->bitsPerPixel + 7) >> 3)); 1047 max_height = 8192 / ((pScrn->bitsPerPixel + 7) >> 3); 1048 1049 xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height); 1050 1051 viaOutputDetect(pScrn); 1052 1053 return TRUE; 1054} 1055