1fc5a983dSmrg/* 271ba42d0Smrg * Copyright (c) 2007,2010 NVIDIA Corporation 3fc5a983dSmrg * 4fc5a983dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5fc5a983dSmrg * copy of this software and associated documentation files (the 6fc5a983dSmrg * "Software"), to deal in the Software without restriction, including 7fc5a983dSmrg * without limitation the rights to use, copy, modify, merge, publish, 8fc5a983dSmrg * distribute, sublicense, and/or sell copies of the Software, and to 9fc5a983dSmrg * permit persons to whom the Software is furnished to do so, subject to 10fc5a983dSmrg * the following conditions: 11fc5a983dSmrg * 12fc5a983dSmrg * The above copyright notice and this permission notice shall be included 13fc5a983dSmrg * in all copies or substantial portions of the Software. 14fc5a983dSmrg * 15fc5a983dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16fc5a983dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17fc5a983dSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18fc5a983dSmrg * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19fc5a983dSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20fc5a983dSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21fc5a983dSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22fc5a983dSmrg */ 23fc5a983dSmrg 24fc5a983dSmrg 25fc5a983dSmrg#ifdef HAVE_CONFIG_H 26fc5a983dSmrg#include "config.h" 27fc5a983dSmrg#endif 28fc5a983dSmrg 29fc5a983dSmrg#include <string.h> 30fc5a983dSmrg 3171ba42d0Smrg#include <xf86.h> 32fc5a983dSmrg#include <xf86_OSproc.h> 3371ba42d0Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 34fc5a983dSmrg#include <xf86Resources.h> 3571ba42d0Smrg#endif 36fc5a983dSmrg#include <mipointer.h> 37fc5a983dSmrg#include <micmap.h> 38fc5a983dSmrg#include <xf86cmap.h> 39fc5a983dSmrg#include <fb.h> 4071ba42d0Smrg#ifdef HAVE_XEXTPROTO_71 4171ba42d0Smrg#include <X11/extensions/dpmsconst.h> 4271ba42d0Smrg#else 43fc5a983dSmrg#define DPMS_SERVER 44fc5a983dSmrg#include <X11/extensions/dpms.h> 4571ba42d0Smrg#endif 4671ba42d0Smrg 4771ba42d0Smrg#include <xf86RandR12.h> 48fc5a983dSmrg 49fc5a983dSmrg#include "nv_const.h" 50fc5a983dSmrg#include "g80_type.h" 51fc5a983dSmrg#include "g80_cursor.h" 52fc5a983dSmrg#include "g80_display.h" 53fc5a983dSmrg#include "g80_dma.h" 54fc5a983dSmrg#include "g80_output.h" 55fc5a983dSmrg#include "g80_exa.h" 56fc5a983dSmrg#include "g80_xaa.h" 57fc5a983dSmrg 58fc5a983dSmrg#define G80_REG_SIZE (1024 * 1024 * 16) 5971ba42d0Smrg#define G80_RESERVED_VIDMEM 0xe000 60fc5a983dSmrg 61fc5a983dSmrgtypedef enum { 62fc5a983dSmrg OPTION_HW_CURSOR, 63fc5a983dSmrg OPTION_NOACCEL, 64fc5a983dSmrg OPTION_ACCEL_METHOD, 65fc5a983dSmrg OPTION_FP_DITHER, 66fc5a983dSmrg OPTION_ALLOW_DUAL_LINK, 67fc5a983dSmrg} G80Opts; 68fc5a983dSmrg 69fc5a983dSmrgstatic const OptionInfoRec G80Options[] = { 70fc5a983dSmrg { OPTION_HW_CURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, 71fc5a983dSmrg { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 72fc5a983dSmrg { OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 73fc5a983dSmrg { OPTION_FP_DITHER, "FPDither", OPTV_BOOLEAN, {0}, FALSE }, 74fc5a983dSmrg { OPTION_ALLOW_DUAL_LINK, "AllowDualLinkModes", OPTV_BOOLEAN, {0}, FALSE }, 75fc5a983dSmrg { -1, NULL, OPTV_NONE, {0}, FALSE } 76fc5a983dSmrg}; 77fc5a983dSmrg 78fc5a983dSmrgstatic Bool 79fc5a983dSmrgG80GetRec(ScrnInfoPtr pScrn) 80fc5a983dSmrg{ 81fc5a983dSmrg if(pScrn->driverPrivate == NULL) 826086d97eSmrg pScrn->driverPrivate = calloc(sizeof(G80Rec), 1); 83fc5a983dSmrg 84fc5a983dSmrg return (pScrn->driverPrivate != NULL); 85fc5a983dSmrg} 86fc5a983dSmrg 87fc5a983dSmrgstatic void 88fc5a983dSmrgG80FreeRec(ScrnInfoPtr pScrn) 89fc5a983dSmrg{ 906086d97eSmrg free(pScrn->driverPrivate); 91fc5a983dSmrg pScrn->driverPrivate = NULL; 92fc5a983dSmrg} 93fc5a983dSmrg 94fc5a983dSmrgstatic Bool 95fc5a983dSmrgG80ResizeScreen(ScrnInfoPtr pScrn, int width, int height) 96fc5a983dSmrg{ 97fc5a983dSmrg ScreenPtr pScreen = pScrn->pScreen; 98fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 99fc5a983dSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 100fc5a983dSmrg int pitch = width * (pScrn->bitsPerPixel / 8); 101fc5a983dSmrg int i; 102fc5a983dSmrg 103fc5a983dSmrg pitch = (pitch + 255) & ~255; 104fc5a983dSmrg 105fc5a983dSmrg pScrn->virtualX = width; 106fc5a983dSmrg pScrn->virtualY = height; 107fc5a983dSmrg 108fc5a983dSmrg /* Can resize if XAA is disabled or EXA is enabled */ 109bd304fc0Smrg if( 110bd304fc0Smrg#ifdef HAVE_XAA_H 111bd304fc0Smrg !pNv->xaa || 112bd304fc0Smrg#endif 113bd304fc0Smrg pNv->exa) { 114fc5a983dSmrg (*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen)->devKind = pitch; 115fc5a983dSmrg pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8); 116fc5a983dSmrg 117fc5a983dSmrg /* Re-set the modes so the new pitch is taken into account */ 118fc5a983dSmrg for(i = 0; i < xf86_config->num_crtc; i++) { 119fc5a983dSmrg xf86CrtcPtr crtc = xf86_config->crtc[i]; 120fc5a983dSmrg if(crtc->enabled) 121fc5a983dSmrg xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); 122fc5a983dSmrg } 123fc5a983dSmrg } 124fc5a983dSmrg 125fc5a983dSmrg /* 126fc5a983dSmrg * If EXA is enabled, use exaOffscreenAlloc to carve out a chunk of memory 127fc5a983dSmrg * for the screen. 128fc5a983dSmrg */ 129fc5a983dSmrg if(pNv->exa) { 130fc5a983dSmrg if(pNv->exaScreenArea) 131fc5a983dSmrg exaOffscreenFree(pScreen, pNv->exaScreenArea); 132fc5a983dSmrg pNv->exaScreenArea = exaOffscreenAlloc(pScreen, pitch * pScrn->virtualY, 133fc5a983dSmrg 256, TRUE, NULL, NULL); 134fc5a983dSmrg if(!pNv->exaScreenArea || pNv->exaScreenArea->offset != 0) { 135fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 136fc5a983dSmrg "Failed to reserve EXA memory for the screen or EXA " 137fc5a983dSmrg "returned an area with a nonzero offset. Don't be " 138fc5a983dSmrg "surprised if your screen is corrupt.\n"); 139fc5a983dSmrg } 140fc5a983dSmrg } 141fc5a983dSmrg 142fc5a983dSmrg return TRUE; 143fc5a983dSmrg} 144fc5a983dSmrg 145fc5a983dSmrgstatic const xf86CrtcConfigFuncsRec randr12_screen_funcs = { 146fc5a983dSmrg .resize = G80ResizeScreen, 147fc5a983dSmrg}; 148fc5a983dSmrg 149fc5a983dSmrgstatic Bool 150fc5a983dSmrgG80PreInit(ScrnInfoPtr pScrn, int flags) 151fc5a983dSmrg{ 152fc5a983dSmrg G80Ptr pNv; 153fc5a983dSmrg EntityInfoPtr pEnt; 15472320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 155fc5a983dSmrg struct pci_device *pPci; 156fc5a983dSmrg int err; 157fc5a983dSmrg void *p; 158fc5a983dSmrg#else 159fc5a983dSmrg pciVideoPtr pPci; 160fc5a983dSmrg PCITAG pcitag; 161fc5a983dSmrg#endif 162fc5a983dSmrg MessageType from; 163fc5a983dSmrg Bool primary; 164fc5a983dSmrg const rgb zeros = {0, 0, 0}; 165fc5a983dSmrg const Gamma gzeros = {0.0, 0.0, 0.0}; 166d136a908Smrg const char *s; 167fc5a983dSmrg CARD32 tmp; 168fc5a983dSmrg memType BAR1sizeKB; 169fc5a983dSmrg 170f3561b8bSmrg if(flags & PROBE_DETECT) 171f3561b8bSmrg return TRUE; 172fc5a983dSmrg 173fc5a983dSmrg /* Check the number of entities, and fail if it isn't one. */ 174fc5a983dSmrg if(pScrn->numEntities != 1) 175fc5a983dSmrg return FALSE; 176fc5a983dSmrg 177fc5a983dSmrg /* Allocate the NVRec driverPrivate */ 178fc5a983dSmrg if(!G80GetRec(pScrn)) { 179fc5a983dSmrg return FALSE; 180fc5a983dSmrg } 181fc5a983dSmrg pNv = G80PTR(pScrn); 182fc5a983dSmrg 183fc5a983dSmrg /* Get the entity, and make sure it is PCI. */ 184fc5a983dSmrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 185fc5a983dSmrg if(pEnt->location.type != BUS_PCI) goto fail; 186fc5a983dSmrg pPci = xf86GetPciInfoForEntity(pEnt->index); 18772320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 188fc5a983dSmrg /* Need this to unmap */ 189fc5a983dSmrg pNv->pPci = pPci; 190fc5a983dSmrg#endif 191fc5a983dSmrg primary = xf86IsPrimaryPci(pPci); 192fc5a983dSmrg 193fc5a983dSmrg /* The ROM size sometimes isn't read correctly, so fix it up here. */ 19472320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 195fc5a983dSmrg if(pPci->rom_size == 0) 196fc5a983dSmrg /* The BIOS is 64k */ 197fc5a983dSmrg pPci->rom_size = 64 * 1024; 198fc5a983dSmrg#else 199fc5a983dSmrg if(pPci->biosSize == 0) 200fc5a983dSmrg /* The BIOS is 64k */ 201fc5a983dSmrg pPci->biosSize = 16; 202fc5a983dSmrg#endif 203fc5a983dSmrg 204fc5a983dSmrg pNv->int10 = NULL; 205fc5a983dSmrg pNv->int10Mode = 0; 206fc5a983dSmrg if(xf86LoadSubModule(pScrn, "int10")) { 207fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); 208fc5a983dSmrg pNv->int10 = xf86InitInt10(pEnt->index); 209fc5a983dSmrg } 210fc5a983dSmrg 211fc5a983dSmrg if(!pNv->int10) { 212fc5a983dSmrg if(primary) { 213fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 214fc5a983dSmrg "Failed to initialize the int10 module; the console " 215fc5a983dSmrg "will not be restored.\n"); 216fc5a983dSmrg } else { 217fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 218fc5a983dSmrg "Failed to initialize the int10 module; this screen " 219fc5a983dSmrg "will not be initialized.\n"); 220fc5a983dSmrg goto fail; 221fc5a983dSmrg } 222fc5a983dSmrg } 223fc5a983dSmrg 224fc5a983dSmrg if(primary && pNv->int10) { 225fc5a983dSmrg const xf86Int10InfoPtr int10 = pNv->int10; 226fc5a983dSmrg 227fc5a983dSmrg /* Get the current video mode */ 228fc5a983dSmrg int10->num = 0x10; 229fc5a983dSmrg int10->ax = 0x4f03; 230fc5a983dSmrg int10->bx = int10->cx = int10->dx = 0; 231fc5a983dSmrg xf86ExecX86int10(int10); 232fc5a983dSmrg pNv->int10Mode = int10->bx & 0x3fff; 233fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Console is VGA mode 0x%x\n", 234fc5a983dSmrg pNv->int10Mode); 235fc5a983dSmrg } 236fc5a983dSmrg 237fc5a983dSmrg /* Disable VGA access */ 23871ba42d0Smrg#ifndef XSERVER_LIBPCIACCESS 239fc5a983dSmrg xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); 240fc5a983dSmrg xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); 24171ba42d0Smrg#endif 242fc5a983dSmrg 243fc5a983dSmrg pScrn->monitor = pScrn->confScreen->monitor; 244fc5a983dSmrg 245fc5a983dSmrg if(!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) goto fail; 246fc5a983dSmrg switch (pScrn->depth) { 247fc5a983dSmrg case 8: 248fc5a983dSmrg case 15: 249fc5a983dSmrg case 16: 250fc5a983dSmrg case 24: 251fc5a983dSmrg /* OK */ 252fc5a983dSmrg break; 253fc5a983dSmrg default: 254fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 255fc5a983dSmrg "Given depth (%d) is not supported by this driver\n", 256fc5a983dSmrg pScrn->depth); 257fc5a983dSmrg goto fail; 258fc5a983dSmrg } 259fc5a983dSmrg xf86PrintDepthBpp(pScrn); 260fc5a983dSmrg 261fc5a983dSmrg if(!xf86SetWeight(pScrn, zeros, zeros)) goto fail; 262fc5a983dSmrg if(!xf86SetDefaultVisual(pScrn, -1)) goto fail; 263fc5a983dSmrg 264fc5a983dSmrg /* We use a programmable clock */ 265fc5a983dSmrg pScrn->progClock = TRUE; 266fc5a983dSmrg 267fc5a983dSmrg /* Process options */ 268fc5a983dSmrg xf86CollectOptions(pScrn, NULL); 2696086d97eSmrg if(!(pNv->Options = malloc(sizeof(G80Options)))) goto fail; 270fc5a983dSmrg memcpy(pNv->Options, G80Options, sizeof(G80Options)); 271fc5a983dSmrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); 272fc5a983dSmrg 273fc5a983dSmrg from = X_DEFAULT; 274fc5a983dSmrg pNv->HWCursor = TRUE; 275fc5a983dSmrg if(xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) 276fc5a983dSmrg from = X_CONFIG; 277fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 278fc5a983dSmrg pNv->HWCursor ? "hardware" : "software"); 279fc5a983dSmrg if(xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { 280fc5a983dSmrg pNv->NoAccel = TRUE; 281fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 282fc5a983dSmrg } 283fc5a983dSmrg s = xf86GetOptValString(pNv->Options, OPTION_ACCEL_METHOD); 284fc5a983dSmrg if(!s || !strcasecmp(s, "xaa")) 285fc5a983dSmrg pNv->AccelMethod = XAA; 286fc5a983dSmrg else if(!strcasecmp(s, "exa")) 287fc5a983dSmrg pNv->AccelMethod = EXA; 288fc5a983dSmrg else { 289fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unrecognized AccelMethod " 290fc5a983dSmrg "\"%s\".\n", s); 291fc5a983dSmrg goto fail; 292fc5a983dSmrg } 293fc5a983dSmrg 294fc5a983dSmrg pNv->Dither = xf86ReturnOptValBool(pNv->Options, OPTION_FP_DITHER, FALSE); 295fc5a983dSmrg pNv->AllowDualLink = xf86ReturnOptValBool(pNv->Options, OPTION_ALLOW_DUAL_LINK, FALSE); 296fc5a983dSmrg 297fc5a983dSmrg /* Set the bits per RGB for 8bpp mode */ 298fc5a983dSmrg if(pScrn->depth == 8) 299fc5a983dSmrg pScrn->rgbBits = 8; 300fc5a983dSmrg 301fc5a983dSmrg if(!xf86SetGamma(pScrn, gzeros)) goto fail; 302fc5a983dSmrg 303fc5a983dSmrg /* Map memory */ 304fc5a983dSmrg pScrn->memPhysBase = MEMBASE(pPci, 1); 305fc5a983dSmrg pScrn->fbOffset = 0; 306fc5a983dSmrg 30772320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 308fc5a983dSmrg err = pci_device_map_range(pPci, pPci->regions[0].base_addr, G80_REG_SIZE, 309fc5a983dSmrg PCI_DEV_MAP_FLAG_WRITABLE, &p); 310fc5a983dSmrg if(err) { 311fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 312fc5a983dSmrg "Failed to map MMIO registers: %s\n", strerror(err)); 313fc5a983dSmrg goto fail; 314fc5a983dSmrg } 315fc5a983dSmrg pNv->reg = p; 316fc5a983dSmrg#else 317fc5a983dSmrg pcitag = pciTag(pPci->bus, pPci->device, pPci->func); 318fc5a983dSmrg pNv->reg = xf86MapPciMem(pScrn->scrnIndex, 319fc5a983dSmrg VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 320fc5a983dSmrg pcitag, pPci->memBase[0], G80_REG_SIZE); 321fc5a983dSmrg#endif 322fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MMIO registers mapped at %p\n", 323fc5a983dSmrg (void*)pNv->reg); 324fc5a983dSmrg 32571ba42d0Smrg#ifndef XSERVER_LIBPCIACCESS 326fc5a983dSmrg if(xf86RegisterResources(pEnt->index, NULL, ResExclusive)) { 327fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86RegisterResources() found " 328fc5a983dSmrg "resource conflicts\n"); 329fc5a983dSmrg goto fail; 330fc5a983dSmrg } 33171ba42d0Smrg#endif 332fc5a983dSmrg 333fc5a983dSmrg pNv->architecture = pNv->reg[0] >> 20 & 0x1ff; 334fc5a983dSmrg tmp = pNv->reg[0x0010020C/4]; 335fc5a983dSmrg pNv->videoRam = pNv->RamAmountKBytes = tmp >> 10 | (tmp & 1) << 22; 336fc5a983dSmrg 337fc5a983dSmrg /* Determine the size of BAR1 */ 338fc5a983dSmrg /* Some configs have BAR1 < total RAM < 256 MB */ 33972320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 340fc5a983dSmrg BAR1sizeKB = pPci->regions[1].size / 1024; 341fc5a983dSmrg#else 342fc5a983dSmrg BAR1sizeKB = 1UL << (pPci->size[1] - 10); 343fc5a983dSmrg#endif 344fc5a983dSmrg if(BAR1sizeKB > 256 * 1024) { 345fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "BAR1 is > 256 MB, which is " 346fc5a983dSmrg "probably wrong. Clamping to 256 MB.\n"); 347fc5a983dSmrg BAR1sizeKB = 256 * 1024; 348fc5a983dSmrg } 349fc5a983dSmrg 350fc5a983dSmrg /* Limit videoRam to the size of BAR1 */ 351fc5a983dSmrg if(pNv->videoRam <= 1024 || BAR1sizeKB == 0) { 352fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to determine the amount of " 353fc5a983dSmrg "available video memory\n"); 354fc5a983dSmrg goto fail; 355fc5a983dSmrg } 356fc5a983dSmrg pNv->videoRam -= 1024; 357fc5a983dSmrg if(pNv->videoRam > BAR1sizeKB) 358fc5a983dSmrg pNv->videoRam = BAR1sizeKB; 359fc5a983dSmrg 360fc5a983dSmrg pScrn->videoRam = pNv->videoRam; 361fc5a983dSmrg 362fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Total video RAM: %.1f MB\n", 363fc5a983dSmrg pNv->RamAmountKBytes / 1024.0); 364fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " BAR1 size: %.1f MB\n", 365fc5a983dSmrg BAR1sizeKB / 1024.0); 366fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " Mapped memory: %.1f MB\n", 367fc5a983dSmrg pScrn->videoRam / 1024.0); 368fc5a983dSmrg 36972320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 370fc5a983dSmrg err = pci_device_map_range(pPci, pPci->regions[1].base_addr, 371fc5a983dSmrg pScrn->videoRam * 1024, 372fc5a983dSmrg PCI_DEV_MAP_FLAG_WRITABLE | 373fc5a983dSmrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 374fc5a983dSmrg &p); 375fc5a983dSmrg if(err) { 376fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 377fc5a983dSmrg "Failed to map framebuffer: %s\n", strerror(err)); 378fc5a983dSmrg goto fail; 379fc5a983dSmrg } 380fc5a983dSmrg pNv->mem = p; 381fc5a983dSmrg#else 382fc5a983dSmrg pNv->mem = xf86MapPciMem(pScrn->scrnIndex, 383fc5a983dSmrg VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 384fc5a983dSmrg pcitag, pPci->memBase[1], pScrn->videoRam * 1024); 385fc5a983dSmrg#endif 386fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer mapped at %p\n", 387fc5a983dSmrg (void*)pNv->mem); 388fc5a983dSmrg 389fc5a983dSmrg pNv->table1 = (unsigned const char*)&pNv->reg[0x00800000/4]; 390fc5a983dSmrg tmp = pNv->reg[0x00619F04/4] >> 8; 391fc5a983dSmrg if(tmp) 392fc5a983dSmrg pNv->table1 -= ((pNv->RamAmountKBytes << 10) - (tmp << 16)); 393fc5a983dSmrg else 394fc5a983dSmrg pNv->table1 -= 0x10000; 395fc5a983dSmrg 396fc5a983dSmrg xf86CrtcConfigInit(pScrn, &randr12_screen_funcs); 397fc5a983dSmrg xf86CrtcSetSizeRange(pScrn, 320, 200, 8192, 8192); 398fc5a983dSmrg 399fc5a983dSmrg if(!xf86LoadSubModule(pScrn, "i2c")) goto fail; 400fc5a983dSmrg if(!xf86LoadSubModule(pScrn, "ddc")) goto fail; 401fc5a983dSmrg 402fc5a983dSmrg if(!G80DispPreInit(pScrn)) goto fail; 403fc5a983dSmrg /* Read the DDC routing table and create outputs */ 404fc5a983dSmrg if(!G80CreateOutputs(pScrn)) goto fail; 405fc5a983dSmrg /* Create the crtcs */ 406fc5a983dSmrg G80DispCreateCrtcs(pScrn); 407fc5a983dSmrg 408fc5a983dSmrg /* We can grow the desktop if XAA is disabled */ 409fc5a983dSmrg if(!xf86InitialConfiguration(pScrn, pNv->NoAccel || pNv->AccelMethod == EXA)) { 410fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 411fc5a983dSmrg "No valid initial configuration found\n"); 412fc5a983dSmrg goto fail; 413fc5a983dSmrg } 414fc5a983dSmrg pScrn->displayWidth = (pScrn->virtualX + 255) & ~255; 415fc5a983dSmrg 416fc5a983dSmrg if(!xf86RandR12PreInit(pScrn)) { 417fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); 418fc5a983dSmrg goto fail; 419fc5a983dSmrg } 420fc5a983dSmrg if(!pScrn->modes) { 421fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes\n"); 422fc5a983dSmrg goto fail; 423fc5a983dSmrg } 424fc5a983dSmrg 425fc5a983dSmrg pScrn->currentMode = pScrn->modes; 426fc5a983dSmrg xf86PrintModes(pScrn); 427fc5a983dSmrg xf86SetDpi(pScrn, 0, 0); 428fc5a983dSmrg 429fc5a983dSmrg /* Load fb */ 430fc5a983dSmrg if(!xf86LoadSubModule(pScrn, "fb")) goto fail; 431fc5a983dSmrg 432fc5a983dSmrg if(!pNv->NoAccel) { 433fc5a983dSmrg switch(pNv->AccelMethod) { 434fc5a983dSmrg case XAA: 435bd304fc0Smrg if(!xf86LoadSubModule(pScrn, "xaa")) pNv->NoAccel = 1; 436fc5a983dSmrg break; 437fc5a983dSmrg case EXA: 438bd304fc0Smrg if(!xf86LoadSubModule(pScrn, "exa")) pNv->NoAccel = 1; 439fc5a983dSmrg break; 440fc5a983dSmrg } 441fc5a983dSmrg } 442fc5a983dSmrg 443fc5a983dSmrg /* Load ramdac if needed */ 444fc5a983dSmrg if(pNv->HWCursor) { 445fc5a983dSmrg if(!xf86LoadSubModule(pScrn, "ramdac")) { 446fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to load ramdac. " 447fc5a983dSmrg "Falling back to software cursor.\n"); 448fc5a983dSmrg pNv->HWCursor = FALSE; 449bd2f6fc9Smrg } 450fc5a983dSmrg } 451fc5a983dSmrg 452fc5a983dSmrg return TRUE; 453fc5a983dSmrg 454fc5a983dSmrgfail: 455fc5a983dSmrg if(pNv->int10) xf86FreeInt10(pNv->int10); 456fc5a983dSmrg G80FreeRec(pScrn); 457fc5a983dSmrg return FALSE; 458fc5a983dSmrg} 459fc5a983dSmrg 460fc5a983dSmrg/* 461fc5a983dSmrg * Initialize the display and set the current mode. 462fc5a983dSmrg */ 463fc5a983dSmrgstatic Bool 464fc5a983dSmrgAcquireDisplay(ScrnInfoPtr pScrn) 465fc5a983dSmrg{ 466fc5a983dSmrg if(!G80DispInit(pScrn)) 467fc5a983dSmrg return FALSE; 468fc5a983dSmrg if(!G80CursorAcquire(pScrn)) 469fc5a983dSmrg return FALSE; 470fc5a983dSmrg xf86SetDesiredModes(pScrn); 471fc5a983dSmrg 472fc5a983dSmrg return TRUE; 473fc5a983dSmrg} 474fc5a983dSmrg 475fc5a983dSmrg/* 476fc5a983dSmrg * Tear down the display and restore the console mode. 477fc5a983dSmrg */ 478fc5a983dSmrgstatic Bool 479fc5a983dSmrgReleaseDisplay(ScrnInfoPtr pScrn) 480fc5a983dSmrg{ 481fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 482fc5a983dSmrg 483fc5a983dSmrg G80CursorRelease(pScrn); 484fc5a983dSmrg G80DispShutdown(pScrn); 485fc5a983dSmrg 486fc5a983dSmrg if(pNv->int10 && pNv->int10Mode) { 487fc5a983dSmrg xf86Int10InfoPtr int10 = pNv->int10; 488fc5a983dSmrg 489fc5a983dSmrg /* Use int10 to restore the console mode */ 490fc5a983dSmrg int10->num = 0x10; 491fc5a983dSmrg int10->ax = 0x4f02; 492fc5a983dSmrg int10->bx = pNv->int10Mode | 0x8000; 493fc5a983dSmrg int10->cx = int10->dx = 0; 494fc5a983dSmrg xf86ExecX86int10(int10); 495fc5a983dSmrg } 496fc5a983dSmrg 497fc5a983dSmrg return TRUE; 498fc5a983dSmrg} 499fc5a983dSmrg 500fc5a983dSmrgstatic Bool 501bd304fc0SmrgG80CloseScreen(CLOSE_SCREEN_ARGS_DECL) 502fc5a983dSmrg{ 503bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 504fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 505fc5a983dSmrg 506fc5a983dSmrg if(pScrn->vtSema) 507fc5a983dSmrg ReleaseDisplay(pScrn); 508fc5a983dSmrg 509bd304fc0Smrg#ifdef HAVE_XAA_H 510fc5a983dSmrg if(pNv->xaa) 511fc5a983dSmrg XAADestroyInfoRec(pNv->xaa); 512bd304fc0Smrg#endif 513fc5a983dSmrg if(pNv->exa) { 514fc5a983dSmrg if(pNv->exaScreenArea) { 515fc5a983dSmrg exaOffscreenFree(pScreen, pNv->exaScreenArea); 516fc5a983dSmrg pNv->exaScreenArea = NULL; 517fc5a983dSmrg } 518fc5a983dSmrg exaDriverFini(pScrn->pScreen); 519fc5a983dSmrg } 520fc5a983dSmrg xf86_cursors_fini(pScreen); 521fc5a983dSmrg 522fc5a983dSmrg if(xf86ServerIsExiting()) { 523fc5a983dSmrg if(pNv->int10) xf86FreeInt10(pNv->int10); 52472320d7bSmrg#ifdef XSERVER_LIBPCIACCESS 525fc5a983dSmrg pci_device_unmap_range(pNv->pPci, pNv->mem, pNv->videoRam * 1024); 526fc5a983dSmrg pci_device_unmap_range(pNv->pPci, (void*)pNv->reg, G80_REG_SIZE); 527fc5a983dSmrg#else 528fc5a983dSmrg xf86UnMapVidMem(pScrn->scrnIndex, pNv->mem, pNv->videoRam * 1024); 529fc5a983dSmrg xf86UnMapVidMem(pScrn->scrnIndex, (void*)pNv->reg, G80_REG_SIZE); 530fc5a983dSmrg#endif 531fc5a983dSmrg pNv->reg = NULL; 532fc5a983dSmrg pNv->mem = NULL; 533fc5a983dSmrg } 534fc5a983dSmrg 535fc5a983dSmrg pScrn->vtSema = FALSE; 536fc5a983dSmrg pScreen->CloseScreen = pNv->CloseScreen; 537fc5a983dSmrg pScreen->BlockHandler = pNv->BlockHandler; 538bd304fc0Smrg return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 539fc5a983dSmrg} 540fc5a983dSmrg 541fc5a983dSmrgstatic void 542bd304fc0SmrgG80BlockHandler(BLOCKHANDLER_ARGS_DECL) 543fc5a983dSmrg{ 544bd304fc0Smrg SCREEN_PTR(arg); 545bd304fc0Smrg ScrnInfoPtr pScrnInfo = xf86ScreenToScrn(pScreen); 546fc5a983dSmrg G80Ptr pNv = G80PTR(pScrnInfo); 547fc5a983dSmrg 548fc5a983dSmrg if(pNv->DMAKickoffCallback) 549fc5a983dSmrg (*pNv->DMAKickoffCallback)(pScrnInfo); 550fc5a983dSmrg 551fc5a983dSmrg G80OutputResetCachedStatus(pScrnInfo); 552fc5a983dSmrg 553fc5a983dSmrg pScreen->BlockHandler = pNv->BlockHandler; 554bd304fc0Smrg (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 555fc5a983dSmrg pScreen->BlockHandler = G80BlockHandler; 556fc5a983dSmrg} 557fc5a983dSmrg 558fc5a983dSmrgstatic Bool 559fc5a983dSmrgG80SaveScreen(ScreenPtr pScreen, int mode) 560fc5a983dSmrg{ 561fc5a983dSmrg return FALSE; 562fc5a983dSmrg} 563fc5a983dSmrg 564fc5a983dSmrgstatic void 565fc5a983dSmrgG80InitHW(ScrnInfoPtr pScrn) 566fc5a983dSmrg{ 567fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 568fc5a983dSmrg CARD32 bar0_pramin = 0; 569fc5a983dSmrg const int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); 570fc5a983dSmrg volatile CARD32 *p; 571fc5a983dSmrg 572fc5a983dSmrg /* Clear registers */ 573fc5a983dSmrg for(p = &pNv->reg[0x00700000/4]; p < (const CARD32*)pNv->table1; p++) 574fc5a983dSmrg *p = 0; 575fc5a983dSmrg 576fc5a983dSmrg bar0_pramin = pNv->reg[0x00001700/4] << 16; 577fc5a983dSmrg 578fc5a983dSmrg pNv->reg[0x00000200/4] = 0xffff00ff; 579fc5a983dSmrg pNv->reg[0x00000200/4] = 0xffffffff; 580fc5a983dSmrg pNv->reg[0x00002100/4] = 0xffffffff; 581fc5a983dSmrg pNv->reg[0x0000250c/4] = 0x6f3cfc34; 582fc5a983dSmrg pNv->reg[0x00400804/4] = 0xc0000000; 583fc5a983dSmrg pNv->reg[0x00406800/4] = 0xc0000000; 584fc5a983dSmrg pNv->reg[0x00400c04/4] = 0xc0000000; 585fc5a983dSmrg pNv->reg[0x00401800/4] = 0xc0000000; 586fc5a983dSmrg pNv->reg[0x00405018/4] = 0xc0000000; 587fc5a983dSmrg pNv->reg[0x00402000/4] = 0xc0000000; 588fc5a983dSmrg pNv->reg[0x00400108/4] = 0xffffffff; 589fc5a983dSmrg pNv->reg[0x00400100/4] = 0xffffffff; 590fc5a983dSmrg 591fc5a983dSmrg if(pNv->architecture != 0x50) { 592fc5a983dSmrg pNv->reg[0x00700000/4] = 0x00000001; 593fc5a983dSmrg pNv->reg[0x00700004/4] = bar0_pramin + 0x00200; 594fc5a983dSmrg pNv->reg[0x00700020/4] = 0x00190002; 595fc5a983dSmrg pNv->reg[0x00700024/4] = bar0_pramin + 0x7ffff; 596fc5a983dSmrg pNv->reg[0x00700028/4] = bar0_pramin + 0x20000; 597fc5a983dSmrg pNv->reg[0x00700034/4] = 0x00010000; 598fc5a983dSmrg } else { 599fc5a983dSmrg pNv->reg[0x00700200/4] = 0x00190002; 600fc5a983dSmrg pNv->reg[0x00700204/4] = bar0_pramin + 0x7ffff; 601fc5a983dSmrg pNv->reg[0x00700208/4] = bar0_pramin + 0x20000; 602fc5a983dSmrg pNv->reg[0x00700214/4] = 0x00010000; 603fc5a983dSmrg } 604fc5a983dSmrg 605fc5a983dSmrg pNv->reg[0x00710004/4] = 0x00100642; 606fc5a983dSmrg pNv->reg[0x00710008/4] = 0x80000011; 607fc5a983dSmrg pNv->reg[0x0071000c/4] = 0x00000644; 608fc5a983dSmrg pNv->reg[0x00710010/4] = 0x80000012; 609fc5a983dSmrg pNv->reg[0x00710014/4] = 0x00100646; 610fc5a983dSmrg pNv->reg[0x00710018/4] = 0x80000013; 611fc5a983dSmrg pNv->reg[0x0071001c/4] = 0x00100648; 612fc5a983dSmrg pNv->reg[0x00710020/4] = 0x80000014; 613fc5a983dSmrg pNv->reg[0x00710024/4] = 0x0000064a; 614fc5a983dSmrg pNv->reg[0x00706420/4] = 0x00190030; 615fc5a983dSmrg pNv->reg[0x00706434/4] = 0x00010000; 616fc5a983dSmrg pNv->reg[0x00706440/4] = 0x0019003d; 617fc5a983dSmrg pNv->reg[0x00706444/4] = (pNv->videoRam << 10) - 0x4001; 618fc5a983dSmrg pNv->reg[0x00706448/4] = (pNv->videoRam << 10) - G80_RESERVED_VIDMEM; 619fc5a983dSmrg pNv->reg[0x00706454/4] = 0x00010000; 620fc5a983dSmrg pNv->reg[0x00706460/4] = 0x0000502d; 621fc5a983dSmrg pNv->reg[0x00706474/4] = 0x00010000; 62271ba42d0Smrg if(pNv->architecture == 0xaa || pNv->architecture == 0xac) { 62371ba42d0Smrg uint64_t base = (uint64_t)pNv->reg[0x00100E10/4] << 12; 62471ba42d0Smrg size_t size = (uint64_t)pNv->reg[0x00100E14/4] << 12; 62571ba42d0Smrg uint64_t limit = base + size - G80_RESERVED_VIDMEM; 62671ba42d0Smrg 62771ba42d0Smrg pNv->reg[0x00706480/4] = 0x1a003d; 62871ba42d0Smrg pNv->reg[0x00706484/4] = limit; 62971ba42d0Smrg pNv->reg[0x00706488/4] = base; 63071ba42d0Smrg pNv->reg[0x0070648c/4] = base >> 32 | ((limit >> 8) & 0xff000000); 63171ba42d0Smrg } else { 63271ba42d0Smrg pNv->reg[0x00706480/4] = 0x0019003d; 63371ba42d0Smrg pNv->reg[0x00706484/4] = (pNv->videoRam << 10) - G80_RESERVED_VIDMEM; 63471ba42d0Smrg pNv->reg[0x00706494/4] = 0x00010000; 63571ba42d0Smrg } 636fc5a983dSmrg pNv->reg[0x007064a0/4] = 0x0019003d; 637fc5a983dSmrg pNv->reg[0x007064a4/4] = bar0_pramin + 0x1100f; 638fc5a983dSmrg pNv->reg[0x007064a8/4] = bar0_pramin + 0x11000; 639fc5a983dSmrg pNv->reg[0x007064b4/4] = 0x00010000; 640fc5a983dSmrg 641fc5a983dSmrg if(pNv->architecture != 0x50) { 642fc5a983dSmrg pNv->reg[0x00002604/4] = 0x80000002 | (bar0_pramin >> 8); 643fc5a983dSmrg } else { 644fc5a983dSmrg pNv->reg[0x00002604/4] = 0x80000000 | (bar0_pramin >> 12); 645fc5a983dSmrg } 646fc5a983dSmrg 647fc5a983dSmrg pNv->reg[0x00003224/4] = 0x000f0078; 648fc5a983dSmrg pNv->reg[0x0000322c/4] = 0x00000644; 64971ba42d0Smrg pNv->reg[0x00003234/4] = G80_RESERVED_VIDMEM - 0x6001; 650fc5a983dSmrg pNv->reg[0x00003254/4] = 0x00000001; 651fc5a983dSmrg pNv->reg[0x00002210/4] = 0x1c001000; 652fc5a983dSmrg 653fc5a983dSmrg if(pNv->architecture != 0x50) { 654fc5a983dSmrg pNv->reg[0x0000340c/4] = (bar0_pramin + 0x1000) >> 10; 655fc5a983dSmrg pNv->reg[0x00003410/4] = (bar0_pramin >> 12); 656fc5a983dSmrg } 657fc5a983dSmrg 658fc5a983dSmrg pNv->reg[0x00400824/4] = 0x00004000; 659fc5a983dSmrg pNv->reg[0x00400784/4] = 0x80000000 | (bar0_pramin >> 12); 660fc5a983dSmrg pNv->reg[0x00400320/4] = 0x00000004; 661fc5a983dSmrg pNv->reg[0x0040032C/4] = 0x80000000 | (bar0_pramin >> 12); 662fc5a983dSmrg pNv->reg[0x00400500/4] = 0x00010001; 663fc5a983dSmrg pNv->reg[0x00003250/4] = 0x00000001; 664fc5a983dSmrg pNv->reg[0x00003200/4] = 0x00000001; 665fc5a983dSmrg pNv->reg[0x00003220/4] = 0x00001001; 666fc5a983dSmrg pNv->reg[0x00003204/4] = 0x00010001; 667fc5a983dSmrg 668fc5a983dSmrg pNv->dmaBase = (CARD32*)(pNv->mem + (pNv->videoRam << 10) - 669fc5a983dSmrg G80_RESERVED_VIDMEM); 670fc5a983dSmrg memset(pNv->dmaBase, 0, SKIPS*4); 671fc5a983dSmrg 672fc5a983dSmrg pNv->dmaPut = 0; 673fc5a983dSmrg pNv->dmaCurrent = SKIPS; 67471ba42d0Smrg pNv->dmaMax = (G80_RESERVED_VIDMEM - 0x6000) / 4 - 2; 675fc5a983dSmrg pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; 676fc5a983dSmrg 677fc5a983dSmrg G80DmaStart(pNv, 0, 1); 678fc5a983dSmrg G80DmaNext (pNv, 0x80000012); 679fc5a983dSmrg G80DmaStart(pNv, 0x180, 3); 680fc5a983dSmrg G80DmaNext (pNv, 0x80000014); 681fc5a983dSmrg G80DmaNext (pNv, 0x80000013); 682fc5a983dSmrg G80DmaNext (pNv, 0x80000013); 683fc5a983dSmrg G80DmaStart(pNv, 0x200, 2); 684fc5a983dSmrg switch(pScrn->depth) { 685fc5a983dSmrg case 8: G80DmaNext (pNv, 0x000000f3); break; 686fc5a983dSmrg case 15: G80DmaNext (pNv, 0x000000f8); break; 687fc5a983dSmrg case 16: G80DmaNext (pNv, 0x000000e8); break; 688fc5a983dSmrg case 24: G80DmaNext (pNv, 0x000000e6); break; 689fc5a983dSmrg } 690fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 691fc5a983dSmrg G80DmaStart(pNv, 0x214, 5); 692fc5a983dSmrg G80DmaNext (pNv, pitch); 693fc5a983dSmrg G80DmaNext (pNv, pitch); 694fc5a983dSmrg G80DmaNext (pNv, pNv->offscreenHeight); 695fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 696fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 697fc5a983dSmrg G80DmaStart(pNv, 0x230, 2); 698fc5a983dSmrg switch(pScrn->depth) { 699fc5a983dSmrg case 8: G80DmaNext (pNv, 0x000000f3); break; 700fc5a983dSmrg case 15: G80DmaNext (pNv, 0x000000f8); break; 701fc5a983dSmrg case 16: G80DmaNext (pNv, 0x000000e8); break; 702fc5a983dSmrg case 24: G80DmaNext (pNv, 0x000000e6); break; 703fc5a983dSmrg } 704fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 705fc5a983dSmrg G80DmaStart(pNv, 0x244, 5); 706fc5a983dSmrg G80DmaNext (pNv, pitch); 707fc5a983dSmrg G80DmaNext (pNv, pitch); 708fc5a983dSmrg G80DmaNext (pNv, pNv->offscreenHeight); 709fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 710fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 711fc5a983dSmrg G80DmaStart(pNv, 0x260, 1); 712fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 713fc5a983dSmrg G80DmaStart(pNv, 0x290, 1); 714fc5a983dSmrg G80DmaNext (pNv, 1); 715fc5a983dSmrg G80DmaStart(pNv, 0x29c, 1); 716fc5a983dSmrg G80DmaNext (pNv, 0); 717fc5a983dSmrg G80DmaStart(pNv, 0x2e8, 2); 718fc5a983dSmrg switch(pScrn->depth) { 719fc5a983dSmrg case 8: G80DmaNext (pNv, 3); break; 720fc5a983dSmrg case 15: G80DmaNext (pNv, 1); break; 721fc5a983dSmrg case 16: G80DmaNext (pNv, 0); break; 722fc5a983dSmrg case 24: G80DmaNext (pNv, 2); break; 723fc5a983dSmrg } 724fc5a983dSmrg G80DmaNext (pNv, 1); 725fc5a983dSmrg G80DmaStart(pNv, 0x584, 1); 726fc5a983dSmrg switch(pScrn->depth) { 727fc5a983dSmrg case 8: G80DmaNext (pNv, 0xf3); break; 728fc5a983dSmrg case 15: G80DmaNext (pNv, 0xf8); break; 729fc5a983dSmrg case 16: G80DmaNext (pNv, 0xe8); break; 730fc5a983dSmrg case 24: G80DmaNext (pNv, 0xe6); break; 731fc5a983dSmrg } 732fc5a983dSmrg G80DmaStart(pNv, 0x58c, 1); 733fc5a983dSmrg G80DmaNext (pNv, 0x111); 734fc5a983dSmrg G80DmaStart(pNv, 0x804, 1); 735fc5a983dSmrg switch(pScrn->depth) { 736fc5a983dSmrg case 8: G80DmaNext (pNv, 0xf3); break; 737fc5a983dSmrg case 15: G80DmaNext (pNv, 0xf8); break; 738fc5a983dSmrg case 16: G80DmaNext (pNv, 0xe8); break; 739fc5a983dSmrg case 24: G80DmaNext (pNv, 0xe6); break; 740fc5a983dSmrg } 741fc5a983dSmrg 742fc5a983dSmrg pNv->currentRop = ~0; /* Set to something invalid */ 743fc5a983dSmrg} 744fc5a983dSmrg 745fc5a983dSmrgstatic Bool 746bd304fc0SmrgG80ScreenInit(SCREEN_INIT_ARGS_DECL) 747fc5a983dSmrg{ 748fc5a983dSmrg ScrnInfoPtr pScrn; 749fc5a983dSmrg G80Ptr pNv; 750fc5a983dSmrg CARD32 pitch; 751fc5a983dSmrg int visualMask, i; 752fc5a983dSmrg BoxRec AvailFBArea; 753fc5a983dSmrg 754fc5a983dSmrg /* First get the ScrnInfoRec */ 755bd304fc0Smrg pScrn = xf86ScreenToScrn(pScreen); 756fc5a983dSmrg pNv = G80PTR(pScrn); 757fc5a983dSmrg 758fc5a983dSmrg pScrn->vtSema = TRUE; 759fc5a983dSmrg 760fc5a983dSmrg /* DIX visual init */ 761fc5a983dSmrg miClearVisualTypes(); 762fc5a983dSmrg visualMask = miGetDefaultVisualMask(pScrn->depth); 763fc5a983dSmrg if(!miSetVisualTypes(pScrn->depth, visualMask, 8, pScrn->defaultVisual)) 764fc5a983dSmrg return FALSE; 765fc5a983dSmrg if(!miSetPixmapDepths()) 766fc5a983dSmrg return FALSE; 767fc5a983dSmrg 768fc5a983dSmrg /* pad the screen pitch to 256 bytes */ 769fc5a983dSmrg pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); 770fc5a983dSmrg 771fc5a983dSmrg /* fb init */ 772fc5a983dSmrg if(!fbScreenInit(pScreen, pNv->mem, 773fc5a983dSmrg pScrn->virtualX, pScrn->virtualY, 774fc5a983dSmrg pScrn->xDpi, pScrn->yDpi, 775fc5a983dSmrg pScrn->displayWidth, pScrn->bitsPerPixel)) 776fc5a983dSmrg return FALSE; 777fc5a983dSmrg 778fc5a983dSmrg if(pScrn->bitsPerPixel > 8) { 779fc5a983dSmrg VisualPtr visual; 780fc5a983dSmrg 781fc5a983dSmrg /* Fixup RGB ordering */ 782fc5a983dSmrg visual = pScreen->visuals + pScreen->numVisuals; 783fc5a983dSmrg while(--visual >= pScreen->visuals) { 784fc5a983dSmrg if((visual->class | DynamicClass) == DirectColor) { 785fc5a983dSmrg visual->offsetRed = pScrn->offset.red; 786fc5a983dSmrg visual->offsetGreen = pScrn->offset.green; 787fc5a983dSmrg visual->offsetBlue = pScrn->offset.blue; 788fc5a983dSmrg visual->redMask = pScrn->mask.red; 789fc5a983dSmrg visual->greenMask = pScrn->mask.green; 790fc5a983dSmrg visual->blueMask = pScrn->mask.blue; 791fc5a983dSmrg } 792fc5a983dSmrg } 793fc5a983dSmrg } 794fc5a983dSmrg 795fc5a983dSmrg fbPictureInit(pScreen, 0, 0); 796fc5a983dSmrg 797fc5a983dSmrg xf86SetBlackWhitePixels(pScreen); 798fc5a983dSmrg 799fc5a983dSmrg pNv->offscreenHeight = ((pNv->videoRam << 10) - G80_RESERVED_VIDMEM) / pitch; 800fc5a983dSmrg if(pNv->offscreenHeight > 32767) pNv->offscreenHeight = 32767; 801fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 802fc5a983dSmrg "%.2f MB available for offscreen pixmaps\n", 803fc5a983dSmrg (pNv->offscreenHeight - pScrn->virtualY) * pitch / 1024.0 / 1024.0); 804fc5a983dSmrg 805fc5a983dSmrg AvailFBArea.x1 = 0; 806fc5a983dSmrg AvailFBArea.y1 = 0; 807fc5a983dSmrg AvailFBArea.x2 = pScrn->displayWidth; 808fc5a983dSmrg AvailFBArea.y2 = pNv->offscreenHeight; 809fc5a983dSmrg xf86InitFBManager(pScreen, &AvailFBArea); 810fc5a983dSmrg 811fc5a983dSmrg pNv->reg[0x00001708/4] = 0; 812fc5a983dSmrg for(i = 0; i < 8; i++) 813fc5a983dSmrg pNv->reg[0x00001900/4 + i] = 0; 814fc5a983dSmrg 815fc5a983dSmrg if(!pNv->NoAccel) { 816fc5a983dSmrg G80InitHW(pScrn); 817fc5a983dSmrg switch(pNv->AccelMethod) { 818fc5a983dSmrg case XAA: 819fc5a983dSmrg if(!G80XAAInit(pScreen)) { 820fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 821fc5a983dSmrg "XAA hardware acceleration initialization failed\n"); 822fc5a983dSmrg return FALSE; 823fc5a983dSmrg } 824fc5a983dSmrg break; 825fc5a983dSmrg case EXA: 826fc5a983dSmrg if(!G80ExaInit(pScreen, pScrn)) { 827fc5a983dSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 828fc5a983dSmrg "EXA hardware acceleration initialization failed\n"); 829fc5a983dSmrg return FALSE; 830fc5a983dSmrg } 831fc5a983dSmrg break; 832fc5a983dSmrg } 833fc5a983dSmrg } 834fc5a983dSmrg 835fc5a983dSmrg xf86SetBackingStore(pScreen); 836fc5a983dSmrg xf86SetSilkenMouse(pScreen); 837fc5a983dSmrg 838fc5a983dSmrg /* Initialize software cursor. 839fc5a983dSmrg Must precede creation of the default colormap */ 840fc5a983dSmrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 841fc5a983dSmrg 84271ba42d0Smrg if(!xf86CrtcScreenInit(pScreen)) 84371ba42d0Smrg return FALSE; 84471ba42d0Smrg 845fc5a983dSmrg /* Initialize default colormap */ 846fc5a983dSmrg if(!miCreateDefColormap(pScreen)) 847fc5a983dSmrg return FALSE; 848fc5a983dSmrg 849fc5a983dSmrg /* Initialize colormap layer. 850fc5a983dSmrg Must follow initialization of the default colormap */ 851fc5a983dSmrg if(!xf86HandleColormaps(pScreen, 256, 8, G80LoadPalette, NULL, 852fc5a983dSmrg CMAP_PALETTED_TRUECOLOR)) 853fc5a983dSmrg return FALSE; 854fc5a983dSmrg 855fc5a983dSmrg xf86DPMSInit(pScreen, xf86DPMSSet, 0); 856fc5a983dSmrg 857bd304fc0Smrg#ifdef HAVE_XAA_H 858fc5a983dSmrg /* Clear the screen */ 859fc5a983dSmrg if(pNv->xaa) { 860fc5a983dSmrg /* Use the acceleration engine */ 861fc5a983dSmrg pNv->xaa->SetupForSolidFill(pScrn, 0, GXcopy, ~0); 862fc5a983dSmrg pNv->xaa->SubsequentSolidFillRect(pScrn, 863fc5a983dSmrg 0, 0, pScrn->displayWidth, pNv->offscreenHeight); 864fc5a983dSmrg G80DmaKickoff(pNv); 865bd304fc0Smrg } else 866bd304fc0Smrg#endif 867bd304fc0Smrg { 868fc5a983dSmrg /* Use a slow software clear path */ 869fc5a983dSmrg memset(pNv->mem, 0, pitch * pNv->offscreenHeight); 870fc5a983dSmrg } 871fc5a983dSmrg 872fc5a983dSmrg /* Initialize the display */ 873fc5a983dSmrg if(!AcquireDisplay(pScrn)) 874fc5a983dSmrg return FALSE; 875fc5a983dSmrg 876f3561b8bSmrg /* Initialize hardware cursor. Must follow software cursor initialization. */ 877f3561b8bSmrg if(pNv->HWCursor && !G80CursorInit(pScreen)) { 878f3561b8bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 879f3561b8bSmrg "Hardware cursor initialization failed\n"); 880f3561b8bSmrg pNv->HWCursor = FALSE; 881f3561b8bSmrg } 882f3561b8bSmrg 883fc5a983dSmrg pScreen->SaveScreen = G80SaveScreen; 884fc5a983dSmrg 885fc5a983dSmrg pNv->CloseScreen = pScreen->CloseScreen; 886fc5a983dSmrg pScreen->CloseScreen = G80CloseScreen; 887fc5a983dSmrg 888fc5a983dSmrg pNv->BlockHandler = pScreen->BlockHandler; 889fc5a983dSmrg pScreen->BlockHandler = G80BlockHandler; 890fc5a983dSmrg 891fc5a983dSmrg return TRUE; 892fc5a983dSmrg} 893fc5a983dSmrg 894fc5a983dSmrgstatic void 895bd304fc0SmrgG80FreeScreen(FREE_SCREEN_ARGS_DECL) 896fc5a983dSmrg{ 897bd304fc0Smrg SCRN_INFO_PTR(arg); 898bd304fc0Smrg G80FreeRec(pScrn); 899fc5a983dSmrg} 900fc5a983dSmrg 901fc5a983dSmrgstatic Bool 902bd304fc0SmrgG80SwitchMode(SWITCH_MODE_ARGS_DECL) 903fc5a983dSmrg{ 904bd304fc0Smrg SCRN_INFO_PTR(arg); 905fc5a983dSmrg return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 906fc5a983dSmrg} 907fc5a983dSmrg 908fc5a983dSmrgstatic void 909bd304fc0SmrgG80AdjustFrame(ADJUST_FRAME_ARGS_DECL) 910fc5a983dSmrg{ 911fc5a983dSmrg} 912fc5a983dSmrg 913fc5a983dSmrgstatic Bool 914bd304fc0SmrgG80EnterVT(VT_FUNC_ARGS_DECL) 915fc5a983dSmrg{ 916bd304fc0Smrg SCRN_INFO_PTR(arg); 917fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 918fc5a983dSmrg 919fc5a983dSmrg /* Reinit the hardware */ 920bd304fc0Smrg#ifdef HAVE_XAA_H 921fc5a983dSmrg if(pNv->xaa) 922fc5a983dSmrg G80InitHW(pScrn); 923bd304fc0Smrg#endif 924fc5a983dSmrg 925fc5a983dSmrg if(!AcquireDisplay(pScrn)) 926fc5a983dSmrg return FALSE; 927fc5a983dSmrg 928fc5a983dSmrg return TRUE; 929fc5a983dSmrg} 930fc5a983dSmrg 931fc5a983dSmrgstatic void 932bd304fc0SmrgG80LeaveVT(VT_FUNC_ARGS_DECL) 933fc5a983dSmrg{ 934bd304fc0Smrg SCRN_INFO_PTR(arg); 935fc5a983dSmrg 936fc5a983dSmrg ReleaseDisplay(pScrn); 937fc5a983dSmrg} 938fc5a983dSmrg 939fc5a983dSmrgBool G80GetScrnInfoRec(PciChipsets *chips, int chip) 940fc5a983dSmrg{ 941fc5a983dSmrg ScrnInfoPtr pScrn; 942fc5a983dSmrg 943fc5a983dSmrg pScrn = xf86ConfigPciEntity(NULL, 0, chip, 944fc5a983dSmrg chips, NULL, NULL, NULL, 945fc5a983dSmrg NULL, NULL); 946fc5a983dSmrg 947fc5a983dSmrg if(!pScrn) return FALSE; 948fc5a983dSmrg 949fc5a983dSmrg pScrn->driverVersion = NV_VERSION; 950fc5a983dSmrg pScrn->driverName = NV_DRIVER_NAME; 951fc5a983dSmrg pScrn->name = NV_NAME; 952fc5a983dSmrg 953fc5a983dSmrg pScrn->PreInit = G80PreInit; 954fc5a983dSmrg pScrn->ScreenInit = G80ScreenInit; 955fc5a983dSmrg pScrn->SwitchMode = G80SwitchMode; 956fc5a983dSmrg pScrn->AdjustFrame = G80AdjustFrame; 957fc5a983dSmrg pScrn->EnterVT = G80EnterVT; 958fc5a983dSmrg pScrn->LeaveVT = G80LeaveVT; 959fc5a983dSmrg pScrn->FreeScreen = G80FreeScreen; 960fc5a983dSmrg // pScrn->ValidMode = G80ValidMode; 961fc5a983dSmrg 962fc5a983dSmrg return TRUE; 963fc5a983dSmrg} 964