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