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