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