via_ums.c revision 4dc64ea9
1/* 2 * Copyright 2011-2015 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 34ViaMMIODisable(ScrnInfoPtr pScrn) 35{ 36 VIAPtr pVia = VIAPTR(pScrn); 37 vgaHWPtr hwp = VGAHWPTR(pScrn); 38 39 switch (pVia->Chipset) { 40 case VIA_CX700: 41 case VIA_K8M890: 42 case VIA_P4M900: 43 case VIA_VX800: 44 case VIA_VX855: 45 case VIA_VX900: 46 ViaSeqMask(hwp, 0x1A, 0x00, 0x08); 47 break; 48 default: 49 ViaSeqMask(hwp, 0x1A, 0x00, 0x60); 50 break; 51 } 52} 53 54void 55VIAUnmapMMIO(ScrnInfoPtr pScrn) 56{ 57 VIAPtr pVia = VIAPTR(pScrn); 58 59 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 60 "Entered VIAUnmapMMIO.\n")); 61 62 ViaMMIODisable(pScrn); 63 64#ifdef HAVE_PCIACCESS 65 if (pVia->MapBase) 66 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 67 VIA_MMIO_REGSIZE); 68 69 if (pVia->BltBase) 70 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 71 VIA_MMIO_BLTSIZE); 72 73 if (pVia->FBBase) 74 pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 75 pVia->videoRambytes); 76#else 77 if (pVia->MapBase) 78 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 79 VIA_MMIO_REGSIZE); 80 81 if (pVia->BltBase) 82 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 83 VIA_MMIO_BLTSIZE); 84 85 if (pVia->FBBase) 86 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 87 pVia->videoRambytes); 88#endif 89 90 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 91 "Exiting VIAUnmapMMIO.\n")); 92} 93 94static void 95ViaMMIOEnable(ScrnInfoPtr pScrn) 96{ 97 VIAPtr pVia = VIAPTR(pScrn); 98 vgaHWPtr hwp = VGAHWPTR(pScrn); 99 100 switch (pVia->Chipset) { 101 case VIA_CX700: 102 case VIA_K8M890: 103 case VIA_P4M900: 104 case VIA_VX800: 105 case VIA_VX855: 106 case VIA_VX900: 107 ViaSeqMask(hwp, 0x1A, 0x08, 0x08); 108 break; 109 default: 110 if (pVia->IsSecondary) 111 ViaSeqMask(hwp, 0x1A, 0x38, 0x38); 112 else 113 ViaSeqMask(hwp, 0x1A, 0x68, 0x68); 114 break; 115 } 116} 117 118static Bool 119VIAMapMMIO(ScrnInfoPtr pScrn) 120{ 121 VIAPtr pVia = VIAPTR(pScrn); 122 123#ifdef HAVE_PCIACCESS 124 pVia->MmioBase = pVia->PciInfo->regions[1].base_addr; 125 int err; 126#else 127 pVia->MmioBase = pVia->PciInfo->memBase[1]; 128#endif 129 130 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n")); 131 132 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 133 "mapping MMIO @ 0x%lx with size 0x%x\n", 134 pVia->MmioBase, VIA_MMIO_REGSIZE); 135 136#ifdef HAVE_PCIACCESS 137 err = pci_device_map_range(pVia->PciInfo, 138 pVia->MmioBase, 139 VIA_MMIO_REGSIZE, 140 PCI_DEV_MAP_FLAG_WRITABLE, 141 (void **)&pVia->MapBase); 142 143 if (err) { 144 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 145 "Unable to map mmio BAR. %s (%d)\n", strerror(err), err); 146 return FALSE; 147 } 148#else 149 pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 150 pVia->MmioBase, VIA_MMIO_REGSIZE); 151 if (!pVia->MapBase) 152 return FALSE; 153#endif 154 155 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 156 "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n", 157 pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE); 158 159#ifdef HAVE_PCIACCESS 160 err = pci_device_map_range(pVia->PciInfo, 161 pVia->MmioBase + VIA_MMIO_BLTBASE, 162 VIA_MMIO_BLTSIZE, 163 PCI_DEV_MAP_FLAG_WRITABLE, 164 (void **)&pVia->BltBase); 165 166 if (err) { 167 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 168 "Unable to map blt BAR. %s (%d)\n", strerror(err), err); 169 return FALSE; 170 } 171#else 172 pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 173 pVia->MmioBase + VIA_MMIO_BLTBASE, 174 VIA_MMIO_BLTSIZE); 175 if (!pVia->BltBase) 176 return FALSE; 177#endif 178 179 if (!pVia->MapBase || !pVia->BltBase) { 180 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 181 "BitBlit could not be mapped.\n"); 182 return FALSE; 183 } 184 185 /* Memory mapped IO for mpeg engine. */ 186 pVia->MpegMapBase = pVia->MapBase + 0xc00; 187 188 /* Set up MMIO vgaHW. */ 189 { 190 vgaHWPtr hwp = VGAHWPTR(pScrn); 191 CARD8 val; 192 193 vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); 194 195 val = hwp->readEnable(hwp); 196 hwp->writeEnable(hwp, val | 0x01); 197 198 val = hwp->readMiscOut(hwp); 199 hwp->writeMiscOut(hwp, val | 0x01); 200 201 /* Unlock extended IO space. */ 202 ViaSeqMask(hwp, 0x10, 0x01, 0x01); 203 204 ViaMMIOEnable(pScrn); 205 206 vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); 207 208 /* Unlock CRTC. */ 209 ViaCrtcMask(hwp, 0x47, 0x00, 0x01); 210 211 vgaHWGetIOBase(hwp); 212 } 213 return TRUE; 214} 215 216static Bool 217VIAMapFB(ScrnInfoPtr pScrn) 218{ 219 VIAPtr pVia = VIAPTR(pScrn); 220 221#ifdef HAVE_PCIACCESS 222 if (pVia->Chipset == VIA_VX900) { 223 pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr; 224 } else { 225 pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr; 226 } 227 int err; 228#else 229 if (pVia->Chipset == VIA_VX900) { 230 pVia->FrameBufferBase = pVia->PciInfo->memBase[2]; 231 } else { 232 pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; 233 } 234#endif 235 236 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n")); 237 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 238 "mapping framebuffer @ 0x%lx with size 0x%lx\n", 239 pVia->FrameBufferBase, pVia->videoRambytes); 240 241 if (pVia->videoRambytes) { 242 243#ifndef HAVE_PCIACCESS 244 /* 245 * FIXME: This is a hack to get rid of offending wrongly sized 246 * MTRR regions set up by the VIA BIOS. Should be taken care of 247 * in the OS support layer. 248 */ 249 unsigned char *tmp; 250 251 tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 252 pVia->FrameBufferBase, pVia->videoRambytes); 253 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes); 254 255 /* 256 * And, as if this wasn't enough, 2.6 series kernels don't 257 * remove MTRR regions on the first attempt. So try again. 258 */ 259 260 tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 261 pVia->FrameBufferBase, pVia->videoRambytes); 262 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes); 263 264 /* 265 * End of hack. 266 */ 267#endif 268 269#ifdef HAVE_PCIACCESS 270 err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase, 271 pVia->videoRambytes, 272 (PCI_DEV_MAP_FLAG_WRITABLE | 273 PCI_DEV_MAP_FLAG_WRITE_COMBINE), 274 (void **)&pVia->FBBase); 275 if (err) { 276 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 277 "Unable to map mmio BAR. %s (%d)\n", strerror(err), err); 278 return FALSE; 279 } 280#else 281 pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 282 pVia->PciTag, pVia->FrameBufferBase, 283 pVia->videoRambytes); 284 285 if (!pVia->FBBase) { 286 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 287 "Internal error: could not map framebuffer\n"); 288 return FALSE; 289 } 290#endif 291 292 pVia->FBFreeStart = 0; 293 pVia->FBFreeEnd = pVia->videoRambytes; 294 295 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 296 "Frame buffer start: %p, free start: 0x%x end: 0x%x\n", 297 pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd); 298 } 299 300#ifdef HAVE_PCIACCESS 301 pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr; 302#else 303 pScrn->memPhysBase = pVia->PciInfo->memBase[0]; 304#endif 305 pScrn->fbOffset = 0; 306 if (pVia->IsSecondary) 307 pScrn->fbOffset = pScrn->videoRam << 10; 308 309 return TRUE; 310} 311 312/* 313 * Leftover from VIA's code. 314 */ 315static void 316viaInitPCIe(VIAPtr pVia) 317{ 318 VIASETREG(0x41c, 0x00100000); 319 VIASETREG(0x420, 0x680A0000); 320 VIASETREG(0x420, 0x02000000); 321} 322 323static void 324viaInitAgp(VIAPtr pVia) 325{ 326 VIASETREG(VIA_REG_TRANSET, 0x00100000); 327 VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 328 VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 329 VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 330 VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 331 VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 332 VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 333 VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 334 VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); 335 336 VIASETREG(VIA_REG_TRANSET, 0xfe020000); 337 VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 338} 339 340/* 341 * Initialize the virtual command queue. Header-2 commands can be put 342 * in this queue for buffering. AFAIK it doesn't handle Header-1 343 * commands, which is really a pity, since it has to be idled before 344 * issuing a Header-1 command. 345 */ 346static void 347viaEnableAgpVQ(VIAPtr pVia) 348{ 349 CARD32 350 vqStartAddr = pVia->VQStart, 351 vqEndAddr = pVia->VQEnd, 352 vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), 353 vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), 354 vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | 355 ((vqEndAddr & 0xFF000000) >> 16), 356 vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); 357 358 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 359 VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); 360 VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); 361 VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); 362 VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); 363 VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); 364 VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); 365 VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); 366 VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); 367 VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); 368 VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); 369 VIASETREG(VIA_REG_TRANSPACE, 0x00000006); 370 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 371 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 372 VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 373 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 374 375 VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); 376 VIASETREG(VIA_REG_TRANSPACE, vqStartL); 377 VIASETREG(VIA_REG_TRANSPACE, vqEndL); 378 VIASETREG(VIA_REG_TRANSPACE, vqLen); 379} 380 381static void 382viaEnablePCIeVQ(VIAPtr pVia) 383{ 384 CARD32 385 vqStartAddr = pVia->VQStart, 386 vqEndAddr = pVia->VQEnd, 387 vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), 388 vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), 389 vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | 390 ((vqEndAddr & 0xFF000000) >> 16), 391 vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); 392 393 VIASETREG(0x41c, 0x00100000); 394 VIASETREG(0x420, vqStartEndH); 395 VIASETREG(0x420, vqStartL); 396 VIASETREG(0x420, vqEndL); 397 VIASETREG(0x420, vqLen); 398 VIASETREG(0x420, 0x74301001); 399 VIASETREG(0x420, 0x00000000); 400} 401 402/* 403 * Disable the virtual command queue. 404 */ 405void 406viaDisableVQ(ScrnInfoPtr pScrn) 407{ 408 VIAPtr pVia = VIAPTR(pScrn); 409 410 switch (pVia->Chipset) { 411 case VIA_K8M890: 412 case VIA_P4M900: 413 case VIA_VX800: 414 case VIA_VX855: 415 case VIA_VX900: 416 VIASETREG(0x41c, 0x00100000); 417 VIASETREG(0x420, 0x74301000); 418 break; 419 default: 420 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 421 VIASETREG(VIA_REG_TRANSPACE, 0x00000004); 422 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 423 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 424 VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 425 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 426 break; 427 } 428} 429 430/* 431 * Initialize the 2D engine and set the 2D context mode to the 432 * current screen depth. Also enable the virtual queue. 433 */ 434static void 435VIAInitialize2DEngine(ScrnInfoPtr pScrn) 436{ 437 VIAPtr pVia = VIAPTR(pScrn); 438 ViaTwodContext *tdc = &pVia->td; 439 int i; 440 441 /* Initialize the 2D engine registers to reset the 2D engine. */ 442 for (i = 0x04; i <= 0x40; i += 4) { 443 VIASETREG(i, 0x0); 444 } 445 446 if (pVia->Chipset == VIA_VX800 || 447 pVia->Chipset == VIA_VX855 || 448 pVia->Chipset == VIA_VX900) { 449 for (i = 0x44; i <= 0x5c; i += 4) { 450 VIASETREG(i, 0x0); 451 } 452 } 453 454 if (pVia->Chipset == VIA_VX900) 455 { 456 /*410 redefine 0x30 34 38*/ 457 VIASETREG(0x60, 0x0); /*already useable here*/ 458 } 459 460 switch (pVia->Chipset) { 461 case VIA_K8M890: 462 case VIA_P4M900: 463 case VIA_VX800: 464 case VIA_VX855: 465 case VIA_VX900: 466 viaInitPCIe(pVia); 467 break; 468 default: 469 viaInitAgp(pVia); 470 break; 471 } 472 473 if (pVia->VQStart != 0) { 474 switch (pVia->Chipset) { 475 case VIA_K8M890: 476 case VIA_P4M900: 477 case VIA_VX800: 478 case VIA_VX855: 479 case VIA_VX900: 480 viaEnablePCIeVQ(pVia); 481 break; 482 default: 483 viaEnableAgpVQ(pVia); 484 break; 485 } 486 } else { 487 viaDisableVQ(pScrn); 488 } 489 490 viaAccelSetMode(pScrn->bitsPerPixel, tdc); 491} 492 493static void 494VIAInitialize3DEngine(ScrnInfoPtr pScrn) 495{ 496 VIAPtr pVia = VIAPTR(pScrn); 497 int i; 498 499 VIASETREG(VIA_REG_TRANSET, 0x00010000); 500 for (i = 0; i <= 0x7D; i++) 501 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 502 503 VIASETREG(VIA_REG_TRANSET, 0x00020000); 504 for (i = 0; i <= 0x94; i++) 505 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 506 VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 507 508 VIASETREG(VIA_REG_TRANSET, 0x01020000); 509 for (i = 0; i <= 0x94; i++) 510 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 511 VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 512 513 VIASETREG(VIA_REG_TRANSET, 0xfe020000); 514 for (i = 0; i <= 0x03; i++) 515 VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 516 517 VIASETREG(VIA_REG_TRANSET, 0x00030000); 518 for (i = 0; i <= 0xff; i++) 519 VIASETREG(VIA_REG_TRANSPACE, 0); 520 521 VIASETREG(VIA_REG_TRANSET, 0x00100000); 522 VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 523 VIASETREG(VIA_REG_TRANSPACE, 0x10000002); 524 VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 525 VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 526 VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 527 VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 528 VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 529 530 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 531 if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3) 532 VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 533 else 534 VIASETREG(VIA_REG_TRANSPACE, 0x4000800f); 535 VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 536 VIASETREG(VIA_REG_TRANSPACE, 0x45080C04); 537 VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 538 VIASETREG(VIA_REG_TRANSPACE, 0x50000000); 539 VIASETREG(VIA_REG_TRANSPACE, 0x51000000); 540 VIASETREG(VIA_REG_TRANSPACE, 0x52000000); 541 VIASETREG(VIA_REG_TRANSPACE, 0x53000000); 542 543 VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 544 VIASETREG(VIA_REG_TRANSPACE, 0x08000001); 545 VIASETREG(VIA_REG_TRANSPACE, 0x0A000183); 546 VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F); 547 VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B); 548 VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B); 549 VIASETREG(VIA_REG_TRANSPACE, 0x0E000000); 550 VIASETREG(VIA_REG_TRANSPACE, 0x0F000000); 551 VIASETREG(VIA_REG_TRANSPACE, 0x10000000); 552 VIASETREG(VIA_REG_TRANSPACE, 0x11000000); 553 VIASETREG(VIA_REG_TRANSPACE, 0x20000000); 554} 555 556/* 557 * Acceleration initialization function. Sets up offscreen memory disposition, 558 * and initializes engines and acceleration method. 559 */ 560Bool 561UMSAccelInit(ScreenPtr pScreen) 562{ 563 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 564 VIAPtr pVia = VIAPTR(pScrn); 565 Bool ret = FALSE; 566 567 pVia->VQStart = 0; 568 pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM); 569 if (!pVia->vq_bo) 570 goto err; 571 572 pVia->VQStart = pVia->vq_bo->offset; 573 pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size; 574 575 VIAInitialize2DEngine(pScrn); 576 VIAInitialize3DEngine(pScrn); 577 578 pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 579 if (!pVia->exa_sync_bo) 580 goto err; 581 582 /* Sync marker space. */ 583 pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 584 if (!pVia->exa_sync_bo) 585 goto err; 586 587 pVia->markerOffset = pVia->exa_sync_bo->offset; 588 pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo); 589 if (!pVia->markerBuf) 590 goto err; 591 pVia->curMarker = 0; 592 pVia->lastMarkerRead = 0; 593 594#ifdef HAVE_DRI 595 pVia->dBounce = NULL; 596 pVia->scratchAddr = NULL; 597#endif /* HAVE_DRI */ 598 ret = TRUE; 599err: 600 if (!ret) { 601 if (pVia->markerBuf) { 602 drm_bo_unmap(pScrn, pVia->exa_sync_bo); 603 pVia->markerBuf = NULL; 604 } 605 if (pVia->exa_sync_bo) 606 drm_bo_free(pScrn, pVia->exa_sync_bo); 607 if (pVia->vq_bo) 608 drm_bo_free(pScrn, pVia->vq_bo); 609 } 610 return ret; 611} 612 613Bool 614ums_create(ScrnInfoPtr pScrn) 615{ 616 ScreenPtr pScreen = pScrn->pScreen; 617 VIAPtr pVia = VIAPTR(pScrn); 618 unsigned long offset; 619 BoxRec AvailFBArea; 620 Bool ret = TRUE; 621 long size; 622 int maxY; 623 624#ifdef HAVE_DRI 625 if (pVia->directRenderingType == DRI_1) { 626 pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2; 627 if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) 628 pVia->driSize = pVia->maxDriSize * 1024; 629 630 /* In the case of DRI we handle all VRAM by the DRI ioctls */ 631 if (pVia->useEXA) 632 return TRUE; 633 634 /* XAA has to use FBManager so we have to split the space with DRI */ 635 maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); 636 } else 637#endif 638 maxY = pVia->FBFreeEnd / pVia->Bpl; 639 640 /* FBManager can't handle more than 32767 scan lines */ 641 if (maxY > 32767) 642 maxY = 32767; 643 644 AvailFBArea.x1 = 0; 645 AvailFBArea.y1 = 0; 646 AvailFBArea.x2 = pScrn->displayWidth; 647 AvailFBArea.y2 = maxY; 648 pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; 649 650 /* 651 * Initialization of the XFree86 framebuffer manager is done via 652 * Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox) 653 * FullBox represents the area of the framebuffer that the manager 654 * is allowed to manage. This is typically a box with a width 655 * of pScrn->displayWidth and a height of as many lines as can be fit 656 * within the total video memory 657 */ 658 ret = xf86InitFBManager(pScreen, &AvailFBArea); 659 if (ret != TRUE) 660 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n"); 661 662 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 663 "Frame Buffer From (%d,%d) To (%d,%d)\n", 664 AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2)); 665 666 offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp; 667 size = pVia->FBFreeEnd / pVia->Bpp - offset; 668 if (size > 0) 669 xf86InitFBManagerLinear(pScreen, offset, size); 670 671 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 672 "Using %d lines for offscreen memory.\n", 673 AvailFBArea.y2 - pScrn->virtualY)); 674 return TRUE; 675} 676 677Bool 678UMSPreInit(ScrnInfoPtr pScrn) 679{ 680 MessageType from = X_PROBED; 681 VIAPtr pVia = VIAPTR(pScrn); 682 CARD8 videoRam; 683 vgaHWPtr hwp; 684#ifdef HAVE_PCIACCESS 685 struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3); 686 struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0); 687#endif 688 int bMemSize = 0; 689 690 if (!xf86LoadSubModule(pScrn, "vgahw")) 691 return FALSE; 692 693 if (!vgaHWGetHWRec(pScrn)) 694 return FALSE; 695 696#if 0 697 /* Here we can alter the number of registers saved and restored by the 698 * standard vgaHWSave and Restore routines. 699 */ 700 vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, 701 VGA_NUM_ATTR); 702#endif 703 hwp = VGAHWPTR(pScrn); 704 705 switch (pVia->Chipset) { 706 case VIA_CLE266: 707#ifdef HAVE_PCIACCESS 708 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 709#else 710 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 711#endif 712 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 713 break; 714 case VIA_KM400: 715#ifdef HAVE_PCIACCESS 716 /* P4M800 Host Bridge PCI Device ID */ 717 if (DEVICE_ID(bridge) == 0x0296) { 718 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 719 } else { 720 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 721 } 722#else 723 /* P4M800 Host Bridge PCI Device ID */ 724 if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) { 725 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 726 } else { 727 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 728 } 729#endif 730 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 731 break; 732 case VIA_PM800: 733 case VIA_P4M800PRO: 734 case VIA_K8M800: 735#ifdef HAVE_PCIACCESS 736 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 737#else 738 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 739#endif 740 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 741 break; 742 case VIA_P4M890: 743 case VIA_K8M890: 744 case VIA_P4M900: 745 case VIA_CX700: 746 case VIA_VX800: 747 case VIA_VX855: 748 case VIA_VX900: 749#ifdef HAVE_PCIACCESS 750 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 751#else 752 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 753#endif 754 pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12; 755 break; 756 default: 757 if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { 758 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 759 "Using old memory-detection method.\n"); 760 bMemSize = hwp->readSeq(hwp, 0x39); 761 if (bMemSize > 16 && bMemSize <= 128) 762 pScrn->videoRam = (bMemSize + 1) << 9; 763 else if (bMemSize > 0 && bMemSize < 31) 764 pScrn->videoRam = bMemSize << 12; 765 else { 766 from = X_DEFAULT; 767 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 768 "Memory size detection failed: using 16 MB.\n"); 769 pScrn->videoRam = 16 << 10; 770 } 771 } else { 772 from = X_DEFAULT; 773 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 774 "No memory-detection done. Use VideoRAM option.\n"); 775 } 776 } 777 778 /* 779 * PCI BAR are limited to 256 MB. 780 */ 781 if (pScrn->videoRam > (256 << 10)) { 782 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 783 "Cannot use more than 256 MB of VRAM.\n"); 784 pScrn->videoRam = (256 << 10); 785 } 786 787 if (from == X_PROBED) { 788 xf86DrvMsg(pScrn->scrnIndex, from, 789 "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); 790 } 791 792 /* Split the FB for SAMM. */ 793 /* FIXME: For now, split the FB into two equal sections. 794 * This should be user-adjustable via a config option. */ 795 if (pVia->IsSecondary) { 796 DevUnion *pPriv; 797 VIAEntPtr pVIAEnt; 798 VIAPtr pVia1; 799 800 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); 801 pVIAEnt = pPriv->ptr; 802 pScrn->videoRam = pScrn->videoRam >> 1; 803 pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; 804 pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); 805 pVia1->videoRambytes = pScrn->videoRam << 10; 806 pVia->FrameBufferBase += (pScrn->videoRam << 10); 807 } 808 809 pVia->videoRambytes = pScrn->videoRam << 10; 810 811 /* maybe throw in some more sanity checks here */ 812#ifndef HAVE_PCIACCESS 813 pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, 814 pVia->PciInfo->func); 815#endif 816 817 /* Detect the amount of installed RAM */ 818 if (!VIAMapMMIO(pScrn)) 819 return FALSE; 820 821 if (!VIAMapFB(pScrn)) 822 return FALSE; 823 return TRUE; 824} 825