1c582b7e3Smrg/* 2c582b7e3Smrg * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, 3c582b7e3Smrg * Precision Insight, Inc., Cedar Park, Texas, and 4c582b7e3Smrg * VA Linux Systems Inc., Fremont, California. 5c582b7e3Smrg * 6c582b7e3Smrg * All Rights Reserved. 7c582b7e3Smrg * 8c582b7e3Smrg * Permission is hereby granted, free of charge, to any person obtaining 9c582b7e3Smrg * a copy of this software and associated documentation files (the 10c582b7e3Smrg * "Software"), to deal in the Software without restriction, including 11c582b7e3Smrg * without limitation on the rights to use, copy, modify, merge, 12c582b7e3Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 13c582b7e3Smrg * and to permit persons to whom the Software is furnished to do so, 14c582b7e3Smrg * subject to the following conditions: 15c582b7e3Smrg * 16c582b7e3Smrg * The above copyright notice and this permission notice (including the 17c582b7e3Smrg * next paragraph) shall be included in all copies or substantial 18c582b7e3Smrg * portions of the Software. 19c582b7e3Smrg * 20c582b7e3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21c582b7e3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22c582b7e3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23c582b7e3Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX 24c582b7e3Smrg * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25c582b7e3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26c582b7e3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27c582b7e3Smrg * OTHER DEALINGS IN THE SOFTWARE. 28c582b7e3Smrg */ 29c582b7e3Smrg 30c582b7e3Smrg#ifdef HAVE_CONFIG_H 31c582b7e3Smrg#include "config.h" 32c582b7e3Smrg#endif 33c582b7e3Smrg 34c582b7e3Smrg/* 35c582b7e3Smrg * Authors: 36c582b7e3Smrg * Rickard E. Faith <faith@valinux.com> 37c582b7e3Smrg * Kevin E. Martin <martin@valinux.com> 38c582b7e3Smrg * Gareth Hughes <gareth@valinux.com> 39c582b7e3Smrg * 40c582b7e3Smrg * Credits: 41c582b7e3Smrg * 42c582b7e3Smrg * Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for 43c582b7e3Smrg * providing source code to their 3.3.x Rage 128 driver. Portions of 44c582b7e3Smrg * this file are based on the initialization code for that driver. 45c582b7e3Smrg * 46c582b7e3Smrg * References: 47c582b7e3Smrg * 48c582b7e3Smrg * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical 49c582b7e3Smrg * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April 50c582b7e3Smrg * 1999. 51c582b7e3Smrg * 52c582b7e3Smrg * RAGE 128 Software Development Manual (Technical Reference Manual P/N 53c582b7e3Smrg * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. 54c582b7e3Smrg * 55c582b7e3Smrg * This server does not yet support these XFree86 4.0 features: 56c582b7e3Smrg * DDC1 & DDC2 57c582b7e3Smrg * shadowfb 58c582b7e3Smrg * overlay planes 59c582b7e3Smrg * 60c582b7e3Smrg * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. 61c582b7e3Smrg * 62c582b7e3Smrg * Dualhead support - Alex Deucher <agd5f@yahoo.com> 63c582b7e3Smrg */ 64c582b7e3Smrg 65c582b7e3Smrg#include <string.h> 66c582b7e3Smrg#include <stdio.h> 67c582b7e3Smrg 68c582b7e3Smrg /* Driver data structures */ 69c582b7e3Smrg#include "r128.h" 70c582b7e3Smrg#include "r128_probe.h" 71c582b7e3Smrg#include "r128_reg.h" 72c582b7e3Smrg#include "r128_version.h" 73c582b7e3Smrg 7484354367Smrg#ifdef R128DRI 75c582b7e3Smrg#define _XF86DRI_SERVER_ 76c582b7e3Smrg#include "r128_dri.h" 77c582b7e3Smrg#include "r128_common.h" 78c582b7e3Smrg#include "r128_sarea.h" 79c582b7e3Smrg#endif 80c582b7e3Smrg 81c582b7e3Smrg /* colormap initialization */ 82c582b7e3Smrg#include "micmap.h" 83c582b7e3Smrg 84c582b7e3Smrg /* X and server generic header files */ 85c582b7e3Smrg#include "xf86.h" 86c582b7e3Smrg#include "xf86_OSproc.h" 87b3ff493bSmrg#include "xf86RandR12.h" 8819019ffeSmrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 89c582b7e3Smrg#include "xf86RAC.h" 90c582b7e3Smrg#include "xf86Resources.h" 9119019ffeSmrg#endif 92a9060c92Schristos#include "xf86_OSlib.h" 93c582b7e3Smrg#include "xf86cmap.h" 94c582b7e3Smrg#include "xf86xv.h" 95c582b7e3Smrg#include "vbe.h" 9699d7194aSmacallan#include "xf86Priv.h" 97a4470643Smrg#include "xf86Privstr.h" 98c582b7e3Smrg 99c582b7e3Smrg /* fbdevhw & vgahw */ 100c582b7e3Smrg#ifdef WITH_VGAHW 101c582b7e3Smrg#include "vgaHW.h" 102c582b7e3Smrg#endif 10379e5230eSmacallan 10479e5230eSmacallan#ifndef AVOID_FBDEV 105c582b7e3Smrg#include "fbdevhw.h" 10679e5230eSmacallan#endif 10779e5230eSmacallan 108c582b7e3Smrg#include "dixstruct.h" 109c582b7e3Smrg 110c582b7e3Smrg /* DPMS support. */ 11119019ffeSmrg#ifdef HAVE_XEXTPROTO_71 11219019ffeSmrg#include <X11/extensions/dpmsconst.h> 11319019ffeSmrg#else 114c582b7e3Smrg#define DPMS_SERVER 115c582b7e3Smrg#include <X11/extensions/dpms.h> 11619019ffeSmrg#endif 11719019ffeSmrg 11899d7194aSmacallan#ifdef __NetBSD__ 11999d7194aSmacallan#include <sys/time.h> 12099d7194aSmacallan#include <dev/wscons/wsconsio.h> 12199d7194aSmacallan#endif 122c582b7e3Smrg 12384354367Smrgstatic Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL); 124c582b7e3Smrgstatic Bool R128SaveScreen(ScreenPtr pScreen, int mode); 125c582b7e3Smrgstatic void R128Save(ScrnInfoPtr pScrn); 126c582b7e3Smrgstatic void R128Restore(ScrnInfoPtr pScrn); 127c582b7e3Smrg 128c582b7e3Smrgtypedef enum { 129c582b7e3Smrg OPTION_NOACCEL, 13081f79626Smrg#ifndef AVOID_FBDEV 13181f79626Smrg OPTION_FBDEV, 13281f79626Smrg#endif 133c582b7e3Smrg OPTION_DAC_6BIT, 13481f79626Smrg OPTION_VGA_ACCESS, 13581f79626Smrg OPTION_SHOW_CACHE, 13681f79626Smrg OPTION_SW_CURSOR, 13781f79626Smrg OPTION_VIDEO_KEY, 13881f79626Smrg OPTION_PANEL_WIDTH, 13981f79626Smrg OPTION_PANEL_HEIGHT, 14081f79626Smrg OPTION_PROG_FP_REGS, 14184354367Smrg#ifdef R128DRI 142c582b7e3Smrg OPTION_XV_DMA, 143c582b7e3Smrg OPTION_IS_PCI, 144c582b7e3Smrg OPTION_CCE_PIO, 145c582b7e3Smrg OPTION_NO_SECURITY, 146c582b7e3Smrg OPTION_USEC_TIMEOUT, 147c582b7e3Smrg OPTION_AGP_MODE, 148c582b7e3Smrg OPTION_AGP_SIZE, 149c582b7e3Smrg OPTION_RING_SIZE, 150c582b7e3Smrg OPTION_BUFFER_SIZE, 151c582b7e3Smrg OPTION_PAGE_FLIP, 152c582b7e3Smrg#endif 15384354367Smrg OPTION_ACCELMETHOD, 15484354367Smrg OPTION_RENDERACCEL 155c582b7e3Smrg} R128Opts; 156c582b7e3Smrg 157c582b7e3Smrgstatic const OptionInfoRec R128Options[] = { 15881f79626Smrg{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 15981f79626Smrg#ifndef AVOID_FBDEV 16081f79626Smrg{ OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 16181f79626Smrg#endif 16281f79626Smrg{ OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, 16381f79626Smrg{ OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE }, 16481f79626Smrg{ OPTION_SHOW_CACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, 16581f79626Smrg{ OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 16681f79626Smrg{ OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 16781f79626Smrg{ OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, 16881f79626Smrg{ OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, 16981f79626Smrg{ OPTION_PROG_FP_REGS, "ProgramFPRegs", OPTV_BOOLEAN, {0}, FALSE }, 17084354367Smrg#ifdef R128DRI 171c582b7e3Smrg { OPTION_XV_DMA, "DMAForXv", OPTV_BOOLEAN, {0}, FALSE }, 172c582b7e3Smrg { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, 173c582b7e3Smrg { OPTION_CCE_PIO, "CCEPIOMode", OPTV_BOOLEAN, {0}, FALSE }, 174c582b7e3Smrg { OPTION_NO_SECURITY, "CCENoSecurity", OPTV_BOOLEAN, {0}, FALSE }, 175c582b7e3Smrg { OPTION_USEC_TIMEOUT, "CCEusecTimeout", OPTV_INTEGER, {0}, FALSE }, 176c582b7e3Smrg { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, 177c582b7e3Smrg { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, 178c582b7e3Smrg { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, 179c582b7e3Smrg { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, 180c582b7e3Smrg { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE }, 181c582b7e3Smrg#endif 18284354367Smrg { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 18384354367Smrg { OPTION_RENDERACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE }, 184c582b7e3Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 185c582b7e3Smrg}; 186c582b7e3Smrg 187c582b7e3Smrgconst OptionInfoRec *R128OptionsWeak(void) { return R128Options; } 188c582b7e3Smrg 189c582b7e3SmrgR128RAMRec R128RAM[] = { /* Memory Specifications 190c582b7e3Smrg From RAGE 128 Software Development 191c582b7e3Smrg Manual (Technical Reference Manual P/N 192c582b7e3Smrg SDK-G04000 Rev 0.01), page 3-21. */ 193c582b7e3Smrg { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, 194c582b7e3Smrg { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, 195c582b7e3Smrg { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, 196c582b7e3Smrg { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, 197c582b7e3Smrg}; 198c582b7e3Smrg 199c582b7e3Smrgextern _X_EXPORT int gR128EntityIndex; 200c582b7e3Smrg 201c582b7e3Smrgint getR128EntityIndex(void) 202c582b7e3Smrg{ 203c582b7e3Smrg return gR128EntityIndex; 204c582b7e3Smrg} 205c582b7e3Smrg 206c582b7e3SmrgR128EntPtr R128EntPriv(ScrnInfoPtr pScrn) 207c582b7e3Smrg{ 208c582b7e3Smrg DevUnion *pPriv; 209c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 210c582b7e3Smrg pPriv = xf86GetEntityPrivate(info->pEnt->index, 211c582b7e3Smrg getR128EntityIndex()); 212c582b7e3Smrg return pPriv->ptr; 213c582b7e3Smrg} 214c582b7e3Smrg 215c582b7e3Smrg/* Allocate our private R128InfoRec. */ 216c582b7e3Smrgstatic Bool R128GetRec(ScrnInfoPtr pScrn) 217c582b7e3Smrg{ 218c582b7e3Smrg if (pScrn->driverPrivate) return TRUE; 219c582b7e3Smrg 220c582b7e3Smrg pScrn->driverPrivate = xnfcalloc(sizeof(R128InfoRec), 1); 221c582b7e3Smrg return TRUE; 222c582b7e3Smrg} 223c582b7e3Smrg 224c582b7e3Smrg/* Free our private R128InfoRec. */ 225c582b7e3Smrgstatic void R128FreeRec(ScrnInfoPtr pScrn) 226c582b7e3Smrg{ 227c582b7e3Smrg if (!pScrn || !pScrn->driverPrivate) return; 22884354367Smrg free(pScrn->driverPrivate); 229c582b7e3Smrg pScrn->driverPrivate = NULL; 230c582b7e3Smrg} 231c582b7e3Smrg 232c582b7e3Smrg/* Memory map the MMIO region. Used during pre-init and by R128MapMem, 233c582b7e3Smrg below. */ 234c582b7e3Smrgstatic Bool R128MapMMIO(ScrnInfoPtr pScrn) 235c582b7e3Smrg{ 236c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 237c582b7e3Smrg 23879e5230eSmacallan#ifndef AVOID_FBDEV 239c582b7e3Smrg if (info->FBDev) { 240c582b7e3Smrg info->MMIO = fbdevHWMapMMIO(pScrn); 24179e5230eSmacallan } else 24279e5230eSmacallan#endif 24379e5230eSmacallan { 244c582b7e3Smrg#ifndef XSERVER_LIBPCIACCESS 245c582b7e3Smrg info->MMIO = xf86MapPciMem(pScrn->scrnIndex, 246c582b7e3Smrg VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 247c582b7e3Smrg info->PciTag, 248c582b7e3Smrg info->MMIOAddr, 249c582b7e3Smrg R128_MMIOSIZE); 250b3ff493bSmrg if (!info->MMIO) return FALSE; 251c582b7e3Smrg#else 252c582b7e3Smrg int err = pci_device_map_range(info->PciInfo, 253c582b7e3Smrg info->MMIOAddr, 254c582b7e3Smrg R128_MMIOSIZE, 255c582b7e3Smrg PCI_DEV_MAP_FLAG_WRITABLE, 256c582b7e3Smrg &info->MMIO); 257c582b7e3Smrg 258c582b7e3Smrg if (err) { 259c582b7e3Smrg xf86DrvMsg (pScrn->scrnIndex, X_ERROR, 260c582b7e3Smrg "Unable to map MMIO aperture. %s (%d)\n", 261c582b7e3Smrg strerror (err), err); 262c582b7e3Smrg return FALSE; 263c582b7e3Smrg } 264c582b7e3Smrg#endif 265c582b7e3Smrg } 266c582b7e3Smrg 267c582b7e3Smrg return TRUE; 268c582b7e3Smrg} 269c582b7e3Smrg 270c582b7e3Smrg/* Unmap the MMIO region. Used during pre-init and by R128UnmapMem, 271c582b7e3Smrg below. */ 272c582b7e3Smrgstatic Bool R128UnmapMMIO(ScrnInfoPtr pScrn) 273c582b7e3Smrg{ 274c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 275c582b7e3Smrg 27679e5230eSmacallan#ifndef AVOID_FBDEV 277c582b7e3Smrg if (info->FBDev) 278c582b7e3Smrg fbdevHWUnmapMMIO(pScrn); 27979e5230eSmacallan else 28079e5230eSmacallan#endif 28179e5230eSmacallan { 282c582b7e3Smrg#ifndef XSERVER_LIBPCIACCESS 283c582b7e3Smrg xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE); 284c582b7e3Smrg#else 285c582b7e3Smrg pci_device_unmap_range(info->PciInfo, info->MMIO, R128_MMIOSIZE); 286c582b7e3Smrg#endif 287c582b7e3Smrg } 288c582b7e3Smrg info->MMIO = NULL; 289c582b7e3Smrg return TRUE; 290c582b7e3Smrg} 291c582b7e3Smrg 292c582b7e3Smrg/* Memory map the frame buffer. Used by R128MapMem, below. */ 293c582b7e3Smrgstatic Bool R128MapFB(ScrnInfoPtr pScrn) 294c582b7e3Smrg{ 295c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 296c582b7e3Smrg 29779e5230eSmacallan#ifndef AVOID_FBDEV 298c582b7e3Smrg if (info->FBDev) { 299c582b7e3Smrg info->FB = fbdevHWMapVidmem(pScrn); 30079e5230eSmacallan } else 30179e5230eSmacallan#endif 30279e5230eSmacallan { 303c582b7e3Smrg#ifndef XSERVER_LIBPCIACCESS 304c582b7e3Smrg info->FB = xf86MapPciMem(pScrn->scrnIndex, 305c582b7e3Smrg VIDMEM_FRAMEBUFFER, 306c582b7e3Smrg info->PciTag, 307c582b7e3Smrg info->LinearAddr, 308c582b7e3Smrg info->FbMapSize); 309c582b7e3Smrg#else 310c582b7e3Smrg int err = pci_device_map_range(info->PciInfo, 311c582b7e3Smrg info->LinearAddr, 312c582b7e3Smrg info->FbMapSize, 313c582b7e3Smrg PCI_DEV_MAP_FLAG_WRITABLE | 314c582b7e3Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 315c582b7e3Smrg &info->FB); 316c582b7e3Smrg 317c582b7e3Smrg if (err) { 318c582b7e3Smrg xf86DrvMsg (pScrn->scrnIndex, X_ERROR, 319c582b7e3Smrg "Unable to map FB aperture. %s (%d)\n", 320c582b7e3Smrg strerror (err), err); 321c582b7e3Smrg return FALSE; 322c582b7e3Smrg } 323c582b7e3Smrg#endif 324c582b7e3Smrg } 325c582b7e3Smrg 326c582b7e3Smrg if (!info->FB) return FALSE; 327c582b7e3Smrg return TRUE; 328c582b7e3Smrg} 329c582b7e3Smrg 330c582b7e3Smrg/* Unmap the frame buffer. Used by R128UnmapMem, below. */ 331c582b7e3Smrgstatic Bool R128UnmapFB(ScrnInfoPtr pScrn) 332c582b7e3Smrg{ 333c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 334c582b7e3Smrg 33579e5230eSmacallan#ifndef AVOID_FBDEV 336c582b7e3Smrg if (info->FBDev) 337c582b7e3Smrg fbdevHWUnmapVidmem(pScrn); 338c582b7e3Smrg else 33979e5230eSmacallan#endif 340c582b7e3Smrg#ifndef XSERVER_LIBPCIACCESS 341c582b7e3Smrg xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); 342c582b7e3Smrg#else 343c582b7e3Smrg pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize); 344c582b7e3Smrg#endif 345c582b7e3Smrg info->FB = NULL; 346c582b7e3Smrg return TRUE; 347c582b7e3Smrg} 348c582b7e3Smrg 349c582b7e3Smrg/* Memory map the MMIO region and the frame buffer. */ 350c582b7e3Smrgstatic Bool R128MapMem(ScrnInfoPtr pScrn) 351c582b7e3Smrg{ 352c582b7e3Smrg if (!R128MapMMIO(pScrn)) return FALSE; 353c582b7e3Smrg if (!R128MapFB(pScrn)) { 354c582b7e3Smrg R128UnmapMMIO(pScrn); 355c582b7e3Smrg return FALSE; 356c582b7e3Smrg } 357c582b7e3Smrg return TRUE; 358c582b7e3Smrg} 359c582b7e3Smrg 360c582b7e3Smrg/* Unmap the MMIO region and the frame buffer. */ 361c582b7e3Smrgstatic Bool R128UnmapMem(ScrnInfoPtr pScrn) 362c582b7e3Smrg{ 363c582b7e3Smrg if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE; 364c582b7e3Smrg return TRUE; 365c582b7e3Smrg} 366c582b7e3Smrg 367c582b7e3Smrg/* Read PLL information */ 368c582b7e3Smrgunsigned R128INPLL(ScrnInfoPtr pScrn, int addr) 369c582b7e3Smrg{ 370c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 371c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 372c582b7e3Smrg 373c582b7e3Smrg OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x3f); 374c582b7e3Smrg return INREG(R128_CLOCK_CNTL_DATA); 375c582b7e3Smrg} 376c582b7e3Smrg 377c582b7e3Smrg#if 0 378c582b7e3Smrg/* Read PAL information (only used for debugging). */ 379c582b7e3Smrgstatic int R128INPAL(int idx) 380c582b7e3Smrg{ 381c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 382c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 383c582b7e3Smrg 384c582b7e3Smrg OUTREG(R128_PALETTE_INDEX, idx << 16); 385c582b7e3Smrg return INREG(R128_PALETTE_DATA); 386c582b7e3Smrg} 387c582b7e3Smrg#endif 388c582b7e3Smrg 389c582b7e3Smrg/* Wait for vertical sync. */ 390c582b7e3Smrgvoid R128WaitForVerticalSync(ScrnInfoPtr pScrn) 391c582b7e3Smrg{ 392c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 393c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 394c582b7e3Smrg int i; 395c582b7e3Smrg 396c582b7e3Smrg OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); 397c582b7e3Smrg for (i = 0; i < R128_TIMEOUT; i++) { 398c582b7e3Smrg if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; 399c582b7e3Smrg } 400c582b7e3Smrg} 401c582b7e3Smrg 402c582b7e3Smrg/* Compute log base 2 of val. */ 403c582b7e3Smrgint R128MinBits(int val) 404c582b7e3Smrg{ 405c582b7e3Smrg int bits; 406c582b7e3Smrg 407c582b7e3Smrg if (!val) return 1; 408c582b7e3Smrg for (bits = 0; val; val >>= 1, ++bits); 409c582b7e3Smrg return bits; 410c582b7e3Smrg} 411c582b7e3Smrg 412b3ff493bSmrg/* Finds the first output using a given crtc. */ 413b3ff493bSmrgxf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc) 414b3ff493bSmrg{ 415b3ff493bSmrg ScrnInfoPtr pScrn = crtc->scrn; 416b3ff493bSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 417b3ff493bSmrg xf86OutputPtr output = xf86_config->output[0]; 418b3ff493bSmrg int o; 419b3ff493bSmrg 420b3ff493bSmrg for (o = 0; o < xf86_config->num_output; o++) { 421b3ff493bSmrg output = xf86_config->output[o]; 422b3ff493bSmrg if (output->crtc == crtc) break; 423b3ff493bSmrg } 424b3ff493bSmrg 425b3ff493bSmrg return output; 426b3ff493bSmrg} 427b3ff493bSmrg 428b3ff493bSmrg/* Read the Video BIOS block. */ 429c582b7e3Smrgstatic Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) 430c582b7e3Smrg{ 431c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 432c582b7e3Smrg 433c582b7e3Smrg#ifdef XSERVER_LIBPCIACCESS 434c582b7e3Smrg int size = info->PciInfo->rom_size > R128_VBIOS_SIZE ? info->PciInfo->rom_size : R128_VBIOS_SIZE; 43584354367Smrg info->VBIOS = malloc(size); 436c582b7e3Smrg#else 43784354367Smrg info->VBIOS = malloc(R128_VBIOS_SIZE); 438c582b7e3Smrg#endif 439c582b7e3Smrg 440c582b7e3Smrg if (!info->VBIOS) { 441c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 442c582b7e3Smrg "Cannot allocate space for hold Video BIOS!\n"); 443c582b7e3Smrg return FALSE; 444c582b7e3Smrg } 445c582b7e3Smrg 446c582b7e3Smrg if (pInt10) { 447c582b7e3Smrg info->BIOSAddr = pInt10->BIOSseg << 4; 448c582b7e3Smrg (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr), 449c582b7e3Smrg R128_VBIOS_SIZE); 450c582b7e3Smrg } else { 451c582b7e3Smrg#ifdef XSERVER_LIBPCIACCESS 452c582b7e3Smrg if (pci_device_read_rom(info->PciInfo, info->VBIOS)) { 453c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 454c582b7e3Smrg "Failed to read PCI ROM!\n"); 455c582b7e3Smrg } 456c582b7e3Smrg#else 457c582b7e3Smrg xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE); 458c582b7e3Smrg if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { 459c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 460c582b7e3Smrg "Video BIOS not detected in PCI space!\n"); 461c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 462c582b7e3Smrg "Attempting to read Video BIOS from legacy ISA space!\n"); 463c582b7e3Smrg info->BIOSAddr = 0x000c0000; 464c582b7e3Smrg xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS); 465c582b7e3Smrg } 466c582b7e3Smrg#endif 467c582b7e3Smrg } 468c582b7e3Smrg if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { 469c582b7e3Smrg info->BIOSAddr = 0x00000000; 47084354367Smrg free(info->VBIOS); 471c582b7e3Smrg info->VBIOS = NULL; 472c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 473c582b7e3Smrg "Video BIOS not found!\n"); 474c582b7e3Smrg } 475c582b7e3Smrg 476b3ff493bSmrg return TRUE; 477b3ff493bSmrg} 478c582b7e3Smrg 479b3ff493bSmrg/* Read the FP parameters if an LVDS panel is expected. */ 480b3ff493bSmrgvoid R128GetPanelInfoFromBIOS(xf86OutputPtr output) 481b3ff493bSmrg{ 482b3ff493bSmrg ScrnInfoPtr pScrn = output->scrn; 483b3ff493bSmrg R128InfoPtr info = R128PTR(pScrn); 484b3ff493bSmrg R128OutputPrivatePtr r128_output = output->driver_private; 485b3ff493bSmrg int FPHeader = 0; 486b3ff493bSmrg int i; 487c582b7e3Smrg 488b3ff493bSmrg r128_output->PanelPwrDly = 200; 489b3ff493bSmrg xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH, &(r128_output->PanelXRes)); 490b3ff493bSmrg xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes)); 491b3ff493bSmrg 492449624caSmacallan if (!info->VBIOS) goto fallback; 493b3ff493bSmrg info->FPBIOSstart = 0; 494b3ff493bSmrg 495b3ff493bSmrg /* FIXME: There should be direct access to the start of the FP info 496b3ff493bSmrg * tables, but until we find out where that offset is stored, we 497b3ff493bSmrg * must search for the ATI signature string: "M3 ". 498b3ff493bSmrg */ 499b3ff493bSmrg for (i = 4; i < R128_VBIOS_SIZE - 8; i++) { 500b3ff493bSmrg if (R128_BIOS8(i) == 'M' && 501b3ff493bSmrg R128_BIOS8(i + 1) == '3' && 502b3ff493bSmrg R128_BIOS8(i + 2) == ' ' && 503b3ff493bSmrg R128_BIOS8(i + 3) == ' ' && 504b3ff493bSmrg R128_BIOS8(i + 4) == ' ' && 505b3ff493bSmrg R128_BIOS8(i + 5) == ' ' && 506b3ff493bSmrg R128_BIOS8(i + 6) == ' ' && 507b3ff493bSmrg R128_BIOS8(i + 7) == ' ') { 508b3ff493bSmrg FPHeader = i - 2; 509b3ff493bSmrg break; 510b3ff493bSmrg } 511b3ff493bSmrg } 512b3ff493bSmrg 513449624caSmacallan if (!FPHeader) goto fallback; 514b3ff493bSmrg 515b3ff493bSmrg 516b3ff493bSmrg /* Assume that only one panel is attached and supported */ 517b3ff493bSmrg for (i = FPHeader + 20; i < FPHeader + 84; i += 2) { 518b3ff493bSmrg if (R128_BIOS16(i) != 0) { 519b3ff493bSmrg info->FPBIOSstart = R128_BIOS16(i); 520b3ff493bSmrg break; 521b3ff493bSmrg } 522c582b7e3Smrg } 523c582b7e3Smrg 524b3ff493bSmrg#ifndef AVOID_FBDEV 525b3ff493bSmrg if (!info->FPBIOSstart) return; 526b3ff493bSmrg#endif 527b3ff493bSmrg 528b3ff493bSmrg if (!r128_output->PanelXRes) 529b3ff493bSmrg r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25); 530b3ff493bSmrg if (!r128_output->PanelYRes) 531b3ff493bSmrg r128_output->PanelYRes = R128_BIOS16(info->FPBIOSstart + 27); 532b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", 533b3ff493bSmrg r128_output->PanelXRes, r128_output->PanelYRes); 534b3ff493bSmrg 535b3ff493bSmrg r128_output->PanelPwrDly = R128_BIOS8(info->FPBIOSstart + 56); 536b3ff493bSmrg 537b3ff493bSmrg if (!r128_output->PanelXRes || !r128_output->PanelYRes) { 538c582b7e3Smrg info->HasPanelRegs = FALSE; 539c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 540c582b7e3Smrg "Can't determine panel dimensions, and none specified.\n" 541c582b7e3Smrg "\tDisabling programming of FP registers.\n"); 542c582b7e3Smrg } 543c582b7e3Smrg 544b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); 545b3ff493bSmrg for (i = 1; i <= 24; i++) 546b3ff493bSmrg ErrorF("%c", R128_BIOS8(info->FPBIOSstart + i)); 547b3ff493bSmrg 548b3ff493bSmrg ErrorF("\n"); 549b3ff493bSmrg 550b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); 551b3ff493bSmrg i = R128_BIOS16(info->FPBIOSstart + 29); 552b3ff493bSmrg if (i & 1) ErrorF("Color, "); 553b3ff493bSmrg else ErrorF("Monochrome, "); 554b3ff493bSmrg if (i & 2) ErrorF("Dual(split), "); 555b3ff493bSmrg else ErrorF("Single, "); 556b3ff493bSmrg 557b3ff493bSmrg switch ((i >> 2) & 0x3f) { 558b3ff493bSmrg case 0: ErrorF("STN"); break; 559b3ff493bSmrg case 1: ErrorF("TFT"); break; 560b3ff493bSmrg case 2: ErrorF("Active STN"); break; 561b3ff493bSmrg case 3: ErrorF("EL"); break; 562b3ff493bSmrg case 4: ErrorF("Plasma"); break; 563b3ff493bSmrg default: ErrorF("UNKNOWN"); break; 564b3ff493bSmrg } 565b3ff493bSmrg 566b3ff493bSmrg ErrorF("\n"); 567b3ff493bSmrg 568b3ff493bSmrg if (R128_BIOS8(info->FPBIOSstart + 61) & 1) { 569b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); 570b3ff493bSmrg } else { 571b3ff493bSmrg /* FIXME: Add Non-LVDS flat pael support */ 572b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 573b3ff493bSmrg "Non-LVDS panel interface detected! " 574b3ff493bSmrg "This support is untested and may not " 575b3ff493bSmrg "function properly\n"); 576b3ff493bSmrg } 577449624caSmacallan return; 578449624caSmacallanfallback: 579449624caSmacallan#ifdef __NetBSD__ 580e1efbb8aSmacallan if ((!r128_output->PanelXRes || !r128_output->PanelYRes) && 581e1efbb8aSmacallan (info->HaveWSDisplay)) { 582449624caSmacallan /* 583449624caSmacallan * we may not be on x86 so check wsdisplay for panel dimensions 584449624caSmacallan * XXX this assumes that the r128 is the console, although that should 585449624caSmacallan * be the case in the vast majority of cases where an LCD is hooked up 586449624caSmacallan * directly 587449624caSmacallan * We should probably just check the relevant registers but I'm not 588449624caSmacallan * sure they're available at this point. 589449624caSmacallan */ 590449624caSmacallan struct wsdisplay_fbinfo fbinfo; 591449624caSmacallan 592a4470643Smrg if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GINFO, &fbinfo) == 0) { 593449624caSmacallan r128_output->PanelXRes = fbinfo.width; 594449624caSmacallan r128_output->PanelYRes = fbinfo.height; 595449624caSmacallan } 596449624caSmacallan } 597449624caSmacallan#endif 598c582b7e3Smrg} 599c582b7e3Smrg 600c582b7e3Smrg/* Read PLL parameters from BIOS block. Default to typical values if there 601c582b7e3Smrg is no BIOS. */ 602c582b7e3Smrgstatic Bool R128GetPLLParameters(ScrnInfoPtr pScrn) 603c582b7e3Smrg{ 604c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 605c582b7e3Smrg R128PLLPtr pll = &info->pll; 606c582b7e3Smrg 607c582b7e3Smrg#if defined(__powerpc__) || defined(__alpha__) 608c582b7e3Smrg /* there is no bios under Linux PowerPC but Open Firmware 609c582b7e3Smrg does set up the PLL registers properly and we can use 610c582b7e3Smrg those to calculate xclk and find the reference divider */ 611c582b7e3Smrg 612c582b7e3Smrg unsigned x_mpll_ref_fb_div; 613c582b7e3Smrg unsigned xclk_cntl; 614c582b7e3Smrg unsigned Nx, M; 615c582b7e3Smrg unsigned PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12}; 616c582b7e3Smrg 617c582b7e3Smrg /* Assume REF clock is 2950 (in units of 10khz) */ 618c582b7e3Smrg /* and that all pllclk must be between 125 Mhz and 250Mhz */ 619c582b7e3Smrg pll->reference_freq = 2950; 620c582b7e3Smrg pll->min_pll_freq = 12500; 621c582b7e3Smrg pll->max_pll_freq = 25000; 622c582b7e3Smrg 623c582b7e3Smrg x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV); 624c582b7e3Smrg xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7; 625c582b7e3Smrg pll->reference_div = 626c582b7e3Smrg INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK; 627c582b7e3Smrg 628c582b7e3Smrg Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8; 629c582b7e3Smrg M = (x_mpll_ref_fb_div & 0x0000FF); 630c582b7e3Smrg 631c582b7e3Smrg pll->xclk = R128Div((2 * Nx * pll->reference_freq), 632c582b7e3Smrg (M * PostDivSet[xclk_cntl])); 633c582b7e3Smrg 634c582b7e3Smrg#else /* !defined(__powerpc__) */ 635c582b7e3Smrg 636c582b7e3Smrg if (!info->VBIOS) { 637c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 638c582b7e3Smrg "Video BIOS not detected, using default PLL parameters!\n"); 639c582b7e3Smrg /* These probably aren't going to work for 640c582b7e3Smrg the card you are using. Specifically, 641c582b7e3Smrg reference freq can be 29.50MHz, 642c582b7e3Smrg 28.63MHz, or 14.32MHz. YMMV. */ 643c582b7e3Smrg pll->reference_freq = 2950; 644c582b7e3Smrg pll->reference_div = 65; 645c582b7e3Smrg pll->min_pll_freq = 12500; 646c582b7e3Smrg pll->max_pll_freq = 25000; 647c582b7e3Smrg pll->xclk = 10300; 648c582b7e3Smrg } else { 649b3ff493bSmrg uint16_t bios_header = R128_BIOS16(0x48); 650b3ff493bSmrg uint16_t pll_info_block = R128_BIOS16(bios_header + 0x30); 65181f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65281f79626Smrg "Header at 0x%04x; PLL Information at 0x%04x\n", 65381f79626Smrg bios_header, pll_info_block)); 654c582b7e3Smrg 655c582b7e3Smrg pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e); 656c582b7e3Smrg pll->reference_div = R128_BIOS16(pll_info_block + 0x10); 657c582b7e3Smrg pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12); 658c582b7e3Smrg pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16); 659c582b7e3Smrg pll->xclk = R128_BIOS16(pll_info_block + 0x08); 660c582b7e3Smrg } 661c582b7e3Smrg#endif /* __powerpc__ */ 662c582b7e3Smrg 663c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 664c582b7e3Smrg "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", 665c582b7e3Smrg pll->reference_freq, 666c582b7e3Smrg pll->reference_div, 667c582b7e3Smrg pll->min_pll_freq, 668c582b7e3Smrg pll->max_pll_freq, 669c582b7e3Smrg pll->xclk); 670c582b7e3Smrg 671c582b7e3Smrg return TRUE; 672c582b7e3Smrg} 673c582b7e3Smrg 674c582b7e3Smrg/* This is called by R128PreInit to set up the default visual. */ 675c582b7e3Smrgstatic Bool R128PreInitVisual(ScrnInfoPtr pScrn) 676c582b7e3Smrg{ 677c582b7e3Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, (Support24bppFb 678c582b7e3Smrg | Support32bppFb 679c582b7e3Smrg | SupportConvert32to24 680c582b7e3Smrg ))) 681c582b7e3Smrg return FALSE; 682c582b7e3Smrg 683c582b7e3Smrg switch (pScrn->depth) { 684c582b7e3Smrg case 8: 685c582b7e3Smrg case 15: 686c582b7e3Smrg case 16: 687c582b7e3Smrg case 24: 688c582b7e3Smrg break; 689c582b7e3Smrg default: 690c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 691c582b7e3Smrg "Given depth (%d) is not supported by %s driver\n", 692c582b7e3Smrg pScrn->depth, R128_DRIVER_NAME); 693c582b7e3Smrg return FALSE; 694c582b7e3Smrg } 695c582b7e3Smrg 696c582b7e3Smrg xf86PrintDepthBpp(pScrn); 697c582b7e3Smrg 698c582b7e3Smrg if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; 699c582b7e3Smrg 700c582b7e3Smrg if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 701c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 702c582b7e3Smrg "Default visual (%s) is not supported at depth %d\n", 703c582b7e3Smrg xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 704c582b7e3Smrg return FALSE; 705c582b7e3Smrg } 706c582b7e3Smrg return TRUE; 707c582b7e3Smrg 708c582b7e3Smrg} 709c582b7e3Smrg 710c582b7e3Smrg/* This is called by R128PreInit to handle all color weight issues. */ 711c582b7e3Smrgstatic Bool R128PreInitWeight(ScrnInfoPtr pScrn) 712c582b7e3Smrg{ 713c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 71481f79626Smrg rgb defaultWeight = { 0, 0, 0 }; 715c582b7e3Smrg 71681f79626Smrg /* 71781f79626Smrg * Save flag for 6 bit DAC to use for setting CRTC registers. 71881f79626Smrg * Otherwise use an 8 bit DAC, even if xf86SetWeight sets 71981f79626Smrg * pScrn->rgbBits to some value other than 8. 72081f79626Smrg */ 72181f79626Smrg if (pScrn->depth <= 8) { 72281f79626Smrg if (info->dac6bits) { 72381f79626Smrg pScrn->rgbBits = 6; 72481f79626Smrg } else { 72581f79626Smrg pScrn->rgbBits = 8; 72681f79626Smrg } 727c582b7e3Smrg } else { 72881f79626Smrg info->dac6bits = FALSE; 72981f79626Smrg pScrn->rgbBits = 8; 73081f79626Smrg } 73181f79626Smrg 73281f79626Smrg if (pScrn->depth > 8) { 73381f79626Smrg if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; 734c582b7e3Smrg } 73581f79626Smrg 736c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 73781f79626Smrg "Using %d bits per RGB (%d bit DAC)\n", 73881f79626Smrg pScrn->rgbBits, info->dac6bits ? 6 : 8); 739c582b7e3Smrg 740c582b7e3Smrg return TRUE; 741c582b7e3Smrg} 742c582b7e3Smrg 743c582b7e3Smrg/* This is called by R128PreInit to handle config file overrides for things 744c582b7e3Smrg like chipset and memory regions. Also determine memory size and type. 745c582b7e3Smrg If memory type ever needs an override, put it in this routine. */ 746c582b7e3Smrgstatic Bool R128PreInitConfig(ScrnInfoPtr pScrn) 747c582b7e3Smrg{ 748c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 749b3ff493bSmrg R128EntPtr pR128Ent = R128EntPriv(pScrn); 750c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 751c582b7e3Smrg EntityInfoPtr pEnt = info->pEnt; 752c582b7e3Smrg GDevPtr dev = pEnt->device; 753c582b7e3Smrg int offset = 0; /* RAM Type */ 754c582b7e3Smrg MessageType from; 755c582b7e3Smrg 756c582b7e3Smrg /* Chipset */ 757c582b7e3Smrg from = X_PROBED; 758c582b7e3Smrg if (dev->chipset && *dev->chipset) { 759c582b7e3Smrg info->Chipset = xf86StringToToken(R128Chipsets, dev->chipset); 760c582b7e3Smrg from = X_CONFIG; 761c582b7e3Smrg } else if (dev->chipID >= 0) { 762c582b7e3Smrg info->Chipset = dev->chipID; 763c582b7e3Smrg from = X_CONFIG; 764c582b7e3Smrg } else { 765c582b7e3Smrg info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo); 766c582b7e3Smrg } 767c582b7e3Smrg pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset); 768c582b7e3Smrg 769c582b7e3Smrg if (!pScrn->chipset) { 770c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 771c582b7e3Smrg "ChipID 0x%04x is not recognized\n", info->Chipset); 772c582b7e3Smrg return FALSE; 773c582b7e3Smrg } 774c582b7e3Smrg 775c582b7e3Smrg if (info->Chipset < 0) { 776c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 777c582b7e3Smrg "Chipset \"%s\" is not recognized\n", pScrn->chipset); 778c582b7e3Smrg return FALSE; 779c582b7e3Smrg } 780c582b7e3Smrg 781c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, from, 782c582b7e3Smrg "Chipset: \"%s\" (ChipID = 0x%04x)\n", 783c582b7e3Smrg pScrn->chipset, 784c582b7e3Smrg info->Chipset); 785c582b7e3Smrg 786c582b7e3Smrg /* Framebuffer */ 787c582b7e3Smrg 788c582b7e3Smrg from = X_PROBED; 789c582b7e3Smrg info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & 0xfc000000; 790c582b7e3Smrg pScrn->memPhysBase = info->LinearAddr; 791c582b7e3Smrg if (dev->MemBase) { 792c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 793c582b7e3Smrg "Linear address override, using 0x%08lx instead of 0x%08lx\n", 794c582b7e3Smrg dev->MemBase, 795c582b7e3Smrg info->LinearAddr); 796c582b7e3Smrg info->LinearAddr = dev->MemBase; 797c582b7e3Smrg from = X_CONFIG; 798c582b7e3Smrg } else if (!info->LinearAddr) { 799c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 800c582b7e3Smrg "No valid linear framebuffer address\n"); 801c582b7e3Smrg return FALSE; 802c582b7e3Smrg } 803c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, from, 804c582b7e3Smrg "Linear framebuffer at 0x%08lx\n", info->LinearAddr); 805c582b7e3Smrg 806c582b7e3Smrg /* MMIO registers */ 807c582b7e3Smrg from = X_PROBED; 808c582b7e3Smrg info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & 0xffffff00; 809c582b7e3Smrg if (dev->IOBase) { 810c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 811c582b7e3Smrg "MMIO address override, using 0x%08lx instead of 0x%08lx\n", 812c582b7e3Smrg dev->IOBase, 813c582b7e3Smrg info->MMIOAddr); 814c582b7e3Smrg info->MMIOAddr = dev->IOBase; 815c582b7e3Smrg from = X_CONFIG; 816c582b7e3Smrg } else if (!info->MMIOAddr) { 817c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); 818c582b7e3Smrg return FALSE; 819c582b7e3Smrg } 820c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, from, 821c582b7e3Smrg "MMIO registers at 0x%08lx\n", info->MMIOAddr); 822c582b7e3Smrg 823c582b7e3Smrg#ifndef XSERVER_LIBPCIACCESS 824c582b7e3Smrg /* BIOS */ 825c582b7e3Smrg from = X_PROBED; 826c582b7e3Smrg info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; 827c582b7e3Smrg if (info->BIOSAddr) { 828c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, from, 829c582b7e3Smrg "BIOS at 0x%08lx\n", info->BIOSAddr); 830c582b7e3Smrg } 831c582b7e3Smrg#endif 832c582b7e3Smrg 833c582b7e3Smrg /* Flat panel (part 1) */ 834c582b7e3Smrg if (xf86GetOptValBool(info->Options, OPTION_PROG_FP_REGS, 835c582b7e3Smrg &info->HasPanelRegs)) { 836c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 837c582b7e3Smrg "Turned flat panel register programming %s\n", 838c582b7e3Smrg info->HasPanelRegs ? "on" : "off"); 839c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 840c582b7e3Smrg "\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"); 841c582b7e3Smrg } else { 842c582b7e3Smrg info->isDFP = FALSE; 843c582b7e3Smrg info->isPro2 = FALSE; 844b3ff493bSmrg pR128Ent->HasCRTC2 = FALSE; 845c582b7e3Smrg switch (info->Chipset) { 846c582b7e3Smrg /* R128 Pro and Pro2 can have DFP, we will deal with it. 847c582b7e3Smrg No support for dual-head/xinerama yet. 848c582b7e3Smrg M3 can also have DFP, no support for now */ 849c582b7e3Smrg case PCI_CHIP_RAGE128TF: 850c582b7e3Smrg case PCI_CHIP_RAGE128TL: 851c582b7e3Smrg case PCI_CHIP_RAGE128TR: 852c582b7e3Smrg /* FIXME: RAGE128 TS/TT/TU are assumed to be PRO2 as all 6 chips came 853c582b7e3Smrg * out at the same time, so are of the same family likely. 854c582b7e3Smrg * This requires confirmation however to be fully correct. 855c582b7e3Smrg * Mike A. Harris <mharris@redhat.com> 856c582b7e3Smrg */ 857c582b7e3Smrg case PCI_CHIP_RAGE128TS: 858c582b7e3Smrg case PCI_CHIP_RAGE128TT: 859c582b7e3Smrg case PCI_CHIP_RAGE128TU: info->isPro2 = TRUE; 860c582b7e3Smrg /* FIXME: RAGE128 P[ABCEGHIJKLMNOQSTUVWX] are assumed to have DFP 861c582b7e3Smrg * capability, as the comment at the top suggests. 862c582b7e3Smrg * This requires confirmation however to be fully correct. 863c582b7e3Smrg * Mike A. Harris <mharris@redhat.com> 864c582b7e3Smrg */ 865c582b7e3Smrg case PCI_CHIP_RAGE128PA: 866c582b7e3Smrg case PCI_CHIP_RAGE128PB: 867c582b7e3Smrg case PCI_CHIP_RAGE128PC: 868c582b7e3Smrg case PCI_CHIP_RAGE128PE: 869c582b7e3Smrg case PCI_CHIP_RAGE128PG: 870c582b7e3Smrg case PCI_CHIP_RAGE128PH: 871c582b7e3Smrg case PCI_CHIP_RAGE128PI: 872c582b7e3Smrg case PCI_CHIP_RAGE128PJ: 873c582b7e3Smrg case PCI_CHIP_RAGE128PK: 874c582b7e3Smrg case PCI_CHIP_RAGE128PL: 875c582b7e3Smrg case PCI_CHIP_RAGE128PM: 876c582b7e3Smrg case PCI_CHIP_RAGE128PN: 877c582b7e3Smrg case PCI_CHIP_RAGE128PO: 878c582b7e3Smrg case PCI_CHIP_RAGE128PQ: 879c582b7e3Smrg case PCI_CHIP_RAGE128PS: 880c582b7e3Smrg case PCI_CHIP_RAGE128PT: 881c582b7e3Smrg case PCI_CHIP_RAGE128PU: 882c582b7e3Smrg case PCI_CHIP_RAGE128PV: 883c582b7e3Smrg case PCI_CHIP_RAGE128PW: 884c582b7e3Smrg case PCI_CHIP_RAGE128PX: 885c582b7e3Smrg 886c582b7e3Smrg case PCI_CHIP_RAGE128PD: 887c582b7e3Smrg case PCI_CHIP_RAGE128PF: 888c582b7e3Smrg case PCI_CHIP_RAGE128PP: 889c582b7e3Smrg case PCI_CHIP_RAGE128PR: info->isDFP = TRUE; break; 890c582b7e3Smrg 891c582b7e3Smrg case PCI_CHIP_RAGE128LE: 892c582b7e3Smrg case PCI_CHIP_RAGE128LF: 893c582b7e3Smrg case PCI_CHIP_RAGE128MF: 894c582b7e3Smrg case PCI_CHIP_RAGE128ML: 895d6cc4c59Smacallan info->HasPanelRegs = TRUE; 896d6cc4c59Smacallan info->isDFP = TRUE; 897c582b7e3Smrg /* which chips support dualhead? */ 898b3ff493bSmrg pR128Ent->HasCRTC2 = TRUE; 899c582b7e3Smrg break; 900c582b7e3Smrg case PCI_CHIP_RAGE128RE: 901c582b7e3Smrg case PCI_CHIP_RAGE128RF: 902c582b7e3Smrg case PCI_CHIP_RAGE128RG: 903c582b7e3Smrg case PCI_CHIP_RAGE128RK: 904c582b7e3Smrg case PCI_CHIP_RAGE128RL: 905c582b7e3Smrg case PCI_CHIP_RAGE128SM: 906c582b7e3Smrg /* FIXME: RAGE128 S[EFGHKLN] are assumed to be like the SM above as 907c582b7e3Smrg * all of them are listed as "Rage 128 4x" in ATI docs. 908c582b7e3Smrg * This requires confirmation however to be fully correct. 909c582b7e3Smrg * Mike A. Harris <mharris@redhat.com> 910c582b7e3Smrg */ 911c582b7e3Smrg case PCI_CHIP_RAGE128SE: 912c582b7e3Smrg case PCI_CHIP_RAGE128SF: 913c582b7e3Smrg case PCI_CHIP_RAGE128SG: 914c582b7e3Smrg case PCI_CHIP_RAGE128SH: 915c582b7e3Smrg case PCI_CHIP_RAGE128SK: 916c582b7e3Smrg case PCI_CHIP_RAGE128SL: 917c582b7e3Smrg case PCI_CHIP_RAGE128SN: 918c582b7e3Smrg default: info->HasPanelRegs = FALSE; break; 919c582b7e3Smrg } 920c582b7e3Smrg } 921c582b7e3Smrg 922c582b7e3Smrg /* Read registers used to determine options */ 923c582b7e3Smrg from = X_PROBED; 924b3ff493bSmrg if (!R128MapMMIO(pScrn)) return FALSE; 925c582b7e3Smrg R128MMIO = info->MMIO; 926c582b7e3Smrg 92779e5230eSmacallan#ifndef AVOID_FBDEV 928c582b7e3Smrg if (info->FBDev) 929c582b7e3Smrg pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; 930c582b7e3Smrg else 93179e5230eSmacallan#endif 932c582b7e3Smrg pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024; 933c582b7e3Smrg 934c582b7e3Smrg info->MemCntl = INREG(R128_MEM_CNTL); 935c582b7e3Smrg info->BusCntl = INREG(R128_BUS_CNTL); 936c582b7e3Smrg 937c582b7e3Smrg /* RAM */ 938c582b7e3Smrg switch (info->MemCntl & 0x3) { 939c582b7e3Smrg case 0: /* SDR SGRAM 1:1 */ 940c582b7e3Smrg switch (info->Chipset) { 941c582b7e3Smrg case PCI_CHIP_RAGE128TF: 942c582b7e3Smrg case PCI_CHIP_RAGE128TL: 943c582b7e3Smrg case PCI_CHIP_RAGE128TR: 944c582b7e3Smrg case PCI_CHIP_RAGE128LE: 945c582b7e3Smrg case PCI_CHIP_RAGE128LF: 946c582b7e3Smrg case PCI_CHIP_RAGE128MF: 947c582b7e3Smrg case PCI_CHIP_RAGE128ML: 948c582b7e3Smrg case PCI_CHIP_RAGE128RE: 949c582b7e3Smrg case PCI_CHIP_RAGE128RF: 950c582b7e3Smrg case PCI_CHIP_RAGE128RG: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */ 951c582b7e3Smrg case PCI_CHIP_RAGE128RK: 952c582b7e3Smrg case PCI_CHIP_RAGE128RL: 953c582b7e3Smrg case PCI_CHIP_RAGE128SM: 954c582b7e3Smrg default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ 955c582b7e3Smrg } 956c582b7e3Smrg break; 957c582b7e3Smrg case 1: offset = 2; break; /* 64-bit SDR SGRAM 2:1 */ 958c582b7e3Smrg case 2: offset = 3; break; /* 64-bit DDR SGRAM */ 959c582b7e3Smrg default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ 960c582b7e3Smrg } 961c582b7e3Smrg info->ram = &R128RAM[offset]; 962c582b7e3Smrg 963c582b7e3Smrg if (dev->videoRam) { 964c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 965c582b7e3Smrg "Video RAM override, using %d kB instead of %d kB\n", 966c582b7e3Smrg dev->videoRam, 967c582b7e3Smrg pScrn->videoRam); 968c582b7e3Smrg from = X_CONFIG; 969c582b7e3Smrg pScrn->videoRam = dev->videoRam; 970c582b7e3Smrg } 971c582b7e3Smrg 972c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, from, 973c582b7e3Smrg "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); 974c582b7e3Smrg 975c582b7e3Smrg pScrn->videoRam &= ~1023; 976c582b7e3Smrg info->FbMapSize = pScrn->videoRam * 1024; 977c582b7e3Smrg 97884354367Smrg#ifdef R128DRI 97981f79626Smrg /* AGP/PCI */ 98081f79626Smrg if (!info->IsPCI) { 981c582b7e3Smrg switch (info->Chipset) { 982c582b7e3Smrg case PCI_CHIP_RAGE128LE: 983c582b7e3Smrg case PCI_CHIP_RAGE128RE: 984c582b7e3Smrg case PCI_CHIP_RAGE128RK: 985c582b7e3Smrg case PCI_CHIP_RAGE128PD: 986c582b7e3Smrg case PCI_CHIP_RAGE128PR: 987c582b7e3Smrg case PCI_CHIP_RAGE128PP: info->IsPCI = TRUE; break; 988c582b7e3Smrg case PCI_CHIP_RAGE128LF: 989c582b7e3Smrg case PCI_CHIP_RAGE128MF: 990c582b7e3Smrg case PCI_CHIP_RAGE128ML: 991c582b7e3Smrg case PCI_CHIP_RAGE128PF: 992c582b7e3Smrg case PCI_CHIP_RAGE128RF: 993c582b7e3Smrg case PCI_CHIP_RAGE128RG: 994c582b7e3Smrg case PCI_CHIP_RAGE128RL: 995c582b7e3Smrg case PCI_CHIP_RAGE128SM: 996c582b7e3Smrg case PCI_CHIP_RAGE128TF: 997c582b7e3Smrg case PCI_CHIP_RAGE128TL: 998c582b7e3Smrg case PCI_CHIP_RAGE128TR: 999c582b7e3Smrg /* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are 1000c582b7e3Smrg * believed to be AGP, but need confirmation. <mharris@redhat.com> 1001c582b7e3Smrg */ 1002c582b7e3Smrg case PCI_CHIP_RAGE128PA: 1003c582b7e3Smrg case PCI_CHIP_RAGE128PB: 1004c582b7e3Smrg case PCI_CHIP_RAGE128PC: 1005c582b7e3Smrg case PCI_CHIP_RAGE128PE: 1006c582b7e3Smrg case PCI_CHIP_RAGE128PG: 1007c582b7e3Smrg case PCI_CHIP_RAGE128PH: 1008c582b7e3Smrg case PCI_CHIP_RAGE128PI: 1009c582b7e3Smrg case PCI_CHIP_RAGE128PJ: 1010c582b7e3Smrg case PCI_CHIP_RAGE128PK: 1011c582b7e3Smrg case PCI_CHIP_RAGE128PL: 1012c582b7e3Smrg case PCI_CHIP_RAGE128PM: 1013c582b7e3Smrg case PCI_CHIP_RAGE128PN: 1014c582b7e3Smrg case PCI_CHIP_RAGE128PO: 1015c582b7e3Smrg case PCI_CHIP_RAGE128PQ: 1016c582b7e3Smrg case PCI_CHIP_RAGE128PS: 1017c582b7e3Smrg case PCI_CHIP_RAGE128PT: 1018c582b7e3Smrg case PCI_CHIP_RAGE128PU: 1019c582b7e3Smrg case PCI_CHIP_RAGE128PV: 1020c582b7e3Smrg case PCI_CHIP_RAGE128PW: 1021c582b7e3Smrg case PCI_CHIP_RAGE128PX: 1022c582b7e3Smrg case PCI_CHIP_RAGE128TS: 1023c582b7e3Smrg case PCI_CHIP_RAGE128TT: 1024c582b7e3Smrg case PCI_CHIP_RAGE128TU: 1025c582b7e3Smrg case PCI_CHIP_RAGE128SE: 1026c582b7e3Smrg case PCI_CHIP_RAGE128SF: 1027c582b7e3Smrg case PCI_CHIP_RAGE128SG: 1028c582b7e3Smrg case PCI_CHIP_RAGE128SH: 1029c582b7e3Smrg case PCI_CHIP_RAGE128SK: 1030c582b7e3Smrg case PCI_CHIP_RAGE128SL: 1031c582b7e3Smrg case PCI_CHIP_RAGE128SN: 1032c582b7e3Smrg default: info->IsPCI = FALSE; break; 1033c582b7e3Smrg } 1034c582b7e3Smrg } 1035c582b7e3Smrg#endif 1036c582b7e3Smrg 1037c582b7e3Smrg return TRUE; 1038c582b7e3Smrg} 1039c582b7e3Smrg 1040c582b7e3Smrgstatic Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) 1041c582b7e3Smrg{ 1042c582b7e3Smrg#if !defined(__powerpc__) && !defined(__alpha__) && !defined(__sparc__) 1043c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1044c582b7e3Smrg vbeInfoPtr pVbe; 1045c582b7e3Smrg#endif 1046c582b7e3Smrg 1047c582b7e3Smrg if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; 1048b3ff493bSmrg if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE; 1049c582b7e3Smrg 1050c582b7e3Smrg#if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__) 1051c582b7e3Smrg /* Int10 is broken on PPC and some Alphas */ 1052c582b7e3Smrg return TRUE; 1053c582b7e3Smrg#else 1054c582b7e3Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 1055c582b7e3Smrg pVbe = VBEInit(pInt10,info->pEnt->index); 1056c582b7e3Smrg if (!pVbe) return FALSE; 1057c582b7e3Smrg xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); 1058c582b7e3Smrg vbeFree(pVbe); 1059c582b7e3Smrg return TRUE; 1060c582b7e3Smrg } else 1061c582b7e3Smrg return FALSE; 1062c582b7e3Smrg#endif 1063c582b7e3Smrg} 1064c582b7e3Smrg 1065c582b7e3Smrg/* This is called by R128PreInit to initialize gamma correction. */ 1066c582b7e3Smrgstatic Bool R128PreInitGamma(ScrnInfoPtr pScrn) 1067c582b7e3Smrg{ 1068c582b7e3Smrg Gamma zeros = { 0.0, 0.0, 0.0 }; 1069c582b7e3Smrg 1070c582b7e3Smrg if (!xf86SetGamma(pScrn, zeros)) return FALSE; 1071c582b7e3Smrg return TRUE; 1072c582b7e3Smrg} 1073c582b7e3Smrg 1074c582b7e3Smrg/* This is called by R128PreInit to initialize the hardware cursor. */ 1075c582b7e3Smrgstatic Bool R128PreInitCursor(ScrnInfoPtr pScrn) 1076c582b7e3Smrg{ 1077c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1078c582b7e3Smrg 107981f79626Smrg if (!info->swCursor) { 1080c582b7e3Smrg if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; 1081c582b7e3Smrg } 1082c582b7e3Smrg return TRUE; 1083c582b7e3Smrg} 1084c582b7e3Smrg 1085c582b7e3Smrgstatic Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10) 1086c582b7e3Smrg{ 1087c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1088b3ff493bSmrg#if !defined(__powerpc__) && !defined(__alpha__) 1089b3ff493bSmrg /* int10 is broken on some Alphas and powerpc */ 1090c582b7e3Smrg if (xf86LoadSubModule(pScrn, "int10")) { 1091c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); 1092c582b7e3Smrg *ppInt10 = xf86InitInt10(info->pEnt->index); 1093c582b7e3Smrg } 1094c582b7e3Smrg#endif 1095c582b7e3Smrg return TRUE; 1096c582b7e3Smrg} 1097c582b7e3Smrg 109884354367Smrg#ifdef R128DRI 1099c582b7e3Smrgstatic Bool R128PreInitDRI(ScrnInfoPtr pScrn) 1100c582b7e3Smrg{ 1101c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1102c582b7e3Smrg 1103c582b7e3Smrg info->agpMode = R128_DEFAULT_AGP_MODE; 1104c582b7e3Smrg info->agpSize = R128_DEFAULT_AGP_SIZE; 1105c582b7e3Smrg info->ringSize = R128_DEFAULT_RING_SIZE; 1106c582b7e3Smrg info->bufSize = R128_DEFAULT_BUFFER_SIZE; 1107c582b7e3Smrg info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; 1108c582b7e3Smrg 1109c582b7e3Smrg info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; 1110c582b7e3Smrg 1111c582b7e3Smrg if (!info->IsPCI) { 1112c582b7e3Smrg if (xf86GetOptValInteger(info->Options, 1113c582b7e3Smrg OPTION_AGP_MODE, &(info->agpMode))) { 1114c582b7e3Smrg if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) { 1115c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1116c582b7e3Smrg "Illegal AGP Mode: %d\n", info->agpMode); 1117c582b7e3Smrg return FALSE; 1118c582b7e3Smrg } 1119c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1120c582b7e3Smrg "Using AGP %dx mode\n", info->agpMode); 1121c582b7e3Smrg } 1122c582b7e3Smrg 1123c582b7e3Smrg if (xf86GetOptValInteger(info->Options, 1124c582b7e3Smrg OPTION_AGP_SIZE, (int *)&(info->agpSize))) { 1125c582b7e3Smrg switch (info->agpSize) { 1126c582b7e3Smrg case 4: 1127c582b7e3Smrg case 8: 1128c582b7e3Smrg case 16: 1129c582b7e3Smrg case 32: 1130c582b7e3Smrg case 64: 1131c582b7e3Smrg case 128: 1132c582b7e3Smrg case 256: 1133c582b7e3Smrg break; 1134c582b7e3Smrg default: 1135c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1136c582b7e3Smrg "Illegal AGP size: %d MB\n", info->agpSize); 1137c582b7e3Smrg return FALSE; 1138c582b7e3Smrg } 1139c582b7e3Smrg } 1140c582b7e3Smrg 1141c582b7e3Smrg if (xf86GetOptValInteger(info->Options, 1142c582b7e3Smrg OPTION_RING_SIZE, &(info->ringSize))) { 1143c582b7e3Smrg if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) { 1144c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1145c582b7e3Smrg "Illegal ring buffer size: %d MB\n", 1146c582b7e3Smrg info->ringSize); 1147c582b7e3Smrg return FALSE; 1148c582b7e3Smrg } 1149c582b7e3Smrg } 1150c582b7e3Smrg 1151c582b7e3Smrg if (xf86GetOptValInteger(info->Options, 1152c582b7e3Smrg OPTION_BUFFER_SIZE, &(info->bufSize))) { 1153c582b7e3Smrg if (info->bufSize < 1 || info->bufSize >= (int)info->agpSize) { 1154c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1155c582b7e3Smrg "Illegal vertex/indirect buffers size: %d MB\n", 1156c582b7e3Smrg info->bufSize); 1157c582b7e3Smrg return FALSE; 1158c582b7e3Smrg } 1159c582b7e3Smrg if (info->bufSize > 2) { 1160c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1161c582b7e3Smrg "Illegal vertex/indirect buffers size: %d MB\n", 1162c582b7e3Smrg info->bufSize); 1163c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1164c582b7e3Smrg "Clamping vertex/indirect buffers size to 2 MB\n"); 1165c582b7e3Smrg info->bufSize = 2; 1166c582b7e3Smrg } 1167c582b7e3Smrg } 1168c582b7e3Smrg 1169c582b7e3Smrg if (info->ringSize + info->bufSize + info->agpTexSize > 1170c582b7e3Smrg (int)info->agpSize) { 1171c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1172c582b7e3Smrg "Buffers are too big for requested AGP space\n"); 1173c582b7e3Smrg return FALSE; 1174c582b7e3Smrg } 1175c582b7e3Smrg 1176c582b7e3Smrg info->agpTexSize = info->agpSize - (info->ringSize + info->bufSize); 1177c582b7e3Smrg } 1178c582b7e3Smrg 1179c582b7e3Smrg if (xf86GetOptValInteger(info->Options, OPTION_USEC_TIMEOUT, 1180c582b7e3Smrg &(info->CCEusecTimeout))) { 1181c582b7e3Smrg /* This option checked by the R128 DRM kernel module */ 1182c582b7e3Smrg } 1183c582b7e3Smrg 1184c582b7e3Smrg if (!xf86LoadSubModule(pScrn, "shadowfb")) { 1185c582b7e3Smrg info->allowPageFlip = 0; 1186c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1187c582b7e3Smrg "Couldn't load shadowfb module:\n"); 1188c582b7e3Smrg } else { 1189c582b7e3Smrg info->allowPageFlip = xf86ReturnOptValBool(info->Options, 1190c582b7e3Smrg OPTION_PAGE_FLIP, 1191c582b7e3Smrg FALSE); 1192c582b7e3Smrg } 1193c582b7e3Smrg 1194c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n", 1195c582b7e3Smrg info->allowPageFlip ? "en" : "dis"); 1196c582b7e3Smrg 1197c582b7e3Smrg return TRUE; 1198c582b7e3Smrg} 1199c582b7e3Smrg#endif 1200c582b7e3Smrg 1201b3ff493bSmrgstatic Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) 1202b3ff493bSmrg{ 1203b3ff493bSmrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 1204b3ff493bSmrg int found = 0; 1205b3ff493bSmrg int i; 1206b3ff493bSmrg 1207b3ff493bSmrg if (!R128GetBIOSParameters(pScrn, pInt10)) 1208b3ff493bSmrg return FALSE; 1209b3ff493bSmrg 1210b3ff493bSmrg if (!R128GetPLLParameters(pScrn)) 1211b3ff493bSmrg return FALSE; 1212b3ff493bSmrg 1213b3ff493bSmrg if (!R128AllocateControllers(pScrn)) 1214b3ff493bSmrg return FALSE; 1215b3ff493bSmrg 1216b3ff493bSmrg if (!R128SetupConnectors(pScrn)) 1217b3ff493bSmrg return FALSE; 1218b3ff493bSmrg 1219b3ff493bSmrg for (i = 0; i < config->num_output; i++) { 1220b3ff493bSmrg xf86OutputPtr output = config->output[i]; 1221b3ff493bSmrg 1222b3ff493bSmrg output->status = (*output->funcs->detect) (output); 1223b3ff493bSmrg if (output->status == XF86OutputStatusConnected) 1224b3ff493bSmrg found++; 1225b3ff493bSmrg } 1226b3ff493bSmrg return !!found; 1227b3ff493bSmrg} 1228b3ff493bSmrg 1229c582b7e3Smrgstatic void 123081f79626Smrgr128UMSOption(ScrnInfoPtr pScrn) 1231c582b7e3Smrg{ 123281f79626Smrg R128InfoPtr info = R128PTR(pScrn); 1233b3ff493bSmrg 123481f79626Smrg info->dac6bits = xf86ReturnOptValBool(info->Options, 123581f79626Smrg OPTION_DAC_6BIT, FALSE); 123681f79626Smrg 123781f79626Smrg#ifndef AVOID_FBDEV 123881f79626Smrg#ifdef __powerpc__ 123981f79626Smrg if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, TRUE)) 124081f79626Smrg#else 124181f79626Smrg if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) 124281f79626Smrg#endif 124381f79626Smrg { 124481f79626Smrg info->FBDev = TRUE; 124581f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 124681f79626Smrg "Using framebuffer device.\n"); 124781f79626Smrg } 124881f79626Smrg#endif 124981f79626Smrg 125081f79626Smrg /* By default, don't access VGA IOs on PowerPC or SPARC. */ 125181f79626Smrg#if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW) 125281f79626Smrg info->VGAAccess = FALSE; 125381f79626Smrg#else 125481f79626Smrg info->VGAAccess = TRUE; 125581f79626Smrg#endif 125681f79626Smrg 125781f79626Smrg#ifdef WITH_VGAHW 125881f79626Smrg xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, 125981f79626Smrg &info->VGAAccess); 126081f79626Smrg if (info->VGAAccess) { 126181f79626Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) 126281f79626Smrg info->VGAAccess = FALSE; 126381f79626Smrg else { 126481f79626Smrg if (!vgaHWGetHWRec(pScrn)) 126581f79626Smrg info->VGAAccess = FALSE; 126681f79626Smrg } 126781f79626Smrg 126881f79626Smrg if (!info->VGAAccess) { 126981f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 127081f79626Smrg "Loading VGA module failed, trying to " 127181f79626Smrg "run without it.\n"); 127281f79626Smrg } 127381f79626Smrg } else 127481f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 127581f79626Smrg "VGAAccess option set to FALSE, VGA " 127681f79626Smrg "module load skipped.\n"); 127781f79626Smrg if (info->VGAAccess) { 127881f79626Smrg vgaHWSetStdFuncs(VGAHWPTR(pScrn)); 127981f79626Smrg vgaHWGetIOBase(VGAHWPTR(pScrn)); 128081f79626Smrg } 128181f79626Smrg#else 128281f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 128381f79626Smrg "VGAHW support not compiled, VGA " 128481f79626Smrg "module load skipped.\n"); 128581f79626Smrg#endif 128681f79626Smrg 128781f79626Smrg if (xf86ReturnOptValBool(info->Options, 128881f79626Smrg OPTION_SHOW_CACHE, FALSE)) { 128981f79626Smrg info->showCache = TRUE; 129081f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 129181f79626Smrg "ShowCache enabled.\n"); 129281f79626Smrg } 129381f79626Smrg 129481f79626Smrg if (xf86ReturnOptValBool(info->Options, 129581f79626Smrg OPTION_SW_CURSOR, FALSE)) { 129681f79626Smrg info->swCursor = TRUE; 129781f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 129881f79626Smrg "Software cursor requested.\n"); 129981f79626Smrg } 130081f79626Smrg 130181f79626Smrg if(xf86GetOptValInteger(info->Options, 130281f79626Smrg OPTION_VIDEO_KEY, &info->videoKey)) { 130381f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 130481f79626Smrg "Video key set to 0x%x.\n", info->videoKey); 130581f79626Smrg } else { 130681f79626Smrg info->videoKey = 0x1E; 130781f79626Smrg } 130881f79626Smrg 130981f79626Smrg#ifdef R128DRI 131081f79626Smrg /* DMA for Xv */ 131181f79626Smrg info->DMAForXv = xf86ReturnOptValBool(info->Options, 131281f79626Smrg OPTION_XV_DMA, FALSE); 131381f79626Smrg if (info->DMAForXv) { 131481f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 131581f79626Smrg "Will try to use DMA for Xv image transfers.\n"); 131681f79626Smrg } 131781f79626Smrg 131881f79626Smrg /* Force PCI Mode */ 131981f79626Smrg info->IsPCI = xf86ReturnOptValBool(info->Options, 132081f79626Smrg OPTION_IS_PCI, FALSE); 132181f79626Smrg if (info->IsPCI) { 132281f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 132381f79626Smrg "Forced into PCI only mode.\n"); 132481f79626Smrg } 132581f79626Smrg 132681f79626Smrg if (xf86ReturnOptValBool(info->Options, OPTION_CCE_PIO, FALSE)) { 132781f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 132881f79626Smrg "Forcing CCE into PIO mode.\n"); 132981f79626Smrg info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; 133081f79626Smrg } else { 133181f79626Smrg info->CCEMode = R128_DEFAULT_CCE_BM_MODE; 133281f79626Smrg } 133381f79626Smrg 133481f79626Smrg if (xf86ReturnOptValBool(info->Options, OPTION_NO_SECURITY, FALSE)) { 133581f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 133681f79626Smrg "WARNING!!! CCE Security checks disabled!!!\n"); 133781f79626Smrg info->CCESecure = FALSE; 133881f79626Smrg } else { 133981f79626Smrg info->CCESecure = TRUE; 134081f79626Smrg } 134181f79626Smrg 134281f79626Smrg 134381f79626Smrg#endif 134481f79626Smrg} 134581f79626Smrg 134681f79626Smrgstatic void 134781f79626Smrgr128AcquireOption(ScrnInfoPtr pScrn) 134881f79626Smrg{ 134981f79626Smrg R128InfoPtr info = R128PTR(pScrn); 135081f79626Smrg#ifdef USE_EXA 135181f79626Smrg char *optstr; 135281f79626Smrg#endif 135381f79626Smrg 135481f79626Smrg if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { 135581f79626Smrg info->noAccel = TRUE; 135681f79626Smrg } 135781f79626Smrg 135881f79626Smrg#ifdef USE_EXA 135981f79626Smrg if (!info->noAccel) { 136081f79626Smrg optstr = (char *) xf86GetOptValString(info->Options, 136181f79626Smrg OPTION_ACCELMETHOD); 136281f79626Smrg if (optstr) { 136381f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 136481f79626Smrg "AccelMethod option found.\n"); 136581f79626Smrg if (xf86NameCmp(optstr, "EXA") == 0) { 136681f79626Smrg info->useEXA = TRUE; 136781f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 136881f79626Smrg "AccelMethod is set to EXA, turning " 136981f79626Smrg "EXA on.\n"); 137081f79626Smrg } 137181f79626Smrg } 137281f79626Smrg 137381f79626Smrg#ifdef RENDER 137481f79626Smrg info->RenderAccel = xf86ReturnOptValBool(info->Options, 137581f79626Smrg OPTION_RENDERACCEL, 137681f79626Smrg TRUE); 137781f79626Smrg if (info->RenderAccel) 137881f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 137981f79626Smrg "Acceleration of RENDER operations will be " 138081f79626Smrg "enabled upon successful loading of DRI and " 138181f79626Smrg "EXA.\n"); 138281f79626Smrg#endif 1383c582b7e3Smrg } 1384b3ff493bSmrg#endif 138581f79626Smrg 138681f79626Smrg r128UMSOption(pScrn); 1387b3ff493bSmrg} 1388b3ff493bSmrg 1389b3ff493bSmrgstatic Bool R128CRTCResize(ScrnInfoPtr pScrn, int width, int height) 1390b3ff493bSmrg{ 1391b3ff493bSmrg pScrn->virtualX = width; 1392b3ff493bSmrg pScrn->virtualY = height; 1393b3ff493bSmrg return TRUE; 1394c582b7e3Smrg} 1395c582b7e3Smrg 1396b3ff493bSmrgstatic const xf86CrtcConfigFuncsRec R128CRTCResizeFuncs = { 1397b3ff493bSmrg R128CRTCResize 1398b3ff493bSmrg}; 1399b3ff493bSmrg 140081f79626Smrgstatic Bool R128LegacyMS(ScrnInfoPtr pScrn) 140181f79626Smrg{ 140281f79626Smrg R128InfoPtr info = R128PTR(pScrn); 140381f79626Smrg xf86Int10InfoPtr pInt10 = NULL; 140481f79626Smrg Bool ret = FALSE; 140581f79626Smrg 140681f79626Smrg#ifndef AVOID_FBDEV 140781f79626Smrg if (info->FBDev) { 140881f79626Smrg /* check for linux framebuffer device */ 140981f79626Smrg if (!xf86LoadSubModule(pScrn, "fbdevhw")) goto exit; 141081f79626Smrg if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) goto exit; 141181f79626Smrg pScrn->SwitchMode = fbdevHWSwitchModeWeak(); 141281f79626Smrg pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); 141381f79626Smrg pScrn->ValidMode = fbdevHWValidModeWeak(); 141481f79626Smrg } else { 141581f79626Smrg#endif /* !AVOID_FBDEV */ 141681f79626Smrg if (!R128PreInitInt10(pScrn, &pInt10)) goto exit; 141781f79626Smrg#ifndef AVOID_FBDEV 141881f79626Smrg } 141981f79626Smrg#endif /* !AVOID_FBDEV */ 142081f79626Smrg 142181f79626Smrg if (!R128PreInitConfig(pScrn)) goto freeInt10; 142281f79626Smrg 142381f79626Smrg xf86CrtcSetSizeRange(pScrn, 320, 200, 4096, 4096); 142481f79626Smrg 142581f79626Smrg if (!R128PreInitCursor(pScrn)) goto freeInt10; 142681f79626Smrg 142781f79626Smrg /* Don't fail on this one */ 142881f79626Smrg info->DDC = R128PreInitDDC(pScrn, pInt10); 142981f79626Smrg 143081f79626Smrg if (!R128PreInitControllers(pScrn, pInt10)) goto freeInt10; 143181f79626Smrg 143281f79626Smrg#ifdef R128DRI 143381f79626Smrg if (!R128PreInitDRI(pScrn)) goto freeInt10; 143481f79626Smrg#endif 143581f79626Smrg 143681f79626Smrg ret = TRUE; 143781f79626SmrgfreeInt10: 143881f79626Smrg /* Free int10 info */ 143981f79626Smrg if (pInt10) { 144081f79626Smrg xf86FreeInt10(pInt10); 144181f79626Smrg } 144281f79626Smrg 144381f79626Smrgexit: 144481f79626Smrg return ret; 144581f79626Smrg} 144681f79626Smrg 144781f79626Smrgstatic void 144881f79626SmrgR128PreInitAccel(ScrnInfoPtr pScrn) 144981f79626Smrg{ 145081f79626Smrg R128InfoPtr info = R128PTR(pScrn); 145181f79626Smrg#ifdef USE_EXA 145281f79626Smrg int errmaj, errmin; 145381f79626Smrg#endif 145481f79626Smrg 145581f79626Smrg if (!info->noAccel) { 145681f79626Smrg if (info->useEXA) { 145781f79626Smrg#ifdef USE_EXA 145881f79626Smrg info->exaReq.majorversion = EXA_VERSION_MAJOR; 145981f79626Smrg info->exaReq.minorversion = EXA_VERSION_MINOR; 146081f79626Smrg 146181f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 146281f79626Smrg "Loading EXA module...\n"); 146381f79626Smrg if (LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, 146481f79626Smrg &info->exaReq, &errmaj, &errmin)) { 146581f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 146681f79626Smrg "Loading EXA module.\n"); 146781f79626Smrg } else { 146881f79626Smrg LoaderErrorMsg(NULL, "exa", errmaj, errmin); 146981f79626Smrg } 147081f79626Smrg#endif 147181f79626Smrg } 147281f79626Smrg 147381f79626Smrg if ((!info->useEXA) || 147481f79626Smrg ((info->useEXA) && (!info->accelOn))) { 147581f79626Smrg#ifdef HAVE_XAA_H 147681f79626Smrg if (xf86LoadSubModule(pScrn, "xaa")) { 147781f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 147881f79626Smrg "Loading XAA module.\n"); 147981f79626Smrg } 148081f79626Smrg#endif 148181f79626Smrg } 148281f79626Smrg } 148381f79626Smrg} 148481f79626Smrg 1485c582b7e3Smrg/* R128PreInit is called once at server startup. */ 1486c582b7e3SmrgBool R128PreInit(ScrnInfoPtr pScrn, int flags) 1487c582b7e3Smrg{ 1488c582b7e3Smrg R128InfoPtr info; 1489e1efbb8aSmacallan#ifdef __NetBSD__ 1490e1efbb8aSmacallan struct wsdisplayio_bus_id bid; 1491e1efbb8aSmacallan#endif 1492c582b7e3Smrg 149381f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 149481f79626Smrg "%s\n", __func__)); 149581f79626Smrg 149681f79626Smrg if (flags & PROBE_DETECT) { 149781f79626Smrg return TRUE; 149881f79626Smrg } 149981f79626Smrg 150081f79626Smrg pScrn->monitor = pScrn->confScreen->monitor; 150181f79626Smrg 150281f79626Smrg if (!R128PreInitVisual(pScrn)) { 150381f79626Smrg return FALSE; 150481f79626Smrg } 150581f79626Smrg 150681f79626Smrg if (!R128PreInitGamma(pScrn)) { 150781f79626Smrg return FALSE; 150881f79626Smrg } 1509c582b7e3Smrg 1510c582b7e3Smrg if (pScrn->numEntities != 1) return FALSE; 1511c582b7e3Smrg 1512c582b7e3Smrg if (!R128GetRec(pScrn)) return FALSE; 1513c582b7e3Smrg 1514b3ff493bSmrg info = R128PTR(pScrn); 1515c582b7e3Smrg info->SwitchingMode = FALSE; 1516b3ff493bSmrg info->MMIO = NULL; 1517c582b7e3Smrg 1518b3ff493bSmrg info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1519c582b7e3Smrg if (info->pEnt->location.type != BUS_PCI) goto fail; 1520c582b7e3Smrg 1521b3ff493bSmrg info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); 1522c582b7e3Smrg 1523c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1524c582b7e3Smrg "PCI bus %d card %d func %d\n", 1525c582b7e3Smrg PCI_DEV_BUS(info->PciInfo), 1526c582b7e3Smrg PCI_DEV_DEV(info->PciInfo), 1527c582b7e3Smrg PCI_DEV_FUNC(info->PciInfo)); 1528c582b7e3Smrg 1529e1efbb8aSmacallan#ifdef __NetBSD__ 1530e1efbb8aSmacallan /* now check if this is the console */ 1531e1efbb8aSmacallan info->HaveWSDisplay = FALSE; 1532e1efbb8aSmacallan info->HaveBacklightControl = FALSE; 1533a4470643Smrg if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GET_BUSID, &bid) != -1) { 1534e1efbb8aSmacallan if ((bid.bus_type == WSDISPLAYIO_BUS_PCI) && 1535e1efbb8aSmacallan (bid.ubus.pci.bus == PCI_DEV_BUS(info->PciInfo)) && 1536e1efbb8aSmacallan (bid.ubus.pci.device == PCI_DEV_DEV(info->PciInfo)) && 1537e1efbb8aSmacallan (bid.ubus.pci.function == PCI_DEV_FUNC(info->PciInfo))) { 1538e1efbb8aSmacallan struct wsdisplay_param p; 1539e1efbb8aSmacallan xf86Msg(X_INFO, "Alright, this is the console\n"); 1540e1efbb8aSmacallan info->HaveWSDisplay = TRUE; 1541e1efbb8aSmacallan 1542e1efbb8aSmacallan /* now see if we have hacklight control */ 1543e1efbb8aSmacallan p.param = WSDISPLAYIO_PARAM_BACKLIGHT; 1544a4470643Smrg if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, &p) != -1) { 1545e1efbb8aSmacallan xf86Msg(X_INFO, "... and we have backlight control\n"); 1546e1efbb8aSmacallan info->HaveBacklightControl = TRUE; 1547e1efbb8aSmacallan } 1548e1efbb8aSmacallan } 1549e1efbb8aSmacallan } 1550e1efbb8aSmacallan#endif 1551e1efbb8aSmacallan 155219019ffeSmrg#ifndef XSERVER_LIBPCIACCESS 1553b3ff493bSmrg info->PciTag = pciTag(PCI_DEV_BUS(info->PciInfo), 1554b3ff493bSmrg PCI_DEV_DEV(info->PciInfo), 1555b3ff493bSmrg PCI_DEV_FUNC(info->PciInfo)); 1556b3ff493bSmrg 1557c582b7e3Smrg if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; 1558c582b7e3Smrg if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail; 1559c582b7e3Smrg 1560b3ff493bSmrg pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; 156119019ffeSmrg#endif 1562b3ff493bSmrg 156381f79626Smrg info->fifo_slots = 0; 156481f79626Smrg info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); 156581f79626Smrg info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; 156681f79626Smrg info->CurrentLayout.depth = pScrn->depth; 156781f79626Smrg info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; 156881f79626Smrg info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 156981f79626Smrg ? pScrn->bitsPerPixel 157081f79626Smrg : pScrn->depth); 1571c582b7e3Smrg 157281f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 157381f79626Smrg "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", 157481f79626Smrg pScrn->depth, 157581f79626Smrg info->CurrentLayout.pixel_bytes, 157681f79626Smrg info->CurrentLayout.pixel_bytes > 1 ? "s" : "", 157781f79626Smrg info->pix24bpp); 1578c582b7e3Smrg 1579c582b7e3Smrg /* We can't do this until we have a 1580c582b7e3Smrg pScrn->display. */ 1581c582b7e3Smrg xf86CollectOptions(pScrn, NULL); 158284354367Smrg if (!(info->Options = malloc(sizeof(R128Options)))) goto fail; 1583c582b7e3Smrg memcpy(info->Options, R128Options, sizeof(R128Options)); 1584c582b7e3Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); 1585c582b7e3Smrg 158681f79626Smrg info->noAccel = FALSE; 158781f79626Smrg info->accelOn = FALSE; 1588c582b7e3Smrg 158981f79626Smrg info->useEXA = FALSE; 159081f79626Smrg#ifdef USE_EXA 159181f79626Smrg info->useEXA = TRUE; 1592c582b7e3Smrg#endif 1593c582b7e3Smrg 159481f79626Smrg info->swCursor = FALSE; 159581f79626Smrg 159681f79626Smrg r128AcquireOption(pScrn); 159781f79626Smrg 1598c582b7e3Smrg if (!R128PreInitWeight(pScrn)) goto fail; 1599c582b7e3Smrg 160081f79626Smrg /* Allocate an xf86CrtcConfig */ 160181f79626Smrg xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs); 1602c582b7e3Smrg 160381f79626Smrg R128LegacyMS(pScrn); 160481f79626Smrg 160581f79626Smrg if (!xf86InitialConfiguration(pScrn, TRUE)) { 160681f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); 160781f79626Smrg goto fail; 1608c582b7e3Smrg } 160981f79626Smrg pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; 1610b3ff493bSmrg 1611b3ff493bSmrg /* Set display resolution */ 1612b3ff493bSmrg xf86SetDpi(pScrn, 0, 0); 1613b3ff493bSmrg 1614b3ff493bSmrg /* Get ScreenInit function */ 1615b3ff493bSmrg if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; 1616b3ff493bSmrg 161781f79626Smrg R128PreInitAccel(pScrn); 1618c582b7e3Smrg 1619b3ff493bSmrg info->CurrentLayout.displayWidth = pScrn->displayWidth; 1620b3ff493bSmrg 1621b3ff493bSmrg if (!xf86RandR12PreInit(pScrn)) { 1622b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); 1623b3ff493bSmrg goto fail; 1624b3ff493bSmrg } 1625b3ff493bSmrg 1626b3ff493bSmrg if (pScrn->modes == NULL) { 1627b3ff493bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 1628b3ff493bSmrg goto fail; 1629b3ff493bSmrg } 1630b3ff493bSmrg 1631c582b7e3Smrg /* Free the video bios (if applicable) */ 1632c582b7e3Smrg if (info->VBIOS) { 163384354367Smrg free(info->VBIOS); 1634c582b7e3Smrg info->VBIOS = NULL; 1635c582b7e3Smrg } 1636c582b7e3Smrg 1637b3ff493bSmrg if (info->MMIO) R128UnmapMMIO(pScrn); 1638b3ff493bSmrg info->MMIO = NULL; 1639b3ff493bSmrg 1640c582b7e3Smrg return TRUE; 1641c582b7e3Smrg 1642c582b7e3Smrg fail: 1643c582b7e3Smrg /* Pre-init failed. */ 1644c582b7e3Smrg 1645c582b7e3Smrg /* Free the video bios (if applicable) */ 1646c582b7e3Smrg if (info->VBIOS) { 164784354367Smrg free(info->VBIOS); 1648c582b7e3Smrg info->VBIOS = NULL; 1649c582b7e3Smrg } 1650c582b7e3Smrg 1651c582b7e3Smrg#ifdef WITH_VGAHW 1652c582b7e3Smrg if (info->VGAAccess) 1653c582b7e3Smrg vgaHWFreeHWRec(pScrn); 1654c582b7e3Smrg#endif 1655b3ff493bSmrg 1656b3ff493bSmrg if (info->MMIO) R128UnmapMMIO(pScrn); 1657b3ff493bSmrg info->MMIO = NULL; 1658b3ff493bSmrg 1659c582b7e3Smrg R128FreeRec(pScrn); 1660c582b7e3Smrg return FALSE; 1661c582b7e3Smrg} 1662c582b7e3Smrg 1663c582b7e3Smrg/* Load a palette. */ 1664c582b7e3Smrgstatic void R128LoadPalette(ScrnInfoPtr pScrn, int numColors, 1665c582b7e3Smrg int *indices, LOCO *colors, VisualPtr pVisual) 1666c582b7e3Smrg{ 1667c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1668b3ff493bSmrg xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1669b3ff493bSmrg int i, j; 1670b3ff493bSmrg int c, index; 1671b3ff493bSmrg uint16_t lut_r[256], lut_g[256], lut_b[256]; 1672b3ff493bSmrg 1673b3ff493bSmrg for (c = 0; c < xf86_config->num_crtc; c++) { 1674b3ff493bSmrg xf86CrtcPtr crtc = xf86_config->crtc[c]; 1675b3ff493bSmrg R128CrtcPrivatePtr r128_crtc = crtc->driver_private; 1676b3ff493bSmrg 1677b3ff493bSmrg for (i = 0 ; i < 256; i++) { 1678b3ff493bSmrg lut_r[i] = r128_crtc->lut_r[i] << 8; 1679b3ff493bSmrg lut_g[i] = r128_crtc->lut_g[i] << 8; 1680b3ff493bSmrg lut_b[i] = r128_crtc->lut_b[i] << 8; 1681b3ff493bSmrg } 1682c582b7e3Smrg 1683b3ff493bSmrg switch (info->CurrentLayout.depth) { 1684b3ff493bSmrg case 15: 1685b3ff493bSmrg for (i = 0; i < numColors; i++) { 1686b3ff493bSmrg index = indices[i]; 1687b3ff493bSmrg for (j = 0; j < 8; j++) { 1688b3ff493bSmrg lut_r[index * 8 + j] = colors[index].red << 8; 1689b3ff493bSmrg lut_g[index * 8 + j] = colors[index].green << 8; 1690b3ff493bSmrg lut_b[index * 8 + j] = colors[index].blue << 8; 1691b3ff493bSmrg } 1692b3ff493bSmrg } 1693b3ff493bSmrg case 16: 1694b3ff493bSmrg for (i = 0; i < numColors; i++) { 1695b3ff493bSmrg index = indices[i]; 1696b3ff493bSmrg 1697b3ff493bSmrg /* XXX: The old version of R128LoadPalette did not do this and 1698b3ff493bSmrg * the old version of RADEONLoadPalette has a comment asking why. 1699b3ff493bSmrg */ 1700b3ff493bSmrg if (i <= 31) { 1701b3ff493bSmrg for (j = 0; j < 8; j++) { 1702b3ff493bSmrg lut_r[index * 8 + j] = colors[index].red << 8; 1703b3ff493bSmrg lut_b[index * 8 + j] = colors[index].blue << 8; 1704b3ff493bSmrg } 1705b3ff493bSmrg } 1706c582b7e3Smrg 1707b3ff493bSmrg for (j = 0; j < 4; j++) { 1708b3ff493bSmrg lut_g[index * 4 + j] = colors[index].green << 8; 1709b3ff493bSmrg } 1710b3ff493bSmrg } 1711b3ff493bSmrg default: 1712b3ff493bSmrg for (i = 0; i < numColors; i++) { 1713b3ff493bSmrg index = indices[i]; 1714b3ff493bSmrg lut_r[index] = colors[index].red << 8; 1715b3ff493bSmrg lut_g[index] = colors[index].green << 8; 1716b3ff493bSmrg lut_b[index] = colors[index].blue << 8; 1717b3ff493bSmrg } 1718b3ff493bSmrg break; 1719b3ff493bSmrg } 1720c582b7e3Smrg 1721b3ff493bSmrg /* Make the change through RandR */ 1722b3ff493bSmrg#ifdef RANDR_12_INTERFACE 1723b3ff493bSmrg if (crtc->randr_crtc) 1724b3ff493bSmrg RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 1725b3ff493bSmrg else 1726b3ff493bSmrg#endif 1727b3ff493bSmrg crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 1728c582b7e3Smrg } 1729c582b7e3Smrg} 1730c582b7e3Smrg 1731c582b7e3Smrgstatic void 173284354367SmrgR128BlockHandler(BLOCKHANDLER_ARGS_DECL) 1733c582b7e3Smrg{ 173484354367Smrg SCREEN_PTR(arg); 173584354367Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1736c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1737c582b7e3Smrg 173884354367Smrg#ifdef R128DRI 1739c582b7e3Smrg if (info->directRenderingEnabled) 1740c582b7e3Smrg FLUSH_RING(); 1741c582b7e3Smrg#endif 1742c582b7e3Smrg 1743c582b7e3Smrg pScreen->BlockHandler = info->BlockHandler; 174484354367Smrg (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 1745c582b7e3Smrg pScreen->BlockHandler = R128BlockHandler; 1746c582b7e3Smrg 1747c582b7e3Smrg if(info->VideoTimerCallback) { 1748c582b7e3Smrg (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds); 1749c582b7e3Smrg } 1750c582b7e3Smrg} 1751c582b7e3Smrg 1752c582b7e3Smrg/* Called at the start of each server generation. */ 175384354367SmrgBool R128ScreenInit(SCREEN_INIT_ARGS_DECL) 1754c582b7e3Smrg{ 175584354367Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1756c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1757c582b7e3Smrg BoxRec MemBox; 175884354367Smrg int width_bytes = (pScrn->displayWidth * 175981f79626Smrg info->CurrentLayout.pixel_bytes); 176081f79626Smrg int scanlines; 176181f79626Smrg int total = info->FbMapSize; 176281f79626Smrg FBAreaPtr fbarea = NULL; 176381f79626Smrg#ifdef R128DRI 176481f79626Smrg int cpp = info->CurrentLayout.pixel_bytes; 176581f79626Smrg int x1 = 0, x2 = 0, y1 = 0, y2 = 0; 176684354367Smrg#ifdef USE_EXA 176784354367Smrg ExaOffscreenArea* osArea = NULL; 176881f79626Smrg#endif /* USE_EXA */ 176981f79626Smrg#endif /* R128DRI */ 177084354367Smrg 177181f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 177281f79626Smrg "%s %lx %lx\n", 177381f79626Smrg __func__, 177481f79626Smrg pScrn->memPhysBase, pScrn->fbOffset)); 1775c582b7e3Smrg 177684354367Smrg#ifdef R128DRI 1777c582b7e3Smrg /* Turn off the CCE for now. */ 1778c582b7e3Smrg info->CCEInUse = FALSE; 1779c582b7e3Smrg info->indirectBuffer = NULL; 1780c582b7e3Smrg#endif 1781c582b7e3Smrg 1782c582b7e3Smrg if (!R128MapMem(pScrn)) return FALSE; 1783c582b7e3Smrg pScrn->fbOffset = 0; 1784b3ff493bSmrg //if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024; 178584354367Smrg#ifdef R128DRI 1786c582b7e3Smrg info->fbX = 0; 1787c582b7e3Smrg info->fbY = 0; 1788c582b7e3Smrg info->frontOffset = 0; 1789c582b7e3Smrg info->frontPitch = pScrn->displayWidth; 1790c582b7e3Smrg#endif 1791c582b7e3Smrg 1792c582b7e3Smrg info->PaletteSavedOnVT = FALSE; 1793c582b7e3Smrg 1794c582b7e3Smrg R128Save(pScrn); 1795c582b7e3Smrg 1796c582b7e3Smrg /* Visual setup */ 1797c582b7e3Smrg miClearVisualTypes(); 1798c582b7e3Smrg if (!miSetVisualTypes(pScrn->depth, 1799c582b7e3Smrg miGetDefaultVisualMask(pScrn->depth), 1800c582b7e3Smrg pScrn->rgbBits, 1801c582b7e3Smrg pScrn->defaultVisual)) return FALSE; 1802c582b7e3Smrg miSetPixmapDepths (); 1803c582b7e3Smrg 180484354367Smrg#ifdef R128DRI 1805c582b7e3Smrg /* Setup DRI after visuals have been 1806c582b7e3Smrg established, but before fbScreenInit is 180781f79626Smrg called. */ 1808c582b7e3Smrg { 1809c582b7e3Smrg /* FIXME: When we move to dynamic allocation of back and depth 1810c582b7e3Smrg buffers, we will want to revisit the following check for 3 1811c582b7e3Smrg times the virtual size of the screen below. */ 1812c582b7e3Smrg int maxy = info->FbMapSize / width_bytes; 1813c582b7e3Smrg 181481f79626Smrg if (info->noAccel) { 181584354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1816c582b7e3Smrg "Acceleration disabled, not initializing the DRI\n"); 1817c582b7e3Smrg info->directRenderingEnabled = FALSE; 1818c582b7e3Smrg } else if (maxy <= pScrn->virtualY * 3) { 181984354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1820c582b7e3Smrg "Static buffer allocation failed -- " 1821c582b7e3Smrg "need at least %d kB video memory\n", 1822c582b7e3Smrg (pScrn->displayWidth * pScrn->virtualY * 1823c582b7e3Smrg info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); 1824c582b7e3Smrg info->directRenderingEnabled = FALSE; 1825c582b7e3Smrg } else { 1826b3ff493bSmrg info->directRenderingEnabled = R128DRIScreenInit(pScreen); 1827c582b7e3Smrg } 1828c582b7e3Smrg } 1829c582b7e3Smrg#endif 1830c582b7e3Smrg 1831c582b7e3Smrg if (!fbScreenInit (pScreen, info->FB, 1832c582b7e3Smrg pScrn->virtualX, pScrn->virtualY, 1833c582b7e3Smrg pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, 1834c582b7e3Smrg pScrn->bitsPerPixel)) 1835c582b7e3Smrg return FALSE; 1836c582b7e3Smrg 1837c582b7e3Smrg xf86SetBlackWhitePixels(pScreen); 1838c582b7e3Smrg 1839c582b7e3Smrg if (pScrn->bitsPerPixel > 8) { 1840c582b7e3Smrg VisualPtr visual; 1841c582b7e3Smrg 1842c582b7e3Smrg visual = pScreen->visuals + pScreen->numVisuals; 1843c582b7e3Smrg while (--visual >= pScreen->visuals) { 1844c582b7e3Smrg if ((visual->class | DynamicClass) == DirectColor) { 1845c582b7e3Smrg visual->offsetRed = pScrn->offset.red; 1846c582b7e3Smrg visual->offsetGreen = pScrn->offset.green; 1847c582b7e3Smrg visual->offsetBlue = pScrn->offset.blue; 1848c582b7e3Smrg visual->redMask = pScrn->mask.red; 1849c582b7e3Smrg visual->greenMask = pScrn->mask.green; 1850c582b7e3Smrg visual->blueMask = pScrn->mask.blue; 1851c582b7e3Smrg } 1852c582b7e3Smrg } 1853c582b7e3Smrg } 1854c582b7e3Smrg 1855c582b7e3Smrg /* must be after RGB order fixed */ 1856c582b7e3Smrg fbPictureInit (pScreen, 0, 0); 1857c582b7e3Smrg 1858c582b7e3Smrg /* Memory manager setup */ 185984354367Smrg#ifdef R128DRI 1860c582b7e3Smrg if (info->directRenderingEnabled) { 1861c582b7e3Smrg int bufferSize = pScrn->virtualY * width_bytes; 186281f79626Smrg int l; 1863c582b7e3Smrg 1864c582b7e3Smrg switch (info->CCEMode) { 1865c582b7e3Smrg case R128_DEFAULT_CCE_PIO_MODE: 1866c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); 1867c582b7e3Smrg break; 1868c582b7e3Smrg case R128_DEFAULT_CCE_BM_MODE: 1869c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); 1870c582b7e3Smrg break; 1871c582b7e3Smrg default: 1872c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); 1873c582b7e3Smrg break; 1874c582b7e3Smrg } 1875c582b7e3Smrg 1876c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1877c582b7e3Smrg "Using %d MB AGP aperture\n", info->agpSize); 1878c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1879c582b7e3Smrg "Using %d MB for the ring buffer\n", info->ringSize); 1880c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1881c582b7e3Smrg "Using %d MB for vertex/indirect buffers\n", info->bufSize); 1882c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1883c582b7e3Smrg "Using %d MB for AGP textures\n", info->agpTexSize); 1884c582b7e3Smrg 1885c582b7e3Smrg /* Try for front, back, depth, and two framebuffers worth of 1886c582b7e3Smrg * pixmap cache. Should be enough for a fullscreen background 1887c582b7e3Smrg * image plus some leftovers. 1888c582b7e3Smrg */ 1889c582b7e3Smrg info->textureSize = info->FbMapSize - 5 * bufferSize; 1890c582b7e3Smrg 1891c582b7e3Smrg /* If that gives us less than half the available memory, let's 1892c582b7e3Smrg * be greedy and grab some more. Sorry, I care more about 3D 1893c582b7e3Smrg * performance than playing nicely, and you'll get around a full 1894c582b7e3Smrg * framebuffer's worth of pixmap cache anyway. 1895c582b7e3Smrg */ 1896c582b7e3Smrg if (info->textureSize < (int)info->FbMapSize / 2) { 1897c582b7e3Smrg info->textureSize = info->FbMapSize - 4 * bufferSize; 1898c582b7e3Smrg } 1899c582b7e3Smrg 1900c582b7e3Smrg if (info->textureSize > 0) { 1901c582b7e3Smrg l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); 1902c582b7e3Smrg if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; 1903c582b7e3Smrg 1904c582b7e3Smrg /* Round the texture size up to the nearest whole number of 1905c582b7e3Smrg * texture regions. Again, be greedy about this, don't 1906c582b7e3Smrg * round down. 1907c582b7e3Smrg */ 1908c582b7e3Smrg info->log2TexGran = l; 1909c582b7e3Smrg info->textureSize = (info->textureSize >> l) << l; 1910c582b7e3Smrg } else { 1911c582b7e3Smrg info->textureSize = 0; 1912c582b7e3Smrg } 1913c582b7e3Smrg 1914c582b7e3Smrg /* Set a minimum usable local texture heap size. This will fit 1915c582b7e3Smrg * two 256x256x32bpp textures. 1916c582b7e3Smrg */ 1917c582b7e3Smrg if (info->textureSize < 512 * 1024) { 1918c582b7e3Smrg info->textureOffset = 0; 1919c582b7e3Smrg info->textureSize = 0; 1920c582b7e3Smrg } 1921c582b7e3Smrg 192281f79626Smrg total = info->FbMapSize - info->textureSize; 192381f79626Smrg } 192481f79626Smrg#endif /* R128DRI */ 1925c582b7e3Smrg 192681f79626Smrg scanlines = total / width_bytes; 192781f79626Smrg if (scanlines > 8191) scanlines = 8191; 192881f79626Smrg 192981f79626Smrg#ifdef R128DRI 193081f79626Smrg if (info->directRenderingEnabled) 193181f79626Smrg /* 1932e8b4ed9fSmrg * Recalculate the texture offset and size to accommodate any 193381f79626Smrg * rounding to a whole number of scanlines. 193481f79626Smrg */ 193581f79626Smrg info->textureOffset = scanlines * width_bytes; 193681f79626Smrg#endif /* R128DRI */ 1937c582b7e3Smrg 193881f79626Smrg MemBox.x1 = 0; 193981f79626Smrg MemBox.y1 = 0; 194081f79626Smrg MemBox.x2 = pScrn->displayWidth; 194181f79626Smrg MemBox.y2 = scanlines; 1942c582b7e3Smrg 194384354367Smrg if (!info->useEXA) { 194484354367Smrg if (!xf86InitFBManager(pScreen, &MemBox)) { 194584354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 194684354367Smrg "Memory manager initialization to (%d,%d) (%d,%d) failed\n", 194784354367Smrg MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); 194884354367Smrg return FALSE; 1949c582b7e3Smrg } else { 195084354367Smrg int width, height; 195184354367Smrg 195284354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 195384354367Smrg "Memory manager initialized to (%d,%d) (%d,%d)\n", 195484354367Smrg MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); 195584354367Smrg if ((fbarea = xf86AllocateOffscreenArea(pScreen, 195684354367Smrg pScrn->displayWidth, 195784354367Smrg 2, 0, NULL, NULL, NULL))) { 195884354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 195984354367Smrg "Reserved area from (%d,%d) to (%d,%d)\n", 196084354367Smrg fbarea->box.x1, fbarea->box.y1, 196184354367Smrg fbarea->box.x2, fbarea->box.y2); 196284354367Smrg } else { 196384354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve area\n"); 196484354367Smrg } 196584354367Smrg if (xf86QueryLargestOffscreenArea(pScreen, &width, 196684354367Smrg &height, 0, 0, 0)) { 196784354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 196884354367Smrg "Largest offscreen area available: %d x %d\n", 196984354367Smrg width, height); 197084354367Smrg } 197184354367Smrg 197281f79626Smrg if (!info->noAccel) { 197381f79626Smrg if (R128XAAAccelInit(pScreen)) { 197481f79626Smrg info->accelOn = TRUE; 197581f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 197681f79626Smrg "XAA acceleration enabled.\n"); 197781f79626Smrg } else { 197881f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 197981f79626Smrg "Acceleration disabled.\n"); 198081f79626Smrg } 198181f79626Smrg } 198281f79626Smrg } 198381f79626Smrg } 198484354367Smrg#ifdef USE_EXA 198581f79626Smrg else { 198681f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 198781f79626Smrg "Filling in EXA memory info\n"); 198884354367Smrg 198984354367Smrg 199081f79626Smrg /* 199181f79626Smrg * Don't give EXA the true full memory size, because 199281f79626Smrg * the textureSize sized chunk on the end is handled 199381f79626Smrg * by DRI. 199481f79626Smrg */ 199581f79626Smrg if (R128EXAInit(pScreen, total)) { 199681f79626Smrg info->accelOn = TRUE; 199781f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 199881f79626Smrg "EXA Acceleration enabled.\n"); 199981f79626Smrg } else { 200081f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 200181f79626Smrg "EXA Acceleration initialization " 200281f79626Smrg "failed.\n"); 200381f79626Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 200481f79626Smrg "Acceleration disabled.\n"); 200581f79626Smrg } 200681f79626Smrg } 200784354367Smrg#endif 2008c582b7e3Smrg 200981f79626Smrg#ifdef R128DRI 201081f79626Smrg if (info->directRenderingEnabled) { 2011c582b7e3Smrg /* Allocate the shared back buffer */ 201284354367Smrg if(!info->useEXA) { 201384354367Smrg fbarea = xf86AllocateOffscreenArea(pScreen, 201484354367Smrg pScrn->virtualX, 201584354367Smrg pScrn->virtualY, 201684354367Smrg 32, NULL, NULL, NULL); 201784354367Smrg 201884354367Smrg if (fbarea) { 201984354367Smrg x1 = fbarea->box.x1; 202084354367Smrg x2 = fbarea->box.x2; 202184354367Smrg y1 = fbarea->box.y1; 202284354367Smrg y2 = fbarea->box.y2; 202384354367Smrg } 202484354367Smrg } 202584354367Smrg#ifdef USE_EXA 202684354367Smrg else { 202784354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 202884354367Smrg "Actually trying an EXA allocation...\n"); 202984354367Smrg osArea = exaOffscreenAlloc(pScreen, 203084354367Smrg pScrn->virtualY * width_bytes, 203184354367Smrg 32, TRUE, NULL, NULL); 203284354367Smrg 203384354367Smrg if (osArea) { 203484354367Smrg x1 = osArea->offset % width_bytes; 203584354367Smrg x2 = (osArea->offset + osArea->size) % width_bytes; 203684354367Smrg y1 = osArea->offset / width_bytes; 203784354367Smrg y2 = (osArea->offset + osArea->size) / width_bytes; 203884354367Smrg 203984354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Went swimmingly...\n"); 204084354367Smrg } 204184354367Smrg } 204284354367Smrg#endif 204384354367Smrg 204484354367Smrg if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) { 204584354367Smrg /* info->backOffset = y1 * width_bytes + x1 * cpp; */ 204684354367Smrg info->backOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16); 204784354367Smrg info->backX = info->backOffset % width_bytes; 204884354367Smrg info->backY = info->backOffset / width_bytes; 2049c582b7e3Smrg info->backPitch = pScrn->displayWidth; 205084354367Smrg 205184354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 205284354367Smrg "Reserved back buffer from (%d,%d) to (%d,%d) offset: %x\n", 205384354367Smrg x1, y1, 205484354367Smrg x2, y2, info->backOffset); 2055c582b7e3Smrg } else { 205684354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); 2057c582b7e3Smrg info->backX = -1; 2058c582b7e3Smrg info->backY = -1; 2059c582b7e3Smrg info->backOffset = -1; 2060c582b7e3Smrg info->backPitch = -1; 2061c582b7e3Smrg } 2062c582b7e3Smrg 2063c582b7e3Smrg /* Allocate the shared depth buffer */ 206484354367Smrg if(!info->useEXA) { 206584354367Smrg fbarea = xf86AllocateOffscreenArea(pScreen, 206684354367Smrg pScrn->virtualX, 206784354367Smrg pScrn->virtualY + 1, 206884354367Smrg 32, NULL, NULL, NULL); 206984354367Smrg if (fbarea) { 207084354367Smrg x1 = fbarea->box.x1; 207184354367Smrg x2 = fbarea->box.x2; 207284354367Smrg y1 = fbarea->box.y1; 207384354367Smrg y2 = fbarea->box.y2; 207484354367Smrg } 207584354367Smrg } 207684354367Smrg#ifdef USE_EXA 207784354367Smrg else { 207884354367Smrg osArea = exaOffscreenAlloc(pScreen, 207984354367Smrg (pScrn->virtualY + 1) * width_bytes, 208084354367Smrg 32, TRUE, NULL, NULL); 208184354367Smrg 208284354367Smrg if (osArea) { 208384354367Smrg x1 = osArea->offset % width_bytes; 208484354367Smrg x2 = (osArea->offset + osArea->size) % width_bytes; 208584354367Smrg y1 = osArea->offset / width_bytes; 208684354367Smrg y2 = (osArea->offset + osArea->size) / width_bytes; 208784354367Smrg } 208884354367Smrg } 208984354367Smrg#endif 209084354367Smrg 209184354367Smrg if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) { 209284354367Smrg /* info->depthOffset = y1 * width_bytes + x1 * cpp; */ 209384354367Smrg info->depthOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16); 209484354367Smrg info->depthX = info->depthOffset % width_bytes; 209584354367Smrg info->depthY = info->depthOffset / width_bytes; 2096c582b7e3Smrg info->depthPitch = pScrn->displayWidth; 209784354367Smrg info->spanOffset = (y2 - 1) * width_bytes + x1 * cpp; 209884354367Smrg 209984354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 210084354367Smrg "Reserved depth buffer from (%d,%d) to (%d,%d) offset: %x\n", 210184354367Smrg x1, y1, 210284354367Smrg x2, y2, info->depthOffset); 210384354367Smrg 210484354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2105c582b7e3Smrg "Reserved depth span from (%d,%d) offset 0x%x\n", 210684354367Smrg x1, y2 - 1, info->spanOffset); 2107c582b7e3Smrg } else { 210884354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); 2109c582b7e3Smrg info->depthX = -1; 2110c582b7e3Smrg info->depthY = -1; 2111c582b7e3Smrg info->depthOffset = -1; 2112c582b7e3Smrg info->depthPitch = -1; 2113c582b7e3Smrg info->spanOffset = -1; 2114c582b7e3Smrg } 2115c582b7e3Smrg 211684354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2117c582b7e3Smrg "Reserved %d kb for textures at offset 0x%x\n", 2118c582b7e3Smrg info->textureSize/1024, info->textureOffset); 2119c582b7e3Smrg } 212084354367Smrg#endif /* R128DRI */ 2121c582b7e3Smrg 2122b3ff493bSmrg pScrn->vtSema = TRUE; 2123b3ff493bSmrg /* xf86CrtcRotate accesses pScrn->pScreen */ 2124b3ff493bSmrg pScrn->pScreen = pScreen; 2125b3ff493bSmrg 21263c921f55Smrg#ifndef AVOID_FBDEV 2127b3ff493bSmrg if (info->FBDev) { 2128b3ff493bSmrg if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; 2129b3ff493bSmrg } else { 21303c921f55Smrg#endif 2131b3ff493bSmrg if (!xf86SetDesiredModes(pScrn)) return FALSE; 21323c921f55Smrg#ifndef AVOID_FBDEV 2133b3ff493bSmrg } 21343c921f55Smrg#endif 2135b3ff493bSmrg 2136b3ff493bSmrg R128SaveScreen(pScreen, SCREEN_SAVER_ON); 2137b3ff493bSmrg //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 2138b3ff493bSmrg 2139c582b7e3Smrg /* DGA setup */ 2140b3ff493bSmrg#ifdef XFreeXDGA 2141b3ff493bSmrg xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); 2142b3ff493bSmrg#endif 2143c582b7e3Smrg 2144c582b7e3Smrg /* Backing store setup */ 2145c582b7e3Smrg xf86SetBackingStore(pScreen); 2146c582b7e3Smrg 2147c582b7e3Smrg /* Set Silken Mouse */ 2148c582b7e3Smrg xf86SetSilkenMouse(pScreen); 2149c582b7e3Smrg 2150c582b7e3Smrg /* Cursor setup */ 2151c582b7e3Smrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 2152c582b7e3Smrg 2153c582b7e3Smrg /* Hardware cursor setup */ 215481f79626Smrg if (!info->swCursor) { 2155c582b7e3Smrg if (R128CursorInit(pScreen)) { 2156c582b7e3Smrg int width, height; 2157c582b7e3Smrg 2158c582b7e3Smrg if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 2159c582b7e3Smrg 0, 0, 0)) { 216084354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2161c582b7e3Smrg "Largest offscreen area available: %d x %d\n", 2162c582b7e3Smrg width, height); 2163c582b7e3Smrg } 2164c582b7e3Smrg } else { 216584354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2166c582b7e3Smrg "Hardware cursor initialization failed\n"); 216784354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n"); 2168c582b7e3Smrg } 2169c582b7e3Smrg } else { 217084354367Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n"); 2171c582b7e3Smrg } 2172c582b7e3Smrg 2173c582b7e3Smrg /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */ 217479e5230eSmacallan#ifndef AVOID_FBDEV 2175c582b7e3Smrg if (info->FBDev) 2176c582b7e3Smrg xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0); 2177b3ff493bSmrg else 217879e5230eSmacallan#endif 21793c921f55Smrg xf86DPMSInit(pScreen, xf86DPMSSet, 0); 2180c582b7e3Smrg 21813c921f55Smrg R128InitVideo(pScreen); 2182c582b7e3Smrg 2183c582b7e3Smrg /* Provide SaveScreen */ 2184c582b7e3Smrg pScreen->SaveScreen = R128SaveScreen; 2185c582b7e3Smrg 2186c582b7e3Smrg /* Wrap CloseScreen */ 2187c582b7e3Smrg info->CloseScreen = pScreen->CloseScreen; 2188c582b7e3Smrg pScreen->CloseScreen = R128CloseScreen; 2189c582b7e3Smrg 2190c582b7e3Smrg /* Note unused options */ 2191c582b7e3Smrg if (serverGeneration == 1) 2192c582b7e3Smrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 2193c582b7e3Smrg 219484354367Smrg#ifdef R128DRI 2195c582b7e3Smrg /* DRI finalization */ 2196c582b7e3Smrg if (info->directRenderingEnabled) { 2197c582b7e3Smrg /* Now that mi, fb, drm and others have 2198c582b7e3Smrg done their thing, complete the DRI 2199c582b7e3Smrg setup. */ 2200c582b7e3Smrg info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen); 2201c582b7e3Smrg } 2202c582b7e3Smrg if (info->directRenderingEnabled) { 2203c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 2204c582b7e3Smrg } else { 2205c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2206c582b7e3Smrg "Direct rendering disabled\n"); 2207c582b7e3Smrg } 2208c582b7e3Smrg#endif 2209c582b7e3Smrg 2210c582b7e3Smrg info->BlockHandler = pScreen->BlockHandler; 2211c582b7e3Smrg pScreen->BlockHandler = R128BlockHandler; 2212c582b7e3Smrg 2213b3ff493bSmrg if (!xf86CrtcScreenInit(pScreen)) return FALSE; 2214b3ff493bSmrg 2215b3ff493bSmrg /* Colormap setup */ 2216b3ff493bSmrg if (!miCreateDefColormap(pScreen)) return FALSE; 2217b3ff493bSmrg if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, 2218b3ff493bSmrg ( 2219b3ff493bSmrg#ifndef AVOID_FBDEV 2220b3ff493bSmrg info->FBDev ? fbdevHWLoadPaletteWeak() : 2221b3ff493bSmrg#endif 2222b3ff493bSmrg R128LoadPalette), NULL, 2223b3ff493bSmrg CMAP_PALETTED_TRUECOLOR 2224b3ff493bSmrg | CMAP_RELOAD_ON_MODE_SWITCH 2225b3ff493bSmrg#if 0 /* This option messes up text mode! (eich@suse.de) */ 2226b3ff493bSmrg | CMAP_LOAD_EVEN_IF_OFFSCREEN 2227b3ff493bSmrg#endif 2228b3ff493bSmrg )) return FALSE; 2229b3ff493bSmrg 2230c582b7e3Smrg return TRUE; 2231c582b7e3Smrg} 2232c582b7e3Smrg 2233c582b7e3Smrg/* Write common registers (initialized to 0). */ 2234b3ff493bSmrgvoid R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2235c582b7e3Smrg{ 2236c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2237c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2238c582b7e3Smrg 2239c582b7e3Smrg OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl | R128_FP_BLANK_DIS); 2240c582b7e3Smrg 2241c582b7e3Smrg OUTREG(R128_OVR_CLR, restore->ovr_clr); 2242c582b7e3Smrg OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); 2243c582b7e3Smrg OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); 2244c582b7e3Smrg OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); 2245c582b7e3Smrg OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); 2246c582b7e3Smrg OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); 2247c582b7e3Smrg OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); 2248c582b7e3Smrg OUTREG(R128_VIPH_CONTROL, restore->viph_control); 2249c582b7e3Smrg OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); 2250c582b7e3Smrg OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); 2251c582b7e3Smrg OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); 2252c582b7e3Smrg OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); 2253c582b7e3Smrg OUTREG(R128_BUS_CNTL, restore->bus_cntl); 2254c582b7e3Smrg OUTREG(R128_CONFIG_CNTL, restore->config_cntl); 2255c582b7e3Smrg} 2256c582b7e3Smrg 2257b3ff493bSmrg/* Write RMX registers */ 2258b3ff493bSmrgvoid R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2259c582b7e3Smrg{ 2260c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2261c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2262c582b7e3Smrg 2263c582b7e3Smrg OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); 2264c582b7e3Smrg OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); 2265c582b7e3Smrg OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); 2266c582b7e3Smrg OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); 2267c582b7e3Smrg OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); 2268c582b7e3Smrg OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); 2269b3ff493bSmrg} 2270b3ff493bSmrg 2271b3ff493bSmrg/* Write flat panel registers */ 2272b3ff493bSmrgvoid R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2273b3ff493bSmrg{ 2274b3ff493bSmrg R128InfoPtr info = R128PTR(pScrn); 2275b3ff493bSmrg unsigned char *R128MMIO = info->MMIO; 2276b3ff493bSmrg 2277b3ff493bSmrg OUTREG(R128_TMDS_CRC, restore->tmds_crc); 2278b3ff493bSmrg OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl); 2279b3ff493bSmrg OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); 2280b3ff493bSmrg OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(uint32_t)R128_FP_BLANK_DIS); 2281b3ff493bSmrg} 2282b3ff493bSmrg 2283b3ff493bSmrg/* Write LVDS registers */ 2284b3ff493bSmrgvoid R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2285b3ff493bSmrg{ 2286b3ff493bSmrg R128InfoPtr info = R128PTR(pScrn); 2287b3ff493bSmrg R128EntPtr pR128Ent = R128EntPriv(pScrn); 2288b3ff493bSmrg unsigned char *R128MMIO = info->MMIO; 2289b3ff493bSmrg uint32_t tmp; 2290c582b7e3Smrg 2291b3ff493bSmrg xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]); 2292b3ff493bSmrg R128OutputPrivatePtr r128_output = output->driver_private; 2293c582b7e3Smrg 2294c582b7e3Smrg tmp = INREG(R128_LVDS_GEN_CNTL); 2295c582b7e3Smrg if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == 2296c582b7e3Smrg (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { 2297c582b7e3Smrg OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2298c582b7e3Smrg } else { 2299c582b7e3Smrg if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { 2300c582b7e3Smrg OUTREG(R128_LVDS_GEN_CNTL, 2301b3ff493bSmrg restore->lvds_gen_cntl & (uint32_t)~R128_LVDS_BLON); 2302b3ff493bSmrg usleep(r128_output->PanelPwrDly * 1000); 2303c582b7e3Smrg OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2304c582b7e3Smrg } else { 2305c582b7e3Smrg OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON); 2306b3ff493bSmrg usleep(r128_output->PanelPwrDly * 1000); 2307c582b7e3Smrg OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2308c582b7e3Smrg } 2309c582b7e3Smrg } 2310c582b7e3Smrg} 2311c582b7e3Smrg 2312c582b7e3Smrg/* Write DDA registers. */ 2313b3ff493bSmrgvoid R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore) 2314c582b7e3Smrg{ 2315c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2316c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2317c582b7e3Smrg 2318c582b7e3Smrg OUTREG(R128_DDA_CONFIG, restore->dda_config); 2319c582b7e3Smrg OUTREG(R128_DDA_ON_OFF, restore->dda_on_off); 2320c582b7e3Smrg} 2321c582b7e3Smrg 2322c582b7e3Smrg/* Write DDA registers. */ 2323b3ff493bSmrgvoid R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore) 2324c582b7e3Smrg{ 2325c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2326c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2327c582b7e3Smrg 2328c582b7e3Smrg OUTREG(R128_DDA2_CONFIG, restore->dda2_config); 2329c582b7e3Smrg OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off); 2330c582b7e3Smrg} 2331c582b7e3Smrg 2332c582b7e3Smrg/* Read common registers. */ 2333c582b7e3Smrgstatic void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2334c582b7e3Smrg{ 2335c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2336c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2337c582b7e3Smrg 2338c582b7e3Smrg save->ovr_clr = INREG(R128_OVR_CLR); 2339c582b7e3Smrg save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); 2340c582b7e3Smrg save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); 2341c582b7e3Smrg save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); 2342c582b7e3Smrg save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); 2343c582b7e3Smrg save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); 2344c582b7e3Smrg save->subpic_cntl = INREG(R128_SUBPIC_CNTL); 2345c582b7e3Smrg save->viph_control = INREG(R128_VIPH_CONTROL); 2346c582b7e3Smrg save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); 2347c582b7e3Smrg save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); 2348c582b7e3Smrg save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); 2349c582b7e3Smrg save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); 2350c582b7e3Smrg save->bus_cntl = INREG(R128_BUS_CNTL); 2351c582b7e3Smrg save->config_cntl = INREG(R128_CONFIG_CNTL); 2352c582b7e3Smrg} 2353c582b7e3Smrg 2354c582b7e3Smrg/* Read CRTC registers. */ 2355c582b7e3Smrgstatic void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2356c582b7e3Smrg{ 2357c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2358c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2359c582b7e3Smrg 2360c582b7e3Smrg save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); 2361c582b7e3Smrg save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); 2362c582b7e3Smrg save->dac_cntl = INREG(R128_DAC_CNTL); 2363c582b7e3Smrg save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); 2364c582b7e3Smrg save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); 2365c582b7e3Smrg save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); 2366c582b7e3Smrg save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); 2367c582b7e3Smrg save->crtc_offset = INREG(R128_CRTC_OFFSET); 2368c582b7e3Smrg save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); 2369c582b7e3Smrg save->crtc_pitch = INREG(R128_CRTC_PITCH); 2370c582b7e3Smrg} 2371c582b7e3Smrg 2372c582b7e3Smrg/* Read flat panel registers */ 2373c582b7e3Smrgstatic void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2374c582b7e3Smrg{ 2375c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2376c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2377c582b7e3Smrg 2378c582b7e3Smrg save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); 2379c582b7e3Smrg save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); 2380c582b7e3Smrg save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); 2381c582b7e3Smrg save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); 2382c582b7e3Smrg save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); 2383c582b7e3Smrg save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); 2384c582b7e3Smrg save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); 2385c582b7e3Smrg save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); 2386c582b7e3Smrg save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); 2387c582b7e3Smrg save->tmds_crc = INREG(R128_TMDS_CRC); 2388c582b7e3Smrg save->tmds_transmitter_cntl = INREG(R128_TMDS_TRANSMITTER_CNTL); 2389c582b7e3Smrg} 2390c582b7e3Smrg 2391c582b7e3Smrg/* Read CRTC2 registers. */ 2392c582b7e3Smrgstatic void R128SaveCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save) 2393c582b7e3Smrg{ 2394c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2395c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2396c582b7e3Smrg 2397c582b7e3Smrg save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); 2398c582b7e3Smrg save->crtc2_h_total_disp = INREG(R128_CRTC2_H_TOTAL_DISP); 2399c582b7e3Smrg save->crtc2_h_sync_strt_wid = INREG(R128_CRTC2_H_SYNC_STRT_WID); 2400c582b7e3Smrg save->crtc2_v_total_disp = INREG(R128_CRTC2_V_TOTAL_DISP); 2401c582b7e3Smrg save->crtc2_v_sync_strt_wid = INREG(R128_CRTC2_V_SYNC_STRT_WID); 2402c582b7e3Smrg save->crtc2_offset = INREG(R128_CRTC2_OFFSET); 2403c582b7e3Smrg save->crtc2_offset_cntl = INREG(R128_CRTC2_OFFSET_CNTL); 2404c582b7e3Smrg save->crtc2_pitch = INREG(R128_CRTC2_PITCH); 2405c582b7e3Smrg} 2406c582b7e3Smrg 2407c582b7e3Smrg/* Read PLL registers. */ 2408c582b7e3Smrgstatic void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2409c582b7e3Smrg{ 2410c582b7e3Smrg save->ppll_ref_div = INPLL(pScrn, R128_PPLL_REF_DIV); 2411c582b7e3Smrg save->ppll_div_3 = INPLL(pScrn, R128_PPLL_DIV_3); 24129e881af1Smacallan save->ppll_div_0 = INPLL(pScrn, R128_PPLL_DIV_0); 2413c582b7e3Smrg save->htotal_cntl = INPLL(pScrn, R128_HTOTAL_CNTL); 2414c582b7e3Smrg 241581f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 241681f79626Smrg "Read: 0x%08x 0x%08x 0x%08x\n", 241781f79626Smrg save->ppll_ref_div, 241881f79626Smrg save->ppll_div_3, 241981f79626Smrg save->htotal_cntl)); 242081f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 242181f79626Smrg "Read: rd=%d, fd=%d, pd=%d\n", 242281f79626Smrg save->ppll_ref_div & R128_PPLL_REF_DIV_MASK, 242381f79626Smrg save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, 242481f79626Smrg (save->ppll_div_3 & 242581f79626Smrg R128_PPLL_POST3_DIV_MASK) >> 16)); 2426c582b7e3Smrg} 2427c582b7e3Smrg 2428c582b7e3Smrg/* Read PLL2 registers. */ 2429c582b7e3Smrgstatic void R128SavePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save) 2430c582b7e3Smrg{ 2431c582b7e3Smrg save->p2pll_ref_div = INPLL(pScrn, R128_P2PLL_REF_DIV); 2432c582b7e3Smrg save->p2pll_div_0 = INPLL(pScrn, R128_P2PLL_DIV_0); 2433c582b7e3Smrg save->htotal_cntl2 = INPLL(pScrn, R128_HTOTAL2_CNTL); 2434c582b7e3Smrg 243581f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 243681f79626Smrg "Read: 0x%08x 0x%08x 0x%08x\n", 243781f79626Smrg save->p2pll_ref_div, 243881f79626Smrg save->p2pll_div_0, 243981f79626Smrg save->htotal_cntl2)); 244081f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 244181f79626Smrg "Read: rd=%d, fd=%d, pd=%d\n", 244281f79626Smrg save->p2pll_ref_div & R128_P2PLL_REF_DIV_MASK, 244381f79626Smrg save->p2pll_div_0 & R128_P2PLL_FB0_DIV_MASK, 244481f79626Smrg (save->p2pll_div_0 & 244581f79626Smrg R128_P2PLL_POST0_DIV_MASK) >> 16)); 2446c582b7e3Smrg} 2447c582b7e3Smrg 2448c582b7e3Smrg/* Read DDA registers. */ 2449c582b7e3Smrgstatic void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save) 2450c582b7e3Smrg{ 2451c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2452c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2453c582b7e3Smrg 2454c582b7e3Smrg save->dda_config = INREG(R128_DDA_CONFIG); 2455c582b7e3Smrg save->dda_on_off = INREG(R128_DDA_ON_OFF); 2456c582b7e3Smrg} 2457c582b7e3Smrg 2458c582b7e3Smrg/* Read DDA2 registers. */ 2459c582b7e3Smrgstatic void R128SaveDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save) 2460c582b7e3Smrg{ 2461c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2462c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2463c582b7e3Smrg 2464c582b7e3Smrg save->dda2_config = INREG(R128_DDA2_CONFIG); 2465c582b7e3Smrg save->dda2_on_off = INREG(R128_DDA2_ON_OFF); 2466c582b7e3Smrg} 2467c582b7e3Smrg 2468c582b7e3Smrg/* Read palette data. */ 2469c582b7e3Smrgstatic void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save) 2470c582b7e3Smrg{ 2471c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2472c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2473c582b7e3Smrg int i; 2474c582b7e3Smrg 2475c582b7e3Smrg PAL_SELECT(1); 2476c582b7e3Smrg INPAL_START(0); 2477c582b7e3Smrg for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT(); 2478c582b7e3Smrg PAL_SELECT(0); 2479c582b7e3Smrg INPAL_START(0); 2480c582b7e3Smrg for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); 2481c582b7e3Smrg save->palette_valid = TRUE; 2482c582b7e3Smrg} 2483c582b7e3Smrg 2484c582b7e3Smrg/* Save state that defines current video mode. */ 2485c582b7e3Smrgstatic void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save) 2486c582b7e3Smrg{ 2487c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2488b3ff493bSmrg R128EntPtr pR128Ent = R128EntPriv(pScrn); 2489c582b7e3Smrg 249081f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 249181f79626Smrg "%s(%p)\n", __func__, save)); 2492c582b7e3Smrg 2493b3ff493bSmrg R128SaveCommonRegisters(pScrn, save); 2494b3ff493bSmrg R128SaveCrtcRegisters(pScrn, save); 2495b3ff493bSmrg R128SavePLLRegisters(pScrn, save); 2496b3ff493bSmrg R128SaveDDARegisters(pScrn, save); 2497b3ff493bSmrg if (pR128Ent->HasCRTC2) { 2498c582b7e3Smrg R128SaveCrtc2Registers(pScrn, save); 2499c582b7e3Smrg R128SavePLL2Registers(pScrn, save); 2500c582b7e3Smrg R128SaveDDA2Registers(pScrn, save); 2501c582b7e3Smrg } 2502b3ff493bSmrg if (info->HasPanelRegs) { 2503b3ff493bSmrg R128SaveFPRegisters(pScrn, save); 2504c582b7e3Smrg } 2505b3ff493bSmrg R128SavePalette(pScrn, save); 2506c582b7e3Smrg 250781f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 250881f79626Smrg "%s returns %p\n", __func__, save)); 2509c582b7e3Smrg} 2510c582b7e3Smrg 2511c582b7e3Smrg/* Save everything needed to restore the original VC state. */ 2512c582b7e3Smrgstatic void R128Save(ScrnInfoPtr pScrn) 2513c582b7e3Smrg{ 2514c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2515c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2516c582b7e3Smrg R128SavePtr save = &info->SavedReg; 2517c582b7e3Smrg 251879e5230eSmacallan#ifndef AVOID_FBDEV 251981f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 252081f79626Smrg "%s\n", __func__)); 2521c582b7e3Smrg if (info->FBDev) { 2522c582b7e3Smrg fbdevHWSave(pScrn); 2523c582b7e3Smrg return; 2524c582b7e3Smrg } 252579e5230eSmacallan#endif 2526c582b7e3Smrg 2527c582b7e3Smrg#ifdef WITH_VGAHW 2528b3ff493bSmrg if (info->VGAAccess) { 2529b3ff493bSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 2530c582b7e3Smrg 2531b3ff493bSmrg vgaHWUnlock(hwp); 2532c582b7e3Smrg# if defined(__powerpc__) 2533b3ff493bSmrg /* temporary hack to prevent crashing on PowerMacs when trying to 2534b3ff493bSmrg * read VGA fonts and colormap, will find a better solution 2535b3ff493bSmrg * in the future. TODO: Check if there's actually some VGA stuff 2536b3ff493bSmrg * setup in the card at all !! 2537b3ff493bSmrg */ 2538b3ff493bSmrg vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ 2539c582b7e3Smrg# else 2540b3ff493bSmrg /* Save mode * & fonts & cmap */ 2541b3ff493bSmrg vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); 2542c582b7e3Smrg# endif 2543b3ff493bSmrg vgaHWLock(hwp); 2544c582b7e3Smrg } 2545b3ff493bSmrg#endif 2546c582b7e3Smrg 2547b3ff493bSmrg save->dp_datatype = INREG(R128_DP_DATATYPE); 2548b3ff493bSmrg save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); 2549b3ff493bSmrg save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); 2550b3ff493bSmrg save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); 2551b3ff493bSmrg save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); 2552c582b7e3Smrg 2553b3ff493bSmrg R128SaveMode(pScrn, save); 2554c582b7e3Smrg} 2555c582b7e3Smrg 2556c582b7e3Smrg/* Restore the original (text) mode. */ 2557c582b7e3Smrgstatic void R128Restore(ScrnInfoPtr pScrn) 2558c582b7e3Smrg{ 2559c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2560b3ff493bSmrg R128EntPtr pR128Ent = R128EntPriv(pScrn); 2561c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2562c582b7e3Smrg R128SavePtr restore = &info->SavedReg; 2563c582b7e3Smrg 256479e5230eSmacallan#ifndef AVOID_FBDEV 256581f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 256681f79626Smrg "%s\n", __func__)); 2567c582b7e3Smrg if (info->FBDev) { 2568c582b7e3Smrg fbdevHWRestore(pScrn); 2569c582b7e3Smrg return; 2570c582b7e3Smrg } 257179e5230eSmacallan#endif 2572c582b7e3Smrg R128Blank(pScrn); 2573c582b7e3Smrg 2574b3ff493bSmrg OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); 2575b3ff493bSmrg OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); 2576b3ff493bSmrg OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); 2577b3ff493bSmrg OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); 2578b3ff493bSmrg OUTREG(R128_DP_DATATYPE, restore->dp_datatype); 2579c582b7e3Smrg 2580b3ff493bSmrg R128RestoreCommonRegisters(pScrn, restore); 2581b3ff493bSmrg if (pR128Ent->HasCRTC2) { 2582b3ff493bSmrg R128RestoreDDA2Registers(pScrn, restore); 2583b3ff493bSmrg R128RestoreCrtc2Registers(pScrn, restore); 2584b3ff493bSmrg R128RestorePLL2Registers(pScrn, restore); 2585b3ff493bSmrg } 2586b3ff493bSmrg R128RestoreDDARegisters(pScrn, restore); 2587b3ff493bSmrg R128RestoreCrtcRegisters(pScrn, restore); 2588b3ff493bSmrg R128RestorePLLRegisters(pScrn, restore); 2589b3ff493bSmrg R128RestoreDACRegisters(pScrn, restore); 2590b3ff493bSmrg R128RestoreRMXRegisters(pScrn, restore); 2591b3ff493bSmrg R128RestoreFPRegisters(pScrn, restore); 2592b3ff493bSmrg R128RestoreLVDSRegisters(pScrn, restore); 25939e881af1Smacallan 25945ef9b84eSmacallan OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); 25955ef9b84eSmacallan OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); 25965ef9b84eSmacallan OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); 25975ef9b84eSmacallan OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); 25985ef9b84eSmacallan OUTREG(R128_DP_DATATYPE, restore->dp_datatype); 25999e881af1Smacallan 2600c582b7e3Smrg#ifdef WITH_VGAHW 2601c582b7e3Smrg if (info->VGAAccess) { 2602c582b7e3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 2603b3ff493bSmrg vgaHWUnlock(hwp); 2604c582b7e3Smrg# if defined(__powerpc__) 2605b3ff493bSmrg /* Temporary hack to prevent crashing on PowerMacs when trying to 2606b3ff493bSmrg * write VGA fonts, will find a better solution in the future 2607b3ff493bSmrg */ 2608b3ff493bSmrg vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); 2609c582b7e3Smrg# else 2610b3ff493bSmrg vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); 2611c582b7e3Smrg# endif 2612b3ff493bSmrg vgaHWLock(hwp); 2613c582b7e3Smrg } 2614c582b7e3Smrg#endif 2615c582b7e3Smrg 2616c582b7e3Smrg R128WaitForVerticalSync(pScrn); 2617c582b7e3Smrg R128Unblank(pScrn); 2618c582b7e3Smrg} 2619c582b7e3Smrg 2620c582b7e3Smrg/* Define common registers for requested video mode. */ 2621b3ff493bSmrgvoid R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info) 2622c582b7e3Smrg{ 2623c582b7e3Smrg save->ovr_clr = 0; 2624c582b7e3Smrg save->ovr_wid_left_right = 0; 2625c582b7e3Smrg save->ovr_wid_top_bottom = 0; 2626c582b7e3Smrg save->ov0_scale_cntl = 0; 2627c582b7e3Smrg save->mpp_tb_config = 0; 2628c582b7e3Smrg save->mpp_gp_config = 0; 2629c582b7e3Smrg save->subpic_cntl = 0; 2630c582b7e3Smrg save->viph_control = 0; 2631c582b7e3Smrg save->i2c_cntl_1 = 0; 263284354367Smrg#ifdef R128DRI 2633c582b7e3Smrg save->gen_int_cntl = info->gen_int_cntl; 2634c582b7e3Smrg#else 2635c582b7e3Smrg save->gen_int_cntl = 0; 2636c582b7e3Smrg#endif 2637c582b7e3Smrg save->cap0_trig_cntl = 0; 2638c582b7e3Smrg save->cap1_trig_cntl = 0; 2639c582b7e3Smrg save->bus_cntl = info->BusCntl; 2640c582b7e3Smrg /* 2641c582b7e3Smrg * If bursts are enabled, turn on discards and aborts 2642c582b7e3Smrg */ 2643c582b7e3Smrg if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST)) 2644c582b7e3Smrg save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; 2645c582b7e3Smrg} 2646c582b7e3Smrg 2647b3ff493bSmrg/* Define RMX registers for the requested video mode. */ 2648b3ff493bSmrgvoid R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save, 2649b3ff493bSmrg xf86OutputPtr output, DisplayModePtr mode) 2650c582b7e3Smrg{ 2651b3ff493bSmrg R128OutputPrivatePtr r128_output = output->driver_private; 2652b3ff493bSmrg 2653c582b7e3Smrg int xres = mode->CrtcHDisplay; 2654c582b7e3Smrg int yres = mode->CrtcVDisplay; 2655c582b7e3Smrg float Hratio, Vratio; 2656c582b7e3Smrg 2657b3ff493bSmrg save->fp_crtc_h_total_disp = save->crtc_h_total_disp; 2658b3ff493bSmrg save->fp_crtc_v_total_disp = save->crtc_v_total_disp; 2659b3ff493bSmrg save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; 2660b3ff493bSmrg save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; 2661b3ff493bSmrg 2662b3ff493bSmrg if (r128_output->MonType != MT_DFP && r128_output->MonType != MT_LCD) 2663c582b7e3Smrg return; 2664c582b7e3Smrg 2665b3ff493bSmrg if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) { 2666b3ff493bSmrg xres = r128_output->PanelXRes; 2667b3ff493bSmrg yres = r128_output->PanelYRes; 2668b3ff493bSmrg 2669b3ff493bSmrg Hratio = 1.0; 2670b3ff493bSmrg Vratio = 1.0; 2671b3ff493bSmrg } else { 2672b3ff493bSmrg if (xres > r128_output->PanelXRes) xres = r128_output->PanelXRes; 2673b3ff493bSmrg if (yres > r128_output->PanelYRes) yres = r128_output->PanelYRes; 2674c582b7e3Smrg 2675b3ff493bSmrg Hratio = (float)xres/(float)r128_output->PanelXRes; 2676b3ff493bSmrg Vratio = (float)yres/(float)r128_output->PanelYRes; 2677b3ff493bSmrg } 2678c582b7e3Smrg 2679c582b7e3Smrg save->fp_horz_stretch = 2680c582b7e3Smrg (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5)) 2681c582b7e3Smrg & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) | 2682c582b7e3Smrg (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE | 2683c582b7e3Smrg R128_HORZ_FP_LOOP_STRETCH | 2684c582b7e3Smrg R128_HORZ_STRETCH_RESERVED))); 2685c582b7e3Smrg save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN; 2686c582b7e3Smrg save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO; 2687b3ff493bSmrg if (xres == r128_output->PanelXRes) 2688c582b7e3Smrg save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE); 2689c582b7e3Smrg else 2690c582b7e3Smrg save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE); 2691c582b7e3Smrg 2692c582b7e3Smrg save->fp_vert_stretch = 2693c582b7e3Smrg (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5)) 2694c582b7e3Smrg & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) | 2695c582b7e3Smrg (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE | 2696c582b7e3Smrg R128_VERT_STRETCH_RESERVED))); 2697c582b7e3Smrg save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN; 2698b3ff493bSmrg if (yres == r128_output->PanelYRes) 2699c582b7e3Smrg save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND); 2700c582b7e3Smrg else 2701c582b7e3Smrg save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND); 2702b3ff493bSmrg} 2703c582b7e3Smrg 2704b3ff493bSmrg/* Define flat panel registers for the requested video mode. */ 2705b3ff493bSmrgvoid R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output) 2706b3ff493bSmrg{ 2707b3ff493bSmrg xf86CrtcPtr crtc = output->crtc; 2708b3ff493bSmrg R128CrtcPrivatePtr r128_crtc = crtc->driver_private; 2709c582b7e3Smrg 2710c582b7e3Smrg /* WARNING: Be careful about turning on the flat panel */ 2711b3ff493bSmrg save->fp_gen_cntl = orig->fp_gen_cntl; 2712b3ff493bSmrg save->fp_panel_cntl = orig->fp_panel_cntl; 2713b3ff493bSmrg save->tmds_transmitter_cntl = orig->tmds_transmitter_cntl; 2714b3ff493bSmrg save->tmds_crc = orig->tmds_crc; 2715b3ff493bSmrg 2716b3ff493bSmrg if (r128_crtc->crtc_id) 2717b3ff493bSmrg save->fp_gen_cntl |= R128_FP_SEL_CRTC2; 2718c582b7e3Smrg else 2719b3ff493bSmrg save->fp_gen_cntl &= ~R128_FP_SEL_CRTC2; 2720c582b7e3Smrg 2721b3ff493bSmrg save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND | 2722b3ff493bSmrg R128_FP_CRTC_USE_SHADOW_ROWCUR | 2723b3ff493bSmrg R128_FP_CRTC_HORZ_DIV2_EN | 2724b3ff493bSmrg R128_FP_CRTC_HOR_CRT_DIV2_DIS | 2725b3ff493bSmrg R128_FP_CRT_SYNC_SEL | 2726b3ff493bSmrg R128_FP_USE_SHADOW_EN); 2727b3ff493bSmrg 2728b3ff493bSmrg save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR | 2729b3ff493bSmrg R128_FP_CRTC_DONT_SHADOW_HEND); 2730b3ff493bSmrg 2731b3ff493bSmrg save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON); 2732b3ff493bSmrg save->tmds_transmitter_cntl &= ~R128_TMDS_PLLRST; 2733b3ff493bSmrg save->tmds_transmitter_cntl |= R128_TMDS_PLLEN; 2734b3ff493bSmrg} 2735b3ff493bSmrg 2736b3ff493bSmrg/* Define LVDS registers for the requested video mode. */ 2737b3ff493bSmrgvoid R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output) 2738b3ff493bSmrg{ 2739b3ff493bSmrg xf86CrtcPtr crtc = output->crtc; 2740b3ff493bSmrg R128CrtcPrivatePtr r128_crtc = crtc->driver_private; 2741b3ff493bSmrg 2742b3ff493bSmrg save->lvds_gen_cntl = orig->lvds_gen_cntl; 2743b3ff493bSmrg 2744b3ff493bSmrg if (r128_crtc->crtc_id) 2745b3ff493bSmrg save->lvds_gen_cntl |= R128_LVDS_SEL_CRTC2; 2746b3ff493bSmrg else 2747b3ff493bSmrg save->lvds_gen_cntl &= ~R128_LVDS_SEL_CRTC2; 2748c582b7e3Smrg} 2749c582b7e3Smrg 2750c582b7e3Smrg#if 0 2751c582b7e3Smrg/* Define initial palette for requested video mode. This doesn't do 2752c582b7e3Smrg anything for XFree86 4.0. */ 2753c582b7e3Smrgstatic void R128InitPalette(R128SavePtr save) 2754c582b7e3Smrg{ 2755c582b7e3Smrg save->palette_valid = FALSE; 2756c582b7e3Smrg} 2757c582b7e3Smrg#endif 2758c582b7e3Smrg 2759c582b7e3Smrgstatic Bool R128SaveScreen(ScreenPtr pScreen, int mode) 2760c582b7e3Smrg{ 276184354367Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2762c582b7e3Smrg Bool unblank; 2763c582b7e3Smrg 2764c582b7e3Smrg unblank = xf86IsUnblank(mode); 2765c582b7e3Smrg if (unblank) 2766c582b7e3Smrg SetTimeSinceLastInputEvent(); 2767c582b7e3Smrg 2768c582b7e3Smrg if ((pScrn != NULL) && pScrn->vtSema) { 2769c582b7e3Smrg if (unblank) 2770c582b7e3Smrg R128Unblank(pScrn); 2771c582b7e3Smrg else 2772c582b7e3Smrg R128Blank(pScrn); 2773c582b7e3Smrg } 2774c582b7e3Smrg return TRUE; 2775c582b7e3Smrg} 2776c582b7e3Smrg 2777c582b7e3Smrg/* 2778c582b7e3Smrg * SwitchMode() doesn't work right on crtc2 on some laptops. 2779c582b7e3Smrg * The workaround is to switch the mode, then switch to another VT, then 2780c582b7e3Smrg * switch back. --AGD 2781c582b7e3Smrg */ 278284354367SmrgBool R128SwitchMode(SWITCH_MODE_ARGS_DECL) 2783c582b7e3Smrg{ 278484354367Smrg SCRN_INFO_PTR(arg); 2785c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2786c582b7e3Smrg Bool ret; 2787c582b7e3Smrg 2788c582b7e3Smrg info->SwitchingMode = TRUE; 2789b3ff493bSmrg ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 2790c582b7e3Smrg info->SwitchingMode = FALSE; 2791c582b7e3Smrg return ret; 2792c582b7e3Smrg} 2793c582b7e3Smrg 2794b3ff493bSmrgModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags) 2795c582b7e3Smrg{ 2796b3ff493bSmrg ScrnInfoPtr pScrn = output->scrn; 2797b3ff493bSmrg R128InfoPtr info = R128PTR(pScrn); 2798b3ff493bSmrg R128OutputPrivatePtr r128_output = output->driver_private; 2799b3ff493bSmrg int i, j; 2800c582b7e3Smrg 2801b3ff493bSmrg if (r128_output->MonType == MT_CRT) 2802b3ff493bSmrg return MODE_OK; 2803c582b7e3Smrg 2804b3ff493bSmrg if (r128_output->MonType == MT_DFP || r128_output->MonType == MT_LCD) { 2805c582b7e3Smrg if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; 2806c582b7e3Smrg if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; 2807c582b7e3Smrg } 2808c582b7e3Smrg 2809b3ff493bSmrg if (r128_output->MonType == MT_LCD && info->VBIOS) { 2810b3ff493bSmrg for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) { 2811b3ff493bSmrg j = R128_BIOS16(i); 2812c582b7e3Smrg 2813c582b7e3Smrg if (mode->CrtcHDisplay == R128_BIOS16(j) && 2814b3ff493bSmrg mode->CrtcVDisplay == R128_BIOS16(j + 2)) { 2815c582b7e3Smrg if ((flags & MODECHECK_FINAL) == MODECHECK_FINAL) { 2816c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2817c582b7e3Smrg "Modifying mode according to VBIOS: %ix%i [pclk %.1f MHz] for FP to: ", 2818b3ff493bSmrg mode->CrtcHDisplay, mode->CrtcVDisplay, 2819b3ff493bSmrg (float)mode->Clock / 1000); 2820c582b7e3Smrg 2821c582b7e3Smrg /* Assume we are using expanded mode */ 2822b3ff493bSmrg if (R128_BIOS16(j + 5)) j = R128_BIOS16(j + 5); 2823b3ff493bSmrg else j += 9; 2824c582b7e3Smrg 2825b3ff493bSmrg mode->Clock = (uint32_t)R128_BIOS16(j) * 10; 2826c582b7e3Smrg 2827c582b7e3Smrg mode->HDisplay = mode->CrtcHDisplay = 2828b3ff493bSmrg ((R128_BIOS16(j + 10) & 0x01ff) + 1) * 8; 2829c582b7e3Smrg mode->HSyncStart = mode->CrtcHSyncStart = 2830b3ff493bSmrg ((R128_BIOS16(j + 12) & 0x01ff) + 1) * 8; 2831c582b7e3Smrg mode->HSyncEnd = mode->CrtcHSyncEnd = 2832b3ff493bSmrg mode->CrtcHSyncStart + (R128_BIOS8(j + 14) & 0x1f); 2833c582b7e3Smrg mode->HTotal = mode->CrtcHTotal = 2834b3ff493bSmrg ((R128_BIOS16(j + 8) & 0x01ff) + 1) * 8; 2835c582b7e3Smrg 2836c582b7e3Smrg mode->VDisplay = mode->CrtcVDisplay = 2837b3ff493bSmrg (R128_BIOS16(j + 17) & 0x07ff) + 1; 2838c582b7e3Smrg mode->VSyncStart = mode->CrtcVSyncStart = 2839b3ff493bSmrg (R128_BIOS16(j + 19) & 0x07ff) + 1; 2840c582b7e3Smrg mode->VSyncEnd = mode->CrtcVSyncEnd = 2841b3ff493bSmrg mode->CrtcVSyncStart + ((R128_BIOS16(j + 19) >> 11) & 0x1f); 2842c582b7e3Smrg mode->VTotal = mode->CrtcVTotal = 2843b3ff493bSmrg (R128_BIOS16(j + 15) & 0x07ff) + 1; 2844c582b7e3Smrg xf86ErrorF("%ix%i [pclk %.1f MHz]\n", 2845c582b7e3Smrg mode->CrtcHDisplay,mode->CrtcVDisplay, 2846b3ff493bSmrg (float)mode->Clock/ 1000); 2847c582b7e3Smrg } 2848c582b7e3Smrg return MODE_OK; 2849c582b7e3Smrg } 2850c582b7e3Smrg } 2851c582b7e3Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, 2852c582b7e3Smrg "Mode rejected for FP %ix%i [pclk: %.1f] " 2853c582b7e3Smrg "(not listed in VBIOS)\n", 2854c582b7e3Smrg mode->CrtcHDisplay, mode->CrtcVDisplay, 2855c582b7e3Smrg (float)mode->Clock / 1000); 2856c582b7e3Smrg return MODE_NOMODE; 2857c582b7e3Smrg } 2858c582b7e3Smrg 2859c582b7e3Smrg return MODE_OK; 2860c582b7e3Smrg} 2861c582b7e3Smrg 2862b3ff493bSmrg/* Used to disallow modes that are not supported by the hardware. */ 2863b3ff493bSmrgModeStatus R128ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 2864b3ff493bSmrg Bool verbose, int flags) 2865b3ff493bSmrg{ 2866b3ff493bSmrg SCRN_INFO_PTR(arg); 2867b3ff493bSmrg R128EntPtr pR128Ent = R128EntPriv(pScrn); 2868b3ff493bSmrg xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]); 2869b3ff493bSmrg 2870b3ff493bSmrg return R128DoValidMode(output, mode, flags); 2871b3ff493bSmrg} 2872b3ff493bSmrg 2873c582b7e3Smrg/* Adjust viewport into virtual desktop such that (0,0) in viewport space 2874c582b7e3Smrg is (x,y) in virtual space. */ 287584354367Smrgvoid R128AdjustFrame(ADJUST_FRAME_ARGS_DECL) 2876c582b7e3Smrg{ 287784354367Smrg SCRN_INFO_PTR(arg); 2878c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2879c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2880c582b7e3Smrg int Base; 2881c582b7e3Smrg 2882c582b7e3Smrg if(info->showCache && y && pScrn->vtSema) 2883c582b7e3Smrg y += pScrn->virtualY - 1; 2884c582b7e3Smrg 2885c582b7e3Smrg Base = y * info->CurrentLayout.displayWidth + x; 2886c582b7e3Smrg 2887c582b7e3Smrg switch (info->CurrentLayout.pixel_code) { 2888c582b7e3Smrg case 15: 2889c582b7e3Smrg case 16: Base *= 2; break; 2890c582b7e3Smrg case 24: Base *= 3; break; 2891c582b7e3Smrg case 32: Base *= 4; break; 2892c582b7e3Smrg } 2893c582b7e3Smrg 2894c582b7e3Smrg Base &= ~7; /* 3 lower bits are always 0 */ 2895c582b7e3Smrg 2896c582b7e3Smrg if (info->CurrentLayout.pixel_code == 24) 2897c582b7e3Smrg Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */ 2898c582b7e3Smrg 2899c582b7e3Smrg OUTREG(R128_CRTC_OFFSET, Base); 2900c582b7e3Smrg} 2901c582b7e3Smrg 2902c582b7e3Smrg/* Called when VT switching back to the X server. Reinitialize the video 2903c582b7e3Smrg mode. */ 290484354367SmrgBool R128EnterVT(VT_FUNC_ARGS_DECL) 2905c582b7e3Smrg{ 290684354367Smrg SCRN_INFO_PTR(arg); 2907c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2908c582b7e3Smrg 290981f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 291081f79626Smrg "%s\n", __func__)); 2911b3ff493bSmrg 2912b3ff493bSmrg pScrn->vtSema = TRUE; 291379e5230eSmacallan#ifndef AVOID_FBDEV 2914c582b7e3Smrg if (info->FBDev) { 291584354367Smrg if (!fbdevHWEnterVT(VT_FUNC_ARGS)) return FALSE; 29163c921f55Smrg } else { 291779e5230eSmacallan#endif 29183c921f55Smrg if (!xf86SetDesiredModes(pScrn)) return FALSE; 29193c921f55Smrg#ifndef AVOID_FBDEV 2920b3ff493bSmrg } 29213c921f55Smrg#endif 2922b3ff493bSmrg 2923c582b7e3Smrg if (info->accelOn) 2924c582b7e3Smrg R128EngineInit(pScrn); 2925c582b7e3Smrg 292684354367Smrg#ifdef R128DRI 2927c582b7e3Smrg if (info->directRenderingEnabled) { 2928c582b7e3Smrg if (info->irq) { 2929c582b7e3Smrg /* Need to make sure interrupts are enabled */ 2930c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 2931c582b7e3Smrg OUTREG(R128_GEN_INT_CNTL, info->gen_int_cntl); 2932c582b7e3Smrg } 2933c582b7e3Smrg R128CCE_START(pScrn, info); 2934c582b7e3Smrg DRIUnlock(pScrn->pScreen); 2935c582b7e3Smrg } 2936c582b7e3Smrg#endif 2937c582b7e3Smrg 2938c582b7e3Smrg info->PaletteSavedOnVT = FALSE; 2939b3ff493bSmrg //pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 2940c582b7e3Smrg 2941c582b7e3Smrg return TRUE; 2942c582b7e3Smrg} 2943c582b7e3Smrg 2944c582b7e3Smrg/* Called when VT switching away from the X server. Restore the original 2945c582b7e3Smrg text mode. */ 294684354367Smrgvoid R128LeaveVT(VT_FUNC_ARGS_DECL) 2947c582b7e3Smrg{ 294884354367Smrg SCRN_INFO_PTR(arg); 2949c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2950c582b7e3Smrg R128SavePtr save = &info->ModeReg; 2951c582b7e3Smrg 295281f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 295381f79626Smrg "%s\n", __func__)); 295484354367Smrg#ifdef R128DRI 2955c582b7e3Smrg if (info->directRenderingEnabled) { 2956c582b7e3Smrg DRILock(pScrn->pScreen, 0); 2957c582b7e3Smrg R128CCE_STOP(pScrn, info); 2958c582b7e3Smrg } 295984354367Smrg#ifdef USE_EXA 296084354367Smrg if (info->useEXA) 296184354367Smrg info->state_2d.composite_setup = FALSE; 296284354367Smrg#endif 2963c582b7e3Smrg#endif 2964c582b7e3Smrg R128SavePalette(pScrn, save); 2965c582b7e3Smrg info->PaletteSavedOnVT = TRUE; 296679e5230eSmacallan#ifndef AVOID_FBDEV 2967c582b7e3Smrg if (info->FBDev) 296884354367Smrg fbdevHWLeaveVT(VT_FUNC_ARGS); 2969c582b7e3Smrg else 297079e5230eSmacallan#endif 2971c582b7e3Smrg R128Restore(pScrn); 2972c582b7e3Smrg} 2973c582b7e3Smrg 2974c582b7e3Smrg 2975c582b7e3Smrg/* Called at the end of each server generation. Restore the original text 2976c582b7e3Smrg mode, unmap video memory, and unwrap and call the saved CloseScreen 2977c582b7e3Smrg function. */ 297884354367Smrgstatic Bool R128CloseScreen(CLOSE_SCREEN_ARGS_DECL) 2979c582b7e3Smrg{ 298084354367Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2981c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 2982c582b7e3Smrg 298381f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 298481f79626Smrg "%s\n", __func__)); 2985c582b7e3Smrg 298684354367Smrg#ifdef R128DRI 2987c582b7e3Smrg /* Disable direct rendering */ 2988c582b7e3Smrg if (info->directRenderingEnabled) { 2989c582b7e3Smrg R128DRICloseScreen(pScreen); 2990c582b7e3Smrg info->directRenderingEnabled = FALSE; 2991c582b7e3Smrg } 2992c582b7e3Smrg#endif 2993c582b7e3Smrg 2994c582b7e3Smrg if (pScrn->vtSema) { 2995c582b7e3Smrg R128Restore(pScrn); 2996c582b7e3Smrg R128UnmapMem(pScrn); 2997c582b7e3Smrg } 2998c582b7e3Smrg 299984354367Smrg#ifdef USE_EXA 300084354367Smrg if (info->useEXA) { 300184354367Smrg exaDriverFini(pScreen); 300284354367Smrg free(info->ExaDriver); 300384354367Smrg } else 300484354367Smrg#endif 300584354367Smrg#ifdef HAVE_XAA_H 300684354367Smrg { 300784354367Smrg if (info->accel) XAADestroyInfoRec(info->accel); 300884354367Smrg info->accel = NULL; 300984354367Smrg } 301084354367Smrg#endif 3011c582b7e3Smrg 301284354367Smrg if (info->scratch_save) free(info->scratch_save); 3013c582b7e3Smrg info->scratch_save = NULL; 3014c582b7e3Smrg 3015c582b7e3Smrg if (info->adaptor) { 301684354367Smrg free(info->adaptor->pPortPrivates[0].ptr); 3017c582b7e3Smrg xf86XVFreeVideoAdaptorRec(info->adaptor); 3018c582b7e3Smrg info->adaptor = NULL; 3019c582b7e3Smrg } 3020c582b7e3Smrg 3021c582b7e3Smrg pScrn->vtSema = FALSE; 3022c582b7e3Smrg 3023c582b7e3Smrg pScreen->BlockHandler = info->BlockHandler; 3024c582b7e3Smrg pScreen->CloseScreen = info->CloseScreen; 302584354367Smrg return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 3026c582b7e3Smrg} 3027c582b7e3Smrg 302884354367Smrgvoid R128FreeScreen(FREE_SCREEN_ARGS_DECL) 3029c582b7e3Smrg{ 303084354367Smrg SCRN_INFO_PTR(arg); 3031c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 3032c582b7e3Smrg 303381f79626Smrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 303481f79626Smrg "%s\n", __func__)); 303519019ffeSmrg if (info == NULL) 303619019ffeSmrg return; 3037c582b7e3Smrg#ifdef WITH_VGAHW 3038c582b7e3Smrg if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 3039c582b7e3Smrg vgaHWFreeHWRec(pScrn); 3040c582b7e3Smrg#endif 3041c582b7e3Smrg R128FreeRec(pScrn); 3042c582b7e3Smrg} 3043