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