1 /* 2 * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, 3 * Precision Insight, Inc., Cedar Park, Texas, and 4 * VA Linux Systems Inc., Fremont, California. 5 * 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining 9 * a copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation on the rights to use, copy, modify, merge, 12 * publish, distribute, sublicense, and/or sell copies of the Software, 13 * and to permit persons to whom the Software is furnished to do so, 14 * subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial 18 * portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX 24 * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 * OTHER DEALINGS IN THE SOFTWARE. 28 */ 29 30 #ifdef HAVE_CONFIG_H 31 #include "config.h" 32 #endif 33 34 /* 35 * Authors: 36 * Rickard E. Faith <faith (at) valinux.com> 37 * Kevin E. Martin <martin (at) valinux.com> 38 * Gareth Hughes <gareth (at) valinux.com> 39 * 40 * Credits: 41 * 42 * Thanks to Alan Hourihane <alanh (at) fairlite.demon..co.uk> and SuSE for 43 * providing source code to their 3.3.x Rage 128 driver. Portions of 44 * this file are based on the initialization code for that driver. 45 * 46 * References: 47 * 48 * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical 49 * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April 50 * 1999. 51 * 52 * RAGE 128 Software Development Manual (Technical Reference Manual P/N 53 * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. 54 * 55 * This server does not yet support these XFree86 4.0 features: 56 * DDC1 & DDC2 57 * shadowfb 58 * overlay planes 59 * 60 * Modified by Marc Aurele La France <tsi (at) xfree86.org> for ATI driver merge. 61 * 62 * Dualhead support - Alex Deucher <agd5f (at) yahoo.com> 63 */ 64 65 #include <string.h> 66 #include <stdio.h> 67 68 /* Driver data structures */ 69 #include "r128.h" 70 #include "r128_probe.h" 71 #include "r128_reg.h" 72 #include "r128_version.h" 73 #include "xf86Priv.h" 74 75 #ifdef HAVE_DEV_WSCONS_WSCONSIO_H 76 #include <sys/time.h> 77 #include <sys/ioctl.h> 78 #include <dev/wscons/wsconsio.h> 79 #endif 80 81 #ifdef R128DRI 82 #define _XF86DRI_SERVER_ 83 #include "r128_dri.h" 84 #include "r128_common.h" 85 #include "r128_sarea.h" 86 #endif 87 88 /* colormap initialization */ 89 #include "micmap.h" 90 91 /* X and server generic header files */ 92 #include "xf86.h" 93 #include "xf86_OSproc.h" 94 #include "xf86RandR12.h" 95 #include "xf86cmap.h" 96 #include "xf86xv.h" 97 #include "vbe.h" 98 #include "xf86Priv.h" 99 #include "xf86Privstr.h" 100 101 /* fbdevhw & vgahw */ 102 #ifdef WITH_VGAHW 103 #include "vgaHW.h" 104 #endif 105 106 #ifndef AVOID_FBDEV 107 #include "fbdevhw.h" 108 #endif 109 110 #include "dixstruct.h" 111 112 /* DPMS support. */ 113 #ifdef HAVE_XEXTPROTO_71 114 #include <X11/extensions/dpmsconst.h> 115 #else 116 #define DPMS_SERVER 117 #include <X11/extensions/dpms.h> 118 #endif 119 120 static Bool R128CloseScreen(ScreenPtr pScreen); 121 static Bool R128SaveScreen(ScreenPtr pScreen, int mode); 122 static void R128Save(ScrnInfoPtr pScrn); 123 static void R128Restore(ScrnInfoPtr pScrn); 124 125 typedef enum { 126 OPTION_NOACCEL, 127 #ifndef AVOID_FBDEV 128 OPTION_FBDEV, 129 #endif 130 OPTION_DAC_6BIT, 131 OPTION_VGA_ACCESS, 132 OPTION_SHOW_CACHE, 133 OPTION_SW_CURSOR, 134 OPTION_VIDEO_KEY, 135 OPTION_PANEL_WIDTH, 136 OPTION_PANEL_HEIGHT, 137 OPTION_PROG_FP_REGS, 138 #ifdef R128DRI 139 OPTION_XV_DMA, 140 OPTION_IS_PCI, 141 OPTION_CCE_PIO, 142 OPTION_NO_SECURITY, 143 OPTION_USEC_TIMEOUT, 144 OPTION_AGP_MODE, 145 OPTION_AGP_SIZE, 146 OPTION_RING_SIZE, 147 OPTION_BUFFER_SIZE, 148 OPTION_PAGE_FLIP, 149 #endif 150 OPTION_ACCELMETHOD, 151 OPTION_RENDERACCEL 152 } R128Opts; 153 154 static const OptionInfoRec R128Options[] = { 155 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 156 #ifndef AVOID_FBDEV 157 { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 158 #endif 159 { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, 160 { OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE }, 161 { OPTION_SHOW_CACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, 162 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 163 { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 164 { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, 165 { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, 166 { OPTION_PROG_FP_REGS, "ProgramFPRegs", OPTV_BOOLEAN, {0}, FALSE }, 167 #ifdef R128DRI 168 { OPTION_XV_DMA, "DMAForXv", OPTV_BOOLEAN, {0}, FALSE }, 169 { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, 170 { OPTION_CCE_PIO, "CCEPIOMode", OPTV_BOOLEAN, {0}, FALSE }, 171 { OPTION_NO_SECURITY, "CCENoSecurity", OPTV_BOOLEAN, {0}, FALSE }, 172 { OPTION_USEC_TIMEOUT, "CCEusecTimeout", OPTV_INTEGER, {0}, FALSE }, 173 { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, 174 { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, 175 { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, 176 { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, 177 { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE }, 178 #endif 179 { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 180 { OPTION_RENDERACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE }, 181 { -1, NULL, OPTV_NONE, {0}, FALSE } 182 }; 183 184 const OptionInfoRec *R128OptionsWeak(void) { return R128Options; } 185 186 R128RAMRec R128RAM[] = { /* Memory Specifications 187 From RAGE 128 Software Development 188 Manual (Technical Reference Manual P/N 189 SDK-G04000 Rev 0.01), page 3-21. */ 190 { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, 191 { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, 192 { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, 193 { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, 194 }; 195 196 extern _X_EXPORT int gR128EntityIndex; 197 198 int getR128EntityIndex(void) 199 { 200 return gR128EntityIndex; 201 } 202 203 R128EntPtr R128EntPriv(ScrnInfoPtr pScrn) 204 { 205 DevUnion *pPriv; 206 R128InfoPtr info = R128PTR(pScrn); 207 pPriv = xf86GetEntityPrivate(info->pEnt->index, 208 getR128EntityIndex()); 209 return pPriv->ptr; 210 } 211 212 /* Allocate our private R128InfoRec. */ 213 static Bool R128GetRec(ScrnInfoPtr pScrn) 214 { 215 if (pScrn->driverPrivate) return TRUE; 216 217 pScrn->driverPrivate = XNFcallocarray(1, sizeof(R128InfoRec)); 218 return TRUE; 219 } 220 221 /* Free our private R128InfoRec. */ 222 static void R128FreeRec(ScrnInfoPtr pScrn) 223 { 224 if (!pScrn || !pScrn->driverPrivate) return; 225 free(pScrn->driverPrivate); 226 pScrn->driverPrivate = NULL; 227 } 228 229 /* Memory map the MMIO region. Used during pre-init and by R128MapMem, 230 below. */ 231 static Bool R128MapMMIO(ScrnInfoPtr pScrn) 232 { 233 R128InfoPtr info = R128PTR(pScrn); 234 235 #ifndef AVOID_FBDEV 236 if (info->FBDev) { 237 info->MMIO = fbdevHWMapMMIO(pScrn); 238 } else 239 #endif 240 { 241 #ifndef XSERVER_LIBPCIACCESS 242 info->MMIO = xf86MapPciMem(pScrn->scrnIndex, 243 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 244 info->PciTag, 245 info->MMIOAddr, 246 R128_MMIOSIZE); 247 if (!info->MMIO) return FALSE; 248 #else 249 int err = pci_device_map_range(info->PciInfo, 250 info->MMIOAddr, 251 R128_MMIOSIZE, 252 PCI_DEV_MAP_FLAG_WRITABLE, 253 &info->MMIO); 254 255 if (err) { 256 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, 257 "Unable to map MMIO aperture. %s (%d)\n", 258 strerror (err), err); 259 return FALSE; 260 } 261 #endif 262 } 263 264 return TRUE; 265 } 266 267 /* Unmap the MMIO region. Used during pre-init and by R128UnmapMem, 268 below. */ 269 static Bool R128UnmapMMIO(ScrnInfoPtr pScrn) 270 { 271 R128InfoPtr info = R128PTR(pScrn); 272 273 #ifndef AVOID_FBDEV 274 if (info->FBDev) 275 fbdevHWUnmapMMIO(pScrn); 276 else 277 #endif 278 { 279 #ifndef XSERVER_LIBPCIACCESS 280 xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE); 281 #else 282 pci_device_unmap_range(info->PciInfo, info->MMIO, R128_MMIOSIZE); 283 #endif 284 } 285 info->MMIO = NULL; 286 return TRUE; 287 } 288 289 /* Memory map the frame buffer. Used by R128MapMem, below. */ 290 static Bool R128MapFB(ScrnInfoPtr pScrn) 291 { 292 R128InfoPtr info = R128PTR(pScrn); 293 294 #ifndef AVOID_FBDEV 295 if (info->FBDev) { 296 info->FB = fbdevHWMapVidmem(pScrn); 297 } else 298 #endif 299 { 300 #ifndef XSERVER_LIBPCIACCESS 301 info->FB = xf86MapPciMem(pScrn->scrnIndex, 302 VIDMEM_FRAMEBUFFER, 303 info->PciTag, 304 info->LinearAddr, 305 info->FbMapSize); 306 #else 307 int err = pci_device_map_range(info->PciInfo, 308 info->LinearAddr, 309 info->FbMapSize, 310 PCI_DEV_MAP_FLAG_WRITABLE | 311 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 312 &info->FB); 313 314 if (err) { 315 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, 316 "Unable to map FB aperture. %s (%d)\n", 317 strerror (err), err); 318 return FALSE; 319 } 320 #endif 321 } 322 323 if (!info->FB) return FALSE; 324 return TRUE; 325 } 326 327 /* Unmap the frame buffer. Used by R128UnmapMem, below. */ 328 static Bool R128UnmapFB(ScrnInfoPtr pScrn) 329 { 330 R128InfoPtr info = R128PTR(pScrn); 331 332 #ifndef AVOID_FBDEV 333 if (info->FBDev) 334 fbdevHWUnmapVidmem(pScrn); 335 else 336 #endif 337 #ifndef XSERVER_LIBPCIACCESS 338 xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); 339 #else 340 pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize); 341 #endif 342 info->FB = NULL; 343 return TRUE; 344 } 345 346 /* Memory map the MMIO region and the frame buffer. */ 347 static Bool R128MapMem(ScrnInfoPtr pScrn) 348 { 349 if (!R128MapMMIO(pScrn)) return FALSE; 350 if (!R128MapFB(pScrn)) { 351 R128UnmapMMIO(pScrn); 352 return FALSE; 353 } 354 return TRUE; 355 } 356 357 /* Unmap the MMIO region and the frame buffer. */ 358 static Bool R128UnmapMem(ScrnInfoPtr pScrn) 359 { 360 if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE; 361 return TRUE; 362 } 363 364 /* Read PLL information */ 365 unsigned R128INPLL(ScrnInfoPtr pScrn, int addr) 366 { 367 R128InfoPtr info = R128PTR(pScrn); 368 unsigned char *R128MMIO = info->MMIO; 369 370 OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x3f); 371 return INREG(R128_CLOCK_CNTL_DATA); 372 } 373 374 #if 0 375 /* Read PAL information (only used for debugging). */ 376 static int R128INPAL(int idx) 377 { 378 R128InfoPtr info = R128PTR(pScrn); 379 unsigned char *R128MMIO = info->MMIO; 380 381 OUTREG(R128_PALETTE_INDEX, idx << 16); 382 return INREG(R128_PALETTE_DATA); 383 } 384 #endif 385 386 /* Wait for vertical sync. */ 387 void R128WaitForVerticalSync(ScrnInfoPtr pScrn) 388 { 389 R128InfoPtr info = R128PTR(pScrn); 390 unsigned char *R128MMIO = info->MMIO; 391 int i; 392 393 OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); 394 for (i = 0; i < R128_TIMEOUT; i++) { 395 if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; 396 } 397 } 398 399 /* Compute log base 2 of val. */ 400 int R128MinBits(int val) 401 { 402 int bits; 403 404 if (!val) return 1; 405 for (bits = 0; val; val >>= 1, ++bits); 406 return bits; 407 } 408 409 /* Finds the first output using a given crtc. */ 410 xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc) 411 { 412 ScrnInfoPtr pScrn = crtc->scrn; 413 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 414 xf86OutputPtr output = xf86_config->output[0]; 415 int o; 416 417 for (o = 0; o < xf86_config->num_output; o++) { 418 output = xf86_config->output[o]; 419 if (output->crtc == crtc) break; 420 } 421 422 return output; 423 } 424 425 /* Read the Video BIOS block. */ 426 static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) 427 { 428 R128InfoPtr info = R128PTR(pScrn); 429 430 #ifdef XSERVER_LIBPCIACCESS 431 int size = info->PciInfo->rom_size > R128_VBIOS_SIZE ? info->PciInfo->rom_size : R128_VBIOS_SIZE; 432 info->VBIOS = malloc(size); 433 #else 434 info->VBIOS = malloc(R128_VBIOS_SIZE); 435 #endif 436 437 if (!info->VBIOS) { 438 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 439 "Cannot allocate space for hold Video BIOS!\n"); 440 return FALSE; 441 } 442 443 if (pInt10) { 444 info->BIOSAddr = pInt10->BIOSseg << 4; 445 (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr), 446 R128_VBIOS_SIZE); 447 } else { 448 #ifdef XSERVER_LIBPCIACCESS 449 if (pci_device_read_rom(info->PciInfo, info->VBIOS)) { 450 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 451 "Failed to read PCI ROM!\n"); 452 } 453 #else 454 xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE); 455 if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { 456 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 457 "Video BIOS not detected in PCI space!\n"); 458 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 459 "Attempting to read Video BIOS from legacy ISA space!\n"); 460 info->BIOSAddr = 0x000c0000; 461 xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS); 462 } 463 #endif 464 } 465 if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { 466 info->BIOSAddr = 0x00000000; 467 free(info->VBIOS); 468 info->VBIOS = NULL; 469 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 470 "Video BIOS not found!\n"); 471 } 472 473 return TRUE; 474 } 475 476 /* Read the FP parameters if an LVDS panel is expected. */ 477 void R128GetPanelInfoFromBIOS(xf86OutputPtr output) 478 { 479 ScrnInfoPtr pScrn = output->scrn; 480 R128InfoPtr info = R128PTR(pScrn); 481 R128OutputPrivatePtr r128_output = output->driver_private; 482 int FPHeader = 0; 483 int i; 484 485 r128_output->PanelPwrDly = 200; 486 xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes)); 487 xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes)); 488 489 if (!info->VBIOS) goto fallback; 490 info->FPBIOSstart = 0; 491 492 /* FIXME: There should be direct access to the start of the FP info 493 * tables, but until we find out where that offset is stored, we 494 * must search for the ATI signature string: "M3 ". 495 */ 496 for (i = 4; i < R128_VBIOS_SIZE - 8; i++) { 497 if (R128_BIOS8(i) == 'M' && 498 R128_BIOS8(i + 1) == '3' && 499 R128_BIOS8(i + 2) == ' ' && 500 R128_BIOS8(i + 3) == ' ' && 501 R128_BIOS8(i + 4) == ' ' && 502 R128_BIOS8(i + 5) == ' ' && 503 R128_BIOS8(i + 6) == ' ' && 504 R128_BIOS8(i + 7) == ' ') { 505 FPHeader = i - 2; 506 break; 507 } 508 } 509 510 if (!FPHeader) goto fallback; 511 512 /* Assume that only one panel is attached and supported */ 513 for (i = FPHeader + 20; i < FPHeader + 84; i += 2) { 514 if (R128_BIOS16(i) != 0) { 515 info->FPBIOSstart = R128_BIOS16(i); 516 break; 517 } 518 } 519 520 #ifndef AVOID_FBDEV 521 if (!info->FPBIOSstart) return; 522 #endif 523 524 if (!r128_output->PanelXRes) 525 r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25); 526 if (!r128_output->PanelYRes) 527 r128_output->PanelYRes = R128_BIOS16(info->FPBIOSstart + 27); 528 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", 529 r128_output->PanelXRes, r128_output->PanelYRes); 530 531 r128_output->PanelPwrDly = R128_BIOS8(info->FPBIOSstart + 56); 532 533 if (!r128_output->PanelXRes || !r128_output->PanelYRes) { 534 info->HasPanelRegs = FALSE; 535 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 536 "Can't determine panel dimensions, and none specified.\n" 537 "\tDisabling programming of FP registers.\n"); 538 } 539 540 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); 541 for (i = 1; i <= 24; i++) 542 ErrorF("%c", R128_BIOS8(info->FPBIOSstart + i)); 543 544 ErrorF("\n"); 545 546 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); 547 i = R128_BIOS16(info->FPBIOSstart + 29); 548 if (i & 1) ErrorF("Color, "); 549 else ErrorF("Monochrome, "); 550 if (i & 2) ErrorF("Dual(split), "); 551 else ErrorF("Single, "); 552 553 switch ((i >> 2) & 0x3f) { 554 case 0: ErrorF("STN"); break; 555 case 1: ErrorF("TFT"); break; 556 case 2: ErrorF("Active STN"); break; 557 case 3: ErrorF("EL"); break; 558 case 4: ErrorF("Plasma"); break; 559 default: ErrorF("UNKNOWN"); break; 560 } 561 562 ErrorF("\n"); 563 564 if (R128_BIOS8(info->FPBIOSstart + 61) & 1) { 565 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); 566 } else { 567 /* FIXME: Add Non-LVDS flat panel support */ 568 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 569 "Non-LVDS panel interface detected! " 570 "This support is untested and may not " 571 "function properly\n"); 572 } 573 return; 574 575 fallback: 576 #ifdef WSDISPLAYIO_GINFO 577 if ((!r128_output->PanelXRes || !r128_output->PanelYRes) && 578 (info->HaveWSDisplay)) { 579 /* 580 * we may not be on x86 so check wsdisplay for panel dimensions 581 * this assumes that the r128 is the console, although that should 582 * be the case in the vast majority of cases where an LCD is hooked up 583 * directly 584 * We should probably just check the relevant registers but I'm not 585 * sure they're available at this point. 586 */ 587 struct wsdisplay_fbinfo fbinfo; 588 589 if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GINFO, &fbinfo) == 0) { 590 r128_output->PanelXRes = fbinfo.width; 591 r128_output->PanelYRes = fbinfo.height; 592 } 593 } 594 #endif 595 return; 596 } 597 598 /* Read PLL parameters from BIOS block. Default to typical values if there 599 is no BIOS. */ 600 static Bool R128GetPLLParameters(ScrnInfoPtr pScrn) 601 { 602 R128InfoPtr info = R128PTR(pScrn); 603 R128PLLPtr pll = &info->pll; 604 605 #if defined(__powerpc__) || defined(__alpha__) 606 /* there is no bios under Linux PowerPC but Open Firmware 607 does set up the PLL registers properly and we can use 608 those to calculate xclk and find the reference divider */ 609 610 unsigned x_mpll_ref_fb_div; 611 unsigned xclk_cntl; 612 unsigned Nx, M; 613 unsigned PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12}; 614 615 /* Assume REF clock is 2950 (in units of 10khz) */ 616 /* and that all pllclk must be between 125 Mhz and 250Mhz */ 617 pll->reference_freq = 2950; 618 pll->min_pll_freq = 12500; 619 pll->max_pll_freq = 25000; 620 621 x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV); 622 xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7; 623 pll->reference_div = 624 INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK; 625 626 Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8; 627 M = (x_mpll_ref_fb_div & 0x0000FF); 628 629 pll->xclk = R128Div((2 * Nx * pll->reference_freq), 630 (M * PostDivSet[xclk_cntl])); 631 632 #else /* !defined(__powerpc__) */ 633 634 if (!info->VBIOS) { 635 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 636 "Video BIOS not detected, using default PLL parameters!\n"); 637 /* These probably aren't going to work for 638 the card you are using. Specifically, 639 reference freq can be 29.50MHz, 640 28.63MHz, or 14.32MHz. YMMV. */ 641 pll->reference_freq = 2950; 642 pll->reference_div = 65; 643 pll->min_pll_freq = 12500; 644 pll->max_pll_freq = 25000; 645 pll->xclk = 10300; 646 } else { 647 uint16_t bios_header = R128_BIOS16(0x48); 648 uint16_t pll_info_block = R128_BIOS16(bios_header + 0x30); 649 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 650 "Header at 0x%04x; PLL Information at 0x%04x\n", 651 bios_header, pll_info_block)); 652 653 pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e); 654 pll->reference_div = R128_BIOS16(pll_info_block + 0x10); 655 pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12); 656 pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16); 657 pll->xclk = R128_BIOS16(pll_info_block + 0x08); 658 } 659 #endif /* __powerpc__ */ 660 661 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 662 "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", 663 pll->reference_freq, 664 pll->reference_div, 665 pll->min_pll_freq, 666 pll->max_pll_freq, 667 pll->xclk); 668 669 return TRUE; 670 } 671 672 /* This is called by R128PreInit to set up the default visual. */ 673 static Bool R128PreInitVisual(ScrnInfoPtr pScrn) 674 { 675 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, (Support24bppFb 676 | Support32bppFb 677 | SupportConvert32to24 678 ))) 679 return FALSE; 680 681 switch (pScrn->depth) { 682 case 8: 683 case 15: 684 case 16: 685 case 24: 686 break; 687 default: 688 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 689 "Given depth (%d) is not supported by %s driver\n", 690 pScrn->depth, R128_DRIVER_NAME); 691 return FALSE; 692 } 693 694 xf86PrintDepthBpp(pScrn); 695 696 if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; 697 698 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 699 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 700 "Default visual (%s) is not supported at depth %d\n", 701 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 702 return FALSE; 703 } 704 return TRUE; 705 706 } 707 708 /* This is called by R128PreInit to handle all color weight issues. */ 709 static Bool R128PreInitWeight(ScrnInfoPtr pScrn) 710 { 711 R128InfoPtr info = R128PTR(pScrn); 712 rgb defaultWeight = { 0, 0, 0 }; 713 714 /* 715 * Save flag for 6 bit DAC to use for setting CRTC registers. 716 * Otherwise use an 8 bit DAC, even if xf86SetWeight sets 717 * pScrn->rgbBits to some value other than 8. 718 */ 719 if (pScrn->depth <= 8) { 720 if (info->dac6bits) { 721 pScrn->rgbBits = 6; 722 } else { 723 pScrn->rgbBits = 8; 724 } 725 } else { 726 info->dac6bits = FALSE; 727 pScrn->rgbBits = 8; 728 } 729 730 if (pScrn->depth > 8) { 731 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; 732 } 733 734 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 735 "Using %d bits per RGB (%d bit DAC)\n", 736 pScrn->rgbBits, info->dac6bits ? 6 : 8); 737 738 return TRUE; 739 } 740 741 /* This is called by R128PreInit to handle config file overrides for things 742 like chipset and memory regions. Also determine memory size and type. 743 If memory type ever needs an override, put it in this routine. */ 744 static Bool R128PreInitConfig(ScrnInfoPtr pScrn) 745 { 746 R128InfoPtr info = R128PTR(pScrn); 747 R128EntPtr pR128Ent = R128EntPriv(pScrn); 748 unsigned char *R128MMIO = info->MMIO; 749 EntityInfoPtr pEnt = info->pEnt; 750 GDevPtr dev = pEnt->device; 751 int offset = 0; /* RAM Type */ 752 MessageType from; 753 754 /* Chipset */ 755 from = X_PROBED; 756 if (dev->chipset && *dev->chipset) { 757 info->Chipset = xf86StringToToken(R128Chipsets, dev->chipset); 758 from = X_CONFIG; 759 } else if (dev->chipID >= 0) { 760 info->Chipset = dev->chipID; 761 from = X_CONFIG; 762 } else { 763 info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo); 764 } 765 pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset); 766 767 if (!pScrn->chipset) { 768 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 769 "ChipID 0x%04x is not recognized\n", info->Chipset); 770 return FALSE; 771 } 772 773 if (info->Chipset < 0) { 774 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 775 "Chipset \"%s\" is not recognized\n", pScrn->chipset); 776 return FALSE; 777 } 778 779 xf86DrvMsg(pScrn->scrnIndex, from, 780 "Chipset: \"%s\" (ChipID = 0x%04x)\n", 781 pScrn->chipset, 782 info->Chipset); 783 784 /* Framebuffer */ 785 786 from = X_PROBED; 787 info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & 0xfc000000; 788 pScrn->memPhysBase = info->LinearAddr; 789 if (dev->MemBase) { 790 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 791 "Linear address override, using 0x%08lx instead of 0x%08lx\n", 792 dev->MemBase, 793 info->LinearAddr); 794 info->LinearAddr = dev->MemBase; 795 from = X_CONFIG; 796 } else if (!info->LinearAddr) { 797 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 798 "No valid linear framebuffer address\n"); 799 return FALSE; 800 } 801 xf86DrvMsg(pScrn->scrnIndex, from, 802 "Linear framebuffer at 0x%08lx\n", info->LinearAddr); 803 804 /* MMIO registers */ 805 from = X_PROBED; 806 info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & 0xffffff00; 807 if (dev->IOBase) { 808 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 809 "MMIO address override, using 0x%08lx instead of 0x%08lx\n", 810 dev->IOBase, 811 info->MMIOAddr); 812 info->MMIOAddr = dev->IOBase; 813 from = X_CONFIG; 814 } else if (!info->MMIOAddr) { 815 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); 816 return FALSE; 817 } 818 xf86DrvMsg(pScrn->scrnIndex, from, 819 "MMIO registers at 0x%08lx\n", info->MMIOAddr); 820 821 #ifndef XSERVER_LIBPCIACCESS 822 /* BIOS */ 823 from = X_PROBED; 824 info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; 825 if (info->BIOSAddr) { 826 xf86DrvMsg(pScrn->scrnIndex, from, 827 "BIOS at 0x%08lx\n", info->BIOSAddr); 828 } 829 #endif 830 831 /* Flat panel (part 1) */ 832 if (xf86GetOptValBool(info->Options, OPTION_PROG_FP_REGS, 833 &info->HasPanelRegs)) { 834 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 835 "Turned flat panel register programming %s\n", 836 info->HasPanelRegs ? "on" : "off"); 837 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 838 "\n\nWARNING: Forcing the driver to use/not use the flat panel registers\nmight damage your flat panel. Use at your *OWN* *RISK*.\n\n"); 839 } else { 840 info->isDFP = FALSE; 841 info->isPro2 = FALSE; 842 pR128Ent->HasCRTC2 = FALSE; 843 switch (info->Chipset) { 844 /* R128 Pro and Pro2 can have DFP, we will deal with it. 845 No support for dual-head/xinerama yet. 846 M3 can also have DFP, no support for now */ 847 case PCI_CHIP_RAGE128TF: 848 case PCI_CHIP_RAGE128TL: 849 case PCI_CHIP_RAGE128TR: 850 /* FIXME: RAGE128 TS/TT/TU are assumed to be PRO2 as all 6 chips came 851 * out at the same time, so are of the same family likely. 852 * This requires confirmation however to be fully correct. 853 * Mike A. Harris <mharris (at) redhat.com> 854 */ 855 case PCI_CHIP_RAGE128TS: 856 case PCI_CHIP_RAGE128TT: 857 case PCI_CHIP_RAGE128TU: info->isPro2 = TRUE; 858 /* FIXME: RAGE128 P[ABCEGHIJKLMNOQSTUVWX] are assumed to have DFP 859 * capability, as the comment at the top suggests. 860 * This requires confirmation however to be fully correct. 861 * Mike A. Harris <mharris (at) redhat.com> 862 */ 863 case PCI_CHIP_RAGE128PA: 864 case PCI_CHIP_RAGE128PB: 865 case PCI_CHIP_RAGE128PC: 866 case PCI_CHIP_RAGE128PE: 867 case PCI_CHIP_RAGE128PG: 868 case PCI_CHIP_RAGE128PH: 869 case PCI_CHIP_RAGE128PI: 870 case PCI_CHIP_RAGE128PJ: 871 case PCI_CHIP_RAGE128PK: 872 case PCI_CHIP_RAGE128PL: 873 case PCI_CHIP_RAGE128PM: 874 case PCI_CHIP_RAGE128PN: 875 case PCI_CHIP_RAGE128PO: 876 case PCI_CHIP_RAGE128PQ: 877 case PCI_CHIP_RAGE128PS: 878 case PCI_CHIP_RAGE128PT: 879 case PCI_CHIP_RAGE128PU: 880 case PCI_CHIP_RAGE128PV: 881 case PCI_CHIP_RAGE128PW: 882 case PCI_CHIP_RAGE128PX: 883 884 case PCI_CHIP_RAGE128PD: 885 case PCI_CHIP_RAGE128PF: 886 case PCI_CHIP_RAGE128PP: 887 case PCI_CHIP_RAGE128PR: info->isDFP = TRUE; break; 888 889 case PCI_CHIP_RAGE128LE: 890 case PCI_CHIP_RAGE128LF: 891 case PCI_CHIP_RAGE128MF: 892 case PCI_CHIP_RAGE128ML: 893 info->HasPanelRegs = TRUE; 894 info->isDFP = TRUE; 895 /* which chips support dualhead? */ 896 pR128Ent->HasCRTC2 = TRUE; 897 break; 898 case PCI_CHIP_RAGE128RE: 899 case PCI_CHIP_RAGE128RF: 900 case PCI_CHIP_RAGE128RG: 901 case PCI_CHIP_RAGE128RK: 902 case PCI_CHIP_RAGE128RL: 903 case PCI_CHIP_RAGE128SM: 904 /* FIXME: RAGE128 S[EFGHKLN] are assumed to be like the SM above as 905 * all of them are listed as "Rage 128 4x" in ATI docs. 906 * This requires confirmation however to be fully correct. 907 * Mike A. Harris <mharris (at) redhat.com> 908 */ 909 case PCI_CHIP_RAGE128SE: 910 case PCI_CHIP_RAGE128SF: 911 case PCI_CHIP_RAGE128SG: 912 case PCI_CHIP_RAGE128SH: 913 case PCI_CHIP_RAGE128SK: 914 case PCI_CHIP_RAGE128SL: 915 case PCI_CHIP_RAGE128SN: 916 default: info->HasPanelRegs = FALSE; break; 917 } 918 } 919 920 /* Read registers used to determine options */ 921 from = X_PROBED; 922 if (!R128MapMMIO(pScrn)) return FALSE; 923 R128MMIO = info->MMIO; 924 925 #ifndef AVOID_FBDEV 926 if (info->FBDev) 927 pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; 928 else 929 #endif 930 pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024; 931 932 info->MemCntl = INREG(R128_MEM_CNTL); 933 info->BusCntl = INREG(R128_BUS_CNTL); 934 935 /* RAM */ 936 switch (info->MemCntl & 0x3) { 937 case 0: /* SDR SGRAM 1:1 */ 938 switch (info->Chipset) { 939 case PCI_CHIP_RAGE128TF: 940 case PCI_CHIP_RAGE128TL: 941 case PCI_CHIP_RAGE128TR: 942 case PCI_CHIP_RAGE128LE: 943 case PCI_CHIP_RAGE128LF: 944 case PCI_CHIP_RAGE128MF: 945 case PCI_CHIP_RAGE128ML: 946 case PCI_CHIP_RAGE128RE: 947 case PCI_CHIP_RAGE128RF: 948 case PCI_CHIP_RAGE128RG: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */ 949 case PCI_CHIP_RAGE128RK: 950 case PCI_CHIP_RAGE128RL: 951 case PCI_CHIP_RAGE128SM: 952 default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ 953 } 954 break; 955 case 1: offset = 2; break; /* 64-bit SDR SGRAM 2:1 */ 956 case 2: offset = 3; break; /* 64-bit DDR SGRAM */ 957 default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ 958 } 959 info->ram = &R128RAM[offset]; 960 961 if (dev->videoRam) { 962 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 963 "Video RAM override, using %d kB instead of %d kB\n", 964 dev->videoRam, 965 pScrn->videoRam); 966 from = X_CONFIG; 967 pScrn->videoRam = dev->videoRam; 968 } 969 970 xf86DrvMsg(pScrn->scrnIndex, from, 971 "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); 972 973 pScrn->videoRam &= ~1023; 974 info->FbMapSize = pScrn->videoRam * 1024; 975 976 #ifdef R128DRI 977 /* AGP/PCI */ 978 if (!info->IsPCI) { 979 switch (info->Chipset) { 980 case PCI_CHIP_RAGE128LE: 981 case PCI_CHIP_RAGE128RE: 982 case PCI_CHIP_RAGE128RK: 983 case PCI_CHIP_RAGE128PD: 984 case PCI_CHIP_RAGE128PR: 985 case PCI_CHIP_RAGE128PP: info->IsPCI = TRUE; break; 986 case PCI_CHIP_RAGE128LF: 987 case PCI_CHIP_RAGE128MF: 988 case PCI_CHIP_RAGE128ML: 989 case PCI_CHIP_RAGE128PF: 990 case PCI_CHIP_RAGE128RF: 991 case PCI_CHIP_RAGE128RG: 992 case PCI_CHIP_RAGE128RL: 993 case PCI_CHIP_RAGE128SM: 994 case PCI_CHIP_RAGE128TF: 995 case PCI_CHIP_RAGE128TL: 996 case PCI_CHIP_RAGE128TR: 997 /* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are 998 * believed to be AGP, but need confirmation. <mharris (at) redhat.com> 999 */ 1000 case PCI_CHIP_RAGE128PA: 1001 case PCI_CHIP_RAGE128PB: 1002 case PCI_CHIP_RAGE128PC: 1003 case PCI_CHIP_RAGE128PE: 1004 case PCI_CHIP_RAGE128PG: 1005 case PCI_CHIP_RAGE128PH: 1006 case PCI_CHIP_RAGE128PI: 1007 case PCI_CHIP_RAGE128PJ: 1008 case PCI_CHIP_RAGE128PK: 1009 case PCI_CHIP_RAGE128PL: 1010 case PCI_CHIP_RAGE128PM: 1011 case PCI_CHIP_RAGE128PN: 1012 case PCI_CHIP_RAGE128PO: 1013 case PCI_CHIP_RAGE128PQ: 1014 case PCI_CHIP_RAGE128PS: 1015 case PCI_CHIP_RAGE128PT: 1016 case PCI_CHIP_RAGE128PU: 1017 case PCI_CHIP_RAGE128PV: 1018 case PCI_CHIP_RAGE128PW: 1019 case PCI_CHIP_RAGE128PX: 1020 case PCI_CHIP_RAGE128TS: 1021 case PCI_CHIP_RAGE128TT: 1022 case PCI_CHIP_RAGE128TU: 1023 case PCI_CHIP_RAGE128SE: 1024 case PCI_CHIP_RAGE128SF: 1025 case PCI_CHIP_RAGE128SG: 1026 case PCI_CHIP_RAGE128SH: 1027 case PCI_CHIP_RAGE128SK: 1028 case PCI_CHIP_RAGE128SL: 1029 case PCI_CHIP_RAGE128SN: 1030 default: info->IsPCI = FALSE; break; 1031 } 1032 } 1033 #endif 1034 1035 return TRUE; 1036 } 1037 1038 static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) 1039 { 1040 #if !defined(__powerpc__) && !defined(__alpha__) && !defined(__sparc__) 1041 R128InfoPtr info = R128PTR(pScrn); 1042 vbeInfoPtr pVbe; 1043 #endif 1044 1045 if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; 1046 if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE; 1047 1048 #if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__) 1049 /* Int10 is broken on PPC and some Alphas */ 1050 return TRUE; 1051 #else 1052 if (xf86LoadSubModule(pScrn, "vbe")) { 1053 pVbe = VBEInit(pInt10,info->pEnt->index); 1054 if (!pVbe) return FALSE; 1055 xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); 1056 vbeFree(pVbe); 1057 return TRUE; 1058 } else 1059 return FALSE; 1060 #endif 1061 } 1062 1063 /* This is called by R128PreInit to initialize gamma correction. */ 1064 static Bool R128PreInitGamma(ScrnInfoPtr pScrn) 1065 { 1066 Gamma zeros = { 0.0, 0.0, 0.0 }; 1067 1068 if (!xf86SetGamma(pScrn, zeros)) return FALSE; 1069 return TRUE; 1070 } 1071 1072 /* This is called by R128PreInit to initialize the hardware cursor. */ 1073 static Bool R128PreInitCursor(ScrnInfoPtr pScrn) 1074 { 1075 R128InfoPtr info = R128PTR(pScrn); 1076 1077 if (!info->swCursor) { 1078 if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; 1079 } 1080 return TRUE; 1081 } 1082 1083 static Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10) 1084 { 1085 R128InfoPtr info = R128PTR(pScrn); 1086 #if !defined(__powerpc__) && !defined(__alpha__) 1087 /* int10 is broken on some Alphas and powerpc */ 1088 if (xf86LoadSubModule(pScrn, "int10")) { 1089 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); 1090 *ppInt10 = xf86InitInt10(info->pEnt->index); 1091 } 1092 #endif 1093 return TRUE; 1094 } 1095 1096 #ifdef R128DRI 1097 static Bool R128PreInitDRI(ScrnInfoPtr pScrn) 1098 { 1099 R128InfoPtr info = R128PTR(pScrn); 1100 1101 info->agpMode = R128_DEFAULT_AGP_MODE; 1102 info->agpSize = R128_DEFAULT_AGP_SIZE; 1103 info->ringSize = R128_DEFAULT_RING_SIZE; 1104 info->bufSize = R128_DEFAULT_BUFFER_SIZE; 1105 info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; 1106 1107 info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; 1108 1109 if (!info->IsPCI) { 1110 if (xf86GetOptValInteger(info->Options, 1111 OPTION_AGP_MODE, &(info->agpMode))) { 1112 if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) { 1113 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1114 "Illegal AGP Mode: %d\n", info->agpMode); 1115 return FALSE; 1116 } 1117 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1118 "Using AGP %dx mode\n", info->agpMode); 1119 } 1120 1121 if (xf86GetOptValInteger(info->Options, 1122 OPTION_AGP_SIZE, (int *)&(info->agpSize))) { 1123 switch (info->agpSize) { 1124 case 4: 1125 case 8: 1126 case 16: 1127 case 32: 1128 case 64: 1129 case 128: 1130 case 256: 1131 break; 1132 default: 1133 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1134 "Illegal AGP size: %d MB\n", info->agpSize); 1135 return FALSE; 1136 } 1137 } 1138 1139 if (xf86GetOptValInteger(info->Options, 1140 OPTION_RING_SIZE, &(info->ringSize))) { 1141 if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) { 1142 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1143 "Illegal ring buffer size: %d MB\n", 1144 info->ringSize); 1145 return FALSE; 1146 } 1147 } 1148 1149 if (xf86GetOptValInteger(info->Options, 1150 OPTION_BUFFER_SIZE, &(info->bufSize))) { 1151 if (info->bufSize < 1 || info->bufSize >= (int)info->agpSize) { 1152 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1153 "Illegal vertex/indirect buffers size: %d MB\n", 1154 info->bufSize); 1155 return FALSE; 1156 } 1157 if (info->bufSize > 2) { 1158 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1159 "Illegal vertex/indirect buffers size: %d MB\n", 1160 info->bufSize); 1161 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1162 "Clamping vertex/indirect buffers size to 2 MB\n"); 1163 info->bufSize = 2; 1164 } 1165 } 1166 1167 if (info->ringSize + info->bufSize + info->agpTexSize > 1168 (int)info->agpSize) { 1169 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1170 "Buffers are too big for requested AGP space\n"); 1171 return FALSE; 1172 } 1173 1174 info->agpTexSize = info->agpSize - (info->ringSize + info->bufSize); 1175 } 1176 1177 if (xf86GetOptValInteger(info->Options, OPTION_USEC_TIMEOUT, 1178 &(info->CCEusecTimeout))) { 1179 /* This option checked by the R128 DRM kernel module */ 1180 } 1181 1182 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 1183 info->allowPageFlip = 0; 1184 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1185 "Couldn't load shadowfb module:\n"); 1186 } else { 1187 info->allowPageFlip = xf86ReturnOptValBool(info->Options, 1188 OPTION_PAGE_FLIP, 1189 FALSE); 1190 } 1191 1192 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n", 1193 info->allowPageFlip ? "en" : "dis"); 1194 1195 return TRUE; 1196 } 1197 #endif 1198 1199 static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) 1200 { 1201 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 1202 int found = 0; 1203 int i; 1204 1205 if (!R128GetBIOSParameters(pScrn, pInt10)) 1206 return FALSE; 1207 1208 if (!R128GetPLLParameters(pScrn)) 1209 return FALSE; 1210 1211 if (!R128AllocateControllers(pScrn)) 1212 return FALSE; 1213 1214 if (!R128SetupConnectors(pScrn)) 1215 return FALSE; 1216 1217 for (i = 0; i < config->num_output; i++) { 1218 xf86OutputPtr output = config->output[i]; 1219 1220 output->status = (*output->funcs->detect) (output); 1221 if (output->status == XF86OutputStatusConnected) 1222 found++; 1223 } 1224 return !!found; 1225 } 1226 1227 static void 1228 r128UMSOption(ScrnInfoPtr pScrn) 1229 { 1230 R128InfoPtr info = R128PTR(pScrn); 1231 1232 info->dac6bits = xf86ReturnOptValBool(info->Options, 1233 OPTION_DAC_6BIT, FALSE); 1234 1235 #ifndef AVOID_FBDEV 1236 #ifdef __powerpc__ 1237 if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, TRUE)) 1238 #else 1239 if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) 1240 #endif 1241 { 1242 info->FBDev = TRUE; 1243 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1244 "Using framebuffer device.\n"); 1245 } 1246 #endif 1247 1248 /* By default, don't access VGA IOs on PowerPC or SPARC. */ 1249 #if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW) 1250 info->VGAAccess = FALSE; 1251 #else 1252 info->VGAAccess = TRUE; 1253 #endif 1254 1255 #ifdef WITH_VGAHW 1256 xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, 1257 &info->VGAAccess); 1258 if (info->VGAAccess) { 1259 if (!xf86LoadSubModule(pScrn, "vgahw")) 1260 info->VGAAccess = FALSE; 1261 else { 1262 if (!vgaHWGetHWRec(pScrn)) 1263 info->VGAAccess = FALSE; 1264 } 1265 1266 if (!info->VGAAccess) { 1267 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1268 "Loading VGA module failed, trying to " 1269 "run without it.\n"); 1270 } 1271 } else 1272 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1273 "VGAAccess option set to FALSE, VGA " 1274 "module load skipped.\n"); 1275 if (info->VGAAccess) { 1276 vgaHWSetStdFuncs(VGAHWPTR(pScrn)); 1277 vgaHWGetIOBase(VGAHWPTR(pScrn)); 1278 } 1279 #else 1280 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1281 "VGAHW support not compiled, VGA " 1282 "module load skipped.\n"); 1283 #endif 1284 1285 if (xf86ReturnOptValBool(info->Options, 1286 OPTION_SHOW_CACHE, FALSE)) { 1287 info->showCache = TRUE; 1288 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1289 "ShowCache enabled.\n"); 1290 } 1291 1292 if (xf86ReturnOptValBool(info->Options, 1293 OPTION_SW_CURSOR, FALSE)) { 1294 info->swCursor = TRUE; 1295 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1296 "Software cursor requested.\n"); 1297 } 1298 1299 if(xf86GetOptValInteger(info->Options, 1300 OPTION_VIDEO_KEY, &info->videoKey)) { 1301 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1302 "Video key set to 0x%x.\n", info->videoKey); 1303 } else { 1304 info->videoKey = 0x1E; 1305 } 1306 1307 #ifdef R128DRI 1308 /* DMA for Xv */ 1309 info->DMAForXv = xf86ReturnOptValBool(info->Options, 1310 OPTION_XV_DMA, FALSE); 1311 if (info->DMAForXv) { 1312 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1313 "Will try to use DMA for Xv image transfers.\n"); 1314 } 1315 1316 /* Force PCI Mode */ 1317 info->IsPCI = xf86ReturnOptValBool(info->Options, 1318 OPTION_IS_PCI, FALSE); 1319 if (info->IsPCI) { 1320 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1321 "Forced into PCI only mode.\n"); 1322 } 1323 1324 if (xf86ReturnOptValBool(info->Options, OPTION_CCE_PIO, FALSE)) { 1325 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1326 "Forcing CCE into PIO mode.\n"); 1327 info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; 1328 } else { 1329 info->CCEMode = R128_DEFAULT_CCE_BM_MODE; 1330 } 1331 1332 if (xf86ReturnOptValBool(info->Options, OPTION_NO_SECURITY, FALSE)) { 1333 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1334 "WARNING!!! CCE Security checks disabled!!!\n"); 1335 info->CCESecure = FALSE; 1336 } else { 1337 info->CCESecure = TRUE; 1338 } 1339 1340 1341 #endif 1342 } 1343 1344 static void 1345 r128AcquireOption(ScrnInfoPtr pScrn) 1346 { 1347 R128InfoPtr info = R128PTR(pScrn); 1348 #ifdef USE_EXA 1349 char *optstr; 1350 #endif 1351 1352 if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { 1353 info->noAccel = TRUE; 1354 } 1355 1356 #ifdef USE_EXA 1357 if (!info->noAccel) { 1358 optstr = (char *) xf86GetOptValString(info->Options, 1359 OPTION_ACCELMETHOD); 1360 if (optstr) { 1361 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1362 "AccelMethod option found.\n"); 1363 if (xf86NameCmp(optstr, "EXA") == 0) { 1364 info->useEXA = TRUE; 1365 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1366 "AccelMethod is set to EXA, turning " 1367 "EXA on.\n"); 1368 } 1369 } 1370 1371 #ifdef RENDER 1372 info->RenderAccel = xf86ReturnOptValBool(info->Options, 1373 OPTION_RENDERACCEL, 1374 TRUE); 1375 if (info->RenderAccel) 1376 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1377 "Acceleration of RENDER operations will be " 1378 "enabled upon successful loading of DRI and " 1379 "EXA.\n"); 1380 #endif 1381 } 1382 #endif 1383 1384 r128UMSOption(pScrn); 1385 } 1386 1387 static Bool R128CRTCResize(ScrnInfoPtr pScrn, int width, int height) 1388 { 1389 pScrn->virtualX = width; 1390 pScrn->virtualY = height; 1391 return TRUE; 1392 } 1393 1394 static const xf86CrtcConfigFuncsRec R128CRTCResizeFuncs = { 1395 R128CRTCResize 1396 }; 1397 1398 static Bool R128LegacyMS(ScrnInfoPtr pScrn) 1399 { 1400 R128InfoPtr info = R128PTR(pScrn); 1401 xf86Int10InfoPtr pInt10 = NULL; 1402 Bool ret = FALSE; 1403 1404 #ifndef AVOID_FBDEV 1405 if (info->FBDev) { 1406 /* check for linux framebuffer device */ 1407 if (!xf86LoadSubModule(pScrn, "fbdevhw")) goto exit; 1408 if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) goto exit; 1409 pScrn->SwitchMode = fbdevHWSwitchModeWeak(); 1410 pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); 1411 pScrn->ValidMode = fbdevHWValidModeWeak(); 1412 } else { 1413 #endif /* !AVOID_FBDEV */ 1414 if (!R128PreInitInt10(pScrn, &pInt10)) goto exit; 1415 #ifndef AVOID_FBDEV 1416 } 1417 #endif /* !AVOID_FBDEV */ 1418 1419 if (!R128PreInitConfig(pScrn)) goto freeInt10; 1420 1421 xf86CrtcSetSizeRange(pScrn, 320, 200, 4096, 4096); 1422 1423 if (!R128PreInitCursor(pScrn)) goto freeInt10; 1424 1425 /* Don't fail on this one */ 1426 info->DDC = R128PreInitDDC(pScrn, pInt10); 1427 1428 if (!R128PreInitControllers(pScrn, pInt10)) goto freeInt10; 1429 1430 #ifdef R128DRI 1431 if (!R128PreInitDRI(pScrn)) goto freeInt10; 1432 #endif 1433 1434 ret = TRUE; 1435 freeInt10: 1436 /* Free int10 info */ 1437 if (pInt10) { 1438 xf86FreeInt10(pInt10); 1439 } 1440 1441 exit: 1442 return ret; 1443 } 1444 1445 static void 1446 R128PreInitAccel(ScrnInfoPtr pScrn) 1447 { 1448 R128InfoPtr info = R128PTR(pScrn); 1449 #ifdef USE_EXA 1450 int errmaj, errmin; 1451 #endif 1452 1453 if (!info->noAccel) { 1454 if (info->useEXA) { 1455 #ifdef USE_EXA 1456 info->exaReq.majorversion = EXA_VERSION_MAJOR; 1457 info->exaReq.minorversion = EXA_VERSION_MINOR; 1458 1459 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1460 "Loading EXA module...\n"); 1461 if (LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 1462 &info->exaReq, &errmaj, &errmin)) { 1463 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1464 "Loading EXA module.\n"); 1465 } else { 1466 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 1467 } 1468 #endif 1469 } 1470 1471 if ((!info->useEXA) || 1472 ((info->useEXA) && (!info->accelOn))) { 1473 } 1474 } 1475 } 1476 1477 /* R128PreInit is called once at server startup. */ 1478 Bool R128PreInit(ScrnInfoPtr pScrn, int flags) 1479 { 1480 R128InfoPtr info; 1481 #ifdef WSDISPLAYIO_GET_BUSID 1482 struct wsdisplayio_bus_id bid; 1483 #endif 1484 1485 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1486 "%s\n", __func__)); 1487 1488 if (flags & PROBE_DETECT) { 1489 return TRUE; 1490 } 1491 1492 pScrn->monitor = pScrn->confScreen->monitor; 1493 1494 if (!R128PreInitVisual(pScrn)) { 1495 return FALSE; 1496 } 1497 1498 if (!R128PreInitGamma(pScrn)) { 1499 return FALSE; 1500 } 1501 1502 if (pScrn->numEntities != 1) return FALSE; 1503 1504 if (!R128GetRec(pScrn)) return FALSE; 1505 1506 info = R128PTR(pScrn); 1507 info->SwitchingMode = FALSE; 1508 info->MMIO = NULL; 1509 1510 info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1511 if (info->pEnt->location.type != BUS_PCI) goto fail; 1512 1513 info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); 1514 1515 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1516 "PCI bus %d card %d func %d\n", 1517 PCI_DEV_BUS(info->PciInfo), 1518 PCI_DEV_DEV(info->PciInfo), 1519 PCI_DEV_FUNC(info->PciInfo)); 1520 1521 #ifdef WSDISPLAYIO_GET_BUSID 1522 /* now check if this is the console */ 1523 info->HaveWSDisplay = FALSE; 1524 info->HaveBacklightControl = FALSE; 1525 if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GET_BUSID, &bid) != -1) { 1526 if ((bid.bus_type == WSDISPLAYIO_BUS_PCI) && 1527 (bid.ubus.pci.bus == PCI_DEV_BUS(info->PciInfo)) && 1528 (bid.ubus.pci.device == PCI_DEV_DEV(info->PciInfo)) && 1529 (bid.ubus.pci.function == PCI_DEV_FUNC(info->PciInfo))) { 1530 struct wsdisplay_param p; 1531 info->HaveWSDisplay = TRUE; 1532 1533 #ifdef WSDISPLAYIO_PARAM_BACKLIGHT 1534 /* now see if we have hacklight control */ 1535 p.param = WSDISPLAYIO_PARAM_BACKLIGHT; 1536 if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, &p) != -1) { 1537 info->HaveBacklightControl = TRUE; 1538 } 1539 #endif 1540 } 1541 } 1542 #endif 1543 1544 #ifndef XSERVER_LIBPCIACCESS 1545 info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo), 1546 PCI_DEV_DEV(info->PciInfo), 1547 PCI_DEV_FUNC(info->PciInfo)); 1548 1549 if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; 1550 if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail; 1551 1552 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; 1553 #endif 1554 1555 info->fifo_slots = 0; 1556 info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); 1557 info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; 1558 info->CurrentLayout.depth = pScrn->depth; 1559 info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; 1560 info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 1561 ? pScrn->bitsPerPixel 1562 : pScrn->depth); 1563 1564 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1565 "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", 1566 pScrn->depth, 1567 info->CurrentLayout.pixel_bytes, 1568 info->CurrentLayout.pixel_bytes > 1 ? "s" : "", 1569 info->pix24bpp); 1570 1571 /* We can't do this until we have a 1572 pScrn->display. */ 1573 xf86CollectOptions(pScrn, NULL); 1574 if (!(info->Options = malloc(sizeof(R128Options)))) goto fail; 1575 memcpy(info->Options, R128Options, sizeof(R128Options)); 1576 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); 1577 1578 info->noAccel = FALSE; 1579 info->accelOn = FALSE; 1580 1581 info->useEXA = FALSE; 1582 #ifdef USE_EXA 1583 info->useEXA = TRUE; 1584 #endif 1585 1586 info->swCursor = FALSE; 1587 1588 r128AcquireOption(pScrn); 1589 1590 if (!R128PreInitWeight(pScrn)) goto fail; 1591 1592 /* Allocate an xf86CrtcConfig */ 1593 xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs); 1594 1595 R128LegacyMS(pScrn); 1596 1597 if (!xf86InitialConfiguration(pScrn, TRUE)) { 1598 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); 1599 goto fail; 1600 } 1601 pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; 1602 1603 /* Set display resolution */ 1604 xf86SetDpi(pScrn, 0, 0); 1605 1606 /* Get ScreenInit function */ 1607 if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; 1608 1609 R128PreInitAccel(pScrn); 1610 1611 info->CurrentLayout.displayWidth = pScrn->displayWidth; 1612 1613 if (!xf86RandR12PreInit(pScrn)) { 1614 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); 1615 goto fail; 1616 } 1617 1618 if (pScrn->modes == NULL) { 1619 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 1620 goto fail; 1621 } 1622 1623 /* Free the video bios (if applicable) */ 1624 if (info->VBIOS) { 1625 free(info->VBIOS); 1626 info->VBIOS = NULL; 1627 } 1628 1629 if (info->MMIO) R128UnmapMMIO(pScrn); 1630 info->MMIO = NULL; 1631 1632 return TRUE; 1633 1634 fail: 1635 /* Pre-init failed. */ 1636 1637 /* Free the video bios (if applicable) */ 1638 if (info->VBIOS) { 1639 free(info->VBIOS); 1640 info->VBIOS = NULL; 1641 } 1642 1643 #ifdef WITH_VGAHW 1644 if (info->VGAAccess) 1645 vgaHWFreeHWRec(pScrn); 1646 #endif 1647 1648 if (info->MMIO) R128UnmapMMIO(pScrn); 1649 info->MMIO = NULL; 1650 1651 R128FreeRec(pScrn); 1652 return FALSE; 1653 } 1654 1655 /* Load a palette. */ 1656 static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors, 1657 int *indices, LOCO *colors, VisualPtr pVisual) 1658 { 1659 R128InfoPtr info = R128PTR(pScrn); 1660 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1661 int i, j; 1662 int c, index; 1663 uint16_t lut_r[256], lut_g[256], lut_b[256]; 1664 1665 for (c = 0; c < xf86_config->num_crtc; c++) { 1666 xf86CrtcPtr crtc = xf86_config->crtc[c]; 1667 R128CrtcPrivatePtr r128_crtc = crtc->driver_private; 1668 1669 for (i = 0 ; i < 256; i++) { 1670 lut_r[i] = r128_crtc->lut_r[i] << 8; 1671 lut_g[i] = r128_crtc->lut_g[i] << 8; 1672 lut_b[i] = r128_crtc->lut_b[i] << 8; 1673 } 1674 1675 switch (info->CurrentLayout.depth) { 1676 case 15: 1677 for (i = 0; i < numColors; i++) { 1678 index = indices[i]; 1679 for (j = 0; j < 8; j++) { 1680 lut_r[index * 8 + j] = colors[index].red << 8; 1681 lut_g[index * 8 + j] = colors[index].green << 8; 1682 lut_b[index * 8 + j] = colors[index].blue << 8; 1683 } 1684 } 1685 case 16: 1686 for (i = 0; i < numColors; i++) { 1687 index = indices[i]; 1688 1689 /* XXX: The old version of R128LoadPalette did not do this and 1690 * the old version of RADEONLoadPalette has a comment asking why. 1691 */ 1692 if (i <= 31) { 1693 for (j = 0; j < 8; j++) { 1694 lut_r[index * 8 + j] = colors[index].red << 8; 1695 lut_b[index * 8 + j] = colors[index].blue << 8; 1696 } 1697 } 1698 1699 for (j = 0; j < 4; j++) { 1700 lut_g[index * 4 + j] = colors[index].green << 8; 1701 } 1702 } 1703 default: 1704 for (i = 0; i < numColors; i++) { 1705 index = indices[i]; 1706 lut_r[index] = colors[index].red << 8; 1707 lut_g[index] = colors[index].green << 8; 1708 lut_b[index] = colors[index].blue << 8; 1709 } 1710 break; 1711 } 1712 1713 /* Make the change through RandR */ 1714 #ifdef RANDR_12_INTERFACE 1715 if (crtc->randr_crtc) 1716 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 1717 else 1718 #endif 1719 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 1720 } 1721 } 1722 1723 static void 1724 R128BlockHandler(BLOCKHANDLER_ARGS_DECL) 1725 { 1726 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1727 R128InfoPtr info = R128PTR(pScrn); 1728 1729 #ifdef R128DRI 1730 if (info->directRenderingEnabled) 1731 FLUSH_RING(); 1732 #endif 1733 1734 pScreen->BlockHandler = info->BlockHandler; 1735 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 1736 pScreen->BlockHandler = R128BlockHandler; 1737 1738 if(info->VideoTimerCallback) { 1739 (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds); 1740 } 1741 } 1742 1743 /* Called at the start of each server generation. */ 1744 Bool R128ScreenInit(ScreenPtr pScreen, int argc, char **argv) 1745 { 1746 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1747 R128InfoPtr info = R128PTR(pScrn); 1748 BoxRec MemBox; 1749 int width_bytes = (pScrn->displayWidth * 1750 info->CurrentLayout.pixel_bytes); 1751 int scanlines; 1752 int total = info->FbMapSize; 1753 FBAreaPtr fbarea = NULL; 1754 #ifdef R128DRI 1755 int cpp = info->CurrentLayout.pixel_bytes; 1756 int x1 = 0, x2 = 0, y1 = 0, y2 = 0; 1757 #ifdef USE_EXA 1758 ExaOffscreenArea* osArea = NULL; 1759 #endif /* USE_EXA */ 1760 #endif /* R128DRI */ 1761 1762 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1763 "%s %lx %lx\n", 1764 __func__, 1765 pScrn->memPhysBase, pScrn->fbOffset)); 1766 1767 #ifdef R128DRI 1768 /* Turn off the CCE for now. */ 1769 info->CCEInUse = FALSE; 1770 info->indirectBuffer = NULL; 1771 #endif 1772 1773 if (!R128MapMem(pScrn)) return FALSE; 1774 pScrn->fbOffset = 0; 1775 //if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024; 1776 #ifdef R128DRI 1777 info->fbX = 0; 1778 info->fbY = 0; 1779 info->frontOffset = 0; 1780 info->frontPitch = pScrn->displayWidth; 1781 #endif 1782 1783 info->PaletteSavedOnVT = FALSE; 1784 1785 R128Save(pScrn); 1786 1787 /* Visual setup */ 1788 miClearVisualTypes(); 1789 if (!miSetVisualTypes(pScrn->depth, 1790 miGetDefaultVisualMask(pScrn->depth), 1791 pScrn->rgbBits, 1792 pScrn->defaultVisual)) return FALSE; 1793 miSetPixmapDepths (); 1794 1795 #ifdef R128DRI 1796 /* Setup DRI after visuals have been 1797 established, but before fbScreenInit is 1798 called. */ 1799 { 1800 /* FIXME: When we move to dynamic allocation of back and depth 1801 buffers, we will want to revisit the following check for 3 1802 times the virtual size of the screen below. */ 1803 int maxy = info->FbMapSize / width_bytes; 1804 1805 if (info->noAccel) { 1806 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1807 "Acceleration disabled, not initializing the DRI\n"); 1808 info->directRenderingEnabled = FALSE; 1809 } else if (maxy <= pScrn->virtualY * 3) { 1810 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1811 "Static buffer allocation failed -- " 1812 "need at least %d kB video memory\n", 1813 (pScrn->displayWidth * pScrn->virtualY * 1814 info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); 1815 info->directRenderingEnabled = FALSE; 1816 } else { 1817 info->directRenderingEnabled = R128DRIScreenInit(pScreen); 1818 } 1819 } 1820 #endif 1821 1822 if (!fbScreenInit (pScreen, info->FB, 1823 pScrn->virtualX, pScrn->virtualY, 1824 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, 1825 pScrn->bitsPerPixel)) 1826 return FALSE; 1827 1828 xf86SetBlackWhitePixels(pScreen); 1829 1830 if (pScrn->bitsPerPixel > 8) { 1831 VisualPtr visual; 1832 1833 visual = pScreen->visuals + pScreen->numVisuals; 1834 while (--visual >= pScreen->visuals) { 1835 if ((visual->class | DynamicClass) == DirectColor) { 1836 visual->offsetRed = pScrn->offset.red; 1837 visual->offsetGreen = pScrn->offset.green; 1838 visual->offsetBlue = pScrn->offset.blue; 1839 visual->redMask = pScrn->mask.red; 1840 visual->greenMask = pScrn->mask.green; 1841 visual->blueMask = pScrn->mask.blue; 1842 } 1843 } 1844 } 1845 1846 /* must be after RGB order fixed */ 1847 fbPictureInit (pScreen, 0, 0); 1848 1849 /* Memory manager setup */ 1850 #ifdef R128DRI 1851 if (info->directRenderingEnabled) { 1852 int bufferSize = pScrn->virtualY * width_bytes; 1853 int l; 1854 1855 switch (info->CCEMode) { 1856 case R128_DEFAULT_CCE_PIO_MODE: 1857 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); 1858 break; 1859 case R128_DEFAULT_CCE_BM_MODE: 1860 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); 1861 break; 1862 default: 1863 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); 1864 break; 1865 } 1866 1867 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1868 "Using %d MB AGP aperture\n", info->agpSize); 1869 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1870 "Using %d MB for the ring buffer\n", info->ringSize); 1871 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1872 "Using %d MB for vertex/indirect buffers\n", info->bufSize); 1873 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1874 "Using %d MB for AGP textures\n", info->agpTexSize); 1875 1876 /* Try for front, back, depth, and two framebuffers worth of 1877 * pixmap cache. Should be enough for a fullscreen background 1878 * image plus some leftovers. 1879 */ 1880 info->textureSize = info->FbMapSize - 5 * bufferSize; 1881 1882 /* If that gives us less than half the available memory, let's 1883 * be greedy and grab some more. Sorry, I care more about 3D 1884 * performance than playing nicely, and you'll get around a full 1885 * framebuffer's worth of pixmap cache anyway. 1886 */ 1887 if (info->textureSize < (int)info->FbMapSize / 2) { 1888 info->textureSize = info->FbMapSize - 4 * bufferSize; 1889 } 1890 1891 if (info->textureSize > 0) { 1892 l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); 1893 if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; 1894 1895 /* Round the texture size up to the nearest whole number of 1896 * texture regions. Again, be greedy about this, don't 1897 * round down. 1898 */ 1899 info->log2TexGran = l; 1900 info->textureSize = (info->textureSize >> l) << l; 1901 } else { 1902 info->textureSize = 0; 1903 } 1904 1905 /* Set a minimum usable local texture heap size. This will fit 1906 * two 256x256x32bpp textures. 1907 */ 1908 if (info->textureSize < 512 * 1024) { 1909 info->textureOffset = 0; 1910 info->textureSize = 0; 1911 } 1912 1913 total = info->FbMapSize - info->textureSize; 1914 } 1915 #endif /* R128DRI */ 1916 1917 scanlines = total / width_bytes; 1918 if (scanlines > 8191) scanlines = 8191; 1919 1920 #ifdef R128DRI 1921 if (info->directRenderingEnabled) 1922 /* 1923 * Recalculate the texture offset and size to accommodate any 1924 * rounding to a whole number of scanlines. 1925 */ 1926 info->textureOffset = scanlines * width_bytes; 1927 #endif /* R128DRI */ 1928 1929 MemBox.x1 = 0; 1930 MemBox.y1 = 0; 1931 MemBox.x2 = pScrn->displayWidth; 1932 MemBox.y2 = scanlines; 1933 1934 if (!info->useEXA) { 1935 if (!xf86InitFBManager(pScreen, &MemBox)) { 1936 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1937 "Memory manager initialization to (%d,%d) (%d,%d) failed\n", 1938 MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); 1939 return FALSE; 1940 } else { 1941 int width, height; 1942 1943 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1944 "Memory manager initialized to (%d,%d) (%d,%d)\n", 1945 MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); 1946 if ((fbarea = xf86AllocateOffscreenArea(pScreen, 1947 pScrn->displayWidth, 1948 2, 0, NULL, NULL, NULL))) { 1949 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1950 "Reserved area from (%d,%d) to (%d,%d)\n", 1951 fbarea->box.x1, fbarea->box.y1, 1952 fbarea->box.x2, fbarea->box.y2); 1953 } else { 1954 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve area\n"); 1955 } 1956 if (xf86QueryLargestOffscreenArea(pScreen, &width, 1957 &height, 0, 0, 0)) { 1958 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1959 "Largest offscreen area available: %d x %d\n", 1960 width, height); 1961 } 1962 1963 if (!info->noAccel) { 1964 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1965 "Acceleration disabled.\n"); 1966 } 1967 } 1968 } 1969 #ifdef USE_EXA 1970 else { 1971 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1972 "Filling in EXA memory info\n"); 1973 1974 1975 /* 1976 * Don't give EXA the true full memory size, because 1977 * the textureSize sized chunk on the end is handled 1978 * by DRI. 1979 */ 1980 if (R128EXAInit(pScreen, total)) { 1981 info->accelOn = TRUE; 1982 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1983 "EXA Acceleration enabled.\n"); 1984 } else { 1985 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1986 "EXA Acceleration initialization " 1987 "failed.\n"); 1988 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1989 "Acceleration disabled.\n"); 1990 } 1991 } 1992 #endif 1993 1994 #ifdef R128DRI 1995 if (info->directRenderingEnabled) { 1996 /* Allocate the shared back buffer */ 1997 if(!info->useEXA) { 1998 fbarea = xf86AllocateOffscreenArea(pScreen, 1999 pScrn->virtualX, 2000 pScrn->virtualY, 2001 32, NULL, NULL, NULL); 2002 2003 if (fbarea) { 2004 x1 = fbarea->box.x1; 2005 x2 = fbarea->box.x2; 2006 y1 = fbarea->box.y1; 2007 y2 = fbarea->box.y2; 2008 } 2009 } 2010 #ifdef USE_EXA 2011 else { 2012 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2013 "Actually trying an EXA allocation...\n"); 2014 osArea = exaOffscreenAlloc(pScreen, 2015 pScrn->virtualY * width_bytes, 2016 32, TRUE, NULL, NULL); 2017 2018 if (osArea) { 2019 x1 = osArea->offset % width_bytes; 2020 x2 = (osArea->offset + osArea->size) % width_bytes; 2021 y1 = osArea->offset / width_bytes; 2022 y2 = (osArea->offset + osArea->size) / width_bytes; 2023 2024 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Went swimmingly...\n"); 2025 } 2026 } 2027 #endif 2028 2029 if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) { 2030 /* info->backOffset = y1 * width_bytes + x1 * cpp; */ 2031 info->backOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16); 2032 info->backX = info->backOffset % width_bytes; 2033 info->backY = info->backOffset / width_bytes; 2034 info->backPitch = pScrn->displayWidth; 2035 2036 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2037 "Reserved back buffer from (%d,%d) to (%d,%d) offset: %x\n", 2038 x1, y1, 2039 x2, y2, info->backOffset); 2040 } else { 2041 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); 2042 info->backX = -1; 2043 info->backY = -1; 2044 info->backOffset = -1; 2045 info->backPitch = -1; 2046 } 2047 2048 /* Allocate the shared depth buffer */ 2049 if(!info->useEXA) { 2050 fbarea = xf86AllocateOffscreenArea(pScreen, 2051 pScrn->virtualX, 2052 pScrn->virtualY + 1, 2053 32, NULL, NULL, NULL); 2054 if (fbarea) { 2055 x1 = fbarea->box.x1; 2056 x2 = fbarea->box.x2; 2057 y1 = fbarea->box.y1; 2058 y2 = fbarea->box.y2; 2059 } 2060 } 2061 #ifdef USE_EXA 2062 else { 2063 osArea = exaOffscreenAlloc(pScreen, 2064 (pScrn->virtualY + 1) * width_bytes, 2065 32, TRUE, NULL, NULL); 2066 2067 if (osArea) { 2068 x1 = osArea->offset % width_bytes; 2069 x2 = (osArea->offset + osArea->size) % width_bytes; 2070 y1 = osArea->offset / width_bytes; 2071 y2 = (osArea->offset + osArea->size) / width_bytes; 2072 } 2073 } 2074 #endif 2075 2076 if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) { 2077 /* info->depthOffset = y1 * width_bytes + x1 * cpp; */ 2078 info->depthOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16); 2079 info->depthX = info->depthOffset % width_bytes; 2080 info->depthY = info->depthOffset / width_bytes; 2081 info->depthPitch = pScrn->displayWidth; 2082 info->spanOffset = (y2 - 1) * width_bytes + x1 * cpp; 2083 2084 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2085 "Reserved depth buffer from (%d,%d) to (%d,%d) offset: %x\n", 2086 x1, y1, 2087 x2, y2, info->depthOffset); 2088 2089 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2090 "Reserved depth span from (%d,%d) offset 0x%x\n", 2091 x1, y2 - 1, info->spanOffset); 2092 } else { 2093 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); 2094 info->depthX = -1; 2095 info->depthY = -1; 2096 info->depthOffset = -1; 2097 info->depthPitch = -1; 2098 info->spanOffset = -1; 2099 } 2100 2101 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2102 "Reserved %d kb for textures at offset 0x%x\n", 2103 info->textureSize/1024, info->textureOffset); 2104 } 2105 #endif /* R128DRI */ 2106 2107 pScrn->vtSema = TRUE; 2108 /* xf86CrtcRotate accesses pScrn->pScreen */ 2109 pScrn->pScreen = pScreen; 2110 2111 #ifndef AVOID_FBDEV 2112 if (info->FBDev) { 2113 if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; 2114 } else { 2115 #endif 2116 if (!xf86SetDesiredModes(pScrn)) return FALSE; 2117 #ifndef AVOID_FBDEV 2118 } 2119 #endif 2120 2121 R128SaveScreen(pScreen, SCREEN_SAVER_ON); 2122 //pScrn->AdjustFrame(pScrn, pScrn->frameX0, pScrn->frameY0); 2123 2124 /* DGA setup */ 2125 #ifdef XFreeXDGA 2126 xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); 2127 #endif 2128 2129 /* Backing store setup */ 2130 xf86SetBackingStore(pScreen); 2131 2132 /* Set Silken Mouse */ 2133 xf86SetSilkenMouse(pScreen); 2134 2135 /* Cursor setup */ 2136 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 2137 2138 /* Hardware cursor setup */ 2139 if (!info->swCursor) { 2140 if (R128CursorInit(pScreen)) { 2141 int width, height; 2142 2143 if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 2144 0, 0, 0)) { 2145 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2146 "Largest offscreen area available: %d x %d\n", 2147 width, height); 2148 } 2149 } else { 2150 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2151 "Hardware cursor initialization failed\n"); 2152 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n"); 2153 } 2154 } else { 2155 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n"); 2156 } 2157 2158 /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */ 2159 #ifndef AVOID_FBDEV 2160 if (info->FBDev) 2161 xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0); 2162 else 2163 #endif 2164 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 2165 2166 R128InitVideo(pScreen); 2167 2168 /* Provide SaveScreen */ 2169 pScreen->SaveScreen = R128SaveScreen; 2170 2171 /* Wrap CloseScreen */ 2172 info->CloseScreen = pScreen->CloseScreen; 2173 pScreen->CloseScreen = R128CloseScreen; 2174 2175 /* Note unused options */ 2176 if (serverGeneration == 1) 2177 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 2178 2179 #ifdef R128DRI 2180 /* DRI finalization */ 2181 if (info->directRenderingEnabled) { 2182 /* Now that mi, fb, drm and others have 2183 done their thing, complete the DRI 2184 setup. */ 2185 info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen); 2186 } 2187 if (info->directRenderingEnabled) { 2188 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 2189 } else { 2190 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2191 "Direct rendering disabled\n"); 2192 } 2193 #endif 2194 2195 info->BlockHandler = pScreen->BlockHandler; 2196 pScreen->BlockHandler = R128BlockHandler; 2197 2198 if (!xf86CrtcScreenInit(pScreen)) return FALSE; 2199 2200 /* Colormap setup */ 2201 if (!miCreateDefColormap(pScreen)) return FALSE; 2202 if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, 2203 ( 2204 #ifndef AVOID_FBDEV 2205 info->FBDev ? fbdevHWLoadPaletteWeak() : 2206 #endif 2207 R128LoadPalette), NULL, 2208 CMAP_PALETTED_TRUECOLOR 2209 | CMAP_RELOAD_ON_MODE_SWITCH 2210 #if 0 /* This option messes up text mode! (eich (at) suse.de) */ 2211 | CMAP_LOAD_EVEN_IF_OFFSCREEN 2212 #endif 2213 )) return FALSE; 2214 2215 return TRUE; 2216 } 2217 2218 /* Write common registers (initialized to 0). */ 2219 void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2220 { 2221 R128InfoPtr info = R128PTR(pScrn); 2222 unsigned char *R128MMIO = info->MMIO; 2223 2224 OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl | R128_FP_BLANK_DIS); 2225 2226 OUTREG(R128_OVR_CLR, restore->ovr_clr); 2227 OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); 2228 OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); 2229 OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); 2230 OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); 2231 OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); 2232 OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); 2233 OUTREG(R128_VIPH_CONTROL, restore->viph_control); 2234 OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); 2235 OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); 2236 OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); 2237 OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); 2238 OUTREG(R128_BUS_CNTL, restore->bus_cntl); 2239 OUTREG(R128_CONFIG_CNTL, restore->config_cntl); 2240 } 2241 2242 /* Write RMX registers */ 2243 void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2244 { 2245 R128InfoPtr info = R128PTR(pScrn); 2246 unsigned char *R128MMIO = info->MMIO; 2247 2248 OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); 2249 OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); 2250 OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); 2251 OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); 2252 OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); 2253 OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); 2254 } 2255 2256 /* Write flat panel registers */ 2257 void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2258 { 2259 R128InfoPtr info = R128PTR(pScrn); 2260 unsigned char *R128MMIO = info->MMIO; 2261 2262 OUTREG(R128_TMDS_CRC, restore->tmds_crc); 2263 OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl); 2264 OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); 2265 OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(uint32_t)R128_FP_BLANK_DIS); 2266 } 2267 2268 /* Write LVDS registers */ 2269 void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2270 { 2271 R128InfoPtr info = R128PTR(pScrn); 2272 R128EntPtr pR128Ent = R128EntPriv(pScrn); 2273 unsigned char *R128MMIO = info->MMIO; 2274 uint32_t tmp; 2275 2276 xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]); 2277 R128OutputPrivatePtr r128_output = output->driver_private; 2278 2279 tmp = INREG(R128_LVDS_GEN_CNTL); 2280 if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == 2281 (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { 2282 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2283 } else { 2284 if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { 2285 OUTREG(R128_LVDS_GEN_CNTL, 2286 restore->lvds_gen_cntl & (uint32_t)~R128_LVDS_BLON); 2287 usleep(r128_output->PanelPwrDly * 1000); 2288 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2289 } else { 2290 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON); 2291 usleep(r128_output->PanelPwrDly * 1000); 2292 OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2293 } 2294 } 2295 } 2296 2297 /* Write DDA registers. */ 2298 void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2299 { 2300 R128InfoPtr info = R128PTR(pScrn); 2301 unsigned char *R128MMIO = info->MMIO; 2302 2303 OUTREG(R128_DDA_CONFIG, restore->dda_config); 2304 OUTREG(R128_DDA_ON_OFF, restore->dda_on_off); 2305 } 2306 2307 /* Write DDA registers. */ 2308 void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore) 2309 { 2310 R128InfoPtr info = R128PTR(pScrn); 2311 unsigned char *R128MMIO = info->MMIO; 2312 2313 OUTREG(R128_DDA2_CONFIG, restore->dda2_config); 2314 OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off); 2315 } 2316 2317 /* Read common registers. */ 2318 static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2319 { 2320 R128InfoPtr info = R128PTR(pScrn); 2321 unsigned char *R128MMIO = info->MMIO; 2322 2323 save->ovr_clr = INREG(R128_OVR_CLR); 2324 save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); 2325 save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); 2326 save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); 2327 save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); 2328 save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); 2329 save->subpic_cntl = INREG(R128_SUBPIC_CNTL); 2330 save->viph_control = INREG(R128_VIPH_CONTROL); 2331 save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); 2332 save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); 2333 save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); 2334 save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); 2335 save->bus_cntl = INREG(R128_BUS_CNTL); 2336 save->config_cntl = INREG(R128_CONFIG_CNTL); 2337 } 2338 2339 /* Read CRTC registers. */ 2340 static void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2341 { 2342 R128InfoPtr info = R128PTR(pScrn); 2343 unsigned char *R128MMIO = info->MMIO; 2344 2345 save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); 2346 save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); 2347 save->dac_cntl = INREG(R128_DAC_CNTL); 2348 save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); 2349 save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); 2350 save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); 2351 save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); 2352 save->crtc_offset = INREG(R128_CRTC_OFFSET); 2353 save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); 2354 save->crtc_pitch = INREG(R128_CRTC_PITCH); 2355 } 2356 2357 /* Read flat panel registers */ 2358 static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2359 { 2360 R128InfoPtr info = R128PTR(pScrn); 2361 unsigned char *R128MMIO = info->MMIO; 2362 2363 save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); 2364 save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); 2365 save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); 2366 save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); 2367 save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); 2368 save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); 2369 save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); 2370 save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); 2371 save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); 2372 save->tmds_crc = INREG(R128_TMDS_CRC); 2373 save->tmds_transmitter_cntl = INREG(R128_TMDS_TRANSMITTER_CNTL); 2374 } 2375 2376 /* Read CRTC2 registers. */ 2377 static void R128SaveCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save) 2378 { 2379 R128InfoPtr info = R128PTR(pScrn); 2380 unsigned char *R128MMIO = info->MMIO; 2381 2382 save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); 2383 save->crtc2_h_total_disp = INREG(R128_CRTC2_H_TOTAL_DISP); 2384 save->crtc2_h_sync_strt_wid = INREG(R128_CRTC2_H_SYNC_STRT_WID); 2385 save->crtc2_v_total_disp = INREG(R128_CRTC2_V_TOTAL_DISP); 2386 save->crtc2_v_sync_strt_wid = INREG(R128_CRTC2_V_SYNC_STRT_WID); 2387 save->crtc2_offset = INREG(R128_CRTC2_OFFSET); 2388 save->crtc2_offset_cntl = INREG(R128_CRTC2_OFFSET_CNTL); 2389 save->crtc2_pitch = INREG(R128_CRTC2_PITCH); 2390 } 2391 2392 /* Read PLL registers. */ 2393 static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2394 { 2395 save->ppll_ref_div = INPLL(pScrn, R128_PPLL_REF_DIV); 2396 save->ppll_div_3 = INPLL(pScrn, R128_PPLL_DIV_3); 2397 save->ppll_div_0 = INPLL(pScrn, R128_PPLL_DIV_0); 2398 save->htotal_cntl = INPLL(pScrn, R128_HTOTAL_CNTL); 2399 2400 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2401 "Read: 0x%08x 0x%08x 0x%08x\n", 2402 save->ppll_ref_div, 2403 save->ppll_div_3, 2404 save->htotal_cntl)); 2405 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2406 "Read: rd=%d, fd=%d, pd=%d\n", 2407 save->ppll_ref_div & R128_PPLL_REF_DIV_MASK, 2408 save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, 2409 (save->ppll_div_3 & 2410 R128_PPLL_POST3_DIV_MASK) >> 16)); 2411 } 2412 2413 /* Read PLL2 registers. */ 2414 static void R128SavePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save) 2415 { 2416 save->p2pll_ref_div = INPLL(pScrn, R128_P2PLL_REF_DIV); 2417 save->p2pll_div_0 = INPLL(pScrn, R128_P2PLL_DIV_0); 2418 save->htotal_cntl2 = INPLL(pScrn, R128_HTOTAL2_CNTL); 2419 2420 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2421 "Read: 0x%08x 0x%08x 0x%08x\n", 2422 save->p2pll_ref_div, 2423 save->p2pll_div_0, 2424 save->htotal_cntl2)); 2425 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2426 "Read: rd=%d, fd=%d, pd=%d\n", 2427 save->p2pll_ref_div & R128_P2PLL_REF_DIV_MASK, 2428 save->p2pll_div_0 & R128_P2PLL_FB0_DIV_MASK, 2429 (save->p2pll_div_0 & 2430 R128_P2PLL_POST0_DIV_MASK) >> 16)); 2431 } 2432 2433 /* Read DDA registers. */ 2434 static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2435 { 2436 R128InfoPtr info = R128PTR(pScrn); 2437 unsigned char *R128MMIO = info->MMIO; 2438 2439 save->dda_config = INREG(R128_DDA_CONFIG); 2440 save->dda_on_off = INREG(R128_DDA_ON_OFF); 2441 } 2442 2443 /* Read DDA2 registers. */ 2444 static void R128SaveDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save) 2445 { 2446 R128InfoPtr info = R128PTR(pScrn); 2447 unsigned char *R128MMIO = info->MMIO; 2448 2449 save->dda2_config = INREG(R128_DDA2_CONFIG); 2450 save->dda2_on_off = INREG(R128_DDA2_ON_OFF); 2451 } 2452 2453 /* Read palette data. */ 2454 static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save) 2455 { 2456 R128InfoPtr info = R128PTR(pScrn); 2457 unsigned char *R128MMIO = info->MMIO; 2458 int i; 2459 2460 PAL_SELECT(1); 2461 INPAL_START(0); 2462 for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT(); 2463 PAL_SELECT(0); 2464 INPAL_START(0); 2465 for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); 2466 save->palette_valid = TRUE; 2467 } 2468 2469 /* Save state that defines current video mode. */ 2470 static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save) 2471 { 2472 R128InfoPtr info = R128PTR(pScrn); 2473 R128EntPtr pR128Ent = R128EntPriv(pScrn); 2474 2475 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2476 "%s(%p)\n", __func__, save)); 2477 2478 R128SaveCommonRegisters(pScrn, save); 2479 R128SaveCrtcRegisters(pScrn, save); 2480 R128SavePLLRegisters(pScrn, save); 2481 R128SaveDDARegisters(pScrn, save); 2482 if (pR128Ent->HasCRTC2) { 2483 R128SaveCrtc2Registers(pScrn, save); 2484 R128SavePLL2Registers(pScrn, save); 2485 R128SaveDDA2Registers(pScrn, save); 2486 } 2487 if (info->HasPanelRegs) { 2488 R128SaveFPRegisters(pScrn, save); 2489 } 2490 R128SavePalette(pScrn, save); 2491 2492 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2493 "%s returns %p\n", __func__, save)); 2494 } 2495 2496 /* Save everything needed to restore the original VC state. */ 2497 static void R128Save(ScrnInfoPtr pScrn) 2498 { 2499 R128InfoPtr info = R128PTR(pScrn); 2500 unsigned char *R128MMIO = info->MMIO; 2501 R128SavePtr save = &info->SavedReg; 2502 2503 #ifndef AVOID_FBDEV 2504 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2505 "%s\n", __func__)); 2506 if (info->FBDev) { 2507 fbdevHWSave(pScrn); 2508 return; 2509 } 2510 #endif 2511 2512 #ifdef WITH_VGAHW 2513 if (info->VGAAccess) { 2514 vgaHWPtr hwp = VGAHWPTR(pScrn); 2515 2516 vgaHWUnlock(hwp); 2517 # if defined(__powerpc__) 2518 /* temporary hack to prevent crashing on PowerMacs when trying to 2519 * read VGA fonts and colormap, will find a better solution 2520 * in the future. TODO: Check if there's actually some VGA stuff 2521 * setup in the card at all !! 2522 */ 2523 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ 2524 # else 2525 /* Save mode * & fonts & cmap */ 2526 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); 2527 # endif 2528 vgaHWLock(hwp); 2529 } 2530 #endif 2531 2532 save->dp_datatype = INREG(R128_DP_DATATYPE); 2533 save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); 2534 save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); 2535 save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); 2536 save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); 2537 2538 R128SaveMode(pScrn, save); 2539 } 2540 2541 /* Restore the original (text) mode. */ 2542 static void R128Restore(ScrnInfoPtr pScrn) 2543 { 2544 R128InfoPtr info = R128PTR(pScrn); 2545 R128EntPtr pR128Ent = R128EntPriv(pScrn); 2546 unsigned char *R128MMIO = info->MMIO; 2547 R128SavePtr restore = &info->SavedReg; 2548 2549 #ifndef AVOID_FBDEV 2550 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2551 "%s\n", __func__)); 2552 if (info->FBDev) { 2553 fbdevHWRestore(pScrn); 2554 return; 2555 } 2556 #endif 2557 R128Blank(pScrn); 2558 2559 OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); 2560 OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); 2561 OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); 2562 OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); 2563 OUTREG(R128_DP_DATATYPE, restore->dp_datatype); 2564 2565 R128RestoreCommonRegisters(pScrn, restore); 2566 if (pR128Ent->HasCRTC2) { 2567 R128RestoreDDA2Registers(pScrn, restore); 2568 R128RestoreCrtc2Registers(pScrn, restore); 2569 R128RestorePLL2Registers(pScrn, restore); 2570 } 2571 R128RestoreDDARegisters(pScrn, restore); 2572 R128RestoreCrtcRegisters(pScrn, restore); 2573 R128RestorePLLRegisters(pScrn, restore); 2574 R128RestoreDACRegisters(pScrn, restore); 2575 R128RestoreRMXRegisters(pScrn, restore); 2576 R128RestoreFPRegisters(pScrn, restore); 2577 R128RestoreLVDSRegisters(pScrn, restore); 2578 2579 OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); 2580 OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); 2581 OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); 2582 OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); 2583 OUTREG(R128_DP_DATATYPE, restore->dp_datatype); 2584 2585 #ifdef WITH_VGAHW 2586 if (info->VGAAccess) { 2587 vgaHWPtr hwp = VGAHWPTR(pScrn); 2588 vgaHWUnlock(hwp); 2589 # if defined(__powerpc__) 2590 /* Temporary hack to prevent crashing on PowerMacs when trying to 2591 * write VGA fonts, will find a better solution in the future 2592 */ 2593 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); 2594 # else 2595 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); 2596 # endif 2597 vgaHWLock(hwp); 2598 } 2599 #endif 2600 2601 R128WaitForVerticalSync(pScrn); 2602 R128Unblank(pScrn); 2603 } 2604 2605 /* Define common registers for requested video mode. */ 2606 void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info) 2607 { 2608 save->ovr_clr = 0; 2609 save->ovr_wid_left_right = 0; 2610 save->ovr_wid_top_bottom = 0; 2611 save->ov0_scale_cntl = 0; 2612 save->mpp_tb_config = 0; 2613 save->mpp_gp_config = 0; 2614 save->subpic_cntl = 0; 2615 save->viph_control = 0; 2616 save->i2c_cntl_1 = 0; 2617 #ifdef R128DRI 2618 save->gen_int_cntl = info->gen_int_cntl; 2619 #else 2620 save->gen_int_cntl = 0; 2621 #endif 2622 save->cap0_trig_cntl = 0; 2623 save->cap1_trig_cntl = 0; 2624 save->bus_cntl = info->BusCntl; 2625 /* 2626 * If bursts are enabled, turn on discards and aborts 2627 */ 2628 if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST)) 2629 save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; 2630 } 2631 2632 /* Define RMX registers for the requested video mode. */ 2633 void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save, 2634 xf86OutputPtr output, DisplayModePtr mode) 2635 { 2636 R128OutputPrivatePtr r128_output = output->driver_private; 2637 2638 int xres = mode->CrtcHDisplay; 2639 int yres = mode->CrtcVDisplay; 2640 float Hratio, Vratio; 2641 2642 save->fp_crtc_h_total_disp = save->crtc_h_total_disp; 2643 save->fp_crtc_v_total_disp = save->crtc_v_total_disp; 2644 save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; 2645 save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; 2646 2647 if (r128_output->MonType != MT_DFP && r128_output->MonType != MT_LCD) 2648 return; 2649 2650 if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) { 2651 xres = r128_output->PanelXRes; 2652 yres = r128_output->PanelYRes; 2653 2654 Hratio = 1.0; 2655 Vratio = 1.0; 2656 } else { 2657 if (xres > r128_output->PanelXRes) xres = r128_output->PanelXRes; 2658 if (yres > r128_output->PanelYRes) yres = r128_output->PanelYRes; 2659 2660 Hratio = (float)xres/(float)r128_output->PanelXRes; 2661 Vratio = (float)yres/(float)r128_output->PanelYRes; 2662 } 2663 2664 save->fp_horz_stretch = 2665 (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5)) 2666 & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) | 2667 (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE | 2668 R128_HORZ_FP_LOOP_STRETCH | 2669 R128_HORZ_STRETCH_RESERVED))); 2670 save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN; 2671 save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO; 2672 if (xres == r128_output->PanelXRes) 2673 save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE); 2674 else 2675 save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE); 2676 2677 save->fp_vert_stretch = 2678 (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5)) 2679 & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) | 2680 (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE | 2681 R128_VERT_STRETCH_RESERVED))); 2682 save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN; 2683 if (yres == r128_output->PanelYRes) 2684 save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND); 2685 else 2686 save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND); 2687 } 2688 2689 /* Define flat panel registers for the requested video mode. */ 2690 void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output) 2691 { 2692 xf86CrtcPtr crtc = output->crtc; 2693 R128CrtcPrivatePtr r128_crtc = crtc->driver_private; 2694 2695 /* WARNING: Be careful about turning on the flat panel */ 2696 save->fp_gen_cntl = orig->fp_gen_cntl; 2697 save->fp_panel_cntl = orig->fp_panel_cntl; 2698 save->tmds_transmitter_cntl = orig->tmds_transmitter_cntl; 2699 save->tmds_crc = orig->tmds_crc; 2700 2701 if (r128_crtc->crtc_id) 2702 save->fp_gen_cntl |= R128_FP_SEL_CRTC2; 2703 else 2704 save->fp_gen_cntl &= ~R128_FP_SEL_CRTC2; 2705 2706 save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND | 2707 R128_FP_CRTC_USE_SHADOW_ROWCUR | 2708 R128_FP_CRTC_HORZ_DIV2_EN | 2709 R128_FP_CRTC_HOR_CRT_DIV2_DIS | 2710 R128_FP_CRT_SYNC_SEL | 2711 R128_FP_USE_SHADOW_EN); 2712 2713 save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR | 2714 R128_FP_CRTC_DONT_SHADOW_HEND); 2715 2716 save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON); 2717 save->tmds_transmitter_cntl &= ~R128_TMDS_PLLRST; 2718 save->tmds_transmitter_cntl |= R128_TMDS_PLLEN; 2719 } 2720 2721 /* Define LVDS registers for the requested video mode. */ 2722 void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output) 2723 { 2724 xf86CrtcPtr crtc = output->crtc; 2725 R128CrtcPrivatePtr r128_crtc = crtc->driver_private; 2726 2727 save->lvds_gen_cntl = orig->lvds_gen_cntl; 2728 2729 if (r128_crtc->crtc_id) 2730 save->lvds_gen_cntl |= R128_LVDS_SEL_CRTC2; 2731 else 2732 save->lvds_gen_cntl &= ~R128_LVDS_SEL_CRTC2; 2733 } 2734 2735 #if 0 2736 /* Define initial palette for requested video mode. This doesn't do 2737 anything for XFree86 4.0. */ 2738 static void R128InitPalette(R128SavePtr save) 2739 { 2740 save->palette_valid = FALSE; 2741 } 2742 #endif 2743 2744 static Bool R128SaveScreen(ScreenPtr pScreen, int mode) 2745 { 2746 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2747 Bool unblank; 2748 2749 unblank = xf86IsUnblank(mode); 2750 if (unblank) 2751 SetTimeSinceLastInputEvent(); 2752 2753 if ((pScrn != NULL) && pScrn->vtSema) { 2754 if (unblank) 2755 R128Unblank(pScrn); 2756 else 2757 R128Blank(pScrn); 2758 } 2759 return TRUE; 2760 } 2761 2762 /* 2763 * SwitchMode() doesn't work right on crtc2 on some laptops. 2764 * The workaround is to switch the mode, then switch to another VT, then 2765 * switch back. --AGD 2766 */ 2767 Bool R128SwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 2768 { 2769 R128InfoPtr info = R128PTR(pScrn); 2770 Bool ret; 2771 2772 info->SwitchingMode = TRUE; 2773 ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 2774 info->SwitchingMode = FALSE; 2775 return ret; 2776 } 2777 2778 ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags) 2779 { 2780 ScrnInfoPtr pScrn = output->scrn; 2781 R128InfoPtr info = R128PTR(pScrn); 2782 R128OutputPrivatePtr r128_output = output->driver_private; 2783 int i, j; 2784 2785 if (r128_output->MonType == MT_CRT) 2786 return MODE_OK; 2787 2788 if (r128_output->MonType == MT_DFP || r128_output->MonType == MT_LCD) { 2789 if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; 2790 if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; 2791 } 2792 2793 if (r128_output->MonType == MT_LCD && info->VBIOS) { 2794 for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) { 2795 j = R128_BIOS16(i); 2796 2797 if (mode->CrtcHDisplay == R128_BIOS16(j) && 2798 mode->CrtcVDisplay == R128_BIOS16(j + 2)) { 2799 if ((flags & MODECHECK_FINAL) == MODECHECK_FINAL) { 2800 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2801 "Modifying mode according to VBIOS: %ix%i [pclk %.1f MHz] for FP to: ", 2802 mode->CrtcHDisplay, mode->CrtcVDisplay, 2803 (float)mode->Clock / 1000); 2804 2805 /* Assume we are using expanded mode */ 2806 if (R128_BIOS16(j + 5)) j = R128_BIOS16(j + 5); 2807 else j += 9; 2808 2809 mode->Clock = (uint32_t)R128_BIOS16(j) * 10; 2810 2811 mode->HDisplay = mode->CrtcHDisplay = 2812 ((R128_BIOS16(j + 10) & 0x01ff) + 1) * 8; 2813 mode->HSyncStart = mode->CrtcHSyncStart = 2814 ((R128_BIOS16(j + 12) & 0x01ff) + 1) * 8; 2815 mode->HSyncEnd = mode->CrtcHSyncEnd = 2816 mode->CrtcHSyncStart + (R128_BIOS8(j + 14) & 0x1f); 2817 mode->HTotal = mode->CrtcHTotal = 2818 ((R128_BIOS16(j + 8) & 0x01ff) + 1) * 8; 2819 2820 mode->VDisplay = mode->CrtcVDisplay = 2821 (R128_BIOS16(j + 17) & 0x07ff) + 1; 2822 mode->VSyncStart = mode->CrtcVSyncStart = 2823 (R128_BIOS16(j + 19) & 0x07ff) + 1; 2824 mode->VSyncEnd = mode->CrtcVSyncEnd = 2825 mode->CrtcVSyncStart + ((R128_BIOS16(j + 19) >> 11) & 0x1f); 2826 mode->VTotal = mode->CrtcVTotal = 2827 (R128_BIOS16(j + 15) & 0x07ff) + 1; 2828 xf86ErrorF("%ix%i [pclk %.1f MHz]\n", 2829 mode->CrtcHDisplay,mode->CrtcVDisplay, 2830 (float)mode->Clock/ 1000); 2831 } 2832 return MODE_OK; 2833 } 2834 } 2835 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, 2836 "Mode rejected for FP %ix%i [pclk: %.1f] " 2837 "(not listed in VBIOS)\n", 2838 mode->CrtcHDisplay, mode->CrtcVDisplay, 2839 (float)mode->Clock / 1000); 2840 return MODE_NOMODE; 2841 } 2842 2843 return MODE_OK; 2844 } 2845 2846 /* Used to disallow modes that are not supported by the hardware. */ 2847 ModeStatus R128ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, 2848 Bool verbose, int flags) 2849 { 2850 R128EntPtr pR128Ent = R128EntPriv(pScrn); 2851 xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]); 2852 2853 return R128DoValidMode(output, mode, flags); 2854 } 2855 2856 /* Adjust viewport into virtual desktop such that (0,0) in viewport space 2857 is (x,y) in virtual space. */ 2858 void R128AdjustFrame(ScrnInfoPtr pScrn, int x, int y) 2859 { 2860 R128InfoPtr info = R128PTR(pScrn); 2861 unsigned char *R128MMIO = info->MMIO; 2862 int Base; 2863 2864 if(info->showCache && y && pScrn->vtSema) 2865 y += pScrn->virtualY - 1; 2866 2867 Base = y * info->CurrentLayout.displayWidth + x; 2868 2869 switch (info->CurrentLayout.pixel_code) { 2870 case 15: 2871 case 16: Base *= 2; break; 2872 case 24: Base *= 3; break; 2873 case 32: Base *= 4; break; 2874 } 2875 2876 Base &= ~7; /* 3 lower bits are always 0 */ 2877 2878 if (info->CurrentLayout.pixel_code == 24) 2879 Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */ 2880 2881 OUTREG(R128_CRTC_OFFSET, Base); 2882 } 2883 2884 /* Called when VT switching back to the X server. Reinitialize the video 2885 mode. */ 2886 Bool R128EnterVT(ScrnInfoPtr pScrn) 2887 { 2888 R128InfoPtr info = R128PTR(pScrn); 2889 2890 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2891 "%s\n", __func__)); 2892 2893 pScrn->vtSema = TRUE; 2894 #ifndef AVOID_FBDEV 2895 if (info->FBDev) { 2896 if (!fbdevHWEnterVT(pScrn)) return FALSE; 2897 } else { 2898 #endif 2899 if (!xf86SetDesiredModes(pScrn)) return FALSE; 2900 #ifndef AVOID_FBDEV 2901 } 2902 #endif 2903 2904 if (info->accelOn) 2905 R128EngineInit(pScrn); 2906 2907 #ifdef R128DRI 2908 if (info->directRenderingEnabled) { 2909 if (info->irq) { 2910 /* Need to make sure interrupts are enabled */ 2911 unsigned char *R128MMIO = info->MMIO; 2912 OUTREG(R128_GEN_INT_CNTL, info->gen_int_cntl); 2913 } 2914 R128CCE_START(pScrn, info); 2915 DRIUnlock(pScrn->pScreen); 2916 } 2917 #endif 2918 2919 info->PaletteSavedOnVT = FALSE; 2920 //pScrn->AdjustFrame(pScrn, pScrn->frameX0, pScrn->frameY0); 2921 2922 return TRUE; 2923 } 2924 2925 /* Called when VT switching away from the X server. Restore the original 2926 text mode. */ 2927 void R128LeaveVT(ScrnInfoPtr pScrn) 2928 { 2929 R128InfoPtr info = R128PTR(pScrn); 2930 R128SavePtr save = &info->ModeReg; 2931 2932 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2933 "%s\n", __func__)); 2934 #ifdef R128DRI 2935 if (info->directRenderingEnabled) { 2936 DRILock(pScrn->pScreen, 0); 2937 R128CCE_STOP(pScrn, info); 2938 } 2939 #ifdef USE_EXA 2940 if (info->useEXA) 2941 info->state_2d.composite_setup = FALSE; 2942 #endif 2943 #endif 2944 R128SavePalette(pScrn, save); 2945 info->PaletteSavedOnVT = TRUE; 2946 #ifndef AVOID_FBDEV 2947 if (info->FBDev) 2948 fbdevHWLeaveVT(pScrn); 2949 else 2950 #endif 2951 R128Restore(pScrn); 2952 } 2953 2954 2955 /* Called at the end of each server generation. Restore the original text 2956 mode, unmap video memory, and unwrap and call the saved CloseScreen 2957 function. */ 2958 static Bool R128CloseScreen(ScreenPtr pScreen) 2959 { 2960 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2961 R128InfoPtr info = R128PTR(pScrn); 2962 2963 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2964 "%s\n", __func__)); 2965 2966 #ifdef R128DRI 2967 /* Disable direct rendering */ 2968 if (info->directRenderingEnabled) { 2969 R128DRICloseScreen(pScreen); 2970 info->directRenderingEnabled = FALSE; 2971 } 2972 #endif 2973 2974 if (pScrn->vtSema) { 2975 R128Restore(pScrn); 2976 R128UnmapMem(pScrn); 2977 } 2978 2979 #ifdef USE_EXA 2980 if (info->useEXA) { 2981 exaDriverFini(pScreen); 2982 free(info->ExaDriver); 2983 } 2984 #endif 2985 2986 if (info->scratch_save) free(info->scratch_save); 2987 info->scratch_save = NULL; 2988 2989 if (info->adaptor) { 2990 free(info->adaptor->pPortPrivates[0].ptr); 2991 xf86XVFreeVideoAdaptorRec(info->adaptor); 2992 info->adaptor = NULL; 2993 } 2994 2995 pScrn->vtSema = FALSE; 2996 2997 pScreen->BlockHandler = info->BlockHandler; 2998 pScreen->CloseScreen = info->CloseScreen; 2999 return (*pScreen->CloseScreen)(pScreen); 3000 } 3001 3002 void R128FreeScreen(ScrnInfoPtr pScrn) 3003 { 3004 R128InfoPtr info = R128PTR(pScrn); 3005 3006 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3007 "%s\n", __func__)); 3008 if (info == NULL) 3009 return; 3010 #ifdef WITH_VGAHW 3011 if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 3012 vgaHWFreeHWRec(pScrn); 3013 #endif 3014 R128FreeRec(pScrn); 3015 } 3016