via_ums.c revision 03bd066f
1/* 2 * Copyright 2011-2016 The OpenChrome Project 3 * [http://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 %u 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 /* Unlock CRTC. */ 282 ViaCrtcMask(hwp, 0x47, 0x00, 0x01); 283 284 vgaHWGetIOBase(hwp); 285 286 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 287 "Exiting viaMapMMIO.\n")); 288 return TRUE; 289 290fail: 291 292#ifdef HAVE_PCIACCESS 293 if (pVia->FBBase) { 294 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 295 pVia->videoRambytes); 296 } 297 298 if (pVia->BltBase) { 299 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 300 VIA_MMIO_BLTSIZE); 301 } 302 303 if (pVia->MapBase) { 304 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 305 VIA_MMIO_REGSIZE); 306 } 307#else 308 if (pVia->FBBase) { 309 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 310 pVia->videoRambytes); 311 } 312 313 if (pVia->BltBase) { 314 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 315 VIA_MMIO_BLTSIZE); 316 } 317 318 if (pVia->MapBase) { 319 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 320 VIA_MMIO_REGSIZE); 321 } 322#endif 323 324 pVia->FBBase = NULL; 325 pVia->BltBase = NULL; 326 pVia->MapBase = NULL; 327 328 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 329 "Exiting viaMapMMIO.\n")); 330 return FALSE; 331} 332 333void 334viaUnmapMMIO(ScrnInfoPtr pScrn) 335{ 336 VIAPtr pVia = VIAPTR(pScrn); 337 338 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 339 "Entered viaUnmapMMIO.\n")); 340 341 viaMMIODisable(pScrn); 342 343#ifdef HAVE_PCIACCESS 344 if (pVia->FBBase) { 345 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 346 pVia->videoRambytes); 347 } 348 349 if (pVia->BltBase) { 350 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 351 VIA_MMIO_BLTSIZE); 352 } 353 354 if (pVia->MapBase) { 355 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 356 VIA_MMIO_REGSIZE); 357 } 358#else 359 if (pVia->FBBase) { 360 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 361 pVia->videoRambytes); 362 } 363 364 if (pVia->BltBase) { 365 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 366 VIA_MMIO_BLTSIZE); 367 } 368 369 if (pVia->MapBase) { 370 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 371 VIA_MMIO_REGSIZE); 372 } 373#endif 374 375 pVia->FBBase = NULL; 376 pVia->BltBase = NULL; 377 pVia->MapBase = NULL; 378 379 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 380 "Exiting viaUnmapMMIO.\n")); 381} 382 383/* 384 * Leftover from VIA's code. 385 */ 386static void 387viaInitPCIe(VIAPtr pVia) 388{ 389 VIASETREG(0x41c, 0x00100000); 390 VIASETREG(0x420, 0x680A0000); 391 VIASETREG(0x420, 0x02000000); 392} 393 394static void 395viaInitAGP(VIAPtr pVia) 396{ 397 VIASETREG(VIA_REG_TRANSET, 0x00100000); 398 VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 399 VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 400 VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 401 VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 402 VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 403 VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 404 VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 405 VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); 406 407 VIASETREG(VIA_REG_TRANSET, 0xfe020000); 408 VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 409} 410 411/* 412 * Initialize the virtual command queue. Header-2 commands can be put 413 * in this queue for buffering. AFAIK it doesn't handle Header-1 414 * commands, which is really a pity, since it has to be idled before 415 * issuing a Header-1 command. 416 */ 417static void 418viaEnableAGPVQ(VIAPtr pVia) 419{ 420 CARD32 421 vqStartAddr = pVia->VQStart, 422 vqEndAddr = pVia->VQEnd, 423 vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), 424 vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), 425 vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | 426 ((vqEndAddr & 0xFF000000) >> 16), 427 vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); 428 429 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 430 VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); 431 VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); 432 VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); 433 VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); 434 VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); 435 VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); 436 VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); 437 VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); 438 VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); 439 VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); 440 VIASETREG(VIA_REG_TRANSPACE, 0x00000006); 441 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 442 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 443 VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 444 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 445 446 VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); 447 VIASETREG(VIA_REG_TRANSPACE, vqStartL); 448 VIASETREG(VIA_REG_TRANSPACE, vqEndL); 449 VIASETREG(VIA_REG_TRANSPACE, vqLen); 450} 451 452static void 453viaEnablePCIeVQ(VIAPtr pVia) 454{ 455 CARD32 456 vqStartAddr = pVia->VQStart, 457 vqEndAddr = pVia->VQEnd, 458 vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), 459 vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), 460 vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | 461 ((vqEndAddr & 0xFF000000) >> 16), 462 vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); 463 464 VIASETREG(0x41c, 0x00100000); 465 VIASETREG(0x420, vqStartEndH); 466 VIASETREG(0x420, vqStartL); 467 VIASETREG(0x420, vqEndL); 468 VIASETREG(0x420, vqLen); 469 VIASETREG(0x420, 0x74301001); 470 VIASETREG(0x420, 0x00000000); 471} 472 473/* 474 * Disable the virtual command queue. 475 */ 476void 477viaDisableVQ(ScrnInfoPtr pScrn) 478{ 479 VIAPtr pVia = VIAPTR(pScrn); 480 481 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 482 "Entered viaDisableVQ.\n")); 483 484 switch (pVia->Chipset) { 485 case VIA_K8M890: 486 case VIA_P4M900: 487 case VIA_VX800: 488 case VIA_VX855: 489 case VIA_VX900: 490 VIASETREG(0x41c, 0x00100000); 491 VIASETREG(0x420, 0x74301000); 492 break; 493 default: 494 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 495 VIASETREG(VIA_REG_TRANSPACE, 0x00000004); 496 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 497 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 498 VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 499 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 500 break; 501 } 502 503 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 504 "Exiting viaDisableVQ.\n")); 505} 506 507/* 508 * Initialize the 2D engine and set the 2D context mode to the 509 * current screen depth. Also enable the virtual queue. 510 */ 511static void 512viaInitialize2DEngine(ScrnInfoPtr pScrn) 513{ 514 VIAPtr pVia = VIAPTR(pScrn); 515 ViaTwodContext *tdc = &pVia->td; 516 int i; 517 518 /* Initialize the 2D engine registers to reset the 2D engine. */ 519 for (i = 0x04; i <= 0x40; i += 4) { 520 VIASETREG(i, 0x0); 521 } 522 523 if (pVia->Chipset == VIA_VX800 || 524 pVia->Chipset == VIA_VX855 || 525 pVia->Chipset == VIA_VX900) { 526 for (i = 0x44; i <= 0x5c; i += 4) { 527 VIASETREG(i, 0x0); 528 } 529 } 530 531 if (pVia->Chipset == VIA_VX900) 532 { 533 /*410 redefine 0x30 34 38*/ 534 VIASETREG(0x60, 0x0); /*already useable here*/ 535 } 536 537 switch (pVia->Chipset) { 538 case VIA_K8M890: 539 case VIA_P4M900: 540 case VIA_VX800: 541 case VIA_VX855: 542 case VIA_VX900: 543 viaInitPCIe(pVia); 544 break; 545 default: 546 viaInitAGP(pVia); 547 break; 548 } 549 550 if (pVia->VQStart != 0) { 551 switch (pVia->Chipset) { 552 case VIA_K8M890: 553 case VIA_P4M900: 554 case VIA_VX800: 555 case VIA_VX855: 556 case VIA_VX900: 557 viaEnablePCIeVQ(pVia); 558 break; 559 default: 560 viaEnableAGPVQ(pVia); 561 break; 562 } 563 } else { 564 viaDisableVQ(pScrn); 565 } 566 567 viaAccelSetMode(pScrn->bitsPerPixel, tdc); 568} 569 570static void 571viaInitialize3DEngine(ScrnInfoPtr pScrn) 572{ 573 VIAPtr pVia = VIAPTR(pScrn); 574 int i; 575 576 VIASETREG(VIA_REG_TRANSET, 0x00010000); 577 for (i = 0; i <= 0x7D; i++) 578 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 579 580 VIASETREG(VIA_REG_TRANSET, 0x00020000); 581 for (i = 0; i <= 0x94; i++) 582 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 583 VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 584 585 VIASETREG(VIA_REG_TRANSET, 0x01020000); 586 for (i = 0; i <= 0x94; i++) 587 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 588 VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 589 590 VIASETREG(VIA_REG_TRANSET, 0xfe020000); 591 for (i = 0; i <= 0x03; i++) 592 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 593 594 VIASETREG(VIA_REG_TRANSET, 0x00030000); 595 for (i = 0; i <= 0xff; i++) 596 VIASETREG(VIA_REG_TRANSPACE, 0); 597 598 VIASETREG(VIA_REG_TRANSET, 0x00100000); 599 VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 600 VIASETREG(VIA_REG_TRANSPACE, 0x10000002); 601 VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 602 VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 603 VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 604 VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 605 VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 606 607 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 608 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3) 609 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 610 else 611 VIASETREG(VIA_REG_TRANSPACE, 0x4000800f); 612 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 613 VIASETREG(VIA_REG_TRANSPACE, 0x45080C04); 614 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 615 VIASETREG(VIA_REG_TRANSPACE, 0x50000000); 616 VIASETREG(VIA_REG_TRANSPACE, 0x51000000); 617 VIASETREG(VIA_REG_TRANSPACE, 0x52000000); 618 VIASETREG(VIA_REG_TRANSPACE, 0x53000000); 619 620 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 621 VIASETREG(VIA_REG_TRANSPACE, 0x08000001); 622 VIASETREG(VIA_REG_TRANSPACE, 0x0A000183); 623 VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F); 624 VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B); 625 VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B); 626 VIASETREG(VIA_REG_TRANSPACE, 0x0E000000); 627 VIASETREG(VIA_REG_TRANSPACE, 0x0F000000); 628 VIASETREG(VIA_REG_TRANSPACE, 0x10000000); 629 VIASETREG(VIA_REG_TRANSPACE, 0x11000000); 630 VIASETREG(VIA_REG_TRANSPACE, 0x20000000); 631} 632 633/* 634 * Acceleration initialization function. Sets up offscreen memory disposition, 635 * and initializes engines and acceleration method. 636 */ 637Bool 638umsAccelInit(ScreenPtr pScreen) 639{ 640 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 641 VIAPtr pVia = VIAPTR(pScrn); 642 Bool ret = FALSE; 643 644 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 645 "Entered umsAccelInit.\n")); 646 647 pVia->VQStart = 0; 648 pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM); 649 if (!pVia->vq_bo) 650 goto err; 651 652 pVia->VQStart = pVia->vq_bo->offset; 653 pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size; 654 655 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 656 "Initializing the 2D engine.\n")); 657 viaInitialize2DEngine(pScrn); 658 659 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 660 "Initializing the 3D engine.\n")); 661 viaInitialize3DEngine(pScrn); 662 663 pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 664 if (!pVia->exa_sync_bo) 665 goto err; 666 667 /* Sync marker space. */ 668 pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 669 if (!pVia->exa_sync_bo) 670 goto err; 671 672 pVia->markerOffset = pVia->exa_sync_bo->offset; 673 pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo); 674 if (!pVia->markerBuf) 675 goto err; 676 pVia->curMarker = 0; 677 pVia->lastMarkerRead = 0; 678 679#ifdef HAVE_DRI 680 pVia->dBounce = NULL; 681 pVia->scratchAddr = NULL; 682#endif /* HAVE_DRI */ 683 ret = TRUE; 684err: 685 if (!ret) { 686 if (pVia->markerBuf) { 687 drm_bo_unmap(pScrn, pVia->exa_sync_bo); 688 pVia->markerBuf = NULL; 689 } 690 if (pVia->exa_sync_bo) 691 drm_bo_free(pScrn, pVia->exa_sync_bo); 692 if (pVia->vq_bo) 693 drm_bo_free(pScrn, pVia->vq_bo); 694 } 695 696 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 697 "Exiting umsAccelInit.\n")); 698 return ret; 699} 700 701Bool 702umsCreate(ScrnInfoPtr pScrn) 703{ 704 ScreenPtr pScreen = pScrn->pScreen; 705 VIAPtr pVia = VIAPTR(pScrn); 706 unsigned long offset; 707 BoxRec AvailFBArea; 708 Bool ret = TRUE; 709 long size; 710 int maxY; 711 712#ifdef HAVE_DRI 713 if (pVia->directRenderingType == DRI_1) { 714 pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2; 715 if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) 716 pVia->driSize = pVia->maxDriSize * 1024; 717 718 /* In the case of DRI we handle all VRAM by the DRI ioctls */ 719 if (pVia->useEXA) 720 return TRUE; 721 722 /* XAA has to use FBManager so we have to split the space with DRI */ 723 maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); 724 } else 725#endif 726 maxY = pVia->FBFreeEnd / pVia->Bpl; 727 728 /* FBManager can't handle more than 32767 scan lines */ 729 if (maxY > 32767) 730 maxY = 32767; 731 732 AvailFBArea.x1 = 0; 733 AvailFBArea.y1 = 0; 734 AvailFBArea.x2 = pScrn->displayWidth; 735 AvailFBArea.y2 = maxY; 736 pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; 737 738 /* 739 * Initialization of the XFree86 framebuffer manager is done via 740 * Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox) 741 * FullBox represents the area of the framebuffer that the manager 742 * is allowed to manage. This is typically a box with a width 743 * of pScrn->displayWidth and a height of as many lines as can be fit 744 * within the total video memory 745 */ 746 ret = xf86InitFBManager(pScreen, &AvailFBArea); 747 if (ret != TRUE) 748 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n"); 749 750 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 751 "Frame Buffer From (%d,%d) To (%d,%d)\n", 752 AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2)); 753 754 offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp; 755 size = pVia->FBFreeEnd / pVia->Bpp - offset; 756 if (size > 0) 757 xf86InitFBManagerLinear(pScreen, offset, size); 758 759 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 760 "Using %d lines for offscreen memory.\n", 761 AvailFBArea.y2 - pScrn->virtualY)); 762 return TRUE; 763} 764 765Bool 766umsPreInit(ScrnInfoPtr pScrn) 767{ 768 MessageType from = X_PROBED; 769 VIAPtr pVia = VIAPTR(pScrn); 770 CARD8 videoRam; 771 vgaHWPtr hwp; 772#ifdef HAVE_PCIACCESS 773 struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3); 774 struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0); 775#endif 776 int bMemSize = 0; 777 778 if (!xf86LoadSubModule(pScrn, "vgahw")) 779 return FALSE; 780 781 if (!vgaHWGetHWRec(pScrn)) 782 return FALSE; 783 784#if 0 785 /* Here we can alter the number of registers saved and restored by the 786 * standard vgaHWSave and Restore routines. 787 */ 788 vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, 789 VGA_NUM_ATTR); 790#endif 791 hwp = VGAHWPTR(pScrn); 792 793 switch (pVia->Chipset) { 794 case VIA_CLE266: 795#ifdef HAVE_PCIACCESS 796 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 797#else 798 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 799#endif 800 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 801 break; 802 case VIA_KM400: 803#ifdef HAVE_PCIACCESS 804 /* P4M800 Host Bridge PCI Device ID */ 805 if (DEVICE_ID(bridge) == 0x0296) { 806 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 807 } else { 808 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 809 } 810#else 811 /* P4M800 Host Bridge PCI Device ID */ 812 if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) { 813 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 814 } else { 815 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 816 } 817#endif 818 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 819 break; 820 case VIA_PM800: 821 case VIA_P4M800PRO: 822 case VIA_K8M800: 823#ifdef HAVE_PCIACCESS 824 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 825#else 826 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 827#endif 828 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 829 break; 830 case VIA_P4M890: 831 case VIA_K8M890: 832 case VIA_P4M900: 833 case VIA_CX700: 834 case VIA_VX800: 835 case VIA_VX855: 836 case VIA_VX900: 837#ifdef HAVE_PCIACCESS 838 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 839#else 840 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 841#endif 842 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12; 843 break; 844 default: 845 if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { 846 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 847 "Using old memory-detection method.\n"); 848 bMemSize = hwp->readSeq(hwp, 0x39); 849 if (bMemSize > 16 && bMemSize <= 128) 850 pScrn->videoRam = (bMemSize + 1) << 9; 851 else if (bMemSize > 0 && bMemSize < 31) 852 pScrn->videoRam = bMemSize << 12; 853 else { 854 from = X_DEFAULT; 855 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 856 "Memory size detection failed: using 16 MB.\n"); 857 pScrn->videoRam = 16 << 10; 858 } 859 } else { 860 from = X_DEFAULT; 861 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 862 "No memory-detection done. Use VideoRAM option.\n"); 863 } 864 } 865 866 /* 867 * PCI BAR are limited to 256 MB. 868 */ 869 if (pScrn->videoRam > (256 << 10)) { 870 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 871 "Cannot use more than 256 MB of VRAM.\n"); 872 pScrn->videoRam = (256 << 10); 873 } 874 875 if (from == X_PROBED) { 876 xf86DrvMsg(pScrn->scrnIndex, from, 877 "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); 878 } 879 880 /* Split the FB for SAMM. */ 881 /* FIXME: For now, split the FB into two equal sections. 882 * This should be user-adjustable via a config option. */ 883 if (pVia->IsSecondary) { 884 DevUnion *pPriv; 885 VIAEntPtr pVIAEnt; 886 VIAPtr pVia1; 887 888 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); 889 pVIAEnt = pPriv->ptr; 890 pScrn->videoRam = pScrn->videoRam >> 1; 891 pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; 892 pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); 893 pVia1->videoRambytes = pScrn->videoRam << 10; 894 pVia->FrameBufferBase += (pScrn->videoRam << 10); 895 } 896 897 pVia->videoRambytes = pScrn->videoRam << 10; 898 899 /* maybe throw in some more sanity checks here */ 900#ifndef HAVE_PCIACCESS 901 pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, 902 pVia->PciInfo->func); 903#endif 904 905 /* Map PCI hardware resources to the memory map. */ 906 if (!viaMapMMIO(pScrn)) { 907 return FALSE; 908 } 909 910 return TRUE; 911} 912 913Bool 914umsCrtcInit(ScrnInfoPtr pScrn) 915{ 916 drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL; 917 vgaHWPtr hwp = VGAHWPTR(pScrn); 918 VIAPtr pVia = VIAPTR(pScrn); 919#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 920 ClockRangePtr clockRanges; 921#else 922 ClockRangesPtr clockRanges; 923#endif 924 int max_pitch, max_height; 925 VIABIOSInfoPtr pBIOSInfo; 926 xf86CrtcPtr iga1, iga2; 927 928 /* Read memory bandwidth from registers. */ 929 pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; 930 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 931 "Detected MemClk %d\n", pVia->MemClk)); 932 if (pVia->MemClk >= VIA_MEM_END) { 933 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 934 "Unknown Memory clock: %d\n", pVia->MemClk); 935 pVia->MemClk = VIA_MEM_END - 1; 936 } 937 pBIOSInfo = pVia->pBIOSInfo; 938 pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); 939 940 if (pBIOSInfo->TVType == TVTYPE_NONE) { 941 /* Use jumper to determine TV type. */ 942 if (hwp->readCrtc(hwp, 0x3B) & 0x02) { 943 pBIOSInfo->TVType = TVTYPE_PAL; 944 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 945 "Detected TV standard: PAL.\n")); 946 } else { 947 pBIOSInfo->TVType = TVTYPE_NTSC; 948 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 949 "Detected TV standard: NTSC.\n")); 950 } 951 } 952 953 if (pVia->drmmode.hwcursor) { 954 if (!xf86LoadSubModule(pScrn, "ramdac")) 955 return FALSE; 956 } 957 958 if (!xf86LoadSubModule(pScrn, "i2c")) 959 return FALSE; 960 else 961 ViaI2CInit(pScrn); 962 963 if (!xf86LoadSubModule(pScrn, "ddc")) 964 return FALSE; 965 966 /* 967 * Set up ClockRanges, which describe what clock ranges are 968 * available, and what sort of modes they can be used for. 969 */ 970 971#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 972 clockRanges = xnfalloc(sizeof(ClockRange)); 973#else 974 clockRanges = xnfalloc(sizeof(ClockRanges)); 975#endif 976 clockRanges->next = NULL; 977 clockRanges->minClock = 20000; 978 clockRanges->maxClock = 230000; 979 980 clockRanges->clockIndex = -1; 981 clockRanges->interlaceAllowed = TRUE; 982 clockRanges->doubleScanAllowed = FALSE; 983 pScrn->clockRanges = clockRanges; 984 985 /* 986 * Now handle the outputs 987 */ 988 iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 989 if (!iga1_rec) { 990 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 991 return FALSE; 992 } 993 994 iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs); 995 if (!iga1) { 996 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 997 free(iga1_rec); 998 return FALSE; 999 } 1000 iga1_rec->drmmode = &pVia->drmmode; 1001 iga1_rec->index = 0; 1002 iga1->driver_private = iga1_rec; 1003 1004 iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 1005 if (!iga2_rec) { 1006 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 1007 xf86CrtcDestroy(iga1); 1008 return FALSE; 1009 } 1010 1011 iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs); 1012 if (!iga2) { 1013 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 1014 xf86CrtcDestroy(iga1); 1015 free(iga2_rec); 1016 return FALSE; 1017 } 1018 iga2_rec->drmmode = &pVia->drmmode; 1019 iga2_rec->index = 1; 1020 iga2->driver_private = iga2_rec; 1021 1022 /* Init HI_X0 for cursor */ 1023 switch (pVia->Chipset) { 1024 case VIA_CX700: 1025 /* case VIA_CN750: */ 1026 case VIA_P4M890: 1027 case VIA_P4M900: 1028 case VIA_VX800: 1029 case VIA_VX855: 1030 case VIA_VX900: 1031 /* set 0 as transparent color key for IGA 2 */ 1032 VIASETREG(HI_TRANSPARENT_COLOR, 0); 1033 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 1034 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 1035 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 1036 1037 /* set 0 as transparent color key for IGA 1 */ 1038 VIASETREG(PRIM_HI_TRANSCOLOR, 0); 1039 VIASETREG(PRIM_HI_FIFO, 0x0D000D0F); 1040 VIASETREG(PRIM_HI_INVTCOLOR, 0x00FFFFFF); 1041 VIASETREG(V327_HI_INVTCOLOR, 0x00FFFFFF); 1042 break; 1043 1044 default: 1045 VIASETREG(HI_TRANSPARENT_COLOR, 0); 1046 VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 1047 VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 1048 VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 1049 break; 1050 } 1051 1052 /* 1053 * CLE266A: 1054 * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) 1055 * Max Height: 4096 (and beyond) 1056 * 1057 * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited 1058 * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). 1059 * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. 1060 * 1061 * We should be able to limit the memory available for a mode to 32 MB, 1062 * but miScanLineWidth fails to catch this properly (apertureSize). 1063 */ 1064 max_pitch = 8192 / ((pScrn->bitsPerPixel + 7) >> 3); 1065 max_height = max_pitch; 1066 1067 xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height); 1068 1069 viaOutputDetect(pScrn); 1070 1071 return TRUE; 1072} 1073