radeon_driver.c revision ce2d3770
11.170Sskrll/*
21.1Saugustss * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
31.1Saugustss *                VA Linux Systems Inc., Fremont, California.
41.71Smycroft *
51.1Saugustss * All Rights Reserved.
61.1Saugustss *
71.1Saugustss * Permission is hereby granted, free of charge, to any person obtaining
81.38Saugustss * a copy of this software and associated documentation files (the
91.1Saugustss * "Software"), to deal in the Software without restriction, including
101.1Saugustss * without limitation on the rights to use, copy, modify, merge,
111.84Sgdt * publish, distribute, sublicense, and/or sell copies of the Software,
121.84Sgdt * and to permit persons to whom the Software is furnished to do so,
131.84Sgdt * subject to the following conditions:
141.84Sgdt *
151.84Sgdt * The above copyright notice and this permission notice (including the
161.1Saugustss * next paragraph) shall be included in all copies or substantial
171.1Saugustss * portions of the Software.
181.1Saugustss *
191.1Saugustss * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
201.1Saugustss * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
211.1Saugustss * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
221.1Saugustss * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
231.1Saugustss * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
241.1Saugustss * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
251.1Saugustss * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
261.1Saugustss * DEALINGS IN THE SOFTWARE.
271.1Saugustss */
281.1Saugustss
291.1Saugustss#ifdef HAVE_CONFIG_H
301.1Saugustss#include "config.h"
311.1Saugustss#endif
321.1Saugustss
331.1Saugustss/*
341.1Saugustss * Authors:
351.1Saugustss *   Kevin E. Martin <martin@xfree86.org>
361.1Saugustss *   Rickard E. Faith <faith@valinux.com>
371.1Saugustss *   Alan Hourihane <alanh@fairlite.demon.co.uk>
381.50Slukem *
391.50Slukem * Credits:
401.170Sskrll *
411.84Sgdt *   Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source
421.122Schristos *   code to his Radeon driver.  Portions of this file are based on the
431.89Spavel *   initialization code for that driver.
441.126Sgson *
451.122Schristos * References:
461.1Saugustss *
471.1Saugustss * !!!! FIXME !!!!
481.1Saugustss *   RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
491.1Saugustss *   Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
501.133Sskrll *   1999.
511.1Saugustss *
521.1Saugustss *   RAGE 128 Software Development Manual (Technical Reference Manual P/N
531.12Saugustss *   SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
541.1Saugustss *
551.1Saugustss * This server does not yet support these XFree86 4.0 features:
561.1Saugustss * !!!! FIXME !!!!
571.1Saugustss *   DDC1 & DDC2
581.1Saugustss *   shadowfb
591.1Saugustss *   overlay planes
601.142Spgoyette *
611.155Sriastrad * Modified by Marc Aurele La France (tsi@xfree86.org) for ATI driver merge.
621.155Sriastrad *
631.1Saugustss * Mergedfb and pseudo xinerama support added by Alex Deucher (agd5f@yahoo.com)
641.1Saugustss * based on the sis driver by Thomas Winischhofer.
651.1Saugustss *
661.1Saugustss */
671.169Smrg
681.1Saugustss#include <string.h>
691.146Smrg#include <stdio.h>
701.146Smrg
711.169Smrg				/* Driver data structures */
721.169Smrg#include "radeon.h"
731.169Smrg#include "radeon_reg.h"
741.169Smrg#include "radeon_macros.h"
751.2Saugustss#include "radeon_probe.h"
761.169Smrg#include "radeon_version.h"
771.169Smrg#include "radeon_atombios.h"
781.169Smrg
791.169Smrg#ifdef XF86DRI
801.169Smrg#define _XF86DRI_SERVER_
811.169Smrg#include "radeon_dri.h"
821.169Smrg#include "radeon_drm.h"
831.169Smrg#include "sarea.h"
841.169Smrg#endif
851.169Smrg
861.169Smrg#include "fb.h"
871.169Smrg
881.169Smrg				/* colormap initialization */
891.169Smrg#include "micmap.h"
901.169Smrg#include "dixstruct.h"
911.169Smrg
921.169Smrg				/* X and server generic header files */
931.169Smrg#include "xf86.h"
941.169Smrg#include "xf86_OSproc.h"
951.169Smrg#include "xf86RandR12.h"
961.169Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
971.169Smrg#include "xf86RAC.h"
981.169Smrg#include "xf86Resources.h"
991.169Smrg#endif
1001.169Smrg#include "xf86cmap.h"
1011.169Smrg#include "vbe.h"
1021.169Smrg
1031.169Smrg#include "shadow.h"
1041.169Smrg				/* vgaHW definitions */
1051.169Smrg#ifdef WITH_VGAHW
1061.169Smrg#include "vgaHW.h"
1071.169Smrg#endif
1081.169Smrg
1091.169Smrg#ifdef HAVE_XEXTPROTO_71
1101.169Smrg#include <X11/extensions/dpmsconst.h>
1111.1Saugustss#else
1121.41Saugustss#define DPMS_SERVER
1131.41Saugustss#include <X11/extensions/dpms.h>
1141.41Saugustss#endif
1151.41Saugustss
1161.110Sjakllsch
1171.110Sjakllsch#include "atipciids.h"
1181.110Sjakllsch#include "radeon_chipset_gen.h"
1191.41Saugustss
1201.84Sgdt
1211.84Sgdt#include "radeon_chipinfo_gen.h"
1221.84Sgdt
1231.125Smatt				/* Forward definitions for driver functions */
1241.125Smattstatic Bool RADEONCloseScreen(CLOSE_SCREEN_ARGS_DECL);
1251.133Sskrllstatic Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
1261.125Smattstatic void RADEONSave(ScrnInfoPtr pScrn);
1271.133Sskrll
1281.125Smattstatic void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
1291.125Smatt
1301.1Saugustssstatic void
1311.1SaugustssRADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
1321.1Saugustss
1331.133Sskrll#ifdef XF86DRI
1341.1Saugustssstatic void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
1351.8Saugustss#endif
1361.84Sgdt
1371.84Sgdtstatic const OptionInfoRec RADEONOptions[] = {
1381.84Sgdt    { OPTION_NOACCEL,        "NoAccel",          OPTV_BOOLEAN, {0}, FALSE },
1391.133Sskrll    { OPTION_SW_CURSOR,      "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
1401.1Saugustss    { OPTION_DAC_6BIT,       "Dac6Bit",          OPTV_BOOLEAN, {0}, FALSE },
1411.41Saugustss    { OPTION_DAC_8BIT,       "Dac8Bit",          OPTV_BOOLEAN, {0}, TRUE  },
1421.41Saugustss#ifdef XF86DRI
1431.41Saugustss    { OPTION_BUS_TYPE,       "BusType",          OPTV_ANYSTR,  {0}, FALSE },
1441.41Saugustss    { OPTION_CP_PIO,         "CPPIOMode",        OPTV_BOOLEAN, {0}, FALSE },
1451.133Sskrll    { OPTION_USEC_TIMEOUT,   "CPusecTimeout",    OPTV_INTEGER, {0}, FALSE },
1461.133Sskrll    { OPTION_AGP_MODE,       "AGPMode",          OPTV_INTEGER, {0}, FALSE },
1471.133Sskrll    { OPTION_AGP_FW,         "AGPFastWrite",     OPTV_BOOLEAN, {0}, FALSE },
1481.133Sskrll    { OPTION_GART_SIZE_OLD,  "AGPSize",          OPTV_INTEGER, {0}, FALSE },
1491.133Sskrll    { OPTION_GART_SIZE,      "GARTSize",         OPTV_INTEGER, {0}, FALSE },
1501.133Sskrll    { OPTION_RING_SIZE,      "RingSize",         OPTV_INTEGER, {0}, FALSE },
1511.125Smatt    { OPTION_BUFFER_SIZE,    "BufferSize",       OPTV_INTEGER, {0}, FALSE },
1521.121Sriastrad    { OPTION_DEPTH_MOVE,     "EnableDepthMoves", OPTV_BOOLEAN, {0}, FALSE },
1531.121Sriastrad    { OPTION_PAGE_FLIP,      "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
1541.121Sriastrad    { OPTION_NO_BACKBUFFER,  "NoBackBuffer",     OPTV_BOOLEAN, {0}, FALSE },
1551.121Sriastrad    { OPTION_XV_DMA,         "DMAForXv",         OPTV_BOOLEAN, {0}, FALSE },
1561.1Saugustss    { OPTION_FBTEX_PERCENT,  "FBTexPercent",     OPTV_INTEGER, {0}, FALSE },
1571.1Saugustss    { OPTION_DEPTH_BITS,     "DepthBits",        OPTV_INTEGER, {0}, FALSE },
1581.1Saugustss    { OPTION_PCIAPER_SIZE,  "PCIAPERSize",      OPTV_INTEGER, {0}, FALSE },
1591.111Sdyoung#ifdef USE_EXA
1601.133Sskrll    { OPTION_ACCEL_DFS,      "AccelDFS",         OPTV_BOOLEAN, {0}, FALSE },
1611.155Sriastrad#endif
1621.155Sriastrad#endif
1631.1Saugustss    { OPTION_IGNORE_EDID,    "IgnoreEDID",       OPTV_BOOLEAN, {0}, FALSE },
1641.120Smrg    { OPTION_CUSTOM_EDID,    "CustomEDID",       OPTV_ANYSTR,  {0}, FALSE },
1651.120Smrg    { OPTION_DISP_PRIORITY,  "DisplayPriority",  OPTV_ANYSTR,  {0}, FALSE },
1661.120Smrg    { OPTION_PANEL_SIZE,     "PanelSize",        OPTV_ANYSTR,  {0}, FALSE },
1671.13Saugustss    { OPTION_MIN_DOTCLOCK,   "ForceMinDotClock", OPTV_FREQ,    {0}, FALSE },
1681.1Saugustss    { OPTION_COLOR_TILING,   "ColorTiling",      OPTV_BOOLEAN, {0}, FALSE },
1691.21Saugustss#ifdef XvExtension
1701.21Saugustss    { OPTION_VIDEO_KEY,                   "VideoKey",                 OPTV_INTEGER, {0}, FALSE },
1711.1Saugustss    { OPTION_RAGE_THEATRE_CRYSTAL,        "RageTheatreCrystal",       OPTV_INTEGER, {0}, FALSE },
1721.12Saugustss    { OPTION_RAGE_THEATRE_TUNER_PORT,     "RageTheatreTunerPort",     OPTV_INTEGER, {0}, FALSE },
1731.83Schristos    { OPTION_RAGE_THEATRE_COMPOSITE_PORT, "RageTheatreCompositePort", OPTV_INTEGER, {0}, FALSE },
1741.12Saugustss    { OPTION_RAGE_THEATRE_SVIDEO_PORT,    "RageTheatreSVideoPort",    OPTV_INTEGER, {0}, FALSE },
1751.157Sriastrad    { OPTION_TUNER_TYPE,                  "TunerType",                OPTV_INTEGER, {0}, FALSE },
1761.1Saugustss    { OPTION_RAGE_THEATRE_MICROC_PATH,    "RageTheatreMicrocPath",    OPTV_STRING, {0}, FALSE },
1771.1Saugustss    { OPTION_RAGE_THEATRE_MICROC_TYPE,    "RageTheatreMicrocType",    OPTV_STRING, {0}, FALSE },
1781.155Sriastrad    { OPTION_SCALER_WIDTH,                "ScalerWidth",              OPTV_INTEGER, {0}, FALSE },
1791.155Sriastrad#endif
1801.155Sriastrad#ifdef RENDER
1811.155Sriastrad    { OPTION_RENDER_ACCEL,   "RenderAccel",      OPTV_BOOLEAN, {0}, TRUE },
1821.155Sriastrad    { OPTION_SUBPIXEL_ORDER, "SubPixelOrder",    OPTV_ANYSTR,  {0}, FALSE },
1831.155Sriastrad#endif
1841.155Sriastrad    { OPTION_CLOCK_GATING,   "ClockGating",      OPTV_BOOLEAN, {0}, FALSE },
1851.155Sriastrad    { OPTION_VGA_ACCESS,     "VGAAccess",        OPTV_BOOLEAN, {0}, TRUE  },
1861.155Sriastrad    { OPTION_REVERSE_DDC,    "ReverseDDC",       OPTV_BOOLEAN, {0}, FALSE },
1871.155Sriastrad    { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL",     OPTV_BOOLEAN, {0}, FALSE },
1881.155Sriastrad    { OPTION_ACCELMETHOD,    "AccelMethod",      OPTV_STRING,  {0}, FALSE },
1891.155Sriastrad    { OPTION_DRI,            "DRI",       	 OPTV_BOOLEAN, {0}, FALSE },
1901.155Sriastrad    { OPTION_CONNECTORTABLE, "ConnectorTable",   OPTV_STRING,  {0}, FALSE },
1911.155Sriastrad    { OPTION_DEFAULT_CONNECTOR_TABLE, "DefaultConnectorTable", OPTV_BOOLEAN, {0}, FALSE },
1921.155Sriastrad    { OPTION_DEFAULT_TMDS_PLL, "DefaultTMDSPLL", OPTV_BOOLEAN, {0}, FALSE },
1931.155Sriastrad#if defined(__powerpc__)
1941.155Sriastrad    { OPTION_MAC_MODEL,      "MacModel",         OPTV_STRING,  {0}, FALSE },
1951.155Sriastrad#endif
1961.155Sriastrad    { OPTION_TVDAC_LOAD_DETECT, "TVDACLoadDetect", OPTV_BOOLEAN, {0}, FALSE },
1971.155Sriastrad    { OPTION_FORCE_TVOUT,    "ForceTVOut",         OPTV_BOOLEAN, {0}, FALSE },
1981.155Sriastrad    { OPTION_TVSTD,          "TVStandard",         OPTV_STRING,  {0}, FALSE },
1991.155Sriastrad    { OPTION_IGNORE_LID_STATUS, "IgnoreLidStatus", OPTV_BOOLEAN, {0}, FALSE },
2001.155Sriastrad    { OPTION_DEFAULT_TVDAC_ADJ, "DefaultTVDACAdj", OPTV_BOOLEAN, {0}, FALSE },
2011.155Sriastrad    { OPTION_INT10,             "Int10",           OPTV_BOOLEAN, {0}, FALSE },
2021.155Sriastrad    { OPTION_EXA_VSYNC,         "EXAVSync",        OPTV_BOOLEAN, {0}, FALSE },
2031.155Sriastrad    { OPTION_ATOM_TVOUT,	"ATOMTVOut",	   OPTV_BOOLEAN, {0}, FALSE },
2041.155Sriastrad    { OPTION_R4XX_ATOM,	        "R4xxATOM",	   OPTV_BOOLEAN, {0}, FALSE },
2051.155Sriastrad    { OPTION_FORCE_LOW_POWER,	"ForceLowPowerMode", OPTV_BOOLEAN, {0}, FALSE },
2061.155Sriastrad    { OPTION_DYNAMIC_PM,	"DynamicPM",       OPTV_BOOLEAN, {0}, FALSE },
2071.155Sriastrad    { OPTION_NEW_PLL,	        "NewPLL",        OPTV_BOOLEAN, {0}, FALSE },
2081.155Sriastrad    { OPTION_ZAPHOD_HEADS,      "ZaphodHeads",     OPTV_STRING,  {0}, FALSE },
2091.155Sriastrad    { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
2101.155Sriastrad};
2111.155Sriastrad
2121.156Sriastradconst OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
2131.155Sriastrad
2141.155Sriastradextern _X_EXPORT int gRADEONEntityIndex;
2151.155Sriastrad
2161.155Sriastradstatic int getRADEONEntityIndex(void)
2171.155Sriastrad{
2181.155Sriastrad    return gRADEONEntityIndex;
2191.155Sriastrad}
2201.155Sriastrad
2211.155Sriastradstruct RADEONInt10Save {
2221.155Sriastrad	uint32_t MEM_CNTL;
2231.155Sriastrad	uint32_t MEMSIZE;
2241.155Sriastrad	uint32_t MPP_TB_CONFIG;
2251.155Sriastrad};
2261.155Sriastrad
2271.155Sriastradstatic Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
2281.155Sriastradstatic Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
2291.155Sriastrad
2301.155Sriastradstatic void *
2311.155SriastradradeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
2321.155Sriastrad		   CARD32 *size, void *closure)
2331.155Sriastrad{
2341.155Sriastrad    ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
2351.155Sriastrad    RADEONInfoPtr  info   = RADEONPTR(pScrn);
2361.155Sriastrad    int stride;
2371.155Sriastrad
2381.155Sriastrad    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
2391.155Sriastrad    *size = stride;
2401.155Sriastrad
2411.155Sriastrad    return ((uint8_t *)info->FB + pScrn->fbOffset + row * stride + offset);
2421.155Sriastrad}
2431.155Sriastradstatic Bool
2441.155SriastradRADEONCreateScreenResources (ScreenPtr pScreen)
2451.155Sriastrad{
2461.155Sriastrad   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2471.155Sriastrad   RADEONInfoPtr  info   = RADEONPTR(pScrn);
2481.155Sriastrad   PixmapPtr pixmap;
2491.155Sriastrad
2501.155Sriastrad   pScreen->CreateScreenResources = info->CreateScreenResources;
2511.155Sriastrad   if (!(*pScreen->CreateScreenResources)(pScreen))
2521.156Sriastrad      return FALSE;
2531.156Sriastrad   pScreen->CreateScreenResources = RADEONCreateScreenResources;
2541.156Sriastrad
2551.156Sriastrad   if (info->r600_shadow_fb) {
2561.155Sriastrad       pixmap = pScreen->GetScreenPixmap(pScreen);
2571.156Sriastrad
2581.156Sriastrad       if (!shadowAdd(pScreen, pixmap, shadowUpdatePackedWeak(),
2591.155Sriastrad		      radeonShadowWindow, 0, NULL))
2601.156Sriastrad	   return FALSE;
2611.156Sriastrad   }
2621.156Sriastrad   return TRUE;
2631.156Sriastrad}
2641.155Sriastrad
2651.155SriastradRADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
2661.155Sriastrad{
2671.155Sriastrad    DevUnion     *pPriv;
2681.155Sriastrad    RADEONInfoPtr  info   = RADEONPTR(pScrn);
2691.155Sriastrad    pPriv = xf86GetEntityPrivate(info->pEnt->index,
2701.155Sriastrad                                 getRADEONEntityIndex());
2711.155Sriastrad    return pPriv->ptr;
2721.155Sriastrad}
2731.155Sriastrad
2741.155Sriastradstatic void
2751.155SriastradRADEONPreInt10Save(ScrnInfoPtr pScrn, void **pPtr)
2761.155Sriastrad{
2771.155Sriastrad    RADEONInfoPtr  info   = RADEONPTR(pScrn);
2781.147Smaxv    unsigned char *RADEONMMIO = info->MMIO;
2791.147Smaxv    uint32_t       CardTmp;
2801.147Smaxv    static struct  RADEONInt10Save SaveStruct = { 0, 0, 0 };
2811.147Smaxv
2821.147Smaxv    if (!IS_AVIVO_VARIANT) {
2831.147Smaxv	/* Save the values and zap MEM_CNTL */
2841.147Smaxv	SaveStruct.MEM_CNTL = INREG(RADEON_MEM_CNTL);
2851.60Sgehenna	SaveStruct.MEMSIZE = INREG(RADEON_CONFIG_MEMSIZE);
2861.60Sgehenna	SaveStruct.MPP_TB_CONFIG = INREG(RADEON_MPP_TB_CONFIG);
2871.123Sdholland
2881.123Sdholland	/*
2891.123Sdholland	 * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4
2901.123Sdholland	 */
2911.123Sdholland	OUTREG(RADEON_MEM_CNTL, 0);
2921.123Sdholland	CardTmp = SaveStruct.MPP_TB_CONFIG & 0x00ffffffu;
2931.123Sdholland	CardTmp |= 0x04 << 24;
2941.123Sdholland	OUTREG(RADEON_MPP_TB_CONFIG, CardTmp);
2951.123Sdholland    }
2961.123Sdholland
2971.124Sdholland    *pPtr = (void *)&SaveStruct;
2981.123Sdholland}
2991.60Sgehenna
3001.14Saugustssstatic void
3011.133SskrllRADEONPostInt10Check(ScrnInfoPtr pScrn, void *ptr)
3021.133Sskrll{
3031.133Sskrll    RADEONInfoPtr  info   = RADEONPTR(pScrn);
3041.133Sskrll    unsigned char *RADEONMMIO = info->MMIO;
3051.133Sskrll    struct RADEONInt10Save *pSave = ptr;
3061.133Sskrll    uint32_t CardTmp;
3071.133Sskrll
3081.133Sskrll    /* If we don't have a valid (non-zero) saved MEM_CNTL, get out now */
3091.40Saugustss    if (!pSave || !pSave->MEM_CNTL)
3101.40Saugustss	return;
3111.55Saugustss
3121.92Schristos    if (IS_AVIVO_VARIANT)
3131.138Sws	return;
3141.133Sskrll
3151.133Sskrll    /*
3161.40Saugustss     * If either MEM_CNTL is currently zero or inconistent (configured for
3171.133Sskrll     * two channels with the two channels configured differently), restore
3181.131Sskrll     * the saved registers.
3191.1Saugustss     */
3201.12Saugustss    CardTmp = INREG(RADEON_MEM_CNTL);
3211.12Saugustss    if (!CardTmp ||
3221.12Saugustss	((CardTmp & 1) &&
3231.1Saugustss	 (((CardTmp >> 8) & 0xff) != ((CardTmp >> 24) & 0xff)))) {
3241.147Smaxv	/* Restore the saved registers */
3251.147Smaxv	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3261.147Smaxv		   "Restoring MEM_CNTL (%08lx), setting to %08lx\n",
3271.147Smaxv		   (unsigned long)CardTmp, (unsigned long)pSave->MEM_CNTL);
3281.147Smaxv	OUTREG(RADEON_MEM_CNTL, pSave->MEM_CNTL);
3291.147Smaxv
3301.146Smrg	CardTmp = INREG(RADEON_CONFIG_MEMSIZE);
3311.138Sws	if (CardTmp != pSave->MEMSIZE) {
3321.138Sws	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3331.138Sws		       "Restoring CONFIG_MEMSIZE (%08lx), setting to %08lx\n",
3341.138Sws		       (unsigned long)CardTmp, (unsigned long)pSave->MEMSIZE);
3351.1Saugustss	    OUTREG(RADEON_CONFIG_MEMSIZE, pSave->MEMSIZE);
3361.105Spooka	}
3371.105Spooka    }
3381.105Spooka
3391.147Smaxv    CardTmp = INREG(RADEON_MPP_TB_CONFIG);
3401.111Sdyoung    if ((CardTmp & 0xff000000u) != (pSave->MPP_TB_CONFIG & 0xff000000u)) {
3411.1Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3421.111Sdyoung	           "Restoring MPP_TB_CONFIG<31:24> (%02lx), setting to %02lx\n",
3431.105Spooka	 	   (unsigned long)CardTmp >> 24,
3441.105Spooka		   (unsigned long)pSave->MPP_TB_CONFIG >> 24);
3451.105Spooka	CardTmp &= 0x00ffffffu;
3461.105Spooka	CardTmp |= (pSave->MPP_TB_CONFIG & 0xff000000u);
3471.105Spooka	OUTREG(RADEON_MPP_TB_CONFIG, CardTmp);
3481.105Spooka    }
3491.1Saugustss}
3501.105Spooka
3511.133Sskrll/* Allocate our private RADEONInfoRec */
3521.133SskrllBool RADEONGetRec(ScrnInfoPtr pScrn)
3531.133Sskrll{
3541.1Saugustss    if (pScrn->driverPrivate) return TRUE;
3551.133Sskrll
3561.1Saugustss    pScrn->driverPrivate = xnfcalloc(sizeof(RADEONInfoRec), 1);
3571.1Saugustss    return TRUE;
3581.147Smaxv}
3591.138Sws
3601.138Sws/* Free our private RADEONInfoRec */
3611.139Swsvoid RADEONFreeRec(ScrnInfoPtr pScrn)
3621.139Sws{
3631.138Sws    RADEONInfoPtr  info;
3641.138Sws    int i;
3651.147Smaxv
3661.111Sdyoung    if (!pScrn || !pScrn->driverPrivate) return;
3671.1Saugustss
3681.138Sws    info = RADEONPTR(pScrn);
3691.138Sws
3701.138Sws    if (info->cp) {
3711.151Sskrll	free(info->cp);
3721.138Sws	info->cp = NULL;
3731.138Sws    }
3741.138Sws
3751.138Sws    if (info->dri) {
3761.138Sws	free(info->dri);
3771.138Sws	info->dri = NULL;
3781.138Sws    }
3791.138Sws
3801.138Sws    if (info->accel_state) {
3811.138Sws	free(info->accel_state);
3821.138Sws	info->accel_state = NULL;
3831.147Smaxv    }
3841.138Sws
3851.138Sws    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
3861.111Sdyoung	if (info->encoders[i]) {
3871.138Sws	    if (info->encoders[i]->dev_priv) {
3881.133Sskrll		free(info->encoders[i]->dev_priv);
3891.72Saugustss		info->encoders[i]->dev_priv = NULL;
3901.28Saugustss	    }
3911.97Srmind	    free(info->encoders[i]);
3921.59Saugustss	    info->encoders[i]= NULL;
3931.103Splunky	}
3941.103Splunky    }
3951.103Splunky
3961.133Sskrll    free(pScrn->driverPrivate);
3971.120Smrg    pScrn->driverPrivate = NULL;
3981.120Smrg}
3991.138Sws
4001.99Scube/* Memory map the MMIO region.  Used during pre-init and by RADEONMapMem,
4011.72Saugustss * below
4021.1Saugustss */
4031.99Scubestatic Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
4041.138Sws{
4051.31Saugustss#ifdef XSERVER_LIBPCIACCESS
4061.121Sriastrad    int err;
4071.121Sriastrad#endif
4081.121Sriastrad    RADEONInfoPtr  info = RADEONPTR(pScrn);
4091.121Sriastrad    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
4101.121Sriastrad
4111.121Sriastrad    if (pRADEONEnt->MMIO) {
4121.121Sriastrad        pRADEONEnt->MMIO_cnt++;
4131.121Sriastrad        info->MMIO = pRADEONEnt->MMIO;
4141.121Sriastrad        return TRUE;
4151.121Sriastrad    }
4161.157Sriastrad
4171.157Sriastrad#ifndef XSERVER_LIBPCIACCESS
4181.157Sriastrad
4191.138Sws    info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
4201.138Sws			       VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
4211.138Sws			       info->PciTag,
4221.138Sws			       info->MMIOAddr,
4231.138Sws			       info->MMIOSize);
4241.138Sws
4251.138Sws    if (!info->MMIO)
4261.138Sws        return FALSE;
4271.138Sws#else
4281.138Sws
4291.138Sws    err = pci_device_map_range(info->PciInfo,
4301.31Saugustss				   info->MMIOAddr,
4311.138Sws				   info->MMIOSize,
4321.138Sws				   PCI_DEV_MAP_FLAG_WRITABLE,
4331.31Saugustss				   &info->MMIO);
4341.31Saugustss
4351.31Saugustss    if (err) {
4361.138Sws	xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
4371.28Saugustss                    "Unable to map MMIO aperture. %s (%d)\n",
4381.99Scube                    strerror (err), err);
4391.99Scube	return FALSE;
4401.111Sdyoung    }
4411.1Saugustss
4421.30Saugustss#endif
4431.155Sriastrad
4441.134Smsaitoh    pRADEONEnt->MMIO = info->MMIO;
4451.157Sriastrad    pRADEONEnt->MMIO_cnt = 1;
4461.1Saugustss    return TRUE;
4471.1Saugustss}
4481.130Sskrll
4491.130Sskrll/* Unmap the MMIO region.  Used during pre-init and by RADEONUnmapMem,
4501.130Sskrll * below
4511.130Sskrll */
4521.130Sskrllstatic Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn)
4531.130Sskrll{
4541.130Sskrll    RADEONInfoPtr  info = RADEONPTR(pScrn);
4551.130Sskrll    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
4561.130Sskrll
4571.130Sskrll    /* refcount for zaphod */
4581.130Sskrll    if (--pRADEONEnt->MMIO_cnt != 0) {
4591.130Sskrll      info->MMIO = NULL;
4601.130Sskrll      return TRUE;
4611.37Saugustss    }
4621.138Sws
4631.1Saugustss#ifndef XSERVER_LIBPCIACCESS
4641.133Sskrll    xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
4651.102Sdrochner#else
4661.133Sskrll    pci_device_unmap_range(info->PciInfo, info->MMIO, info->MMIOSize);
4671.1Saugustss#endif
4681.1Saugustss
4691.133Sskrll    pRADEONEnt->MMIO = NULL;
4701.1Saugustss    info->MMIO = NULL;
4711.28Saugustss    return TRUE;
4721.130Sskrll}
4731.1Saugustss
4741.169Smrg/* Memory map the frame buffer.  Used by RADEONMapMem, below. */
4751.169Smrgstatic Bool RADEONMapFB(ScrnInfoPtr pScrn)
4761.170Sskrll{
4771.170Sskrll#ifdef XSERVER_LIBPCIACCESS
4781.53Saugustss    int err;
4791.159Sriastrad#endif
4801.159Sriastrad    RADEONInfoPtr  info = RADEONPTR(pScrn);
4811.138Sws    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
4821.138Sws
4831.138Sws    if (pRADEONEnt->FB) {
4841.138Sws        pRADEONEnt->FB_cnt++;
4851.138Sws        info->FB = pRADEONEnt->FB;
4861.138Sws        return TRUE;
4871.138Sws    }
4881.138Sws
4891.170Sskrll    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
4901.170Sskrll		   "Map: 0x%016llx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
4911.138Sws
4921.138Sws#ifndef XSERVER_LIBPCIACCESS
4931.161Sriastrad
4941.161Sriastrad    info->FB = xf86MapPciMem(pScrn->scrnIndex,
4951.161Sriastrad			     VIDMEM_FRAMEBUFFER,
4961.161Sriastrad			     info->PciTag,
4971.161Sriastrad			     info->LinearAddr,
4981.161Sriastrad			     info->FbMapSize);
4991.138Sws
5001.53Saugustss    if (!info->FB) return FALSE;
5011.31Saugustss
5021.102Sdrochner#else
5031.102Sdrochner
5041.43Saugustss    err = pci_device_map_range(info->PciInfo,
5051.28Saugustss				   info->LinearAddr,
5061.161Sriastrad				   info->FbMapSize,
5071.7Saugustss				   PCI_DEV_MAP_FLAG_WRITABLE |
5081.1Saugustss				   PCI_DEV_MAP_FLAG_WRITE_COMBINE,
5091.138Sws				   &info->FB);
5101.138Sws
5111.28Saugustss    if (err) {
5121.28Saugustss	xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
5131.161Sriastrad                    "Unable to map FB aperture. %s (%d)\n",
5141.120Smrg                    strerror (err), err);
5151.1Saugustss	return FALSE;
5161.169Smrg    }
5171.28Saugustss
5181.28Saugustss#endif
5191.161Sriastrad
5201.28Saugustss    pRADEONEnt->FB = info->FB;
5211.28Saugustss    pRADEONEnt->FB_cnt = 1;
5221.161Sriastrad    return TRUE;
5231.1Saugustss}
5241.1Saugustss
5251.82Schristos/* Unmap the frame buffer.  Used by RADEONUnmapMem, below. */
5261.1Saugustssstatic Bool RADEONUnmapFB(ScrnInfoPtr pScrn)
5271.21Saugustss{
5281.21Saugustss    RADEONInfoPtr  info = RADEONPTR(pScrn);
5291.169Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
5301.169Smrg
5311.169Smrg    /* refcount for zaphod */
5321.1Saugustss    if (--pRADEONEnt->FB_cnt != 0) {
5331.1Saugustss      info->FB = NULL;
5341.1Saugustss      return TRUE;
5351.1Saugustss    }
5361.1Saugustss
5371.161Sriastrad#ifndef XSERVER_LIBPCIACCESS
5381.161Sriastrad    xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
5391.161Sriastrad#else
5401.161Sriastrad    pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize);
5411.161Sriastrad#endif
5421.161Sriastrad
5431.161Sriastrad    pRADEONEnt->FB = NULL;
5441.161Sriastrad    info->FB = NULL;
5451.161Sriastrad    return TRUE;
5461.161Sriastrad}
5471.161Sriastrad
5481.161Sriastrad/* Memory map the MMIO region and the frame buffer */
5491.161Sriastradstatic Bool RADEONMapMem(ScrnInfoPtr pScrn)
5501.1Saugustss{
5511.1Saugustss    if (!RADEONMapMMIO(pScrn)) return FALSE;
5521.147Smaxv    if (!RADEONMapFB(pScrn)) {
5531.88Schristos	RADEONUnmapMMIO(pScrn);
5541.1Saugustss	return FALSE;
5551.24Saugustss    }
5561.1Saugustss    return TRUE;
5571.1Saugustss}
5581.1Saugustss
5591.1Saugustss/* Unmap the MMIO region and the frame buffer */
5601.1Saugustssstatic Bool RADEONUnmapMem(ScrnInfoPtr pScrn)
5611.28Saugustss{
5621.133Sskrll    if (!RADEONUnmapMMIO(pScrn) || !RADEONUnmapFB(pScrn)) return FALSE;
5631.41Saugustss    return TRUE;
5641.155Sriastrad}
5651.160Sriastrad
5661.1Saugustssvoid RADEONPllErrataAfterIndex(RADEONInfoPtr info)
5671.169Smrg{
5681.169Smrg    unsigned char *RADEONMMIO = info->MMIO;
5691.159Sriastrad
5701.159Sriastrad    if (!(info->ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS))
5711.155Sriastrad	return;
5721.111Sdyoung
5731.30Saugustss    /* This workaround is necessary on rv200 and RS200 or PLL
5741.169Smrg     * reads may return garbage (among others...)
5751.169Smrg     */
5761.1Saugustss    (void)INREG(RADEON_CLOCK_CNTL_DATA);
5771.73Saugustss    (void)INREG(RADEON_CRTC_GEN_CNTL);
5781.1Saugustss}
5791.160Sriastrad
5801.155Sriastradvoid RADEONPllErrataAfterData(RADEONInfoPtr info)
5811.155Sriastrad{
5821.13Saugustss    unsigned char *RADEONMMIO = info->MMIO;
5831.35Saugustss
5841.155Sriastrad    /* This workarounds is necessary on RV100, RS100 and RS200 chips
5851.155Sriastrad     * or the chip could hang on a subsequent access
5861.155Sriastrad     */
5871.155Sriastrad    if (info->ChipErrata & CHIP_ERRATA_PLL_DELAY) {
5881.160Sriastrad	/* we can't deal with posted writes here ... */
5891.73Saugustss	usleep(5000);
5901.13Saugustss    }
5911.13Saugustss
5921.13Saugustss    /* This function is required to workaround a hardware bug in some (all?)
5931.13Saugustss     * revisions of the R300.  This workaround should be called after every
5941.155Sriastrad     * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
5951.155Sriastrad     * may not be correct.
5961.155Sriastrad     */
5971.155Sriastrad    if (info->ChipErrata & CHIP_ERRATA_R300_CG) {
5981.1Saugustss	uint32_t save, tmp;
5991.13Saugustss
6001.13Saugustss	save = INREG(RADEON_CLOCK_CNTL_INDEX);
6011.13Saugustss	tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
6021.13Saugustss	OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);
6031.13Saugustss	tmp = INREG(RADEON_CLOCK_CNTL_DATA);
6041.13Saugustss	OUTREG(RADEON_CLOCK_CNTL_INDEX, save);
6051.13Saugustss    }
6061.1Saugustss}
6071.13Saugustss
6081.17Saugustss/* Read PLL register */
6091.169Smrgunsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr)
6101.170Sskrll{
6111.1Saugustss    RADEONInfoPtr  info       = RADEONPTR(pScrn);
6121.1Saugustss    unsigned char *RADEONMMIO = info->MMIO;
6131.1Saugustss    uint32_t       data;
6141.69Saugustss
6151.69Saugustss    OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
6161.69Saugustss    RADEONPllErrataAfterIndex(info);
6171.155Sriastrad    data = INREG(RADEON_CLOCK_CNTL_DATA);
6181.155Sriastrad    RADEONPllErrataAfterData(info);
6191.155Sriastrad
6201.155Sriastrad    return data;
6211.69Saugustss}
6221.69Saugustss
6231.1Saugustss/* Write PLL information */
6241.155Sriastradvoid RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, uint32_t data)
6251.155Sriastrad{
6261.155Sriastrad    RADEONInfoPtr  info       = RADEONPTR(pScrn);
6271.155Sriastrad    unsigned char *RADEONMMIO = info->MMIO;
6281.133Sskrll
6291.169Smrg    OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) |
6301.169Smrg				      RADEON_PLL_WR_EN));
6311.121Sriastrad    RADEONPllErrataAfterIndex(info);
6321.133Sskrll    OUTREG(RADEON_CLOCK_CNTL_DATA, data);
6331.121Sriastrad    RADEONPllErrataAfterData(info);
6341.155Sriastrad}
6351.155Sriastrad
6361.121Sriastrad/* Read MC register */
6371.55Saugustssunsigned RADEONINMC(ScrnInfoPtr pScrn, int addr)
6381.55Saugustss{
6391.55Saugustss    RADEONInfoPtr  info       = RADEONPTR(pScrn);
6401.55Saugustss    unsigned char *RADEONMMIO = info->MMIO;
6411.32Saugustss    uint32_t       data;
6421.28Saugustss
6431.121Sriastrad    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
6441.133Sskrll	(info->ChipFamily == CHIP_FAMILY_RS740)) {
6451.121Sriastrad	OUTREG(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
6461.155Sriastrad	data = INREG(RS690_MC_DATA);
6471.155Sriastrad    } else if (info->ChipFamily == CHIP_FAMILY_RS600) {
6481.1Saugustss	OUTREG(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0));
6491.169Smrg	data = INREG(RS600_MC_DATA);
6501.1Saugustss    } else if ((info->ChipFamily == CHIP_FAMILY_RS780) ||
6511.1Saugustss	       (info->ChipFamily == CHIP_FAMILY_RS880)) {
6521.55Saugustss	OUTREG(RS780_MC_INDEX, (addr & RS780_MC_INDEX_MASK));
6531.28Saugustss	data = INREG(RS780_MC_DATA);
6541.155Sriastrad    } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
6551.155Sriastrad	data = 0;
6561.155Sriastrad    } else if (IS_AVIVO_VARIANT) {
6571.155Sriastrad	OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000);
6581.84Sgdt	(void)INREG(AVIVO_MC_INDEX);
6591.121Sriastrad	data = INREG(AVIVO_MC_DATA);
6601.84Sgdt
6611.84Sgdt	OUTREG(AVIVO_MC_INDEX, 0);
6621.84Sgdt	(void)INREG(AVIVO_MC_INDEX);
6631.84Sgdt    } else {
6641.1Saugustss	OUTREG(R300_MC_IND_INDEX, addr & 0x3f);
6651.41Saugustss	(void)INREG(R300_MC_IND_INDEX);
6661.155Sriastrad	data = INREG(R300_MC_IND_DATA);
6671.155Sriastrad
6681.155Sriastrad	OUTREG(R300_MC_IND_INDEX, 0);
6691.155Sriastrad	(void)INREG(R300_MC_IND_INDEX);
6701.41Saugustss    }
6711.156Sriastrad
6721.156Sriastrad    return data;
6731.156Sriastrad}
6741.156Sriastrad
6751.133Sskrll/* Write MC information */
6761.133Sskrllvoid RADEONOUTMC(ScrnInfoPtr pScrn, int addr, uint32_t data)
6771.41Saugustss{
6781.41Saugustss    RADEONInfoPtr  info       = RADEONPTR(pScrn);
6791.169Smrg    unsigned char *RADEONMMIO = info->MMIO;
6801.169Smrg
6811.41Saugustss    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
6821.41Saugustss	(info->ChipFamily == CHIP_FAMILY_RS740)) {
6831.41Saugustss	OUTREG(RS690_MC_INDEX, ((addr & RS690_MC_INDEX_MASK) |
6841.133Sskrll				RS690_MC_INDEX_WR_EN));
6851.121Sriastrad	OUTREG(RS690_MC_DATA, data);
6861.155Sriastrad	OUTREG(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
6871.155Sriastrad    } else if (info->ChipFamily == CHIP_FAMILY_RS600) {
6881.41Saugustss	OUTREG(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) |
6891.132Sskrll				RS600_MC_IND_CITF_ARB0 |
6901.41Saugustss				RS600_MC_IND_WR_EN));
6911.133Sskrll	OUTREG(RS600_MC_DATA, data);
6921.133Sskrll    } else if ((info->ChipFamily == CHIP_FAMILY_RS780) ||
6931.133Sskrll	       (info->ChipFamily == CHIP_FAMILY_RS880)) {
6941.133Sskrll	OUTREG(RS780_MC_INDEX, ((addr & RS780_MC_INDEX_MASK) |
6951.41Saugustss				      RS780_MC_INDEX_WR_EN));
6961.41Saugustss	OUTREG(RS780_MC_DATA, data);
6971.133Sskrll    } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
6981.132Sskrll	// do nothing
6991.41Saugustss    } else if (IS_AVIVO_VARIANT) {
7001.133Sskrll	OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0xff0000);
7011.133Sskrll	(void)INREG(AVIVO_MC_INDEX);
7021.133Sskrll	OUTREG(AVIVO_MC_DATA, data);
7031.41Saugustss	OUTREG(AVIVO_MC_INDEX, 0);
7041.41Saugustss	(void)INREG(AVIVO_MC_INDEX);
7051.169Smrg    } else {
7061.41Saugustss	OUTREG(R300_MC_IND_INDEX, (((addr) & 0x3f) |
7071.41Saugustss				   R300_MC_IND_WR_EN));
7081.167Sriastrad	(void)INREG(R300_MC_IND_INDEX);
7091.133Sskrll	OUTREG(R300_MC_IND_DATA, data);
7101.167Sriastrad	OUTREG(R300_MC_IND_INDEX, 0);
7111.167Sriastrad	(void)INREG(R300_MC_IND_INDEX);
7121.121Sriastrad    }
7131.121Sriastrad}
7141.133Sskrll
7151.121Sriastrad/* Read PCIE register */
7161.155Sriastradunsigned RADEONINPCIE(ScrnInfoPtr pScrn, int addr)
7171.155Sriastrad{
7181.1Saugustss    RADEONInfoPtr  info       = RADEONPTR(pScrn);
7191.57Saugustss    unsigned char *RADEONMMIO = info->MMIO;
7201.155Sriastrad    CARD32         data;
7211.155Sriastrad
7221.1Saugustss    OUTREG(RADEON_PCIE_INDEX, addr & 0xff);
7231.1Saugustss    data = INREG(RADEON_PCIE_DATA);
7241.155Sriastrad
7251.160Sriastrad    return data;
7261.160Sriastrad}
7271.160Sriastrad
7281.155Sriastrad/* Write PCIE register */
7291.1Saugustssvoid RADEONOUTPCIE(ScrnInfoPtr pScrn, int addr, uint32_t data)
7301.1Saugustss{
7311.163Sriastrad    RADEONInfoPtr  info       = RADEONPTR(pScrn);
7321.163Sriastrad    unsigned char *RADEONMMIO = info->MMIO;
7331.1Saugustss
7341.1Saugustss    OUTREG(RADEON_PCIE_INDEX, ((addr) & 0xff));
7351.1Saugustss    OUTREG(RADEON_PCIE_DATA, data);
7361.41Saugustss}
7371.1Saugustss
7381.169Smrg/* Read PCIE PORT register */
7391.169Smrgunsigned R600INPCIE_PORT(ScrnInfoPtr pScrn, int addr)
7401.159Sriastrad{
7411.159Sriastrad    RADEONInfoPtr  info       = RADEONPTR(pScrn);
7421.167Sriastrad    unsigned char *RADEONMMIO = info->MMIO;
7431.167Sriastrad    CARD32         data;
7441.1Saugustss
7451.1Saugustss    OUTREG(R600_PCIE_PORT_INDEX, addr & 0xff);
7461.169Smrg    data = INREG(R600_PCIE_PORT_DATA);
7471.155Sriastrad
7481.1Saugustss    return data;
7491.9Saugustss}
7501.9Saugustss
7511.13Saugustss/* Write PCIE PORT register */
7521.13Saugustssvoid R600OUTPCIE_PORT(ScrnInfoPtr pScrn, int addr, uint32_t data)
7531.13Saugustss{
7541.129Sskrll    RADEONInfoPtr  info       = RADEONPTR(pScrn);
7551.13Saugustss    unsigned char *RADEONMMIO = info->MMIO;
7561.169Smrg
7571.170Sskrll    OUTREG(R600_PCIE_PORT_INDEX, ((addr) & 0xff));
7581.59Saugustss    OUTREG(R600_PCIE_PORT_DATA, data);
7591.13Saugustss}
7601.133Sskrll
7611.133Sskrllstatic Bool radeon_get_mc_idle(ScrnInfoPtr pScrn)
7621.133Sskrll{
7631.41Saugustss    RADEONInfoPtr  info       = RADEONPTR(pScrn);
7641.56Saugustss    unsigned char *RADEONMMIO = info->MMIO;
7651.56Saugustss
7661.56Saugustss    if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
7671.56Saugustss	if (INREG(R600_SRBM_STATUS) & 0x1f00)
7681.133Sskrll	    return FALSE;
7691.56Saugustss	else
7701.56Saugustss	    return TRUE;
7711.167Sriastrad    } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
7721.133Sskrll	if (INREG(R600_SRBM_STATUS) & 0x3f00)
7731.167Sriastrad	    return FALSE;
7741.167Sriastrad	else
7751.133Sskrll	    return TRUE;
7761.84Sgdt    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
7771.84Sgdt	if (INMC(pScrn, RV515_MC_STATUS) & RV515_MC_STATUS_IDLE)
7781.133Sskrll	    return TRUE;
7791.133Sskrll	else
7801.167Sriastrad	    return FALSE;
7811.133Sskrll    } else if (info->ChipFamily == CHIP_FAMILY_RS600) {
7821.133Sskrll	if (INMC(pScrn, RS600_MC_STATUS) & RS600_MC_IDLE)
7831.84Sgdt	    return TRUE;
7841.56Saugustss	else
7851.56Saugustss	    return FALSE;
7861.41Saugustss    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
7871.133Sskrll	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
7881.133Sskrll	if (INMC(pScrn, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE)
7891.28Saugustss	    return TRUE;
7901.133Sskrll	else
7911.30Saugustss	    return FALSE;
7921.9Saugustss    } else if (info->ChipFamily >= CHIP_FAMILY_R520) {
7931.1Saugustss	if (INMC(pScrn, R520_MC_STATUS) & R520_MC_STATUS_IDLE)
7941.1Saugustss	    return TRUE;
7951.163Sriastrad	else
7961.167Sriastrad	    return FALSE;
7971.167Sriastrad    } else if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
7981.167Sriastrad	       (info->ChipFamily == CHIP_FAMILY_RS480)) {
7991.167Sriastrad	if (INREG(RADEON_MC_STATUS) & RADEON_MC_IDLE)
8001.167Sriastrad	    return TRUE;
8011.167Sriastrad	else
8021.167Sriastrad	    return FALSE;
8031.167Sriastrad    } else if (IS_R300_VARIANT) {
8041.163Sriastrad	if (INREG(RADEON_MC_STATUS) & R300_MC_IDLE)
8051.163Sriastrad	    return TRUE;
8061.163Sriastrad	else
8071.163Sriastrad	    return FALSE;
8081.163Sriastrad    } else {
8091.163Sriastrad	if (INREG(RADEON_MC_STATUS) & RADEON_MC_IDLE)
8101.163Sriastrad	    return TRUE;
8111.163Sriastrad	else
8121.169Smrg	    return FALSE;
8131.169Smrg    }
8141.169Smrg}
8151.169Smrg
8161.163Sriastrad#define LOC_FB 0x1
8171.163Sriastrad#define LOC_AGP 0x2
8181.163Sriastradstatic void radeon_write_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, uint32_t fb_loc, uint32_t agp_loc, uint32_t agp_loc_hi)
8191.163Sriastrad{
8201.163Sriastrad    RADEONInfoPtr  info       = RADEONPTR(pScrn);
8211.163Sriastrad    unsigned char *RADEONMMIO = info->MMIO;
8221.163Sriastrad
8231.163Sriastrad    /* evergreen is same as r7xx */
8241.163Sriastrad    if (info->ChipFamily >= CHIP_FAMILY_RV770) {
8251.163Sriastrad	if (mask & LOC_FB)
8261.163Sriastrad	    OUTREG(R700_MC_VM_FB_LOCATION, fb_loc);
8271.163Sriastrad	if (mask & LOC_AGP) {
8281.163Sriastrad	    OUTREG(R700_MC_VM_AGP_BOT, agp_loc);
8291.1Saugustss	    OUTREG(R700_MC_VM_AGP_TOP, agp_loc_hi);
8301.1Saugustss	}
8311.37Saugustss    } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
8321.40Saugustss	if (mask & LOC_FB)
8331.1Saugustss	    OUTREG(R600_MC_VM_FB_LOCATION, fb_loc);
8341.1Saugustss	if (mask & LOC_AGP) {
8351.133Sskrll	    OUTREG(R600_MC_VM_AGP_BOT, agp_loc);
8361.133Sskrll	    OUTREG(R600_MC_VM_AGP_TOP, agp_loc_hi);
8371.28Saugustss	}
8381.1Saugustss    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
8391.1Saugustss	if (mask & LOC_FB)
8401.169Smrg	    OUTMC(pScrn, RV515_MC_FB_LOCATION, fb_loc);
8411.169Smrg	if (mask & LOC_AGP)
8421.169Smrg	    OUTMC(pScrn, RV515_MC_AGP_LOCATION, agp_loc);
8431.26Saugustss	(void)INMC(pScrn, RV515_MC_AGP_LOCATION);
8441.26Saugustss    } else if (info->ChipFamily == CHIP_FAMILY_RS600) {
8451.133Sskrll	if (mask & LOC_FB)
8461.26Saugustss	    OUTMC(pScrn, RS600_MC_FB_LOCATION, fb_loc);
8471.154Sriastrad	if (mask & LOC_AGP)
8481.154Sriastrad	    OUTMC(pScrn, RS600_MC_AGP_LOCATION, agp_loc);
8491.1Saugustss    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
8501.1Saugustss	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
8511.1Saugustss	if (mask & LOC_FB)
8521.47Swiz	    OUTMC(pScrn, RS690_MC_FB_LOCATION, fb_loc);
8531.120Smrg	if (mask & LOC_AGP)
8541.1Saugustss	    OUTMC(pScrn, RS690_MC_AGP_LOCATION, agp_loc);
8551.1Saugustss    } else if (info->ChipFamily >= CHIP_FAMILY_R520) {
8561.120Smrg	if (mask & LOC_FB)
8571.133Sskrll	    OUTMC(pScrn, R520_MC_FB_LOCATION, fb_loc);
8581.1Saugustss	if (mask & LOC_AGP)
8591.170Sskrll	    OUTMC(pScrn, R520_MC_AGP_LOCATION, agp_loc);
8601.120Smrg	(void)INMC(pScrn, R520_MC_FB_LOCATION);
8611.120Smrg    } else {
8621.120Smrg	if (mask & LOC_FB)
8631.169Smrg	    OUTREG(RADEON_MC_FB_LOCATION, fb_loc);
8641.169Smrg	if (mask & LOC_AGP)
8651.12Saugustss	    OUTREG(RADEON_MC_AGP_LOCATION, agp_loc);
8661.12Saugustss    }
8671.152Sriastrad}
8681.12Saugustss
8691.1Saugustssstatic void radeon_read_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, uint32_t *fb_loc, uint32_t *agp_loc, uint32_t *agp_loc_hi)
8701.120Smrg{
8711.1Saugustss    RADEONInfoPtr  info       = RADEONPTR(pScrn);
8721.1Saugustss    unsigned char *RADEONMMIO = info->MMIO;
8731.12Saugustss
8741.140Sriastrad    /* evergreen is same as r7xx */
8751.83Schristos    if (info->ChipFamily >= CHIP_FAMILY_RV770) {
8761.83Schristos	if (mask & LOC_FB)
8771.1Saugustss	    *fb_loc = INREG(R700_MC_VM_FB_LOCATION);
8781.1Saugustss	if (mask & LOC_AGP) {
8791.83Schristos	    *agp_loc = INREG(R700_MC_VM_AGP_BOT);
8801.169Smrg	    *agp_loc_hi = INREG(R700_MC_VM_AGP_TOP);
8811.1Saugustss	}
8821.1Saugustss    } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
8831.83Schristos	if (mask & LOC_FB)
8841.1Saugustss	    *fb_loc = INREG(R600_MC_VM_FB_LOCATION);
8851.1Saugustss	if (mask & LOC_AGP) {
8861.1Saugustss	    *agp_loc = INREG(R600_MC_VM_AGP_BOT);
8871.1Saugustss	    *agp_loc_hi = INREG(R600_MC_VM_AGP_TOP);
8881.1Saugustss	}
8891.84Sgdt    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
8901.169Smrg	if (mask & LOC_FB)
8911.169Smrg	    *fb_loc = INMC(pScrn, RV515_MC_FB_LOCATION);
8921.84Sgdt	if (mask & LOC_AGP) {
8931.84Sgdt	    *agp_loc = INMC(pScrn, RV515_MC_AGP_LOCATION);
8941.120Smrg	    *agp_loc_hi = 0;
8951.84Sgdt	}
8961.120Smrg    } else if (info->ChipFamily == CHIP_FAMILY_RS600) {
8971.133Sskrll	if (mask & LOC_FB)
8981.84Sgdt	    *fb_loc = INMC(pScrn, RS600_MC_FB_LOCATION);
8991.84Sgdt	if (mask & LOC_AGP) {
9001.84Sgdt	    *agp_loc = INMC(pScrn, RS600_MC_AGP_LOCATION);
9011.169Smrg	    *agp_loc_hi = 0;
9021.170Sskrll	}
9031.120Smrg    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
9041.120Smrg	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
9051.120Smrg	if (mask & LOC_FB)
9061.169Smrg	    *fb_loc = INMC(pScrn, RS690_MC_FB_LOCATION);
9071.169Smrg	if (mask & LOC_AGP) {
9081.84Sgdt	    *agp_loc = INMC(pScrn, RS690_MC_AGP_LOCATION);
9091.84Sgdt	    *agp_loc_hi = 0;
9101.152Sriastrad	}
9111.84Sgdt    } else if (info->ChipFamily >= CHIP_FAMILY_R520) {
9121.84Sgdt	if (mask & LOC_FB)
9131.84Sgdt	    *fb_loc = INMC(pScrn, R520_MC_FB_LOCATION);
9141.84Sgdt	if (mask & LOC_AGP) {
9151.84Sgdt	    *agp_loc = INMC(pScrn, R520_MC_AGP_LOCATION);
9161.84Sgdt	    *agp_loc_hi = 0;
9171.140Sriastrad	}
9181.84Sgdt    } else {
9191.140Sriastrad	if (mask & LOC_FB)
9201.84Sgdt	    *fb_loc = INREG(RADEON_MC_FB_LOCATION);
9211.84Sgdt	if (mask & LOC_AGP)
9221.84Sgdt	    *agp_loc = INREG(RADEON_MC_AGP_LOCATION);
9231.84Sgdt    }
9241.84Sgdt}
9251.84Sgdt
9261.84Sgdt#if 0
9271.84Sgdt/* Read PAL information (only used for debugging) */
9281.84Sgdtstatic int RADEONINPAL(int idx)
9291.122Schristos{
9301.84Sgdt    RADEONInfoPtr  info       = RADEONPTR(pScrn);
9311.84Sgdt    unsigned char *RADEONMMIO = info->MMIO;
9321.84Sgdt
9331.84Sgdt    OUTREG(RADEON_PALETTE_INDEX, idx << 16);
9341.84Sgdt    return INREG(RADEON_PALETTE_DATA);
9351.84Sgdt}
9361.84Sgdt#endif
9371.133Sskrll
9381.140Sriastrad/* Wait for vertical sync on primary CRTC */
9391.133Sskrllvoid RADEONWaitForVerticalSync(ScrnInfoPtr pScrn)
9401.84Sgdt{
9411.84Sgdt    RADEONInfoPtr  info       = RADEONPTR(pScrn);
9421.84Sgdt    unsigned char *RADEONMMIO = info->MMIO;
9431.84Sgdt    uint32_t       crtc_gen_cntl;
9441.84Sgdt    struct timeval timeout;
9451.84Sgdt
9461.84Sgdt    crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
9471.84Sgdt    if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
9481.84Sgdt	!(crtc_gen_cntl & RADEON_CRTC_EN))
9491.84Sgdt	return;
9501.84Sgdt
9511.84Sgdt    /* Clear the CRTC_VBLANK_SAVE bit */
9521.84Sgdt    OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);
9531.120Smrg
9541.84Sgdt    /* Wait for it to go back up */
9551.84Sgdt    radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT);
9561.133Sskrll    while (!(INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) &&
9571.137Sskrll        !radeon_timedout(&timeout))
9581.133Sskrll	usleep(100);
9591.133Sskrll}
9601.140Sriastrad
9611.169Smrg/* Wait for vertical sync on secondary CRTC */
9621.10Saugustssvoid RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn)
9631.133Sskrll{
9641.133Sskrll    RADEONInfoPtr  info       = RADEONPTR(pScrn);
9651.133Sskrll    unsigned char *RADEONMMIO = info->MMIO;
9661.30Saugustss    uint32_t       crtc2_gen_cntl;
9671.28Saugustss    struct timeval timeout;
9681.8Saugustss
9691.28Saugustss    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
9701.17Saugustss    if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
9711.8Saugustss	!(crtc2_gen_cntl & RADEON_CRTC2_EN))
9721.8Saugustss	return;
9731.1Saugustss
9741.1Saugustss    /* Clear the CRTC2_VBLANK_SAVE bit */
9751.169Smrg    OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);
9761.83Schristos
9771.9Saugustss    /* Wait for it to go back up */
9781.1Saugustss    radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT);
9791.1Saugustss    while (!(INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) &&
9801.133Sskrll        !radeon_timedout(&timeout))
9811.1Saugustss	usleep(100);
9821.41Saugustss}
9831.120Smrg
9841.41Saugustss
9851.41Saugustss/* Compute log base 2 of val */
9861.120Smrgint RADEONMinBits(int val)
9871.133Sskrll{
9881.41Saugustss    int  bits;
9891.120Smrg
9901.170Sskrll    if (!val) return 1;
9911.120Smrg    for (bits = 0; val; val >>= 1, ++bits);
9921.120Smrg    return bits;
9931.169Smrg}
9941.41Saugustss
9951.41Saugustss/* Compute n/d with rounding */
9961.152Sriastradstatic int RADEONDiv(int n, int d)
9971.41Saugustss{
9981.41Saugustss    return (n + (d / 2)) / d;
9991.41Saugustss}
10001.41Saugustss
10011.41Saugustssstatic Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
10021.140Sriastrad{
10031.41Saugustss    RADEONInfoPtr info = RADEONPTR(pScrn);
10041.140Sriastrad    RADEONPLLPtr  pll  = &info->pll;
10051.41Saugustss    unsigned char *RADEONMMIO = info->MMIO;
10061.169Smrg    unsigned char ppll_div_sel;
10071.41Saugustss    unsigned mpll_fb_div, spll_fb_div, M;
10081.41Saugustss    unsigned xclk, tmp, ref_div;
10091.41Saugustss    int hTotal, vTotal, num, denom, m, n;
10101.41Saugustss    float hz, prev_xtal, vclk, xtal, mpll, spll;
10111.41Saugustss    long total_usecs;
10121.41Saugustss    struct timeval start, stop, to1, to2;
10131.120Smrg    unsigned int f1, f2, f3;
10141.41Saugustss    int tries = 0;
10151.41Saugustss
10161.120Smrg    prev_xtal = 0;
10171.41Saugustss again:
10181.41Saugustss    xtal = 0;
10191.59Saugustss    if (++tries > 10)
10201.1Saugustss           goto failed;
10211.133Sskrll
10221.1Saugustss    gettimeofday(&to1, NULL);
10231.133Sskrll    f1 = INREG(RADEON_CRTC_CRNT_FRAME);
10241.1Saugustss    for (;;) {
10251.1Saugustss       f2 = INREG(RADEON_CRTC_CRNT_FRAME);
10261.147Smaxv       if (f1 != f2)
10271.40Saugustss	    break;
10281.1Saugustss       gettimeofday(&to2, NULL);
10291.1Saugustss       if ((to2.tv_sec - to1.tv_sec) > 1) {
10301.24Saugustss           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Clock not counting...\n");
10311.12Saugustss           goto failed;
10321.12Saugustss       }
10331.155Sriastrad    }
10341.111Sdyoung    gettimeofday(&start, NULL);
10351.12Saugustss    for(;;) {
10361.155Sriastrad       f3 = INREG(RADEON_CRTC_CRNT_FRAME);
10371.120Smrg       if (f3 != f2)
10381.133Sskrll	    break;
10391.12Saugustss       gettimeofday(&to2, NULL);
10401.12Saugustss       if ((to2.tv_sec - start.tv_sec) > 1)
10411.37Saugustss           goto failed;
10421.87Sxtraeme    }
10431.88Schristos    gettimeofday(&stop, NULL);
10441.12Saugustss
10451.10Saugustss    if ((stop.tv_sec - start.tv_sec) != 0)
10461.133Sskrll           goto again;
10471.1Saugustss    total_usecs = abs(stop.tv_usec - start.tv_usec);
10481.133Sskrll    if (total_usecs == 0)
10491.84Sgdt           goto again;
10501.133Sskrll    hz = 1000000.0/(float)total_usecs;
10511.28Saugustss
10521.1Saugustss    hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x3ff) + 1) * 8;
10531.169Smrg    vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0xfff) + 1);
10541.169Smrg    vclk = (float)(hTotal * (float)(vTotal * hz));
10551.169Smrg
10561.26Saugustss    switch((INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x30000) >> 16) {
10571.26Saugustss    case 0:
10581.133Sskrll    default:
10591.26Saugustss        num = 1;
10601.154Sriastrad        denom = 1;
10611.154Sriastrad        break;
10621.1Saugustss    case 1:
10631.1Saugustss        n = ((INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) >> 16) & 0xff);
10641.1Saugustss        m = (INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) & 0xff);
10651.84Sgdt        num = 2*n;
10661.169Smrg        denom = 2*m;
10671.169Smrg        break;
10681.84Sgdt    case 2:
10691.84Sgdt        n = ((INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) >> 8) & 0xff);
10701.120Smrg        m = (INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV) & 0xff);
10711.84Sgdt        num = 2*n;
10721.84Sgdt        denom = 2*m;
10731.120Smrg        break;
10741.133Sskrll     }
10751.84Sgdt
10761.84Sgdt    ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
10771.122Schristos    RADEONPllErrataAfterIndex(info);
10781.84Sgdt
10791.170Sskrll    n = (INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
10801.170Sskrll    m = (INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff);
10811.120Smrg
10821.120Smrg    num *= n;
10831.120Smrg    denom *= m;
10841.169Smrg
10851.169Smrg    switch ((INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) {
10861.84Sgdt    case 1:
10871.84Sgdt        denom *= 2;
10881.152Sriastrad        break;
10891.84Sgdt    case 2:
10901.84Sgdt        denom *= 4;
10911.84Sgdt        break;
10921.84Sgdt    case 3:
10931.84Sgdt        denom *= 8;
10941.84Sgdt        break;
10951.140Sriastrad    case 4:
10961.84Sgdt        denom *= 3;
10971.84Sgdt        break;
10981.140Sriastrad    case 6:
10991.84Sgdt        denom *= 6;
11001.84Sgdt        break;
11011.84Sgdt    case 7:
11021.84Sgdt        denom *= 12;
11031.84Sgdt        break;
11041.84Sgdt    }
11051.84Sgdt
11061.84Sgdt    xtal = (int)(vclk *(float)denom/(float)num);
11071.84Sgdt
11081.84Sgdt    if ((xtal > 26900000) && (xtal < 27100000))
11091.84Sgdt        xtal = 2700;
11101.84Sgdt    else if ((xtal > 14200000) && (xtal < 14400000))
11111.84Sgdt        xtal = 1432;
11121.84Sgdt    else if ((xtal > 29400000) && (xtal < 29600000))
11131.84Sgdt        xtal = 2950;
11141.84Sgdt    else
11151.140Sriastrad       goto again;
11161.84Sgdt failed:
11171.140Sriastrad    if (xtal == 0) {
11181.84Sgdt       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to probe xtal value ! "
11191.84Sgdt                  "Using default 27Mhz\n");
11201.84Sgdt       xtal = 2700;
11211.84Sgdt    } else {
11221.84Sgdt       if (prev_xtal == 0) {
11231.133Sskrll	   prev_xtal = xtal;
11241.133Sskrll	   tries = 0;
11251.84Sgdt	   goto again;
11261.84Sgdt       } else if (prev_xtal != xtal) {
11271.84Sgdt	   prev_xtal = 0;
11281.84Sgdt	   goto again;
11291.84Sgdt       }
11301.84Sgdt    }
11311.84Sgdt
11321.84Sgdt    tmp = INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV);
11331.84Sgdt    ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff;
11341.84Sgdt
11351.84Sgdt    /* Some sanity check based on the BIOS code .... */
11361.84Sgdt    if (ref_div < 2) {
11371.84Sgdt       uint32_t tmp;
11381.120Smrg       tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
11391.84Sgdt       if (IS_R300_VARIANT
11401.84Sgdt	   || (info->ChipFamily == CHIP_FAMILY_RS300)
11411.133Sskrll	   || (info->ChipFamily == CHIP_FAMILY_RS400)
11421.137Sskrll	   || (info->ChipFamily == CHIP_FAMILY_RS480))
11431.133Sskrll	   ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >>
11441.133Sskrll	       R300_PPLL_REF_DIV_ACC_SHIFT;
11451.140Sriastrad       else
11461.83Schristos	   ref_div = tmp & RADEON_PPLL_REF_DIV_MASK;
11471.1Saugustss       if (ref_div < 2)
11481.1Saugustss	   ref_div = 12;
11491.169Smrg    }
11501.133Sskrll
11511.133Sskrll    /* Calculate "base" xclk straight from MPLL, though that isn't
11521.28Saugustss     * really useful (hopefully). This isn't called XCLK anymore on
11531.28Saugustss     * radeon's...
11541.8Saugustss     */
11551.36Saugustss    mpll_fb_div = (tmp & 0xff00) >> 8;
11561.36Saugustss    spll_fb_div = (tmp & 0xff0000) >> 16;
11571.8Saugustss    M = (tmp & 0xff);
11581.8Saugustss    xclk = RADEONDiv((2 * mpll_fb_div * xtal), (M));
11591.1Saugustss
11601.1Saugustss    /*
11611.1Saugustss     * Calculate MCLK based on MCLK-A
11621.133Sskrll     */
11631.1Saugustss    mpll = (2.0 * (float)mpll_fb_div * (xtal / 100.0)) / (float)M;
11641.69Saugustss    spll = (2.0 * (float)spll_fb_div * (xtal / 100.0)) / (float)M;
11651.133Sskrll
11661.133Sskrll    tmp = INPLL(pScrn, RADEON_MCLK_CNTL) & 0x7;
11671.133Sskrll    switch(tmp) {
11681.133Sskrll    case 1: info->mclk = mpll; break;
11691.140Sriastrad    case 2: info->mclk = mpll / 2.0; break;
11701.69Saugustss    case 3: info->mclk = mpll / 4.0; break;
11711.83Schristos    case 4: info->mclk = mpll / 8.0; break;
11721.69Saugustss    case 7: info->mclk = spll; break;
11731.69Saugustss    default:
11741.169Smrg           info->mclk = 200.00;
11751.69Saugustss           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported MCLKA source"
11761.133Sskrll                      " setting %d, can't probe MCLK value !\n", tmp);
11771.69Saugustss    }
11781.69Saugustss
11791.69Saugustss    /*
11801.69Saugustss     * Calculate SCLK
11811.69Saugustss     */
11821.69Saugustss    tmp = INPLL(pScrn, RADEON_SCLK_CNTL) & 0x7;
11831.69Saugustss    switch(tmp) {
11841.69Saugustss    case 1: info->sclk = spll; break;
11851.69Saugustss    case 2: info->sclk = spll / 2.0; break;
11861.69Saugustss    case 3: info->sclk = spll / 4.0; break;
11871.133Sskrll    case 4: info->sclk = spll / 8.0; break;
11881.69Saugustss    case 7: info->sclk = mpll; break;
11891.1Saugustss    default:
11901.133Sskrll           info->sclk = 200.00;
11911.1Saugustss           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported SCLK source"
11921.133Sskrll                      " setting %d, can't probe SCLK value !\n", tmp);
11931.1Saugustss    }
11941.1Saugustss
11951.147Smaxv    /* we're done, hopefully these are sane values */
11961.40Saugustss    pll->reference_div = ref_div;
11971.12Saugustss    pll->xclk = xclk;
11981.12Saugustss    pll->reference_freq = xtal;
11991.24Saugustss
12001.12Saugustss    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probed PLL values: xtal: %f Mhz, "
12011.12Saugustss              "sclk: %f Mhz, mclk: %f Mhz\n", xtal/100.0, info->sclk, info->mclk);
12021.155Sriastrad
12031.111Sdyoung    return TRUE;
12041.12Saugustss}
12051.155Sriastrad
12061.120Smrgstatic void RADEONGetClockInfo(ScrnInfoPtr pScrn)
12071.133Sskrll{
12081.12Saugustss    RADEONInfoPtr info = RADEONPTR (pScrn);
12091.12Saugustss    RADEONPLLPtr pll = &info->pll;
12101.147Smaxv    double min_dotclock;
12111.111Sdyoung
12121.12Saugustss    if (RADEONGetClockInfoFromBIOS(pScrn)) {
12131.99Scube	if (pll->reference_div < 2) {
12141.18Saugustss	    /* retrive it from register setting for fitting into current PLL algorithm.
12151.18Saugustss	       We'll probably need a new routine to calculate the best ref_div from BIOS
12161.18Saugustss	       provided min_input_pll and max_input_pll
12171.18Saugustss	    */
12181.106Sdyoung	    if (!IS_AVIVO_VARIANT) {
12191.106Sdyoung		uint32_t tmp;
12201.106Sdyoung		tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
12211.18Saugustss		if (IS_R300_VARIANT ||
12221.12Saugustss		    (info->ChipFamily == CHIP_FAMILY_RS300) ||
12231.12Saugustss		    (info->ChipFamily == CHIP_FAMILY_RS400) ||
12241.147Smaxv		    (info->ChipFamily == CHIP_FAMILY_RS480)) {
12251.111Sdyoung		    pll->reference_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
12261.12Saugustss		} else {
12271.111Sdyoung		    pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
12281.12Saugustss		}
12291.12Saugustss	    }
12301.25Saugustss	    if (pll->reference_div < 2) pll->reference_div = 12;
12311.12Saugustss	}
12321.169Smrg    } else {
12331.169Smrg	xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
12341.170Sskrll		    "Video BIOS not detected, using default clock settings!\n");
12351.12Saugustss
12361.162Sriastrad       /* Default min/max PLL values */
12371.162Sriastrad       if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) {
12381.162Sriastrad	   pll->pll_in_min = 100;
12391.162Sriastrad	   pll->pll_in_max = 1350;
12401.162Sriastrad	   pll->pll_out_min = 20000;
12411.162Sriastrad	   pll->pll_out_max = 50000;
12421.162Sriastrad       } else {
12431.162Sriastrad	   pll->pll_in_min = 40;
12441.162Sriastrad	   pll->pll_in_max = 500;
12451.162Sriastrad	   pll->pll_out_min = 12500;
12461.162Sriastrad	   pll->pll_out_max = 35000;
12471.162Sriastrad       }
12481.162Sriastrad
12491.162Sriastrad       if (!RADEONProbePLLParameters(pScrn)) {
12501.12Saugustss	   if (info->IsIGP)
12511.96Ssmb	       pll->reference_freq = 1432;
12521.157Sriastrad	   else
12531.162Sriastrad	       pll->reference_freq = 2700;
12541.162Sriastrad
12551.162Sriastrad	   pll->reference_div = 12;
12561.162Sriastrad	   pll->xclk = 10300;
12571.157Sriastrad
12581.157Sriastrad	   info->sclk = 200.00;
12591.157Sriastrad	   info->mclk = 200.00;
12601.164Sriastrad       }
12611.12Saugustss    }
12621.12Saugustss
12631.12Saugustss    /* card limits for computing PLLs */
12641.129Sskrll    if (IS_AVIVO_VARIANT) {
12651.12Saugustss	pll->min_post_div = 2;
12661.12Saugustss	pll->max_post_div = 0x7f;
12671.12Saugustss	pll->min_frac_feedback_div = 0;
12681.12Saugustss	pll->max_frac_feedback_div = 9;
12691.166Sriastrad    } else {
12701.166Sriastrad	pll->min_post_div = 1;
12711.166Sriastrad	pll->max_post_div = 12; //16 on crtc0
12721.166Sriastrad	pll->min_frac_feedback_div = 0;
12731.166Sriastrad	pll->max_frac_feedback_div = 0;
12741.166Sriastrad    }
12751.120Smrg    pll->min_ref_div = 2;
12761.12Saugustss    pll->max_ref_div = 0x3ff;
12771.12Saugustss    pll->min_feedback_div = 4;
12781.164Sriastrad    pll->max_feedback_div = 0x7ff;
12791.164Sriastrad    pll->best_vco = 0;
12801.165Sriastrad
12811.164Sriastrad    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
12821.12Saugustss		"PLL parameters: rf=%u rd=%u min=%u max=%u; xclk=%u\n",
12831.166Sriastrad		pll->reference_freq,
12841.166Sriastrad		pll->reference_div,
12851.166Sriastrad		(unsigned)pll->pll_out_min, (unsigned)pll->pll_out_max,
12861.12Saugustss		pll->xclk);
12871.120Smrg
12881.12Saugustss    /* (Some?) Radeon BIOSes seem too lie about their minimum dot
12891.12Saugustss     * clocks.  Allow users to override the detected minimum dot clock
12901.60Sgehenna     * value (e.g., and allow it to be suitable for TV sets).
12911.12Saugustss     */
12921.163Sriastrad    if (xf86GetOptValFreq(info->Options, OPTION_MIN_DOTCLOCK,
12931.163Sriastrad			  OPTUNITS_MHZ, &min_dotclock)) {
12941.163Sriastrad	if (min_dotclock < 12 || min_dotclock*100 >= pll->pll_out_max) {
12951.163Sriastrad	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
12961.155Sriastrad		       "Illegal minimum dotclock specified %.2f MHz "
12971.12Saugustss		       "(option ignored)\n",
12981.33Saugustss		       min_dotclock);
12991.163Sriastrad	} else {
13001.163Sriastrad	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
13011.163Sriastrad		       "Forced minimum dotclock to %.2f MHz "
13021.163Sriastrad		       "(instead of detected %.2f MHz)\n",
13031.134Smsaitoh		       min_dotclock, ((double)pll->pll_out_min/1000));
13041.155Sriastrad	    pll->pll_out_min = min_dotclock * 1000;
13051.12Saugustss	}
13061.157Sriastrad    }
13071.97Srmind}
13081.97Srmind
13091.97Srmind
13101.120Smrg
13111.97Srmind/* This is called by RADEONPreInit to set up the default visual */
13121.97SrmindBool RADEONPreInitVisual(ScrnInfoPtr pScrn)
13131.97Srmind{
13141.120Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
13151.120Smrg
13161.120Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb))
13171.133Sskrll	return FALSE;
13181.12Saugustss
13191.1Saugustss    switch (pScrn->depth) {
13201.37Saugustss    case 8:
13211.133Sskrll    case 15:
13221.1Saugustss    case 16:
13231.1Saugustss    case 24:
13241.120Smrg	break;
13251.133Sskrll
13261.1Saugustss    default:
13271.1Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13281.169Smrg		   "Given depth (%d) is not supported by %s driver\n",
13291.169Smrg		   pScrn->depth, RADEON_DRIVER_NAME);
13301.1Saugustss	return FALSE;
13311.1Saugustss    }
13321.1Saugustss
13331.1Saugustss    xf86PrintDepthBpp(pScrn);
13341.169Smrg
13351.52Saugustss    info->pix24bpp                   = xf86GetBppFromDepth(pScrn,
13361.52Saugustss							   pScrn->depth);
13371.1Saugustss    info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
13381.1Saugustss    info->CurrentLayout.depth        = pScrn->depth;
13391.1Saugustss    info->CurrentLayout.pixel_bytes  = pScrn->bitsPerPixel / 8;
13401.34Saugustss    info->CurrentLayout.pixel_code   = (pScrn->bitsPerPixel != 16
13411.1Saugustss				       ? pScrn->bitsPerPixel
13421.1Saugustss				       : pScrn->depth);
13431.170Sskrll
13441.170Sskrll    if (info->pix24bpp == 24) {
13451.169Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13461.169Smrg		   "Radeon does NOT support 24bpp\n");
13471.1Saugustss	return FALSE;
13481.152Sriastrad    }
13491.8Saugustss
13501.152Sriastrad    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
13511.120Smrg	       "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n",
13521.97Srmind	       pScrn->depth,
13531.1Saugustss	       info->CurrentLayout.pixel_bytes,
13541.1Saugustss	       info->CurrentLayout.pixel_bytes > 1 ? "s" : "",
13551.41Saugustss	       info->pix24bpp);
13561.133Sskrll
13571.42Saugustss    if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE;
13581.41Saugustss
13591.41Saugustss    if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
13601.41Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13611.120Smrg		   "Default visual (%s) is not supported at depth %d\n",
13621.133Sskrll		   xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
13631.48Syamt	return FALSE;
13641.41Saugustss    }
13651.169Smrg    return TRUE;
13661.169Smrg}
13671.41Saugustss
13681.41Saugustss/* This is called by RADEONPreInit to handle all color weight issues */
13691.41SaugustssBool RADEONPreInitWeight(ScrnInfoPtr pScrn)
13701.41Saugustss{
13711.41Saugustss    RADEONInfoPtr  info = RADEONPTR(pScrn);
13721.169Smrg
13731.169Smrg				/* Save flag for 6 bit DAC to use for
13741.41Saugustss				   setting CRTC registers.  Otherwise use
13751.152Sriastrad				   an 8 bit DAC, even if xf86SetWeight sets
13761.152Sriastrad				   pScrn->rgbBits to some value other than
13771.41Saugustss				   8. */
13781.152Sriastrad    info->dac6bits = FALSE;
13791.41Saugustss
13801.152Sriastrad    if (pScrn->depth > 8) {
13811.41Saugustss	rgb  defaultWeight = { 0, 0, 0 };
13821.169Smrg
13831.169Smrg	if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE;
13841.41Saugustss    } else {
13851.41Saugustss	pScrn->rgbBits = 8;
13861.48Syamt	if (xf86ReturnOptValBool(info->Options, OPTION_DAC_6BIT, FALSE)) {
13871.48Syamt	    pScrn->rgbBits = 6;
13881.133Sskrll	    info->dac6bits = TRUE;
13891.74Schristos	}
13901.48Syamt    }
13911.48Syamt
13921.48Syamt    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
13931.140Sriastrad	       "Using %d bits per RGB (%d bit DAC)\n",
13941.74Schristos	       pScrn->rgbBits, info->dac6bits ? 6 : 8);
13951.48Syamt
13961.74Schristos    return TRUE;
13971.48Syamt}
13981.48Syamt
13991.152Sriastradvoid RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
14001.48Syamt				      RADEONInfoPtr info)
14011.48Syamt{
14021.48Syamt    save->mc_fb_location = info->mc_fb_location;
14031.48Syamt    save->mc_agp_location = info->mc_agp_location;
14041.48Syamt
14051.41Saugustss    if (IS_AVIVO_VARIANT) {
14061.41Saugustss	save->mc_agp_location_hi = info->mc_agp_location_hi;
14071.133Sskrll    } else {
14081.133Sskrll	save->display_base_addr = info->fbLocation;
14091.41Saugustss	save->display2_base_addr = info->fbLocation;
14101.41Saugustss	save->ov0_base_addr = info->fbLocation;
14111.152Sriastrad    }
14121.120Smrg}
14131.97Srmind
14141.41Saugustssstatic void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
14151.41Saugustss{
14161.84Sgdt    RADEONInfoPtr  info   = RADEONPTR(pScrn);
14171.133Sskrll    unsigned char *RADEONMMIO = info->MMIO;
14181.84Sgdt    uint64_t       mem_size;
14191.84Sgdt    uint64_t       aper_size;
14201.84Sgdt
14211.120Smrg    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &info->mc_fb_location,
14221.133Sskrll				   &info->mc_agp_location, &info->mc_agp_location_hi);
14231.84Sgdt
14241.84Sgdt    /* We shouldn't use info->videoRam here which might have been clipped
14251.84Sgdt     * but the real video RAM instead
14261.169Smrg     */
14271.169Smrg    if (info->ChipFamily >= CHIP_FAMILY_PALM) {
14281.84Sgdt	/* size in bytes on fusion */
14291.84Sgdt	mem_size = INREG(R600_CONFIG_MEMSIZE);
14301.84Sgdt	/* size in MB on fusion */
14311.84Sgdt	aper_size = INREG(R600_CONFIG_APER_SIZE) * 1024 * 1024;
14321.84Sgdt    } else if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
14331.169Smrg	/* size in MB on evergreen */
14341.84Sgdt	/* XXX watch for overflow!!! */
14351.84Sgdt	mem_size = INREG(R600_CONFIG_MEMSIZE) * 1024 * 1024;
14361.84Sgdt	aper_size = INREG(R600_CONFIG_APER_SIZE) * 1024 * 1024;
14371.84Sgdt    } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
14381.84Sgdt	mem_size = INREG(R600_CONFIG_MEMSIZE);
14391.84Sgdt	aper_size = INREG(R600_CONFIG_APER_SIZE);
14401.84Sgdt    } else {
14411.84Sgdt	mem_size = INREG(RADEON_CONFIG_MEMSIZE);
14421.152Sriastrad	aper_size = INREG(RADEON_CONFIG_APER_SIZE);
14431.152Sriastrad    }
14441.84Sgdt
14451.84Sgdt    if (mem_size == 0)
14461.84Sgdt	mem_size = 0x800000;
14471.84Sgdt
14481.84Sgdt    /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM -
14491.140Sriastrad       Novell bug 204882 + along with lots of ubuntu ones */
14501.84Sgdt    if (aper_size > mem_size)
14511.84Sgdt	mem_size = aper_size;
14521.84Sgdt
14531.84Sgdt    /* don't map the whole FB in the internal address space.
14541.84Sgdt     * we don't currently use fb space larger than the aperture
14551.84Sgdt     * size and on cards with more than 512 MB of vram, this can overflow
14561.84Sgdt     * the internal top of gart calculation on some systems.
14571.84Sgdt     * Limit it to cards with more than 512 MB as this causes problems
14581.84Sgdt     * on some other cards due to the way the ddx and drm set up the
14591.84Sgdt     * internal memory map.
14601.84Sgdt     * See fdo bug 24301.
14611.84Sgdt     */
14621.84Sgdt    if (mem_size > 0x20000000)
14631.84Sgdt	mem_size = aper_size;
14641.140Sriastrad
14651.84Sgdt#ifdef XF86DRI
14661.84Sgdt    /* Apply memory map limitation if using an old DRI */
14671.84Sgdt    if (info->directRenderingEnabled && !info->dri->newMemoryMap) {
14681.169Smrg	    if (aper_size < mem_size)
14691.84Sgdt		mem_size = aper_size;
14701.84Sgdt    }
14711.84Sgdt#endif
14721.84Sgdt
14731.84Sgdt    if ((info->ChipFamily != CHIP_FAMILY_RS600) &&
14741.84Sgdt	(info->ChipFamily != CHIP_FAMILY_RS690) &&
14751.84Sgdt	(info->ChipFamily != CHIP_FAMILY_RS740) &&
14761.84Sgdt	(info->ChipFamily != CHIP_FAMILY_RS780) &&
14771.84Sgdt	(info->ChipFamily != CHIP_FAMILY_RS880) &&
14781.84Sgdt	(info->ChipFamily != CHIP_FAMILY_PALM) &&
14791.152Sriastrad	(info->ChipFamily != CHIP_FAMILY_SUMO) &&
14801.120Smrg	(info->ChipFamily != CHIP_FAMILY_SUMO2)) {
14811.97Srmind	if (info->IsIGP)
14821.84Sgdt	    info->mc_fb_location = INREG(RADEON_NB_TOM);
14831.84Sgdt	else
14841.84Sgdt#ifdef XF86DRI
14851.133Sskrll	/* Old DRI has restrictions on the memory map */
14861.84Sgdt	if ( info->directRenderingEnabled &&
14871.84Sgdt	     info->dri->pKernelDRMVersion->version_minor < 10 )
14881.84Sgdt	    info->mc_fb_location = (mem_size - 1) & 0xffff0000U;
14891.120Smrg	else
14901.133Sskrll#endif
14911.84Sgdt	{
14921.84Sgdt	    uint64_t aper0_base;
14931.84Sgdt
14941.169Smrg	    if (info->ChipFamily >= CHIP_FAMILY_R600) {
14951.169Smrg		aper0_base = INREG(R600_CONFIG_F0_BASE);
14961.84Sgdt	    } else {
14971.84Sgdt		aper0_base = INREG(RADEON_CONFIG_APER_0_BASE);
14981.84Sgdt	    }
14991.84Sgdt
15001.84Sgdt	    /* Recent chips have an "issue" with the memory controller, the
15011.169Smrg	     * location must be aligned to the size. We just align it down,
15021.84Sgdt	     * too bad if we walk over the top of system memory, we don't
15031.84Sgdt	     * use DMA without a remapped anyway.
15041.84Sgdt	     * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
15051.84Sgdt	     */
15061.84Sgdt	    if (info->ChipFamily == CHIP_FAMILY_RV280 ||
15071.84Sgdt		info->ChipFamily == CHIP_FAMILY_R300 ||
15081.84Sgdt		info->ChipFamily == CHIP_FAMILY_R350 ||
15091.84Sgdt		info->ChipFamily == CHIP_FAMILY_RV350 ||
15101.152Sriastrad		info->ChipFamily == CHIP_FAMILY_RV380 ||
15111.152Sriastrad		info->ChipFamily == CHIP_FAMILY_R420 ||
15121.84Sgdt		info->ChipFamily == CHIP_FAMILY_RV410)
15131.84Sgdt		    aper0_base &= ~(mem_size - 1);
15141.84Sgdt
15151.84Sgdt	    if (info->ChipFamily >= CHIP_FAMILY_R600) {
15161.84Sgdt		uint64_t mc_fb = ((aper0_base >> 24) & 0xffff) |
15171.84Sgdt		    (((aper0_base + mem_size - 1) >> 8) & 0xffff0000);
15181.122Schristos		info->mc_fb_location = mc_fb & 0xffffffff;
15191.84Sgdt		ErrorF("mc fb loc is %08x\n", (unsigned int)info->mc_fb_location);
15201.84Sgdt	    } else {
15211.84Sgdt		uint64_t mc_fb = ((aper0_base >> 16) & 0xffff) |
15221.84Sgdt		    ((aper0_base + mem_size - 1) & 0xffff0000U);
15231.84Sgdt		info->mc_fb_location = mc_fb & 0xffffffff;
15241.140Sriastrad	    }
15251.140Sriastrad	}
15261.84Sgdt    }
15271.84Sgdt    if (info->ChipFamily >= CHIP_FAMILY_R600) {
15281.84Sgdt	info->fbLocation = ((uint64_t)info->mc_fb_location & 0xffff) << 24;
15291.84Sgdt    } else {
15301.84Sgdt	info->fbLocation = ((uint64_t)info->mc_fb_location & 0xffff) << 16;
15311.133Sskrll    }
15321.133Sskrll    /* Just disable the damn AGP apertures for now, it may be
15331.84Sgdt     * re-enabled later by the DRM
15341.84Sgdt     */
15351.169Smrg    if (IS_AVIVO_VARIANT)
15361.84Sgdt	info->mc_agp_location = 0x003f0000;
15371.84Sgdt    else
15381.84Sgdt	info->mc_agp_location = 0xffffffc0;
15391.84Sgdt    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
15401.84Sgdt	       "RADEONInitMemoryMap() : \n");
15411.84Sgdt    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
15421.84Sgdt	       "  mem_size         : 0x%08x\n", (unsigned)mem_size);
15431.84Sgdt    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
15441.84Sgdt	       "  MC_FB_LOCATION   : 0x%08x\n", (unsigned)info->mc_fb_location);
15451.84Sgdt    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
15461.152Sriastrad	       "  MC_AGP_LOCATION  : 0x%08x\n",
15471.120Smrg	       (unsigned)info->mc_agp_location);
15481.97Srmind}
15491.84Sgdt
15501.84Sgdtstatic void RADEONGetVRamType(ScrnInfoPtr pScrn)
15511.37Saugustss{
15521.40Saugustss    RADEONInfoPtr  info   = RADEONPTR(pScrn);
15531.1Saugustss    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
15541.133Sskrll    unsigned char *RADEONMMIO = info->MMIO;
15551.1Saugustss    uint32_t tmp;
15561.28Saugustss
15571.1Saugustss    if (info->IsIGP || (info->ChipFamily >= CHIP_FAMILY_R300))
15581.133Sskrll	info->IsDDR = TRUE;
15591.21Saugustss    else if (INREG(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR)
15601.1Saugustss	info->IsDDR = TRUE;
15611.169Smrg    else
15621.169Smrg	info->IsDDR = FALSE;
15631.169Smrg
15641.1Saugustss    if ((info->ChipFamily >= CHIP_FAMILY_R600) &&
15651.28Saugustss	(info->ChipFamily <= CHIP_FAMILY_RV635)) {
15661.28Saugustss	int chansize;
15671.133Sskrll	/* r6xx */
15681.1Saugustss	tmp = INREG(R600_RAMCFG);
15691.133Sskrll	if (tmp & R600_CHANSIZE_OVERRIDE)
15701.59Saugustss	    chansize = 16;
15711.28Saugustss	else if (tmp & R600_CHANSIZE)
15721.28Saugustss	    chansize = 64;
15731.133Sskrll	else
15741.28Saugustss	    chansize = 32;
15751.28Saugustss	if (info->ChipFamily == CHIP_FAMILY_R600)
15761.133Sskrll	    info->RamWidth = 8 * chansize;
15771.1Saugustss	else if (info->ChipFamily == CHIP_FAMILY_RV670)
15781.1Saugustss	    info->RamWidth = 4 * chansize;
15791.28Saugustss	else if ((info->ChipFamily == CHIP_FAMILY_RV610) ||
15801.28Saugustss		 (info->ChipFamily == CHIP_FAMILY_RV620))
15811.133Sskrll	    info->RamWidth = chansize;
15821.28Saugustss	else if ((info->ChipFamily == CHIP_FAMILY_RV630) ||
15831.28Saugustss		 (info->ChipFamily == CHIP_FAMILY_RV635))
15841.28Saugustss	    info->RamWidth = 2 * chansize;
15851.133Sskrll    } else if (info->ChipFamily == CHIP_FAMILY_RV515) {
15861.130Sskrll	/* rv515/rv550 */
15871.130Sskrll	tmp = INMC(pScrn, RV515_MC_CNTL);
15881.130Sskrll	tmp &= RV515_MEM_NUM_CHANNELS_MASK;
15891.1Saugustss	switch (tmp) {
15901.1Saugustss	case 0: info->RamWidth = 64; break;
15911.81Schristos	case 1: info->RamWidth = 128; break;
15921.1Saugustss	default: info->RamWidth = 128; break;
15931.21Saugustss	}
15941.21Saugustss    } else if ((info->ChipFamily >= CHIP_FAMILY_R520) &&
15951.1Saugustss	       (info->ChipFamily <= CHIP_FAMILY_RV570)){
15961.1Saugustss	/* r520/rv530/rv560/rv570/r580 */
15971.1Saugustss	tmp = INMC(pScrn, R520_MC_CNTL0);
15981.1Saugustss	switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) {
15991.133Sskrll	case 0: info->RamWidth = 32; break;
16001.1Saugustss	case 1: info->RamWidth = 64; break;
16011.1Saugustss	case 2: info->RamWidth = 128; break;
16021.1Saugustss	case 3: info->RamWidth = 256; break;
16031.37Saugustss	default: info->RamWidth = 64; break;
16041.40Saugustss	}
16051.1Saugustss	if (tmp & R520_MC_CHANNEL_SIZE) {
16061.1Saugustss	    info->RamWidth *= 2;
16071.1Saugustss	}
16081.28Saugustss    } else if ((info->ChipFamily >= CHIP_FAMILY_R300) &&
16091.1Saugustss	       (info->ChipFamily <= CHIP_FAMILY_RV410)) {
16101.169Smrg	/* r3xx, r4xx */
16111.169Smrg	tmp = INREG(RADEON_MEM_CNTL);
16121.1Saugustss	tmp &= R300_MEM_NUM_CHANNELS_MASK;
16131.1Saugustss	switch (tmp) {
16141.148Sbouyer	case 0: info->RamWidth = 64; break;
16151.148Sbouyer	case 1: info->RamWidth = 128; break;
16161.1Saugustss	case 2: info->RamWidth = 256; break;
16171.1Saugustss	default: info->RamWidth = 128; break;
16181.1Saugustss	}
16191.133Sskrll    } else if ((info->ChipFamily == CHIP_FAMILY_RV100) ||
16201.1Saugustss	       (info->ChipFamily == CHIP_FAMILY_RS100) ||
16211.169Smrg	       (info->ChipFamily == CHIP_FAMILY_RS200)){
16221.1Saugustss	tmp = INREG(RADEON_MEM_CNTL);
16231.28Saugustss	if (tmp & RV100_HALF_MODE)
16241.28Saugustss	    info->RamWidth = 32;
16251.133Sskrll	else
16261.1Saugustss	    info->RamWidth = 64;
16271.169Smrg
16281.1Saugustss	if (!pRADEONEnt->HasCRTC2) {
16291.1Saugustss	    info->RamWidth /= 4;
16301.133Sskrll	    info->IsDDR = TRUE;
16311.56Saugustss	}
16321.28Saugustss    } else if (info->ChipFamily <= CHIP_FAMILY_RV280) {
16331.133Sskrll	tmp = INREG(RADEON_MEM_CNTL);
16341.133Sskrll	if (tmp & RADEON_MEM_NUM_CHANNELS_MASK)
16351.1Saugustss	    info->RamWidth = 128;
16361.1Saugustss	else
16371.133Sskrll	    info->RamWidth = 64;
16381.1Saugustss    } else {
16391.1Saugustss	/* newer IGPs */
16401.37Saugustss	info->RamWidth = 128;
16411.40Saugustss    }
16421.1Saugustss
16431.133Sskrll    /* This may not be correct, as some cards can have half of channel disabled
16441.28Saugustss     * ToDo: identify these cases
16451.1Saugustss     */
16461.28Saugustss}
16471.28Saugustss
16481.133Sskrll/*
16491.133Sskrll * Depending on card genertation, chipset bugs, etc... the amount of vram
16501.1Saugustss * accessible to the CPU can vary. This function is our best shot at figuring
16511.1Saugustss * it out. Returns a value in KB.
16521.37Saugustss */
16531.40Saugustssstatic uint32_t RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
16541.92Schristos{
16551.1Saugustss    RADEONInfoPtr  info   = RADEONPTR(pScrn);
16561.8Saugustss    unsigned char *RADEONMMIO = info->MMIO;
16571.28Saugustss    uint32_t	   aper_size;
16581.133Sskrll    unsigned char  byte;
16591.1Saugustss
16601.1Saugustss    if (info->ChipFamily >= CHIP_FAMILY_CEDAR)
16611.1Saugustss	/* size in MB on evergreen and fusion */
16621.1Saugustss	aper_size = INREG(R600_CONFIG_APER_SIZE) * 1024;
16631.1Saugustss    else if (info->ChipFamily >= CHIP_FAMILY_R600)
16641.1Saugustss	aper_size = INREG(R600_CONFIG_APER_SIZE) / 1024;
16651.1Saugustss    else
16661.2Saugustss	aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024;
16671.133Sskrll
16681.133Sskrll#ifdef XF86DRI
16691.133Sskrll    /* If we use the DRI, we need to check if it's a version that has the
16701.141Smanu     * bug of always cropping MC_FB_LOCATION to one aperture, in which case
16711.1Saugustss     * we need to limit the amount of accessible video memory
16721.169Smrg     */
16731.169Smrg    if (info->directRenderingEnabled &&
16741.159Sriastrad	info->dri->pKernelDRMVersion->version_minor < 23) {
16751.159Sriastrad	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
16761.169Smrg		   "[dri] limiting video memory to one aperture of %uK\n",
16771.1Saugustss		   (unsigned)aper_size);
16781.2Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
16791.2Saugustss		   "[dri] detected radeon kernel module version 1.%d but"
16801.2Saugustss		   " 1.23 or newer is required for full memory mapping.\n",
16811.133Sskrll		   info->dri->pKernelDRMVersion->version_minor);
16821.8Saugustss	info->dri->newMemoryMap = FALSE;
16831.13Saugustss	return aper_size;
16841.133Sskrll    }
16851.51Saugustss    info->dri->newMemoryMap = TRUE;
16861.8Saugustss#endif /* XF86DRI */
16871.51Saugustss
16881.133Sskrll    if (info->ChipFamily >= CHIP_FAMILY_R600)
16891.8Saugustss	return aper_size;
16901.8Saugustss
16911.8Saugustss    /* Set HDP_APER_CNTL only on cards that are known not to be broken,
16921.8Saugustss     * that is has the 2nd generation multifunction PCI interface
16931.133Sskrll     */
16941.17Saugustss    if (info->ChipFamily == CHIP_FAMILY_RV280 ||
16951.141Smanu	info->ChipFamily == CHIP_FAMILY_RV350 ||
16961.141Smanu	info->ChipFamily == CHIP_FAMILY_RV380 ||
16971.141Smanu	info->ChipFamily == CHIP_FAMILY_R420 ||
16981.141Smanu	info->ChipFamily == CHIP_FAMILY_RV410 ||
16991.141Smanu	IS_AVIVO_VARIANT) {
17001.141Smanu	    OUTREGP (RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL,
17011.141Smanu		     ~RADEON_HDP_APER_CNTL);
17021.133Sskrll	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
17031.84Sgdt		       "Generation 2 PCI interface, using max accessible memory\n");
17041.84Sgdt	    return aper_size * 2;
17051.133Sskrll    }
17061.84Sgdt
17071.84Sgdt    /* Older cards have all sorts of funny issues to deal with. First
17081.133Sskrll     * check if it's a multifunction card by reading the PCI config
17091.84Sgdt     * header type... Limit those to one aperture size
17101.84Sgdt     */
17111.133Sskrll    PCI_READ_BYTE(info->PciInfo, &byte, 0xe);
17121.84Sgdt    if (byte & 0x80) {
17131.84Sgdt	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
17141.84Sgdt		   "Generation 1 PCI interface in multifunction mode"
17151.84Sgdt		   ", accessible memory limited to one aperture\n");
17161.133Sskrll	return aper_size;
17171.167Sriastrad    }
17181.167Sriastrad
17191.84Sgdt    /* Single function older card. We read HDP_APER_CNTL to see how the BIOS
17201.84Sgdt     * have set it up. We don't write this as it's broken on some ASICs but
17211.84Sgdt     * we expect the BIOS to have done the right thing (might be too optimistic...)
17221.133Sskrll     */
17231.133Sskrll    if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
17241.133Sskrll        return aper_size * 2;
17251.133Sskrll
17261.133Sskrll    return aper_size;
17271.84Sgdt}
17281.133Sskrll
17291.84Sgdtstatic Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
17301.84Sgdt{
17311.84Sgdt    RADEONInfoPtr  info   = RADEONPTR(pScrn);
17321.84Sgdt    EntityInfoPtr  pEnt   = info->pEnt;
17331.84Sgdt    GDevPtr        dev    = pEnt->device;
17341.84Sgdt    unsigned char *RADEONMMIO = info->MMIO;
17351.133Sskrll    MessageType    from = X_PROBED;
17361.140Sriastrad    uint32_t         accessible, bar_size;
17371.133Sskrll
17381.84Sgdt    if ((!IS_AVIVO_VARIANT) && info->IsIGP) {
17391.84Sgdt	uint32_t tom = INREG(RADEON_NB_TOM);
17401.84Sgdt
17411.133Sskrll	pScrn->videoRam = (((tom >> 16) -
17421.84Sgdt			    (tom & 0xffff) + 1) << 6);
17431.133Sskrll
17441.167Sriastrad	OUTREG(RADEON_CONFIG_MEMSIZE, pScrn->videoRam * 1024);
17451.133Sskrll    } else {
17461.84Sgdt	if (info->ChipFamily >= CHIP_FAMILY_PALM)
17471.84Sgdt	    /* R600_CONFIG_MEMSIZE is bytes on fusion */
17481.84Sgdt	    pScrn->videoRam = INREG(R600_CONFIG_MEMSIZE) / 1024;
17491.84Sgdt	else if (info->ChipFamily >= CHIP_FAMILY_CEDAR)
17501.133Sskrll	    /* R600_CONFIG_MEMSIZE is MB on evergreen */
17511.84Sgdt	    /* XXX watch for overflow!!! */
17521.84Sgdt	    pScrn->videoRam = INREG(R600_CONFIG_MEMSIZE) * 1024;
17531.84Sgdt	else if (info->ChipFamily >= CHIP_FAMILY_R600)
17541.133Sskrll	    pScrn->videoRam = INREG(R600_CONFIG_MEMSIZE) / 1024;
17551.167Sriastrad	else {
17561.84Sgdt	    /* Read VRAM size from card */
17571.84Sgdt	    pScrn->videoRam      = INREG(RADEON_CONFIG_MEMSIZE) / 1024;
17581.84Sgdt
17591.84Sgdt	    /* Some production boards of m6 will return 0 if it's 8 MB */
17601.84Sgdt	    if (pScrn->videoRam == 0) {
17611.133Sskrll		pScrn->videoRam = 8192;
17621.84Sgdt		OUTREG(RADEON_CONFIG_MEMSIZE, 0x800000);
17631.84Sgdt	    }
17641.133Sskrll	}
17651.84Sgdt    }
17661.84Sgdt
17671.133Sskrll    /* Get accessible memory */
17681.84Sgdt    accessible = RADEONGetAccessibleVRAM(pScrn);
17691.84Sgdt
17701.133Sskrll    /* Crop it to the size of the PCI BAR */
17711.84Sgdt    bar_size = PCI_REGION_SIZE(info->PciInfo, 0) / 1024;
17721.84Sgdt    if (bar_size == 0)
17731.133Sskrll	bar_size = 0x20000;
17741.84Sgdt    if (accessible > bar_size)
17751.84Sgdt	accessible = bar_size;
17761.84Sgdt
17771.84Sgdt    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
17781.133Sskrll	       "Detected total video RAM=%dK, accessible=%uK (PCI BAR=%uK)\n",
17791.167Sriastrad	       pScrn->videoRam, (unsigned)accessible, (unsigned)bar_size);
17801.167Sriastrad    if (pScrn->videoRam > accessible)
17811.84Sgdt	pScrn->videoRam = accessible;
17821.84Sgdt
17831.84Sgdt    if (!IS_AVIVO_VARIANT) {
17841.133Sskrll	info->MemCntl            = INREG(RADEON_SDRAM_MODE_REG);
17851.133Sskrll	info->BusCntl            = INREG(RADEON_BUS_CNTL);
17861.133Sskrll    }
17871.167Sriastrad
17881.84Sgdt    RADEONGetVRamType(pScrn);
17891.133Sskrll
17901.84Sgdt    if (dev->videoRam) {
17911.84Sgdt	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
17921.84Sgdt		   "Video RAM override, using %d kB instead of %d kB\n",
17931.84Sgdt		   dev->videoRam,
17941.84Sgdt		   pScrn->videoRam);
17951.84Sgdt	from             = X_CONFIG;
17961.84Sgdt	pScrn->videoRam  = dev->videoRam;
17971.133Sskrll    }
17981.84Sgdt
17991.84Sgdt    xf86DrvMsg(pScrn->scrnIndex, from,
18001.84Sgdt	       "Mapped VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR");
18011.84Sgdt
18021.122Schristos    /* Do this before we truncate since we only map fb once */
18031.84Sgdt    info->FbMapSize  = (pScrn->videoRam & ~1023) * 1024;
18041.84Sgdt
18051.84Sgdt    if (info->IsPrimary) {
18061.133Sskrll	pScrn->videoRam /= 2;
18071.167Sriastrad	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
18081.133Sskrll		   "Using %dk of videoram for primary head\n",
18091.84Sgdt		   pScrn->videoRam);
18101.84Sgdt    } else if (info->IsSecondary) {
18111.133Sskrll	pScrn->videoRam /= 2;
18121.84Sgdt	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
18131.84Sgdt		   "Using %dk of videoram for secondary head\n",
18141.84Sgdt		   pScrn->videoRam);
18151.84Sgdt    }
18161.84Sgdt    pScrn->videoRam  &= ~1023;
18171.84Sgdt
18181.133Sskrll    /* if the card is PCI Express reserve the last 32k for the gart table */
18191.84Sgdt#ifdef XF86DRI
18201.84Sgdt    if (info->cardType == CARD_PCIE && info->directRenderingEnabled)
18211.84Sgdt      /* work out the size of pcie aperture */
18221.84Sgdt        info->FbSecureSize = RADEONDRIGetPciAperTableSize(pScrn);
18231.84Sgdt    else
18241.84Sgdt#endif
18251.133Sskrll	info->FbSecureSize = 0;
18261.84Sgdt
18271.84Sgdt    return TRUE;
18281.84Sgdt}
18291.84Sgdt
18301.133Sskrll
18311.122Schristos/* This is called by RADEONPreInit to handle config file overrides for
18321.84Sgdt * things like chipset and memory regions.  Also determine memory size
18331.84Sgdt * and type.  If memory type ever needs an override, put it in this
18341.84Sgdt * routine.
18351.84Sgdt */
18361.84Sgdtstatic Bool RADEONPreInitChipType(ScrnInfoPtr pScrn)
18371.84Sgdt{
18381.133Sskrll    RADEONInfoPtr  info   = RADEONPTR(pScrn);
18391.84Sgdt    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
18401.2Saugustss    EntityInfoPtr  pEnt   = info->pEnt;
18411.2Saugustss    GDevPtr        dev    = pEnt->device;
18421.2Saugustss    unsigned char *RADEONMMIO = info->MMIO;
18431.2Saugustss    MessageType    from = X_PROBED;
18441.1Saugustss    int i;
18451.133Sskrll#ifdef XF86DRI
18461.1Saugustss    const char *s;
18471.1Saugustss    uint32_t cmd_stat;
18481.30Saugustss#endif
18491.8Saugustss
18501.8Saugustss    /* Chipset */
18511.8Saugustss    from = X_PROBED;
18521.8Saugustss    if (dev->chipset && *dev->chipset) {
18531.1Saugustss	info->Chipset  = xf86StringToToken(RADEONChipsets, dev->chipset);
18541.28Saugustss	from           = X_CONFIG;
18551.28Saugustss    } else if (dev->chipID >= 0) {
18561.133Sskrll	info->Chipset  = dev->chipID;
18571.1Saugustss	from           = X_CONFIG;
18581.1Saugustss    } else {
18591.1Saugustss	info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
18601.2Saugustss    }
18611.133Sskrll
18621.138Sws    pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
18631.53Saugustss    if (!pScrn->chipset) {
18641.53Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
18651.53Saugustss		   "ChipID 0x%04x is not recognized\n", info->Chipset);
18661.53Saugustss	return FALSE;
18671.133Sskrll    }
18681.53Saugustss    if (info->Chipset < 0) {
18691.133Sskrll	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
18701.53Saugustss		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
18711.1Saugustss	return FALSE;
18721.1Saugustss    }
18731.1Saugustss    xf86DrvMsg(pScrn->scrnIndex, from,
18741.55Saugustss	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
18751.58Schristos	       pScrn->chipset,
18761.28Saugustss	       info->Chipset);
18771.133Sskrll
18781.1Saugustss    pRADEONEnt->HasCRTC2 = TRUE;
18791.28Saugustss    info->IsMobility = FALSE;
18801.133Sskrll    info->IsIGP = FALSE;
18811.58Schristos    info->IsDellServer = FALSE;
18821.1Saugustss    info->HasSingleDAC = FALSE;
18831.1Saugustss    info->InternalTVOut = TRUE;
18841.2Saugustss    info->get_hardcoded_edid_from_bios = FALSE;
18851.133Sskrll
18861.1Saugustss    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
18871.55Saugustss	if (info->Chipset == RADEONCards[i].pci_device_id) {
18881.58Schristos	    RADEONCardInfo *card = &RADEONCards[i];
18891.28Saugustss	    info->ChipFamily = card->chip_family;
18901.133Sskrll	    info->IsMobility = card->mobility;
18911.58Schristos	    info->IsIGP = card->igp;
18921.58Schristos	    pRADEONEnt->HasCRTC2 = !card->nocrtc2;
18931.28Saugustss	    info->HasSingleDAC = card->singledac;
18941.133Sskrll	    info->InternalTVOut = !card->nointtvout;
18951.1Saugustss	    break;
18961.1Saugustss	}
18971.1Saugustss    }
18981.133Sskrll
18991.28Saugustss    if (info->ChipFamily >= CHIP_FAMILY_SUMO) {
19001.133Sskrll	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
19011.58Schristos		   "Chipset: \"%s\" (ChipID = 0x%04x) requires KMS\n",
19021.28Saugustss		   pScrn->chipset,
19031.133Sskrll		   info->Chipset);
19041.133Sskrll	return FALSE;
19051.12Saugustss    }
19061.58Schristos
19071.58Schristos    switch (info->Chipset) {
19081.133Sskrll    case PCI_CHIP_RN50_515E:  /* RN50 is based on the RV100 but 3D isn't guaranteed to work.  YMMV. */
19091.1Saugustss    case PCI_CHIP_RN50_5969:
19101.1Saugustss	/* Some Sun servers have a hardcoded edid so KVMs work properly */
19111.1Saugustss	if ((PCI_SUB_VENDOR_ID(info->PciInfo) == 0x108e) &&
19121.1Saugustss	    (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x4133))
19131.1Saugustss	    info->get_hardcoded_edid_from_bios = TRUE;
19141.1Saugustss    case PCI_CHIP_RV100_QY:
19151.1Saugustss    case PCI_CHIP_RV100_QZ:
19161.133Sskrll	/* DELL triple-head configuration. */
19171.28Saugustss	if (((PCI_SUB_VENDOR_ID(info->PciInfo) == PCI_VENDOR_DELL) &&
19181.133Sskrll	     ((PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016c) ||
19191.58Schristos	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016d) ||
19201.133Sskrll	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016e) ||
19211.1Saugustss	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x016f) ||
19221.1Saugustss	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0170) ||
19231.1Saugustss	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x017d) ||
19241.133Sskrll	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x017e) ||
19251.28Saugustss	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0183) ||
19261.133Sskrll	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x018a) ||
19271.58Schristos	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x019a) ||
19281.58Schristos	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x01b1) ||
19291.58Schristos	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x01b2) ||
19301.1Saugustss	      (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x0205))) ||
19311.58Schristos           ((PCI_SUB_VENDOR_ID(info->PciInfo) == PCI_VENDOR_HP) &&
19321.58Schristos              (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x31fb))) {
19331.28Saugustss	    info->IsDellServer = TRUE;
19341.133Sskrll	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DELL/HP server detected, force to special setup\n");
19351.133Sskrll	}
19361.1Saugustss	break;
19371.58Schristos    case PCI_CHIP_RS482_5974:
19381.133Sskrll	/* RH BZ 444586 - non mobility version
19391.1Saugustss 	 * Dell appear to have the Vostro 1100 with a mobility part with the same pci-id */
19401.1Saugustss	if ((PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1462) &&
19411.1Saugustss            (PCI_SUB_DEVICE_ID(info->PciInfo) == 0x7141)) {
19421.133Sskrll		info->IsMobility = FALSE;
19431.28Saugustss	}
19441.133Sskrll    default:
19451.58Schristos	break;
19461.58Schristos    }
19471.58Schristos
19481.1Saugustss    from               = X_PROBED;
19491.58Schristos    info->LinearAddr   = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & ~0x1ffffffULL;
19501.58Schristos    pScrn->memPhysBase = info->LinearAddr;
19511.58Schristos    if (dev->MemBase) {
19521.28Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
19531.133Sskrll		   "Linear address override, using 0x%016lx instead of 0x%016llx\n",
19541.133Sskrll		   dev->MemBase,
19551.1Saugustss		   info->LinearAddr);
19561.58Schristos	info->LinearAddr = dev->MemBase;
19571.133Sskrll	from             = X_CONFIG;
19581.1Saugustss    } else if (!info->LinearAddr) {
19591.1Saugustss	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
19601.1Saugustss		   "No valid linear framebuffer address\n");
19611.1Saugustss	return FALSE;
19621.1Saugustss    }
19631.1Saugustss    xf86DrvMsg(pScrn->scrnIndex, from,
19641.1Saugustss	       "Linear framebuffer at 0x%016llx\n", info->LinearAddr);
19651.1Saugustss
19661.133Sskrll#ifndef XSERVER_LIBPCIACCESS
19671.104Spooka				/* BIOS */
19681.133Sskrll    from              = X_PROBED;
19691.133Sskrll    info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
19701.58Schristos    if (info->BIOSAddr) {
19711.58Schristos	xf86DrvMsg(pScrn->scrnIndex, from,
19721.92Schristos		   "BIOS at 0x%08lx\n", (unsigned long)info->BIOSAddr);
19731.1Saugustss    }
19741.1Saugustss#endif
19751.1Saugustss
19761.1Saugustss				/* Read registers used to determine options */
19771.1Saugustss    /* Check chip errata */
19781.1Saugustss    info->ChipErrata = 0;
19791.79Syamt
19801.30Saugustss    if (info->ChipFamily == CHIP_FAMILY_R300 &&
19811.133Sskrll	(INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
19821.133Sskrll	== RADEON_CFG_ATI_REV_A11)
19831.1Saugustss	    info->ChipErrata |= CHIP_ERRATA_R300_CG;
19841.68Smycroft
19851.68Smycroft    if (info->ChipFamily == CHIP_FAMILY_RV200 ||
19861.2Saugustss	info->ChipFamily == CHIP_FAMILY_RS200)
19871.58Schristos	    info->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS;
19881.68Smycroft
19891.28Saugustss    if (info->ChipFamily == CHIP_FAMILY_RV100 ||
19901.133Sskrll	info->ChipFamily == CHIP_FAMILY_RS100 ||
19911.2Saugustss	info->ChipFamily == CHIP_FAMILY_RS200)
19921.68Smycroft	    info->ChipErrata |= CHIP_ERRATA_PLL_DELAY;
19931.1Saugustss
19941.1Saugustss#ifdef XF86DRI
19951.1Saugustss				/* AGP/PCI */
19961.58Schristos    /* Proper autodetection of an AGP capable device requires examining
19971.1Saugustss     * PCI config registers to determine if the device implements extended
19981.1Saugustss     * PCI capabilities, and then walking the capability list as indicated
19991.1Saugustss     * in the PCI 2.2 and AGP 2.0 specifications, to determine if AGP
20001.74Schristos     * capability is present.  The procedure is outlined as follows:
20011.133Sskrll     *
20021.133Sskrll     * 1) Test bit 4 (CAP_LIST) of the PCI status register of the device
20031.1Saugustss     *    to determine wether or not this device implements any extended
20041.2Saugustss     *    capabilities.  If this bit is zero, then the device is a PCI 2.1
20051.133Sskrll     *    or earlier device and is not AGP capable, and we can conclude it
20061.1Saugustss     *    to be a PCI device.
20071.58Schristos     *
20081.58Schristos     * 2) If bit 4 of the status register is set, then the device implements
20091.58Schristos     *    extended capabilities.  There is an 8 bit wide capabilities pointer
20101.58Schristos     *    register located at offset 0x34 in PCI config space which points to
20111.58Schristos     *    the first capability in a linked list of extended capabilities that
20121.58Schristos     *    this device implements.  The lower two bits of this register are
20131.133Sskrll     *    reserved and MBZ so must be masked out.
20141.1Saugustss     *
20151.1Saugustss     * 3) The extended capabilities list is formed by one or more extended
20161.133Sskrll     *    capabilities structures which are aligned on DWORD boundaries.
20171.1Saugustss     *    The first byte of the structure is the capability ID (CAP_ID)
20181.92Schristos     *    indicating what extended capability this structure refers to.  The
20191.1Saugustss     *    second byte of the structure is an offset from the beginning of
20201.1Saugustss     *    PCI config space pointing to the next capability in the linked
20211.1Saugustss     *    list (NEXT_PTR) or NULL (0x00) at the end of the list.  The lower
20221.1Saugustss     *    two bits of this pointer are reserved and MBZ.  By examining the
20231.1Saugustss     *    CAP_ID of each capability and walking through the list, we will
20241.1Saugustss     *    either find the AGP_CAP_ID (0x02) indicating this device is an
20251.58Schristos     *    AGP device, or we'll reach the end of the list, indicating it is
20261.1Saugustss     *    a PCI device.
20271.79Syamt     *
20281.133Sskrll     * Mike A. Harris <mharris@redhat.com>
20291.1Saugustss     *
20301.1Saugustss     * References:
20311.1Saugustss     *	- PCI Local Bus Specification Revision 2.2, Chapter 6
20321.1Saugustss     *	- AGP Interface Specification Revision 2.0, Section 6.1.5
20331.1Saugustss     */
20341.1Saugustss
20351.57Saugustss    info->cardType = CARD_PCI;
20361.74Schristos
20371.58Schristos    PCI_READ_LONG(info->PciInfo, &cmd_stat, PCI_CMD_STAT_REG);
20381.74Schristos    if (cmd_stat & RADEON_CAP_LIST) {
20391.1Saugustss	uint32_t cap_ptr, cap_id;
20401.1Saugustss
20411.1Saugustss	PCI_READ_LONG(info->PciInfo, &cap_ptr, RADEON_CAPABILITIES_PTR_PCI_CONFIG);
20421.1Saugustss	cap_ptr &= RADEON_CAP_PTR_MASK;
20431.1Saugustss
20441.140Sriastrad	while(cap_ptr != RADEON_CAP_ID_NULL) {
20451.133Sskrll	    PCI_READ_LONG(info->PciInfo, &cap_id, cap_ptr);
20461.1Saugustss	    if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) {
20471.1Saugustss		info->cardType = CARD_AGP;
20481.1Saugustss		break;
20491.1Saugustss	    }
20501.1Saugustss	    if ((cap_id & 0xff)== RADEON_CAP_ID_EXP) {
20511.1Saugustss		info->cardType = CARD_PCIE;
20521.133Sskrll		break;
20531.133Sskrll	    }
20541.1Saugustss	    cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK;
20551.2Saugustss	}
20561.2Saugustss    }
20571.91Sdrochner
20581.2Saugustss    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
20591.89Spavel	       (info->cardType==CARD_PCI) ? "PCI" :
20601.142Spgoyette		(info->cardType==CARD_PCIE) ? "PCIE" : "AGP");
20611.142Spgoyette
20621.145Spgoyette    /* treat PCIE IGP cards as PCI */
20631.142Spgoyette    if (info->cardType == CARD_PCIE && info->IsIGP)
20641.142Spgoyette	info->cardType = CARD_PCI;
20651.142Spgoyette
20661.142Spgoyette    /* some rs4xx cards report as agp */
20671.142Spgoyette    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
20681.142Spgoyette	(info->ChipFamily == CHIP_FAMILY_RS480))
20691.142Spgoyette	info->cardType = CARD_PCI;
20701.1Saugustss
20711.133Sskrll    if ((info->ChipFamily >= CHIP_FAMILY_R600) && info->IsIGP)
20721.1Saugustss	info->cardType = CARD_PCIE;
20731.133Sskrll
20741.1Saugustss    /* not sure about gart table requirements */
20751.1Saugustss    if ((info->ChipFamily == CHIP_FAMILY_RS600) && info->IsIGP)
20761.147Smaxv	info->cardType = CARD_PCIE;
20771.92Schristos
20781.12Saugustss    if ((s = xf86GetOptValString(info->Options, OPTION_BUS_TYPE))) {
20791.12Saugustss	if (strcmp(s, "AGP") == 0) {
20801.24Saugustss	    info->cardType = CARD_AGP;
20811.12Saugustss	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into AGP mode\n");
20821.12Saugustss	} else if ((strcmp(s, "PCI") == 0) ||
20831.155Sriastrad		   (strcmp(s, "PCIE") == 0)) {
20841.111Sdyoung	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
20851.155Sriastrad		(info->ChipFamily == CHIP_FAMILY_RS480) ||
20861.155Sriastrad		(info->ChipFamily == CHIP_FAMILY_RS690) ||
20871.30Saugustss		(info->ChipFamily == CHIP_FAMILY_RS740)) {
20881.133Sskrll		info->cardType = CARD_PCI;
20891.12Saugustss		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI mode\n");
20901.12Saugustss	    } else if (info->ChipFamily >= CHIP_FAMILY_RV380) {
20911.147Smaxv		info->cardType = CARD_PCIE;
20921.78Schristos		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI Express mode\n");
20931.1Saugustss	    } else {
20941.24Saugustss		info->cardType = CARD_PCI;
20951.84Sgdt		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI mode\n");
20961.1Saugustss	    }
20971.1Saugustss	} else {
20981.155Sriastrad	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
20991.133Sskrll		       "Invalid BusType option, using detected type\n");
21001.1Saugustss	}
21011.155Sriastrad    }
21021.155Sriastrad#endif
21031.155Sriastrad#ifdef RENDER
21041.155Sriastrad    info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL,
21051.113Sjakllsch					     info->Chipset != PCI_CHIP_RN50_515E &&
21061.84Sgdt					     info->Chipset != PCI_CHIP_RN50_5969);
21071.84Sgdt#endif
21081.154Sriastrad
21091.154Sriastrad    info->r4xx_atom = FALSE;
21101.120Smrg    if (((info->ChipFamily == CHIP_FAMILY_R420) || (info->ChipFamily == CHIP_FAMILY_RV410)) &&
21111.120Smrg	xf86ReturnOptValBool(info->Options, OPTION_R4XX_ATOM, FALSE)) {
21121.84Sgdt	info->r4xx_atom = TRUE;
21131.84Sgdt	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using ATOMBIOS for R4xx chip\n");
21141.84Sgdt    }
21151.84Sgdt
21161.41Saugustss    return TRUE;
21171.41Saugustss}
21181.84Sgdt
21191.84Sgdt
21201.84Sgdtstatic void RADEONPreInitDDC(ScrnInfoPtr pScrn)
21211.84Sgdt{
21221.1Saugustss    RADEONInfoPtr  info = RADEONPTR(pScrn);
21231.1Saugustss /* vbeInfoPtr     pVbe; */
21241.84Sgdt
21251.84Sgdt    info->ddc1     = FALSE;
21261.84Sgdt    info->ddc_bios = FALSE;
21271.84Sgdt    if (!xf86LoadSubModule(pScrn, "ddc")) {
21281.84Sgdt	info->ddc2 = FALSE;
21291.84Sgdt    } else {
21301.84Sgdt	info->ddc2 = TRUE;
21311.84Sgdt    }
21321.84Sgdt
21331.84Sgdt    /* DDC can use I2C bus */
21341.84Sgdt    /* Load I2C if we have the code to use it */
21351.84Sgdt    if (info->ddc2) {
21361.84Sgdt	xf86LoadSubModule(pScrn, "i2c");
21371.84Sgdt    }
21381.84Sgdt}
21391.84Sgdt
21401.155Sriastrad/* This is called by RADEONPreInit to initialize gamma correction */
21411.155Sriastradstatic Bool RADEONPreInitGamma(ScrnInfoPtr pScrn)
21421.84Sgdt{
21431.84Sgdt    Gamma  zeros = { 0.0, 0.0, 0.0 };
21441.1Saugustss
21451.84Sgdt    if (!xf86SetGamma(pScrn, zeros)) return FALSE;
21461.84Sgdt    return TRUE;
21471.84Sgdt}
21481.84Sgdt
21491.84Sgdt/* This is called by RADEONPreInit to initialize the hardware cursor */
21501.84Sgdtstatic Bool RADEONPreInitCursor(ScrnInfoPtr pScrn)
21511.84Sgdt{
21521.84Sgdt    RADEONInfoPtr  info = RADEONPTR(pScrn);
21531.84Sgdt
21541.84Sgdt    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
21551.84Sgdt	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
21561.84Sgdt    }
21571.84Sgdt    return TRUE;
21581.84Sgdt}
21591.84Sgdt
21601.84Sgdt/* This is called by RADEONPreInit to initialize hardware acceleration */
21611.84Sgdtstatic Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
21621.84Sgdt{
21631.84Sgdt    RADEONInfoPtr  info = RADEONPTR(pScrn);
21641.84Sgdt    MessageType from;
21651.84Sgdt#if defined(USE_EXA) && defined(USE_XAA)
21661.84Sgdt    char *optstr;
21671.84Sgdt#endif
21681.84Sgdt#ifdef XF86DRI /* zaphod FbMapSize is wrong, but no dri then */
21691.84Sgdt    int maxy = info->FbMapSize / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes);
21701.84Sgdt#endif
21711.84Sgdt
21721.120Smrg    if (!(info->accel_state = calloc(1, sizeof(struct radeon_accel_state)))) {
21731.84Sgdt	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
21741.155Sriastrad	return FALSE;
21751.133Sskrll    }
21761.62Sjdolecek    info->accel_state->fifo_slots                 = 0;
21771.62Sjdolecek
21781.62Sjdolecek    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
21791.62Sjdolecek	(info->ChipFamily == CHIP_FAMILY_RS200) ||
21801.62Sjdolecek	(info->ChipFamily == CHIP_FAMILY_RS300) ||
21811.62Sjdolecek	(info->ChipFamily == CHIP_FAMILY_RS400) ||
21821.120Smrg	(info->ChipFamily == CHIP_FAMILY_RS480) ||
21831.62Sjdolecek	(info->ChipFamily == CHIP_FAMILY_RS600) ||
21841.120Smrg	(info->ChipFamily == CHIP_FAMILY_RS690) ||
21851.158Sthorpej	(info->ChipFamily == CHIP_FAMILY_RS740))
21861.120Smrg	info->accel_state->has_tcl = FALSE;
21871.62Sjdolecek    else {
21881.62Sjdolecek	info->accel_state->has_tcl = TRUE;
21891.62Sjdolecek    }
21901.88Schristos
21911.62Sjdolecek    /* if we have shadow fb bail */
21921.62Sjdolecek    if (info->r600_shadow_fb) {
21931.135Smrg	info->useEXA = FALSE;
21941.153Sriastrad	return TRUE;
21951.135Smrg    }
21961.153Sriastrad
21971.153Sriastrad#ifdef XF86DRI
21981.153Sriastrad    if ((!info->directRenderingEnabled) ||
21991.153Sriastrad	(maxy <= pScrn->virtualY * 3) ||
22001.153Sriastrad	(pScrn->videoRam <= 32768))
22011.153Sriastrad	info->useEXA = FALSE;
22021.153Sriastrad    else
22031.153Sriastrad	info->useEXA = TRUE;
22041.62Sjdolecek#else
22051.153Sriastrad	info->useEXA = FALSE;
22061.62Sjdolecek#endif
22071.62Sjdolecek
22081.62Sjdolecek    if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
22091.88Schristos	int errmaj = 0, errmin = 0;
22101.62Sjdolecek
22111.62Sjdolecek	from = X_DEFAULT;
22121.135Smrg#if defined(USE_EXA)
22131.153Sriastrad#if defined(USE_XAA)
22141.135Smrg	optstr = (char *)xf86GetOptValString(info->Options, OPTION_ACCELMETHOD);
22151.153Sriastrad	if (optstr != NULL) {
22161.153Sriastrad	    if (xf86NameCmp(optstr, "EXA") == 0) {
22171.153Sriastrad		from = X_CONFIG;
22181.153Sriastrad		info->useEXA = TRUE;
22191.153Sriastrad	    } else if (xf86NameCmp(optstr, "XAA") == 0) {
22201.153Sriastrad		from = X_CONFIG;
22211.62Sjdolecek		if (info->ChipFamily < CHIP_FAMILY_R600)
22221.153Sriastrad		    info->useEXA = FALSE;
22231.153Sriastrad	    }
22241.62Sjdolecek	}
22251.62Sjdolecek#else /* USE_XAA */
22261.153Sriastrad	info->useEXA = TRUE;
22271.153Sriastrad#endif /* !USE_XAA */
22281.153Sriastrad#else
22291.62Sjdolecek	info->useEXA = FALSE;
22301.153Sriastrad#endif /* USE_EXA */
22311.62Sjdolecek        if (info->ChipFamily < CHIP_FAMILY_R600)
22321.62Sjdolecek	    xf86DrvMsg(pScrn->scrnIndex, from,
22331.84Sgdt		       "Using %s acceleration architecture\n",
22341.84Sgdt		       info->useEXA ? "EXA" : "XAA");
22351.84Sgdt	else
22361.84Sgdt	    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
22371.135Smrg		       "Will attempt to use R6xx/R7xx EXA support if DRI is enabled.\n");
22381.153Sriastrad
22391.135Smrg#ifdef USE_EXA
22401.153Sriastrad	if (info->useEXA) {
22411.153Sriastrad	    info->exaReq.majorversion = EXA_VERSION_MAJOR;
22421.153Sriastrad	    info->exaReq.minorversion = EXA_VERSION_MINOR;
22431.153Sriastrad
22441.84Sgdt	    if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
22451.84Sgdt			       &info->exaReq, &errmaj, &errmin)) {
22461.84Sgdt		LoaderErrorMsg(NULL, "exa", errmaj, errmin);
22471.84Sgdt		return FALSE;
22481.84Sgdt	    }
22491.153Sriastrad	}
22501.153Sriastrad#endif /* USE_EXA */
22511.153Sriastrad#ifdef USE_XAA
22521.153Sriastrad	if (!info->useEXA) {
22531.153Sriastrad	    info->xaaReq.majorversion = 1;
22541.153Sriastrad	    info->xaaReq.minorversion = 2;
22551.153Sriastrad
22561.153Sriastrad	    if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL,
22571.84Sgdt			   &info->xaaReq, &errmaj, &errmin)) {
22581.153Sriastrad		info->xaaReq.minorversion = 1;
22591.84Sgdt
22601.84Sgdt		if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL,
22611.84Sgdt			       &info->xaaReq, &errmaj, &errmin)) {
22621.84Sgdt		    info->xaaReq.minorversion = 0;
22631.84Sgdt
22641.84Sgdt		    if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL,
22651.135Smrg			       &info->xaaReq, &errmaj, &errmin)) {
22661.153Sriastrad			LoaderErrorMsg(NULL, "xaa", errmaj, errmin);
22671.135Smrg			return FALSE;
22681.153Sriastrad		    }
22691.153Sriastrad		}
22701.153Sriastrad	    }
22711.153Sriastrad	}
22721.84Sgdt#endif /* USE_XAA */
22731.84Sgdt    } else {
22741.84Sgdt	/* NoAccel */
22751.84Sgdt	info->useEXA = FALSE;
22761.84Sgdt    }
22771.153Sriastrad
22781.153Sriastrad    return TRUE;
22791.153Sriastrad}
22801.153Sriastrad
22811.153Sriastradstatic Bool RADEONPreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
22821.153Sriastrad{
22831.153Sriastrad#if (!defined(__powerpc__) && !defined(__sparc__)) || \
22841.153Sriastrad    (defined(XSERVER_LIBPCIACCESS) && HAVE_PCI_DEVICE_ENABLE)
22851.84Sgdt    RADEONInfoPtr  info = RADEONPTR(pScrn);
22861.153Sriastrad#endif
22871.84Sgdt#if !defined(__powerpc__) && !defined(__sparc__)
22881.84Sgdt    unsigned char *RADEONMMIO = info->MMIO;
22891.136Smaya    uint32_t       fp2_gen_ctl_save   = 0;
22901.168Sthorpej#endif
22911.136Smaya
22921.136Smaya#ifdef XSERVER_LIBPCIACCESS
22931.136Smaya#if HAVE_PCI_DEVICE_ENABLE
22941.136Smaya    pci_device_enable(info->PciInfo);
22951.62Sjdolecek#endif
22961.136Smaya#endif
22971.168Sthorpej
22981.136Smaya#if !defined(__powerpc__) && !defined(__sparc__)
22991.136Smaya    /* don't need int10 on atom cards.
23001.136Smaya     * in theory all radeons, but the older stuff
23011.136Smaya     * isn't 100% yet
23021.62Sjdolecek     * secondary atom cards tend to hang when initializing int10,
23031.136Smaya     * however, on some stom cards, you can't read the bios without
23041.168Sthorpej     * intitializing int10.
23051.136Smaya     */
23061.136Smaya    if (!xf86ReturnOptValBool(info->Options, OPTION_INT10, TRUE))
23071.136Smaya	return TRUE;
23081.136Smaya
23091.84Sgdt    if (xf86LoadSubModule(pScrn, "int10")) {
23101.136Smaya	/* The VGA BIOS on the RV100/QY cannot be read when the digital output
23111.168Sthorpej	 * is enabled.  Clear and restore FP2_ON around int10 to avoid this.
23121.136Smaya	 */
23131.136Smaya	if (PCI_DEV_DEVICE_ID(info->PciInfo) == PCI_CHIP_RV100_QY) {
23141.136Smaya	    fp2_gen_ctl_save = INREG(RADEON_FP2_GEN_CNTL);
23151.136Smaya	    if (fp2_gen_ctl_save & RADEON_FP2_ON) {
23161.62Sjdolecek		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "disabling digital out\n");
23171.147Smaxv		OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_ctl_save & ~RADEON_FP2_ON);
23181.62Sjdolecek	    }
23191.62Sjdolecek	}
23201.62Sjdolecek
23211.62Sjdolecek	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
23221.158Sthorpej	*ppInt10 = xf86InitInt10(info->pEnt->index);
23231.155Sriastrad
23241.62Sjdolecek	if (PCI_DEV_DEVICE_ID(info->PciInfo) == PCI_CHIP_RV100_QY) {
23251.155Sriastrad	    if (fp2_gen_ctl_save & RADEON_FP2_ON) {
23261.133Sskrll		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "re-enabling digital out\n");
23271.62Sjdolecek		OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_ctl_save);
23281.155Sriastrad	    }
23291.155Sriastrad	}
23301.155Sriastrad    }
23311.155Sriastrad#endif
23321.113Sjakllsch    return TRUE;
23331.62Sjdolecek}
23341.62Sjdolecek
23351.84Sgdt#ifdef XF86DRI
23361.155Sriastradstatic Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
23371.155Sriastrad{
23381.155Sriastrad    RADEONInfoPtr  info = RADEONPTR(pScrn);
23391.155Sriastrad    Bool           ret;
23401.84Sgdt    MessageType    from;
23411.158Sthorpej    char          *reason;
23421.62Sjdolecek
23431.62Sjdolecek    info->directRenderingEnabled = FALSE;
23441.62Sjdolecek    info->directRenderingInited = FALSE;
23451.62Sjdolecek
23461.62Sjdolecek    if (!(info->dri = calloc(1, sizeof(struct radeon_dri)))) {
23471.62Sjdolecek	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n");
23481.62Sjdolecek	return FALSE;
23491.62Sjdolecek    }
23501.84Sgdt
23511.84Sgdt    if (!(info->cp = calloc(1, sizeof(struct radeon_cp)))) {
23521.62Sjdolecek	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n");
23531.155Sriastrad	return FALSE;
23541.155Sriastrad    }
23551.62Sjdolecek    info->cp->CPInUse = FALSE;
23561.62Sjdolecek    info->cp->CPStarted = FALSE;
23571.62Sjdolecek    info->cp->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT;
23581.62Sjdolecek
23591.84Sgdt   if (xf86IsEntityShared(info->pEnt->index)) {
23601.155Sriastrad        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
23611.155Sriastrad                   "Direct Rendering Disabled -- "
23621.155Sriastrad                   "Zaphod Dual-head configuration is not working with "
23631.155Sriastrad                   "DRI at present.\n"
23641.84Sgdt                   "Please use the xrandr 1.2 if you "
23651.158Sthorpej                   "want Dual-head with DRI.\n");
23661.62Sjdolecek        return FALSE;
23671.62Sjdolecek    }
23681.62Sjdolecek    if (info->IsSecondary)
23691.62Sjdolecek        return FALSE;
23701.155Sriastrad
23711.155Sriastrad    if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
23721.62Sjdolecek	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
23731.62Sjdolecek		   "No DRI yet on Evergreen\n");
23741.84Sgdt	return FALSE;
23751.62Sjdolecek    }
23761.62Sjdolecek
23771.155Sriastrad    if (info->Chipset == PCI_CHIP_RN50_515E ||
23781.155Sriastrad	info->Chipset == PCI_CHIP_RN50_5969) {
23791.62Sjdolecek	if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) {
23801.62Sjdolecek	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
23811.62Sjdolecek		"Direct rendering for RN50 forced on -- "
23821.62Sjdolecek		"This is NOT officially supported at the hardware level "
23831.155Sriastrad		"and may cause instability or lockups\n");
23841.155Sriastrad	} else {
23851.62Sjdolecek	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
23861.62Sjdolecek		"Direct rendering not officially supported on RN50\n");
23871.62Sjdolecek	    return FALSE;
23881.62Sjdolecek	}
23891.120Smrg    }
23901.158Sthorpej
23911.120Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_DRI, TRUE)) {
23921.62Sjdolecek	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
23931.155Sriastrad		"Direct rendering forced off\n");
23941.155Sriastrad	return FALSE;
23951.155Sriastrad    }
23961.155Sriastrad
23971.155Sriastrad    if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
23981.155Sriastrad	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
23991.155Sriastrad		   "[dri] Acceleration disabled, not initializing the DRI\n");
24001.155Sriastrad	return FALSE;
24011.155Sriastrad    }
24021.155Sriastrad
24031.155Sriastrad    info->dri->pLibDRMVersion = NULL;
24041.155Sriastrad    info->dri->pKernelDRMVersion = NULL;
24051.155Sriastrad
24061.155Sriastrad    ret = RADEONDRIGetVersion(pScrn);
24071.155Sriastrad    if (ret <= 0)
24081.155Sriastrad	return ret;
24091.155Sriastrad
24101.155Sriastrad    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
24111.155Sriastrad	       "[dri] Found DRI library version %d.%d.%d and kernel"
24121.155Sriastrad	       " module version %d.%d.%d\n",
24131.1Saugustss	       info->dri->pLibDRMVersion->version_major,
2414	       info->dri->pLibDRMVersion->version_minor,
2415	       info->dri->pLibDRMVersion->version_patchlevel,
2416	       info->dri->pKernelDRMVersion->version_major,
2417	       info->dri->pKernelDRMVersion->version_minor,
2418	       info->dri->pKernelDRMVersion->version_patchlevel);
2419
2420    if (info->Chipset == PCI_CHIP_RS400_5A41 ||
2421	info->Chipset == PCI_CHIP_RS400_5A42 ||
2422	info->Chipset == PCI_CHIP_RC410_5A61 ||
2423	info->Chipset == PCI_CHIP_RC410_5A62 ||
2424	info->Chipset == PCI_CHIP_RS480_5954 ||
2425	info->Chipset == PCI_CHIP_RS480_5955 ||
2426	info->Chipset == PCI_CHIP_RS482_5974 ||
2427	info->Chipset == PCI_CHIP_RS485_5975) {
2428
2429	if (info->dri->pKernelDRMVersion->version_minor < 27) {
2430 	     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2431			"Direct rendering broken on XPRESS 200 and 200M with DRI less than 1.27\n");
2432	     return FALSE;
2433	}
2434 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2435	"Direct rendering experimental on RS400/Xpress 200 enabled\n");
2436    }
2437
2438    if (info->ChipFamily >= CHIP_FAMILY_R300)
2439	info->dri->gartSize      = R300_DEFAULT_GART_SIZE;
2440    else
2441	info->dri->gartSize      = RADEON_DEFAULT_GART_SIZE;
2442
2443    info->dri->ringSize      = RADEON_DEFAULT_RING_SIZE;
2444    info->dri->bufSize       = RADEON_DEFAULT_BUFFER_SIZE;
2445    info->dri->gartTexSize   = RADEON_DEFAULT_GART_TEX_SIZE;
2446    info->dri->pciAperSize   = RADEON_DEFAULT_PCI_APER_SIZE;
2447    info->cp->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT;
2448
2449    if ((xf86GetOptValInteger(info->Options,
2450			     OPTION_GART_SIZE, (int *)&(info->dri->gartSize))) ||
2451			     (xf86GetOptValInteger(info->Options,
2452			     OPTION_GART_SIZE_OLD, (int *)&(info->dri->gartSize)))) {
2453	switch (info->dri->gartSize) {
2454	case 4:
2455	case 8:
2456	case 16:
2457	case 32:
2458	case 64:
2459	case 128:
2460	case 256:
2461	    break;
2462
2463	default:
2464	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2465		       "Illegal GART size: %d MB\n", info->dri->gartSize);
2466	    return FALSE;
2467	}
2468    }
2469
2470    if (xf86GetOptValInteger(info->Options,
2471			     OPTION_RING_SIZE, &(info->dri->ringSize))) {
2472	if (info->dri->ringSize < 1 || info->dri->ringSize >= (int)info->dri->gartSize) {
2473	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2474		       "Illegal ring buffer size: %d MB\n",
2475		       info->dri->ringSize);
2476	    return FALSE;
2477	}
2478    }
2479
2480    if (xf86GetOptValInteger(info->Options,
2481			     OPTION_PCIAPER_SIZE, &(info->dri->pciAperSize))) {
2482      switch(info->dri->pciAperSize) {
2483      case 32:
2484      case 64:
2485      case 128:
2486      case 256:
2487	break;
2488      default:
2489	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2490		       "Illegal pci aper size: %d MB\n",
2491		       info->dri->pciAperSize);
2492	return FALSE;
2493      }
2494    }
2495
2496
2497    if (xf86GetOptValInteger(info->Options,
2498			     OPTION_BUFFER_SIZE, &(info->dri->bufSize))) {
2499	if (info->dri->bufSize < 1 || info->dri->bufSize >= (int)info->dri->gartSize) {
2500	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2501		       "Illegal vertex/indirect buffers size: %d MB\n",
2502		       info->dri->bufSize);
2503	    return FALSE;
2504	}
2505	if (info->dri->bufSize > 2) {
2506	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2507		       "Illegal vertex/indirect buffers size: %d MB\n",
2508		       info->dri->bufSize);
2509	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2510		       "Clamping vertex/indirect buffers size to 2 MB\n");
2511	    info->dri->bufSize = 2;
2512	}
2513    }
2514
2515    if (info->dri->ringSize + info->dri->bufSize + info->dri->gartTexSize >
2516	(int)info->dri->gartSize) {
2517	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2518		   "Buffers are too big for requested GART space\n");
2519	return FALSE;
2520    }
2521
2522    info->dri->gartTexSize = info->dri->gartSize - (info->dri->ringSize + info->dri->bufSize);
2523
2524    if (xf86GetOptValInteger(info->Options, OPTION_USEC_TIMEOUT,
2525			     &(info->cp->CPusecTimeout))) {
2526	/* This option checked by the RADEON DRM kernel module */
2527    }
2528
2529    /* Two options to try and squeeze as much texture memory as possible
2530     * for dedicated 3d rendering boxes
2531     */
2532    info->dri->noBackBuffer = xf86ReturnOptValBool(info->Options,
2533						   OPTION_NO_BACKBUFFER,
2534						   FALSE);
2535
2536    info->dri->allowPageFlip = 0;
2537
2538#ifdef DAMAGE
2539    if (info->dri->noBackBuffer) {
2540	from = X_DEFAULT;
2541	reason = " because back buffer disabled";
2542    } else {
2543	from = xf86GetOptValBool(info->Options, OPTION_PAGE_FLIP,
2544				 &info->dri->allowPageFlip) ? X_CONFIG : X_DEFAULT;
2545
2546	if (IS_AVIVO_VARIANT) {
2547	    info->dri->allowPageFlip = 0;
2548	    reason = " on r5xx and newer chips.\n";
2549	} else {
2550	    reason = "";
2551	}
2552
2553    }
2554#else
2555    from = X_DEFAULT;
2556    reason = " because Damage layer not available at build time";
2557#endif
2558
2559    xf86DrvMsg(pScrn->scrnIndex, from, "Page Flipping %sabled%s\n",
2560	       info->dri->allowPageFlip ? "en" : "dis", reason);
2561
2562    /* AGP seems to have problems with gart transfers */
2563    if ((info->ChipFamily >= CHIP_FAMILY_R600) && (info->cardType == CARD_AGP))
2564	info->DMAForXv = FALSE;
2565    else
2566	info->DMAForXv = TRUE;
2567    from = xf86GetOptValBool(info->Options, OPTION_XV_DMA, &info->DMAForXv)
2568	 ? X_CONFIG : X_INFO;
2569    xf86DrvMsg(pScrn->scrnIndex, from,
2570	       "Will %stry to use DMA for Xv image transfers\n",
2571	       info->DMAForXv ? "" : "not ");
2572
2573    return TRUE;
2574}
2575#endif /* XF86DRI */
2576
2577static void RADEONPreInitColorTiling(ScrnInfoPtr pScrn)
2578{
2579    RADEONInfoPtr  info = RADEONPTR(pScrn);
2580
2581    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
2582				        OPTION_COLOR_TILING, TRUE);
2583    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
2584	/* this may be 4096 on r4xx -- need to double check */
2585	info->MaxSurfaceWidth = 3968; /* one would have thought 4096...*/
2586	info->MaxLines = 4096;
2587    } else {
2588	info->MaxSurfaceWidth = 2048;
2589	info->MaxLines = 2048;
2590    }
2591
2592    if (!info->allowColorTiling)
2593	return;
2594
2595    if (info->ChipFamily >= CHIP_FAMILY_R600)
2596	info->allowColorTiling = FALSE;
2597
2598    /* for zaphod disable tiling for now */
2599    if (info->IsPrimary || info->IsSecondary)
2600	info->allowColorTiling = FALSE;
2601
2602#ifdef XF86DRI
2603    if (info->directRenderingEnabled &&
2604	info->dri->pKernelDRMVersion->version_minor < 14) {
2605	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2606		   "[dri] color tiling disabled because of version "
2607		   "mismatch.\n"
2608		   "[dri] radeon.o kernel module version is %d.%d.%d but "
2609		   "1.14.0 or later is required for color tiling.\n",
2610		   info->dri->pKernelDRMVersion->version_major,
2611		   info->dri->pKernelDRMVersion->version_minor,
2612		   info->dri->pKernelDRMVersion->version_patchlevel);
2613	   info->allowColorTiling = FALSE;
2614	   return;
2615    }
2616#endif /* XF86DRI */
2617
2618    if (info->allowColorTiling) {
2619	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling enabled by default\n");
2620    } else {
2621	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling disabled\n");
2622    }
2623}
2624
2625
2626static Bool RADEONPreInitXv(ScrnInfoPtr pScrn)
2627{
2628    RADEONInfoPtr  info = RADEONPTR(pScrn);
2629    uint16_t mm_table;
2630    uint16_t bios_header;
2631    uint16_t pll_info_block;
2632#ifdef XvExtension
2633    char* microc_path = NULL;
2634    char* microc_type = NULL;
2635    MessageType from;
2636
2637    if (xf86GetOptValInteger(info->Options, OPTION_VIDEO_KEY,
2638			     &(info->videoKey))) {
2639	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
2640		   info->videoKey);
2641    } else {
2642	info->videoKey = 0x1E;
2643    }
2644
2645    if(xf86GetOptValInteger(info->Options, OPTION_RAGE_THEATRE_CRYSTAL, &(info->RageTheatreCrystal))) {
2646        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rage Theatre Crystal frequency was specified as %d.%d Mhz\n",
2647                                info->RageTheatreCrystal/100, info->RageTheatreCrystal % 100);
2648    } else {
2649	info->RageTheatreCrystal=-1;
2650    }
2651
2652    if(xf86GetOptValInteger(info->Options, OPTION_RAGE_THEATRE_TUNER_PORT, &(info->RageTheatreTunerPort))) {
2653        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rage Theatre tuner port was specified as %d\n",
2654                                info->RageTheatreTunerPort);
2655    } else {
2656	info->RageTheatreTunerPort=-1;
2657    }
2658
2659    if(info->RageTheatreTunerPort>5){
2660         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to assign Rage Theatre tuner port to invalid value. Disabling setting\n");
2661	 info->RageTheatreTunerPort=-1;
2662	 }
2663
2664    if(xf86GetOptValInteger(info->Options, OPTION_RAGE_THEATRE_COMPOSITE_PORT, &(info->RageTheatreCompositePort))) {
2665        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rage Theatre composite port was specified as %d\n",
2666                                info->RageTheatreCompositePort);
2667    } else {
2668	info->RageTheatreCompositePort=-1;
2669    }
2670
2671    if(info->RageTheatreCompositePort>6){
2672         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to assign Rage Theatre composite port to invalid value. Disabling setting\n");
2673	 info->RageTheatreCompositePort=-1;
2674	 }
2675
2676    if(xf86GetOptValInteger(info->Options, OPTION_RAGE_THEATRE_SVIDEO_PORT, &(info->RageTheatreSVideoPort))) {
2677        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rage Theatre SVideo Port was specified as %d\n",
2678                                info->RageTheatreSVideoPort);
2679    } else {
2680	info->RageTheatreSVideoPort=-1;
2681    }
2682
2683    if(info->RageTheatreSVideoPort>6){
2684         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to assign Rage Theatre SVideo port to invalid value. Disabling setting\n");
2685	 info->RageTheatreSVideoPort=-1;
2686	 }
2687
2688    if(xf86GetOptValInteger(info->Options, OPTION_TUNER_TYPE, &(info->tunerType))) {
2689        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tuner type was specified as %d\n",
2690                                info->tunerType);
2691    } else {
2692	info->tunerType=-1;
2693    }
2694
2695    if(info->tunerType>31){
2696         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to set tuner type to invalid value. Disabling setting\n");
2697	 info->tunerType=-1;
2698	 }
2699
2700	if((microc_path = xf86GetOptValString(info->Options, OPTION_RAGE_THEATRE_MICROC_PATH)) != NULL)
2701	{
2702		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rage Theatre Microcode path was specified as %s\n", microc_path);
2703		info->RageTheatreMicrocPath = microc_path;
2704    } else {
2705		info->RageTheatreMicrocPath= NULL;
2706    }
2707
2708	if((microc_type = xf86GetOptValString(info->Options, OPTION_RAGE_THEATRE_MICROC_TYPE)) != NULL)
2709	{
2710		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rage Theatre Microcode type was specified as %s\n", microc_type);
2711		info->RageTheatreMicrocType = microc_type;
2712	} else {
2713		info->RageTheatreMicrocType= NULL;
2714	}
2715
2716    if(xf86GetOptValInteger(info->Options, OPTION_SCALER_WIDTH, &(info->overlay_scaler_buffer_width))) {
2717	if ((info->overlay_scaler_buffer_width < 1024) ||
2718	  (info->overlay_scaler_buffer_width > 2048) ||
2719	  ((info->overlay_scaler_buffer_width % 64) != 0)) {
2720	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to set illegal scaler width. Using default\n");
2721	    from = X_DEFAULT;
2722	    info->overlay_scaler_buffer_width = 0;
2723	} else
2724	    from = X_CONFIG;
2725    } else {
2726	from = X_DEFAULT;
2727	info->overlay_scaler_buffer_width = 0;
2728    }
2729    if (!info->overlay_scaler_buffer_width) {
2730       /* overlay scaler line length differs for different revisions
2731       this needs to be maintained by hand  */
2732	switch(info->ChipFamily){
2733	case CHIP_FAMILY_R200:
2734	case CHIP_FAMILY_R300:
2735	case CHIP_FAMILY_R350:
2736	case CHIP_FAMILY_RV350:
2737	case CHIP_FAMILY_RV380:
2738	case CHIP_FAMILY_R420:
2739	case CHIP_FAMILY_RV410:
2740		info->overlay_scaler_buffer_width = 1920;
2741		break;
2742	default:
2743		info->overlay_scaler_buffer_width = 1536;
2744	}
2745    }
2746    xf86DrvMsg(pScrn->scrnIndex, from, "Assuming overlay scaler buffer width is %d\n",
2747	info->overlay_scaler_buffer_width);
2748#endif
2749
2750    /* Rescue MM_TABLE before VBIOS is freed */
2751    info->MM_TABLE_valid = FALSE;
2752
2753    if((info->VBIOS==NULL)||(info->VBIOS[0]!=0x55)||(info->VBIOS[1]!=0xaa)){
2754       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Cannot access BIOS or it is not valid.\n"
2755               "\t\tIf your card is TV-in capable you will need to specify options RageTheatreCrystal, RageTheatreTunerPort, \n"
2756               "\t\tRageTheatreSVideoPort and TunerType in /etc/X11/xorg.conf.\n"
2757               );
2758       info->MM_TABLE_valid = FALSE;
2759       return TRUE;
2760       }
2761
2762    bios_header=info->VBIOS[0x48];
2763    bios_header+=(((int)info->VBIOS[0x49]+0)<<8);
2764
2765    mm_table=info->VBIOS[bios_header+0x38];
2766    if(mm_table==0)
2767    {
2768        xf86DrvMsg(pScrn->scrnIndex,X_INFO,"No MM_TABLE found - assuming CARD is not TV-in capable.\n");
2769        info->MM_TABLE_valid = FALSE;
2770        return TRUE;
2771    }
2772    mm_table+=(((int)info->VBIOS[bios_header+0x39]+0)<<8)-2;
2773
2774    if(mm_table>0)
2775    {
2776        memcpy(&(info->MM_TABLE), &(info->VBIOS[mm_table]), sizeof(info->MM_TABLE));
2777        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MM_TABLE: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
2778            info->MM_TABLE.table_revision,
2779            info->MM_TABLE.table_size,
2780            info->MM_TABLE.tuner_type,
2781            info->MM_TABLE.audio_chip,
2782            info->MM_TABLE.product_id,
2783            info->MM_TABLE.tuner_voltage_teletext_fm,
2784            info->MM_TABLE.i2s_config,
2785            info->MM_TABLE.video_decoder_type,
2786            info->MM_TABLE.video_decoder_host_config,
2787            info->MM_TABLE.input[0],
2788            info->MM_TABLE.input[1],
2789            info->MM_TABLE.input[2],
2790            info->MM_TABLE.input[3],
2791            info->MM_TABLE.input[4]);
2792
2793	  /* Is it an MM_TABLE we know about ? */
2794	  if(info->MM_TABLE.table_size != 0xc){
2795	       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "This card has MM_TABLE we do not recognize.\n"
2796			"\t\tIf your card is TV-in capable you will need to specify options RageTheatreCrystal, RageTheatreTunerPort, \n"
2797			"\t\tRageTheatreSVideoPort and TunerType in /etc/X11/xorg.conf.\n"
2798			);
2799		info->MM_TABLE_valid = FALSE;
2800		return TRUE;
2801	  	}
2802        info->MM_TABLE_valid = TRUE;
2803    } else {
2804        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No MM_TABLE found - assuming card is not TV-in capable (mm_table=%d).\n", mm_table);
2805        info->MM_TABLE_valid = FALSE;
2806    }
2807
2808    pll_info_block=info->VBIOS[bios_header+0x30];
2809    pll_info_block+=(((int)info->VBIOS[bios_header+0x31]+0)<<8);
2810
2811    info->video_decoder_type=info->VBIOS[pll_info_block+0x08];
2812    info->video_decoder_type+=(((int)info->VBIOS[pll_info_block+0x09]+0)<<8);
2813
2814    return TRUE;
2815}
2816
2817static Bool
2818RADEONPreInitBIOS(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
2819{
2820    RADEONInfoPtr info = RADEONPTR(pScrn);
2821
2822    if (!RADEONGetBIOSInfo(pScrn, pInt10)) {
2823	/* Avivo chips require bios for atom */
2824	if (IS_AVIVO_VARIANT)
2825	    return FALSE;
2826    }
2827    return TRUE;
2828}
2829
2830Bool
2831RADEONZaphodStringMatches(ScrnInfoPtr pScrn, const char *s, char *output_name)
2832{
2833    int i = 0;
2834    char s1[20];
2835
2836    do {
2837	switch(*s) {
2838	case ',':
2839	    s1[i] = '\0';
2840	    i = 0;
2841	    if (strcmp(s1, output_name) == 0)
2842		return TRUE;
2843	    break;
2844	case ' ':
2845	case '\t':
2846	case '\n':
2847	case '\r':
2848	    break;
2849	default:
2850	    s1[i] = *s;
2851	    i++;
2852	    break;
2853	}
2854    } while(*s++);
2855
2856    s1[i] = '\0';
2857    if (strcmp(s1, output_name) == 0)
2858	return TRUE;
2859
2860    return FALSE;
2861}
2862
2863static void RADEONFixZaphodOutputs(ScrnInfoPtr pScrn)
2864{
2865    RADEONInfoPtr info = RADEONPTR(pScrn);
2866    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
2867    int o;
2868    char *s;
2869
2870    if ((s = xf86GetOptValString(info->Options, OPTION_ZAPHOD_HEADS))) {
2871	for (o = config->num_output; o > 0; o--) {
2872	    if (!RADEONZaphodStringMatches(pScrn, s, config->output[o - 1]->name))
2873		xf86OutputDestroy(config->output[o - 1]);
2874	}
2875    } else {
2876	if (info->IsPrimary) {
2877	    xf86OutputDestroy(config->output[0]);
2878	    while (config->num_output > 1) {
2879		xf86OutputDestroy(config->output[1]);
2880	    }
2881	} else {
2882	    while (config->num_output > 1) {
2883		xf86OutputDestroy(config->output[1]);
2884	    }
2885	}
2886    }
2887}
2888
2889static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn)
2890{
2891    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
2892    RADEONInfoPtr info = RADEONPTR(pScrn);
2893    int i;
2894    int mask;
2895    int found = 0;
2896
2897    if (info->IsPrimary)
2898	mask = 1;
2899    else if (info->IsSecondary)
2900	mask = 2;
2901    else
2902	mask = 3;
2903
2904    if (!RADEONAllocateControllers(pScrn, mask))
2905	return FALSE;
2906
2907    RADEONGetClockInfo(pScrn);
2908
2909    if (info->IsAtomBios && info->IsIGP)
2910	RADEONATOMGetIGPInfo(pScrn);
2911
2912    if (!RADEONSetupConnectors(pScrn)) {
2913	return FALSE;
2914    }
2915
2916    if (info->IsPrimary || info->IsSecondary) {
2917	/* fixup outputs for zaphod */
2918	RADEONFixZaphodOutputs(pScrn);
2919    }
2920
2921    RADEONPrintPortMap(pScrn);
2922
2923    info->first_load_no_devices = FALSE;
2924    for (i = 0; i < config->num_output; i++) {
2925	xf86OutputPtr	      output = config->output[i];
2926
2927	output->status = (*output->funcs->detect) (output);
2928	ErrorF("finished output detect: %d\n", i);
2929	if (info->IsPrimary || info->IsSecondary) {
2930	    if (output->status != XF86OutputStatusConnected)
2931		return FALSE;
2932	}
2933	if (output->status != XF86OutputStatusDisconnected)
2934	    found++;
2935    }
2936
2937    if (!found) {
2938	/* nothing connected, light up some defaults so the server comes up */
2939	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No connected devices found!\n");
2940	info->first_load_no_devices = TRUE;
2941    }
2942
2943    ErrorF("finished all detect\n");
2944    return TRUE;
2945}
2946
2947static void
2948RADEONProbeDDC(ScrnInfoPtr pScrn, int indx)
2949{
2950    vbeInfoPtr  pVbe;
2951
2952    if (xf86LoadSubModule(pScrn, "vbe")) {
2953	pVbe = VBEInit(NULL,indx);
2954	ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
2955	vbeFree(pVbe);
2956    }
2957}
2958
2959static Bool
2960RADEONCRTCResize(ScrnInfoPtr scrn, int width, int height)
2961{
2962    scrn->virtualX = width;
2963    scrn->virtualY = height;
2964    /* RADEONSetPitch(scrn); */
2965    return TRUE;
2966}
2967
2968static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = {
2969    RADEONCRTCResize
2970};
2971
2972Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
2973{
2974    xf86CrtcConfigPtr   xf86_config;
2975    RADEONInfoPtr     info;
2976    xf86Int10InfoPtr  pInt10 = NULL;
2977    void *int10_save = NULL;
2978    const char *s;
2979    RADEONEntPtr pRADEONEnt;
2980    DevUnion* pPriv;
2981
2982    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
2983		   "RADEONPreInit\n");
2984    if (pScrn->numEntities != 1) return FALSE;
2985
2986    if (!RADEONGetRec(pScrn)) return FALSE;
2987
2988    info               = RADEONPTR(pScrn);
2989    info->MMIO         = NULL;
2990
2991    info->IsSecondary  = FALSE;
2992    info->IsPrimary = FALSE;
2993    info->kms_enabled = FALSE;
2994
2995    info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
2996    if (info->pEnt->location.type != BUS_PCI) goto fail;
2997
2998    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
2999				 getRADEONEntityIndex());
3000    pRADEONEnt = pPriv->ptr;
3001
3002    if(xf86IsEntityShared(pScrn->entityList[0]))
3003    {
3004        if(xf86IsPrimInitDone(pScrn->entityList[0]))
3005        {
3006            info->IsSecondary = TRUE;
3007            pRADEONEnt->pSecondaryScrn = pScrn;
3008	    info->SavedReg = &pRADEONEnt->SavedReg;
3009	    info->ModeReg = &pRADEONEnt->ModeReg;
3010        }
3011        else
3012        {
3013	    info->IsPrimary = TRUE;
3014            xf86SetPrimInitDone(pScrn->entityList[0]);
3015            pRADEONEnt->pPrimaryScrn = pScrn;
3016            pRADEONEnt->HasSecondary = FALSE;
3017	    info->SavedReg = &pRADEONEnt->SavedReg;
3018	    info->ModeReg = &pRADEONEnt->ModeReg;
3019        }
3020    } else {
3021	info->SavedReg = &pRADEONEnt->SavedReg;
3022	info->ModeReg = &pRADEONEnt->ModeReg;
3023    }
3024
3025    info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
3026#ifndef XSERVER_LIBPCIACCESS
3027    info->PciTag  = pciTag(PCI_DEV_BUS(info->PciInfo),
3028			   PCI_DEV_DEV(info->PciInfo),
3029			   PCI_DEV_FUNC(info->PciInfo));
3030#endif
3031    info->MMIOAddr = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & ~0xffULL;
3032    info->MMIOSize = PCI_REGION_SIZE(info->PciInfo, 2);
3033	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TOTO SAYS %016llx\n",
3034		(unsigned long long)PCI_REGION_BASE(info->PciInfo,
3035		2, REGION_MEM));
3036    if (info->pEnt->device->IOBase) {
3037	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
3038		   "MMIO address override, using 0x%08lx instead of 0x%016llx\n",
3039		   info->pEnt->device->IOBase,
3040		   info->MMIOAddr);
3041	info->MMIOAddr = info->pEnt->device->IOBase;
3042    } else if (!info->MMIOAddr) {
3043	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
3044	goto fail1;
3045    }
3046    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3047	       "MMIO registers at 0x%016llx: size %ldKB\n", info->MMIOAddr, info->MMIOSize / 1024);
3048
3049    if(!RADEONMapMMIO(pScrn)) {
3050	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3051		   "Memory map the MMIO region failed\n");
3052	goto fail1;
3053    }
3054
3055#if !defined(__alpha__)
3056    if (
3057#ifndef XSERVER_LIBPCIACCESS
3058	xf86GetPciDomain(info->PciTag) ||
3059#endif
3060	!xf86IsPrimaryPci(info->PciInfo))
3061	RADEONPreInt10Save(pScrn, &int10_save);
3062#else
3063    /* [Alpha] On the primary, the console already ran the BIOS and we're
3064     *         going to run it again - so make sure to "fix up" the card
3065     *         so that (1) we can read the BIOS ROM and (2) the BIOS will
3066     *         get the memory config right.
3067     */
3068    RADEONPreInt10Save(pScrn, &int10_save);
3069#endif
3070
3071    if (flags & PROBE_DETECT) {
3072	RADEONProbeDDC(pScrn, info->pEnt->index);
3073	RADEONPostInt10Check(pScrn, int10_save);
3074	if(info->MMIO) RADEONUnmapMMIO(pScrn);
3075	return TRUE;
3076    }
3077
3078
3079    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3080	       "PCI bus %d card %d func %d\n",
3081	       PCI_DEV_BUS(info->PciInfo),
3082	       PCI_DEV_DEV(info->PciInfo),
3083	       PCI_DEV_FUNC(info->PciInfo));
3084
3085#ifndef XSERVER_LIBPCIACCESS
3086    if (xf86RegisterResources(info->pEnt->index, 0, ResExclusive))
3087	goto fail;
3088
3089    xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr);
3090
3091    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
3092#endif
3093    pScrn->monitor     = pScrn->confScreen->monitor;
3094
3095   /* Allocate an xf86CrtcConfig */
3096    xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
3097    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
3098
3099
3100    if (!RADEONPreInitVisual(pScrn))
3101	goto fail;
3102
3103				/* We can't do this until we have a
3104				   pScrn->display. */
3105    xf86CollectOptions(pScrn, NULL);
3106    if (!(info->Options = malloc(sizeof(RADEONOptions))))
3107	goto fail;
3108
3109    memcpy(info->Options, RADEONOptions, sizeof(RADEONOptions));
3110    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
3111
3112    /* By default, don't do VGA IOs on ppc/sparc */
3113#if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
3114    info->VGAAccess = FALSE;
3115#else
3116    info->VGAAccess = TRUE;
3117#endif
3118
3119#ifdef WITH_VGAHW
3120    xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess);
3121    if (info->VGAAccess) {
3122       if (!xf86LoadSubModule(pScrn, "vgahw"))
3123           info->VGAAccess = FALSE;
3124        else {
3125            if (!vgaHWGetHWRec(pScrn))
3126               info->VGAAccess = FALSE;
3127       }
3128       if (!info->VGAAccess)
3129           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed,"
3130                      " trying to run without it\n");
3131    } else
3132           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE,"
3133                      " VGA module load skipped\n");
3134    if (info->VGAAccess) {
3135	vgaHWSetStdFuncs(VGAHWPTR(pScrn));
3136        vgaHWGetIOBase(VGAHWPTR(pScrn));
3137    }
3138#endif
3139
3140
3141    if (!RADEONPreInitWeight(pScrn))
3142	goto fail;
3143
3144    info->DispPriority = 1;
3145    if ((s = xf86GetOptValString(info->Options, OPTION_DISP_PRIORITY))) {
3146	if (strcmp(s, "AUTO") == 0) {
3147	    info->DispPriority = 1;
3148	} else if (strcmp(s, "BIOS") == 0) {
3149	    info->DispPriority = 0;
3150	} else if (strcmp(s, "HIGH") == 0) {
3151	    info->DispPriority = 2;
3152	} else
3153	    info->DispPriority = 1;
3154    }
3155
3156    if (!RADEONPreInitChipType(pScrn))
3157	goto fail;
3158
3159    if (!RADEONPreInitInt10(pScrn, &pInt10))
3160	goto fail;
3161
3162    RADEONPostInt10Check(pScrn, int10_save);
3163
3164    if (!RADEONPreInitBIOS(pScrn, pInt10))
3165	goto fail;
3166
3167    /* Save BIOS scratch registers */
3168    RADEONSaveBIOSRegisters(pScrn, info->SavedReg);
3169
3170#ifdef XF86DRI
3171    /* PreInit DRI first of all since we need that for getting a proper
3172     * memory map
3173     */
3174    info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
3175    if (info->directRenderingEnabled < 0)
3176	goto fail;
3177#endif
3178    if (!info->directRenderingEnabled) {
3179	if (info->ChipFamily >= CHIP_FAMILY_R600) {
3180	    info->r600_shadow_fb = TRUE;
3181	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3182			   "using shadow framebuffer\n");
3183	    if (!xf86LoadSubModule(pScrn, "shadow"))
3184		info->r600_shadow_fb = FALSE;
3185	}
3186    }
3187
3188    if (!RADEONPreInitVRAM(pScrn))
3189	goto fail;
3190
3191    RADEONPreInitColorTiling(pScrn);
3192
3193    if (IS_AVIVO_VARIANT)
3194	xf86CrtcSetSizeRange (pScrn, 320, 200, 8192, 8192);
3195    else
3196	xf86CrtcSetSizeRange (pScrn, 320, 200, 4096, 4096);
3197
3198    RADEONPreInitDDC(pScrn);
3199
3200    if (!RADEONPreInitControllers(pScrn))
3201       goto fail;
3202
3203    if (!xf86InitialConfiguration (pScrn, FALSE))
3204   {
3205      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
3206      goto fail;
3207   }
3208
3209    /* fix up cloning on rn50 cards
3210     * since they only have one crtc sometimes the xserver doesn't assign
3211     * a crtc to one of the outputs even though both outputs have common modes
3212     * which results in only one monitor being enabled.  Assign a crtc here so
3213     * that both outputs light up.
3214     */
3215    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
3216	int i;
3217
3218	for (i = 0; i < xf86_config->num_output; i++) {
3219	    xf86OutputPtr output = xf86_config->output[i];
3220
3221	    /* XXX: double check crtc mode */
3222	    if ((output->probed_modes != NULL) && (output->crtc == NULL))
3223		output->crtc = xf86_config->crtc[0];
3224	}
3225    }
3226
3227    RADEONSetPitch(pScrn);
3228
3229   /* Set display resolution */
3230   xf86SetDpi(pScrn, 0, 0);
3231
3232	/* Get ScreenInit function */
3233    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
3234
3235    if (!RADEONPreInitGamma(pScrn))              goto fail;
3236
3237    if (!RADEONPreInitCursor(pScrn))             goto fail;
3238
3239    if (!RADEONPreInitAccel(pScrn))              goto fail;
3240
3241    if (!IS_AVIVO_VARIANT) {
3242	if (!RADEONPreInitXv(pScrn))                 goto fail;
3243    }
3244
3245    if (!xf86RandR12PreInit (pScrn))
3246    {
3247      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
3248      goto fail;
3249    }
3250
3251    if (pScrn->modes == NULL) {
3252      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
3253      goto fail;
3254   }
3255
3256
3257				/* Free int10 info */
3258    if (pInt10)
3259	xf86FreeInt10(pInt10);
3260
3261    if(info->MMIO) RADEONUnmapMMIO(pScrn);
3262    info->MMIO = NULL;
3263
3264    xf86DrvMsg(pScrn->scrnIndex, X_NOTICE,
3265	       "MergedFB support has been removed and replaced with"
3266	       " xrandr 1.2 support\n");
3267
3268    return TRUE;
3269
3270fail:
3271				/* Pre-init failed. */
3272				/* Free the video bios (if applicable) */
3273    if (info->VBIOS) {
3274	free(info->VBIOS);
3275	info->VBIOS = NULL;
3276    }
3277
3278				/* Free int10 info */
3279    if (pInt10)
3280	xf86FreeInt10(pInt10);
3281
3282#ifdef WITH_VGAHW
3283    if (info->VGAAccess)
3284           vgaHWFreeHWRec(pScrn);
3285#endif
3286
3287    if(info->MMIO) RADEONUnmapMMIO(pScrn);
3288    info->MMIO = NULL;
3289
3290 fail1:
3291    RADEONFreeRec(pScrn);
3292
3293    return FALSE;
3294}
3295
3296/* Load a palette */
3297static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
3298			      int *indices, LOCO *colors, VisualPtr pVisual)
3299{
3300    RADEONInfoPtr  info       = RADEONPTR(pScrn);
3301    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
3302    int            i;
3303    int            index, j;
3304    uint16_t       lut_r[256], lut_g[256], lut_b[256];
3305    int c;
3306
3307#ifdef XF86DRI
3308    if (info->cp->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
3309#endif
3310
3311    if (info->accelOn && pScrn->pScreen)
3312        RADEON_SYNC(info, pScrn);
3313
3314    {
3315
3316      for (c = 0; c < xf86_config->num_crtc; c++) {
3317	  xf86CrtcPtr crtc = xf86_config->crtc[c];
3318	  RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
3319
3320	  for (i = 0 ; i < 256; i++) {
3321	      lut_r[i] = radeon_crtc->lut_r[i] << 6;
3322	      lut_g[i] = radeon_crtc->lut_g[i] << 6;
3323	      lut_b[i] = radeon_crtc->lut_b[i] << 6;
3324	  }
3325
3326	  switch (info->CurrentLayout.depth) {
3327	  case 15:
3328	      for (i = 0; i < numColors; i++) {
3329		  index = indices[i];
3330		  for (j = 0; j < 8; j++) {
3331		      lut_r[index * 8 + j] = colors[index].red << 6;
3332		      lut_g[index * 8 + j] = colors[index].green << 6;
3333		      lut_b[index * 8 + j] = colors[index].blue << 6;
3334		  }
3335	      }
3336	  case 16:
3337	      for (i = 0; i < numColors; i++) {
3338		  index = indices[i];
3339
3340		  if (i <= 31) {
3341		      for (j = 0; j < 8; j++) {
3342			  lut_r[index * 8 + j] = colors[index].red << 6;
3343			  lut_b[index * 8 + j] = colors[index].blue << 6;
3344		      }
3345		  }
3346
3347		  for (j = 0; j < 4; j++) {
3348		      lut_g[index * 4 + j] = colors[index].green << 6;
3349		  }
3350	      }
3351	  default:
3352	      for (i = 0; i < numColors; i++) {
3353		  index = indices[i];
3354		  lut_r[index] = colors[index].red << 6;
3355		  lut_g[index] = colors[index].green << 6;
3356		  lut_b[index] = colors[index].blue << 6;
3357	      }
3358	      break;
3359	  }
3360
3361	      /* Make the change through RandR */
3362#ifdef RANDR_12_INTERFACE
3363	  if (crtc->randr_crtc)
3364	      RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
3365	  else
3366#endif
3367	      crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
3368      }
3369    }
3370
3371#ifdef XF86DRI
3372    if (info->cp->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
3373#endif
3374}
3375
3376static void RADEONBlockHandler(BLOCKHANDLER_ARGS_DECL)
3377{
3378    SCREEN_PTR(arg);
3379    ScrnInfoPtr    pScrn   = xf86ScreenToScrn(pScreen);
3380    RADEONInfoPtr  info    = RADEONPTR(pScrn);
3381
3382    pScreen->BlockHandler = info->BlockHandler;
3383    (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
3384    pScreen->BlockHandler = RADEONBlockHandler;
3385
3386    if (info->VideoTimerCallback)
3387	(*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
3388
3389#if defined(RENDER) && defined(USE_XAA)
3390    if(info->accel_state->RenderCallback)
3391	(*info->accel_state->RenderCallback)(pScrn);
3392#endif
3393
3394#ifdef USE_EXA
3395    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
3396#endif
3397
3398    if (info->pm.dynamic_mode_enabled)
3399	RADEONPMBlockHandler(pScrn);
3400}
3401
3402static void
3403RADEONInitBIOSRegisters(ScrnInfoPtr pScrn)
3404{
3405    RADEONInfoPtr  info  = RADEONPTR(pScrn);
3406    unsigned char *RADEONMMIO = info->MMIO;
3407    RADEONSavePtr save = info->ModeReg;
3408
3409    save->bios_0_scratch = info->SavedReg->bios_0_scratch;
3410    save->bios_1_scratch = info->SavedReg->bios_1_scratch;
3411    save->bios_2_scratch = info->SavedReg->bios_2_scratch;
3412    save->bios_3_scratch = info->SavedReg->bios_3_scratch;
3413    save->bios_4_scratch = info->SavedReg->bios_4_scratch;
3414    save->bios_5_scratch = info->SavedReg->bios_5_scratch;
3415    save->bios_6_scratch = info->SavedReg->bios_6_scratch;
3416    save->bios_7_scratch = info->SavedReg->bios_7_scratch;
3417
3418    if (info->IsAtomBios) {
3419	/* let the bios control the backlight */
3420	save->bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
3421	/* tell the bios not to handle mode switching */
3422	save->bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH |
3423				 ATOM_S6_ACC_MODE);
3424
3425	if (info->ChipFamily >= CHIP_FAMILY_R600) {
3426	    OUTREG(R600_BIOS_2_SCRATCH, save->bios_2_scratch);
3427	    OUTREG(R600_BIOS_6_SCRATCH, save->bios_6_scratch);
3428	} else {
3429	    OUTREG(RADEON_BIOS_2_SCRATCH, save->bios_2_scratch);
3430	    OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch);
3431	}
3432    } else {
3433	/* let the bios control the backlight */
3434	save->bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
3435	/* tell the bios not to handle mode switching */
3436	save->bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
3437				 RADEON_ACC_MODE_CHANGE);
3438	/* tell the bios a driver is loaded */
3439	save->bios_7_scratch |= RADEON_DRV_LOADED;
3440
3441	OUTREG(RADEON_BIOS_0_SCRATCH, save->bios_0_scratch);
3442	OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch);
3443	//OUTREG(RADEON_BIOS_7_SCRATCH, save->bios_7_scratch);
3444    }
3445
3446}
3447
3448
3449/* Called at the start of each server generation. */
3450Bool RADEONScreenInit(SCREEN_INIT_ARGS_DECL)
3451{
3452    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
3453    RADEONInfoPtr  info  = RADEONPTR(pScrn);
3454    int            hasDRI = 0;
3455#ifdef RENDER
3456    int            subPixelOrder = SubPixelUnknown;
3457    char*          s;
3458#endif
3459
3460
3461    info->accelOn      = FALSE;
3462#ifdef USE_XAA
3463    info->accel_state->accel        = NULL;
3464#endif
3465#ifdef XF86DRI
3466    pScrn->fbOffset    = info->dri->frontOffset;
3467#endif
3468
3469    if (info->IsSecondary)
3470        pScrn->fbOffset = pScrn->videoRam * 1024;
3471#ifdef XF86DRI
3472    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3473		   "RADEONScreenInit %lx %ld %d\n",
3474		   pScrn->memPhysBase, pScrn->fbOffset, info->dri->frontOffset);
3475#else
3476    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3477		   "RADEONScreenInit %lx %ld\n",
3478		   pScrn->memPhysBase, pScrn->fbOffset);
3479#endif
3480    if (!RADEONMapMem(pScrn)) return FALSE;
3481
3482#ifdef XF86DRI
3483    info->dri->fbX = 0;
3484    info->dri->fbY = 0;
3485#endif
3486
3487    info->PaletteSavedOnVT = FALSE;
3488
3489    info->crtc_on = FALSE;
3490    info->crtc2_on = FALSE;
3491
3492    /* save the real front buffer size
3493     * it changes with randr, rotation, etc.
3494     */
3495    info->virtualX = pScrn->virtualX;
3496    info->virtualY = pScrn->virtualY;
3497
3498    RADEONSave(pScrn);
3499
3500    /* set initial bios scratch reg state */
3501    RADEONInitBIOSRegisters(pScrn);
3502
3503    /* blank the outputs/crtcs */
3504    RADEONBlank(pScrn);
3505
3506    RADEONPMInit(pScrn);
3507
3508    if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
3509	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3510		   "Color tiling not supported with virtual x resolutions larger than %d, disabling\n",
3511		    info->MaxSurfaceWidth);
3512	info->allowColorTiling = FALSE;
3513    }
3514    if (info->allowColorTiling) {
3515        info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
3516    }
3517
3518    /* Visual setup */
3519    miClearVisualTypes();
3520    if (!miSetVisualTypes(pScrn->depth,
3521			  miGetDefaultVisualMask(pScrn->depth),
3522			  pScrn->rgbBits,
3523			  pScrn->defaultVisual)) return FALSE;
3524    miSetPixmapDepths ();
3525
3526#ifdef XF86DRI
3527    if (info->directRenderingEnabled) {
3528	MessageType from;
3529
3530	info->dri->depthBits = pScrn->depth;
3531
3532	from = xf86GetOptValInteger(info->Options, OPTION_DEPTH_BITS,
3533				    &info->dri->depthBits)
3534	     ? X_CONFIG : X_DEFAULT;
3535
3536	if (info->dri->depthBits != 16 && info->dri->depthBits != 24) {
3537	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3538		       "Value for Option \"DepthBits\" must be 16 or 24\n");
3539	    info->dri->depthBits = pScrn->depth;
3540	    from = X_DEFAULT;
3541	}
3542
3543	xf86DrvMsg(pScrn->scrnIndex, from,
3544		   "Using %d bit depth buffer\n", info->dri->depthBits);
3545    }
3546
3547
3548    hasDRI = info->directRenderingEnabled;
3549#endif /* XF86DRI */
3550
3551    /* Initialize the memory map, this basically calculates the values
3552     * we'll use later on for MC_FB_LOCATION & MC_AGP_LOCATION
3553     */
3554    RADEONInitMemoryMap(pScrn);
3555
3556    /* empty the surfaces */
3557    if (info->ChipFamily < CHIP_FAMILY_R600) {
3558	unsigned char *RADEONMMIO = info->MMIO;
3559	unsigned int j;
3560	for (j = 0; j < 8; j++) {
3561	    OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
3562	    OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
3563	    OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
3564	}
3565    }
3566
3567#ifdef XF86DRI
3568    /* Depth moves are disabled by default since they are extremely slow */
3569    info->dri->depthMoves = xf86ReturnOptValBool(info->Options,
3570						 OPTION_DEPTH_MOVE, FALSE);
3571    if (info->dri->depthMoves && info->allowColorTiling) {
3572	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling depth moves\n");
3573    } else if (info->dri->depthMoves) {
3574	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3575		   "Depth moves don't work without color tiling, disabled\n");
3576	info->dri->depthMoves = FALSE;
3577    } else {
3578	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3579		   "Depth moves disabled by default\n");
3580    }
3581#endif
3582
3583    /* Initial setup of surfaces */
3584    if (info->ChipFamily < CHIP_FAMILY_R600) {
3585        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3586                       "Setting up initial surfaces\n");
3587        RADEONChangeSurfaces(pScrn);
3588    }
3589
3590				/* Memory manager setup */
3591
3592    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3593		   "Setting up accel memmap\n");
3594
3595#ifdef USE_EXA
3596    if (info->useEXA) {
3597#ifdef XF86DRI
3598	if (hasDRI) {
3599	    info->accelDFS = xf86ReturnOptValBool(info->Options, OPTION_ACCEL_DFS,
3600						  info->cardType != CARD_AGP);
3601
3602	    /* Reserve approx. half of offscreen memory for local textures by
3603	     * default, can be overridden with Option "FBTexPercent".
3604	     * Round down to a whole number of texture regions.
3605	     */
3606	    info->dri->textureSize = 50;
3607
3608	    if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT,
3609				     &(info->dri->textureSize))) {
3610		if (info->dri->textureSize < 0 || info->dri->textureSize > 100) {
3611		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3612			       "Illegal texture memory percentage: %dx, setting to default 50%%\n",
3613			       info->dri->textureSize);
3614		    info->dri->textureSize = 50;
3615		}
3616	    }
3617	}
3618#endif /* XF86DRI */
3619
3620	if (!RADEONSetupMemEXA(pScreen))
3621	    return FALSE;
3622    }
3623#endif
3624
3625#if defined(XF86DRI) && defined(USE_XAA)
3626    if (!info->useEXA && hasDRI) {
3627	info->dri->textureSize = -1;
3628	if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT,
3629				 &(info->dri->textureSize))) {
3630	    if (info->dri->textureSize < 0 || info->dri->textureSize > 100) {
3631		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3632			   "Illegal texture memory percentage: %dx, using default behaviour\n",
3633			   info->dri->textureSize);
3634		info->dri->textureSize = -1;
3635	    }
3636	}
3637	if (!RADEONSetupMemXAA_DRI(pScreen))
3638	    return FALSE;
3639    	pScrn->fbOffset    = info->dri->frontOffset;
3640    }
3641#endif
3642
3643#ifdef USE_XAA
3644    if (!info->useEXA && !hasDRI && !RADEONSetupMemXAA(pScreen))
3645	return FALSE;
3646#endif
3647
3648    info->accel_state->dst_pitch_offset =
3649	(((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64)
3650	  << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10));
3651
3652    /* Setup DRI after visuals have been established, but before fbScreenInit is
3653     * called.  fbScreenInit will eventually call the driver's InitGLXVisuals
3654     * call back. */
3655#ifdef XF86DRI
3656    if (info->directRenderingEnabled) {
3657	/* FIXME: When we move to dynamic allocation of back and depth
3658	 * buffers, we will want to revisit the following check for 3
3659	 * times the virtual size of the screen below.
3660	 */
3661	int  width_bytes = (pScrn->displayWidth *
3662			    info->CurrentLayout.pixel_bytes);
3663	int  maxy        = info->FbMapSize / width_bytes;
3664
3665	if (maxy <= pScrn->virtualY * 3) {
3666	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3667		       "Static buffer allocation failed.  Disabling DRI.\n");
3668	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3669		       "At least %d kB of video memory needed at this "
3670		       "resolution and depth.\n",
3671		       (pScrn->displayWidth * pScrn->virtualY *
3672			info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
3673	    info->directRenderingEnabled = FALSE;
3674	} else {
3675	    info->directRenderingEnabled = RADEONDRIScreenInit(pScreen);
3676	}
3677    }
3678
3679    /* Tell DRI about new memory map */
3680    if (info->directRenderingEnabled && info->dri->newMemoryMap) {
3681        if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
3682		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3683			   "[drm] failed to enable new memory map\n");
3684		RADEONDRICloseScreen(pScreen);
3685		info->directRenderingEnabled = FALSE;
3686	}
3687    }
3688#endif
3689    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3690		   "Initializing fb layer\n");
3691
3692    if (info->r600_shadow_fb) {
3693	info->fb_shadow = calloc(1,
3694				 pScrn->displayWidth * pScrn->virtualY *
3695				 ((pScrn->bitsPerPixel + 7) >> 3));
3696	if (info->fb_shadow == NULL) {
3697	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3698                       "Failed to allocate shadow framebuffer\n");
3699	    info->r600_shadow_fb = FALSE;
3700	} else {
3701	    if (!fbScreenInit(pScreen, info->fb_shadow,
3702			      pScrn->virtualX, pScrn->virtualY,
3703			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
3704			      pScrn->bitsPerPixel))
3705		return FALSE;
3706	}
3707    }
3708
3709    if (info->r600_shadow_fb == FALSE) {
3710	/* Init fb layer */
3711	if (!fbScreenInit(pScreen, info->FB + pScrn->fbOffset,
3712			  pScrn->virtualX, pScrn->virtualY,
3713			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
3714			  pScrn->bitsPerPixel))
3715	    return FALSE;
3716    }
3717
3718    xf86SetBlackWhitePixels(pScreen);
3719
3720    if (pScrn->bitsPerPixel > 8) {
3721	VisualPtr  visual;
3722
3723	visual = pScreen->visuals + pScreen->numVisuals;
3724	while (--visual >= pScreen->visuals) {
3725	    if ((visual->class | DynamicClass) == DirectColor) {
3726		visual->offsetRed   = pScrn->offset.red;
3727		visual->offsetGreen = pScrn->offset.green;
3728		visual->offsetBlue  = pScrn->offset.blue;
3729		visual->redMask     = pScrn->mask.red;
3730		visual->greenMask   = pScrn->mask.green;
3731		visual->blueMask    = pScrn->mask.blue;
3732	    }
3733	}
3734    }
3735
3736    /* Must be after RGB order fixed */
3737    fbPictureInit (pScreen, 0, 0);
3738
3739#ifdef RENDER
3740    if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
3741	if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB;
3742	else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR;
3743	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
3744	PictureSetSubpixelOrder (pScreen, subPixelOrder);
3745    }
3746#endif
3747
3748    pScrn->vtSema = TRUE;
3749
3750    /* restore the memory map here otherwise we may get a hang when
3751     * initializing the drm below
3752     */
3753    RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
3754    RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
3755
3756    /* Backing store setup */
3757    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3758		   "Initializing backing store\n");
3759    xf86SetBackingStore(pScreen);
3760
3761    /* DRI finalisation */
3762#ifdef XF86DRI
3763    if (info->directRenderingEnabled &&
3764	(info->cardType==CARD_PCIE || info->cardType==CARD_PCI) &&
3765        info->dri->pKernelDRMVersion->version_minor >= 19)
3766    {
3767      if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_PCIGART_LOCATION, info->dri->pciGartOffset) < 0)
3768	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3769		   "[drm] failed set pci gart location\n");
3770
3771      if (info->dri->pKernelDRMVersion->version_minor >= 26) {
3772	if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_PCIGART_TABLE_SIZE, info->dri->pciGartSize) < 0)
3773	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3774		     "[drm] failed set pci gart table size\n");
3775      }
3776    }
3777    if (info->directRenderingEnabled) {
3778        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3779		       "DRI Finishing init !\n");
3780	info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen);
3781    }
3782    if (info->directRenderingEnabled) {
3783	/* DRI final init might have changed the memory map, we need to adjust
3784	 * our local image to make sure we restore them properly on mode
3785	 * changes or VT switches
3786	 */
3787	RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
3788
3789	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
3790
3791	/* we might already be in tiled mode, tell drm about it */
3792	if (info->directRenderingEnabled && info->tilingEnabled) {
3793	  if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
3794  	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3795			 "[drm] failed changing tiling status\n");
3796	}
3797    } else {
3798	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3799		   "Direct rendering disabled\n");
3800    }
3801#endif
3802
3803    /* Make sure surfaces are allright since DRI setup may have changed them */
3804    if (info->ChipFamily < CHIP_FAMILY_R600) {
3805        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3806                       "Setting up final surfaces\n");
3807
3808        RADEONChangeSurfaces(pScrn);
3809    }
3810
3811
3812    /* Enable aceleration */
3813    if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
3814	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3815		       "Initializing Acceleration\n");
3816	if (RADEONAccelInit(pScreen)) {
3817	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
3818	    info->accelOn = TRUE;
3819	} else {
3820	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3821		       "Acceleration initialization failed\n");
3822	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
3823	    info->accelOn = FALSE;
3824	}
3825    } else {
3826	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
3827	info->accelOn = FALSE;
3828    }
3829
3830    /* Init DPMS */
3831    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3832		   "Initializing DPMS\n");
3833    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
3834
3835    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3836		   "Initializing Cursor\n");
3837
3838    /* Set Silken Mouse */
3839    xf86SetSilkenMouse(pScreen);
3840
3841    /* Cursor setup */
3842    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
3843
3844    /* Hardware cursor setup */
3845    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
3846	if (RADEONCursorInit(pScreen)) {
3847#ifdef USE_XAA
3848	    if (!info->useEXA) {
3849		int  width, height;
3850
3851		if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
3852					      0, 0, 0)) {
3853		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3854			       "Largest offscreen area available: %d x %d\n",
3855			       width, height);
3856		}
3857	    }
3858#endif /* USE_XAA */
3859	} else {
3860	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
3861		       "Hardware cursor initialization failed\n");
3862	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
3863	}
3864    } else {
3865	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
3866    }
3867
3868    /* DGA setup */
3869#ifdef XFreeXDGA
3870    xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset);
3871#endif
3872
3873    /* Init Xv */
3874    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3875		   "Initializing Xv\n");
3876    RADEONInitVideo(pScreen);
3877
3878    if (info->r600_shadow_fb == TRUE) {
3879        if (!shadowSetup(pScreen)) {
3880            return FALSE;
3881        }
3882    }
3883
3884    /* Clear the framebuffer */
3885    memset(info->FB + pScrn->fbOffset, 0,
3886           pScrn->virtualY * pScrn->displayWidth * info->CurrentLayout.pixel_bytes);
3887
3888    pScrn->pScreen = pScreen;
3889
3890    /* set the modes with desired rotation, etc. */
3891    if (!xf86SetDesiredModes (pScrn))
3892	return FALSE;
3893
3894    /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
3895    /* Wrap CloseScreen */
3896    info->CloseScreen    = pScreen->CloseScreen;
3897    pScreen->CloseScreen = RADEONCloseScreen;
3898    pScreen->SaveScreen  = RADEONSaveScreen;
3899    info->BlockHandler = pScreen->BlockHandler;
3900    pScreen->BlockHandler = RADEONBlockHandler;
3901    info->CreateScreenResources = pScreen->CreateScreenResources;
3902    pScreen->CreateScreenResources = RADEONCreateScreenResources;
3903
3904   if (!xf86CrtcScreenInit (pScreen))
3905       return FALSE;
3906
3907    /* Colormap setup */
3908    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3909                   "Initializing color map\n");
3910    if (!miCreateDefColormap(pScreen)) return FALSE;
3911    /* all radeons support 10 bit CLUTs */
3912    if (!xf86HandleColormaps(pScreen, 256, 10,
3913			     RADEONLoadPalette, NULL,
3914			     CMAP_PALETTED_TRUECOLOR
3915#if 0 /* This option messes up text mode! (eich@suse.de) */
3916			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
3917#endif
3918			     | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
3919
3920    /* Note unused options */
3921    if (serverGeneration == 1)
3922	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
3923
3924    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
3925		   "RADEONScreenInit finished\n");
3926
3927    return TRUE;
3928}
3929
3930/* Write memory mapping registers */
3931void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
3932					 RADEONSavePtr restore)
3933{
3934    RADEONInfoPtr  info       = RADEONPTR(pScrn);
3935    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
3936    unsigned char *RADEONMMIO = info->MMIO;
3937    int timeout;
3938    uint32_t mc_fb_loc, mc_agp_loc, mc_agp_loc_hi;
3939
3940    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &mc_fb_loc,
3941				   &mc_agp_loc, &mc_agp_loc_hi);
3942
3943    if (info->IsSecondary)
3944      return;
3945    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3946	       "RADEONRestoreMemMapRegisters() : \n");
3947    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3948	       "  MC_FB_LOCATION   : 0x%08x 0x%08x\n",
3949	       (unsigned)restore->mc_fb_location, (unsigned int)mc_fb_loc);
3950    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3951	       "  MC_AGP_LOCATION  : 0x%08x\n",
3952	       (unsigned)restore->mc_agp_location);
3953
3954    if (IS_DCE4_VARIANT) {
3955	if (mc_fb_loc != restore->mc_fb_location ||
3956	    mc_agp_loc != restore->mc_agp_location) {
3957	    uint32_t tmp;
3958
3959	    //XXX
3960	    //RADEONWaitForIdleMMIO(pScrn);
3961
3962            /* disable VGA rendering core */
3963    	    OUTREG(AVIVO_VGA_RENDER_CONTROL, INREG(AVIVO_VGA_RENDER_CONTROL) & ~AVIVO_VGA_VSTATUS_CNTL_MASK);
3964	    OUTREG(AVIVO_D1VGA_CONTROL, INREG(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
3965	    OUTREG(AVIVO_D2VGA_CONTROL, INREG(AVIVO_D2VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
3966	    OUTREG(EVERGREEN_D3VGA_CONTROL, INREG(EVERGREEN_D3VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
3967	    OUTREG(EVERGREEN_D4VGA_CONTROL, INREG(EVERGREEN_D4VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
3968	    OUTREG(EVERGREEN_D5VGA_CONTROL, INREG(EVERGREEN_D5VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
3969	    OUTREG(EVERGREEN_D6VGA_CONTROL, INREG(EVERGREEN_D6VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
3970
3971	    /* Stop display & memory access */
3972	    tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
3973	    OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
3974	    tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
3975
3976	    tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
3977	    OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
3978	    tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
3979
3980	    if (!IS_DCE41_VARIANT) {
3981		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
3982		OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
3983		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
3984
3985		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
3986		OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
3987		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
3988
3989		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
3990		OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
3991		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
3992
3993		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
3994		OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
3995		tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
3996	    }
3997
3998	    usleep(10000);
3999	    timeout = 0;
4000	    while (!(radeon_get_mc_idle(pScrn))) {
4001		if (++timeout > 1000000) {
4002		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4003			       "Timeout trying to update memory controller settings !\n");
4004		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4005			       "You will probably crash now ... \n");
4006		    /* Nothing we can do except maybe try to kill the server,
4007		     * let's wait 2 seconds to leave the above message a chance
4008		     * to maybe hit the disk and continue trying to setup despite
4009		     * the MC being non-idle
4010		     */
4011		    usleep(2000000);
4012		}
4013		usleep(10);
4014	    }
4015
4016	    radeon_write_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP,
4017					    restore->mc_fb_location,
4018					    restore->mc_agp_location,
4019					    restore->mc_agp_location_hi);
4020
4021	    OUTREG(R600_HDP_NONSURFACE_BASE, (restore->mc_fb_location & 0xffff) << 16);
4022
4023	}
4024    } else if (IS_AVIVO_VARIANT) {
4025	if (mc_fb_loc != restore->mc_fb_location ||
4026	    mc_agp_loc != restore->mc_agp_location) {
4027	    uint32_t tmp;
4028
4029	    RADEONWaitForIdleMMIO(pScrn);
4030
4031            /* disable VGA rendering core */
4032    	    OUTREG(AVIVO_VGA_RENDER_CONTROL, INREG(AVIVO_VGA_RENDER_CONTROL) &~ AVIVO_VGA_VSTATUS_CNTL_MASK);
4033
4034	    OUTREG(AVIVO_D1VGA_CONTROL, INREG(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
4035	    OUTREG(AVIVO_D2VGA_CONTROL, INREG(AVIVO_D2VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
4036
4037	    /* Stop display & memory access */
4038	    tmp = INREG(AVIVO_D1CRTC_CONTROL);
4039	    OUTREG(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
4040
4041	    tmp = INREG(AVIVO_D2CRTC_CONTROL);
4042	    OUTREG(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
4043
4044	    tmp = INREG(AVIVO_D2CRTC_CONTROL);
4045
4046	    usleep(10000);
4047	    timeout = 0;
4048	    while (!(radeon_get_mc_idle(pScrn))) {
4049		if (++timeout > 1000000) {
4050		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4051			       "Timeout trying to update memory controller settings !\n");
4052		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4053			       "You will probably crash now ... \n");
4054		    /* Nothing we can do except maybe try to kill the server,
4055		     * let's wait 2 seconds to leave the above message a chance
4056		     * to maybe hit the disk and continue trying to setup despite
4057		     * the MC being non-idle
4058		     */
4059		    usleep(2000000);
4060		}
4061		usleep(10);
4062	    }
4063
4064	    radeon_write_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP,
4065					    restore->mc_fb_location,
4066					    restore->mc_agp_location,
4067					    restore->mc_agp_location_hi);
4068
4069	    if (info->ChipFamily < CHIP_FAMILY_R600) {
4070		OUTREG(AVIVO_HDP_FB_LOCATION, restore->mc_fb_location);
4071	    } else {
4072		OUTREG(R600_HDP_NONSURFACE_BASE, (restore->mc_fb_location << 16) & 0xff0000);
4073	    }
4074
4075	    /* Reset the engine and HDP */
4076	    if (info->ChipFamily < CHIP_FAMILY_R600)
4077		RADEONEngineReset(pScrn);
4078	}
4079    } else {
4080
4081	/* Write memory mapping registers only if their value change
4082	 * since we must ensure no access is done while they are
4083	 * reprogrammed
4084	 */
4085	if (mc_fb_loc != restore->mc_fb_location ||
4086	    mc_agp_loc != restore->mc_agp_location) {
4087	    uint32_t crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl;
4088	    uint32_t old_mc_status;
4089
4090	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
4091			   "  Map Changed ! Applying ...\n");
4092
4093	    /* Make sure engine is idle. We assume the CCE is stopped
4094	     * at this point
4095	     */
4096	    RADEONWaitForIdleMMIO(pScrn);
4097
4098	    if (info->IsIGP)
4099		goto igp_no_mcfb;
4100
4101	    /* Capture MC_STATUS in case things go wrong ... */
4102	    old_mc_status = INREG(RADEON_MC_STATUS);
4103
4104	    /* Stop display & memory access */
4105	    ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL);
4106	    OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
4107	    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
4108	    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
4109	    crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
4110	    RADEONWaitForVerticalSync(pScrn);
4111	    OUTREG(RADEON_CRTC_GEN_CNTL,
4112		   (crtc_gen_cntl
4113		    & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN))
4114		   | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
4115
4116	    if (pRADEONEnt->HasCRTC2) {
4117		crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
4118		RADEONWaitForVerticalSync2(pScrn);
4119		OUTREG(RADEON_CRTC2_GEN_CNTL,
4120		       (crtc2_gen_cntl
4121			& ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN))
4122		       | RADEON_CRTC2_DISP_REQ_EN_B);
4123	    }
4124
4125	    /* Make sure the chip settles down (paranoid !) */
4126	    usleep(100000);
4127	    timeout = 0;
4128	    while (!(radeon_get_mc_idle(pScrn))) {
4129		if (++timeout > 1000000) {
4130		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4131			       "Timeout trying to update memory controller settings !\n");
4132		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4133			       "MC_STATUS = 0x%08x (on entry = 0x%08x)\n",
4134			       (unsigned int)INREG(RADEON_MC_STATUS), (unsigned int)old_mc_status);
4135		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4136			       "You will probably crash now ... \n");
4137		    /* Nothing we can do except maybe try to kill the server,
4138		     * let's wait 2 seconds to leave the above message a chance
4139		     * to maybe hit the disk and continue trying to setup despite
4140		     * the MC being non-idle
4141		     */
4142		    usleep(2000000);
4143		}
4144		usleep(10);
4145	    }
4146
4147	    /* Update maps, first clearing out AGP to make sure we don't get
4148	     * a temporary overlap
4149	     */
4150	    OUTREG(RADEON_MC_AGP_LOCATION, 0xfffffffc);
4151	    OUTREG(RADEON_MC_FB_LOCATION, restore->mc_fb_location);
4152	    radeon_write_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, restore->mc_fb_location,
4153					    0xfffffffc, 0);
4154	igp_no_mcfb:
4155	    radeon_write_mc_fb_agp_location(pScrn, LOC_AGP, 0,
4156					    restore->mc_agp_location, 0);
4157	    /* Make sure map fully reached the chip */
4158	    (void)INREG(RADEON_MC_FB_LOCATION);
4159
4160	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
4161			   "  Map applied, resetting engine ...\n");
4162
4163	    /* Reset the engine and HDP */
4164	    RADEONEngineReset(pScrn);
4165
4166	    /* Make sure we have sane offsets before re-enabling the CRTCs, disable
4167	     * stereo, clear offsets, and wait for offsets to catch up with hw
4168	     */
4169
4170	    OUTREG(RADEON_CRTC_OFFSET_CNTL, RADEON_CRTC_OFFSET_FLIP_CNTL);
4171	    OUTREG(RADEON_CRTC_OFFSET, 0);
4172	    OUTREG(RADEON_CUR_OFFSET, 0);
4173	    timeout = 0;
4174	    while(INREG(RADEON_CRTC_OFFSET) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) {
4175		if (timeout++ > 1000000) {
4176		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4177			       "Timeout waiting for CRTC offset to update !\n");
4178		    break;
4179		}
4180		usleep(1000);
4181	    }
4182	    if (pRADEONEnt->HasCRTC2) {
4183		OUTREG(RADEON_CRTC2_OFFSET_CNTL, RADEON_CRTC2_OFFSET_FLIP_CNTL);
4184		OUTREG(RADEON_CRTC2_OFFSET, 0);
4185		OUTREG(RADEON_CUR2_OFFSET, 0);
4186		timeout = 0;
4187		while(INREG(RADEON_CRTC2_OFFSET) & RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET) {
4188		    if (timeout++ > 1000000) {
4189			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4190				   "Timeout waiting for CRTC2 offset to update !\n");
4191			break;
4192		    }
4193		    usleep(1000);
4194		}
4195	    }
4196	}
4197
4198	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
4199		       "Updating display base addresses...\n");
4200
4201	OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr);
4202	if (pRADEONEnt->HasCRTC2)
4203	    OUTREG(RADEON_DISPLAY2_BASE_ADDR, restore->display2_base_addr);
4204	OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr);
4205	(void)INREG(RADEON_OV0_BASE_ADDR);
4206
4207	/* More paranoia delays, wait 100ms */
4208	usleep(100000);
4209
4210	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
4211		       "Memory map updated.\n");
4212    }
4213}
4214
4215#ifdef XF86DRI
4216static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
4217{
4218    RADEONInfoPtr  info   = RADEONPTR(pScrn);
4219    uint32_t fb, agp, agp_hi;
4220    int changed = 0;
4221
4222    if (info->IsSecondary)
4223      return;
4224
4225    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &fb, &agp, &agp_hi);
4226
4227    if (fb != save->mc_fb_location || agp != save->mc_agp_location ||
4228	agp_hi != save->mc_agp_location_hi)
4229	changed = 1;
4230
4231    if (changed) {
4232	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
4233		   "DRI init changed memory map, adjusting ...\n");
4234	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
4235		   "  MC_FB_LOCATION  was: 0x%08lx is: 0x%08lx\n",
4236		   (long unsigned int)info->mc_fb_location, (long unsigned int)fb);
4237	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
4238		   "  MC_AGP_LOCATION was: 0x%08lx is: 0x%08lx\n",
4239		   (long unsigned int)info->mc_agp_location, (long unsigned int)agp);
4240	info->mc_fb_location = fb;
4241	info->mc_agp_location = agp;
4242	if (info->ChipFamily >= CHIP_FAMILY_R600)
4243	    info->fbLocation = ((uint64_t)info->mc_fb_location & 0xffff) << 24;
4244	else
4245	    info->fbLocation = ((uint64_t)info->mc_fb_location & 0xffff) << 16;
4246
4247	info->accel_state->dst_pitch_offset =
4248	    (((pScrn->displayWidth * info->CurrentLayout.pixel_bytes / 64)
4249	      << 22) | ((info->fbLocation + pScrn->fbOffset) >> 10));
4250	RADEONInitMemMapRegisters(pScrn, save, info);
4251	RADEONRestoreMemMapRegisters(pScrn, save);
4252    }
4253
4254#ifdef USE_EXA
4255    if (info->accelDFS || (info->ChipFamily >= CHIP_FAMILY_R600))
4256    {
4257	drm_radeon_getparam_t gp;
4258	int gart_base;
4259
4260	memset(&gp, 0, sizeof(gp));
4261	gp.param = RADEON_PARAM_GART_BASE;
4262	gp.value = &gart_base;
4263
4264	if (drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GETPARAM, &gp,
4265				sizeof(gp)) < 0) {
4266	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4267		       "Failed to determine GART area MC location, not using "
4268		       "accelerated DownloadFromScreen hook!\n");
4269	    info->accelDFS = FALSE;
4270	} else {
4271	    info->gartLocation = gart_base;
4272	}
4273    }
4274#endif /* USE_EXA */
4275}
4276#endif
4277
4278/* restore original surface info (for fb console). */
4279static void RADEONRestoreSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr restore)
4280{
4281    RADEONInfoPtr      info = RADEONPTR(pScrn);
4282    unsigned char *RADEONMMIO = info->MMIO;
4283    unsigned int surfnr;
4284
4285    for ( surfnr = 0; surfnr < 8; surfnr++ ) {
4286	OUTREG(RADEON_SURFACE0_INFO + 16 * surfnr, restore->surfaces[surfnr][0]);
4287	OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * surfnr, restore->surfaces[surfnr][1]);
4288	OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * surfnr, restore->surfaces[surfnr][2]);
4289    }
4290}
4291
4292/* save original surface info (for fb console). */
4293static void RADEONSaveSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr save)
4294{
4295    RADEONInfoPtr      info = RADEONPTR(pScrn);
4296    unsigned char *RADEONMMIO = info->MMIO;
4297    unsigned int surfnr;
4298
4299    for ( surfnr = 0; surfnr < 8; surfnr++ ) {
4300	save->surfaces[surfnr][0] = INREG(RADEON_SURFACE0_INFO + 16 * surfnr);
4301	save->surfaces[surfnr][1] = INREG(RADEON_SURFACE0_LOWER_BOUND + 16 * surfnr);
4302	save->surfaces[surfnr][2] = INREG(RADEON_SURFACE0_UPPER_BOUND + 16 * surfnr);
4303    }
4304}
4305
4306void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
4307{
4308   /* the idea here is to only set up front buffer as tiled, and back/depth buffer when needed.
4309      Everything else is left as untiled. This means we need to use eplicit src/dst pitch control
4310      when blitting, based on the src/target address, and can no longer use a default offset.
4311      But OTOH we don't need to dynamically change surfaces (for xv for instance), and some
4312      ugly offset / fb reservation (cursor) is gone. And as a bonus, everything actually works...
4313      For simplicity, just always update everything (just let the ioctl fail - could do better).
4314      All surface addresses are relative to RADEON_MC_FB_LOCATION */
4315
4316    RADEONInfoPtr  info  = RADEONPTR(pScrn);
4317    int cpp = info->CurrentLayout.pixel_bytes;
4318    /* depth/front/back pitch must be identical (and the same as displayWidth) */
4319    int width_bytes = pScrn->displayWidth * cpp;
4320    int bufferSize = RADEON_ALIGN((RADEON_ALIGN(pScrn->virtualY, 16)) * width_bytes,
4321        RADEON_GPU_PAGE_SIZE);
4322    unsigned int color_pattern, swap_pattern;
4323
4324    if (!info->allowColorTiling)
4325	return;
4326
4327    swap_pattern = 0;
4328#if X_BYTE_ORDER == X_BIG_ENDIAN
4329    switch (pScrn->bitsPerPixel) {
4330    case 16:
4331	swap_pattern = RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP;
4332	break;
4333
4334    case 32:
4335	swap_pattern = RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
4336	break;
4337    }
4338#endif
4339    if (info->ChipFamily < CHIP_FAMILY_R200) {
4340	color_pattern = RADEON_SURF_TILE_COLOR_MACRO;
4341    } else if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
4342       color_pattern = R300_SURF_TILE_COLOR_MACRO;
4343    } else {
4344	color_pattern = R200_SURF_TILE_COLOR_MACRO;
4345    }
4346#ifdef XF86DRI
4347    if (info->directRenderingInited) {
4348	drm_radeon_surface_free_t drmsurffree;
4349	drm_radeon_surface_alloc_t drmsurfalloc;
4350	int retvalue;
4351	int depthCpp = (info->dri->depthBits - 8) / 4;
4352	int depth_width_bytes = pScrn->displayWidth * depthCpp;
4353	int depthBufferSize = RADEON_ALIGN((RADEON_ALIGN(pScrn->virtualY, 16)) * depth_width_bytes,
4354				RADEON_GPU_PAGE_SIZE);
4355	unsigned int depth_pattern;
4356
4357	drmsurffree.address = info->dri->frontOffset;
4358	retvalue = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SURF_FREE,
4359	    &drmsurffree, sizeof(drmsurffree));
4360
4361	if (!((info->ChipFamily == CHIP_FAMILY_RV100) ||
4362	    (info->ChipFamily == CHIP_FAMILY_RS100) ||
4363	    (info->ChipFamily == CHIP_FAMILY_RS200))) {
4364	    drmsurffree.address = info->dri->depthOffset;
4365	    retvalue = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SURF_FREE,
4366		&drmsurffree, sizeof(drmsurffree));
4367	}
4368
4369	if (!info->dri->noBackBuffer) {
4370	    drmsurffree.address = info->dri->backOffset;
4371	    retvalue = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SURF_FREE,
4372		&drmsurffree, sizeof(drmsurffree));
4373	}
4374
4375	drmsurfalloc.size = bufferSize;
4376	drmsurfalloc.address = info->dri->frontOffset;
4377	drmsurfalloc.flags = swap_pattern;
4378
4379	if (info->tilingEnabled) {
4380	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
4381		drmsurfalloc.flags |= (width_bytes / 8) | color_pattern;
4382	    else
4383		drmsurfalloc.flags |= (width_bytes / 16) | color_pattern;
4384	}
4385	retvalue = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SURF_ALLOC,
4386				   &drmsurfalloc, sizeof(drmsurfalloc));
4387	if (retvalue < 0)
4388	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4389		       "drm: could not allocate surface for front buffer!\n");
4390
4391	if ((info->dri->have3DWindows) && (!info->dri->noBackBuffer)) {
4392	    drmsurfalloc.address = info->dri->backOffset;
4393	    retvalue = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SURF_ALLOC,
4394				       &drmsurfalloc, sizeof(drmsurfalloc));
4395	    if (retvalue < 0)
4396		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4397			   "drm: could not allocate surface for back buffer!\n");
4398	}
4399
4400	if (info->ChipFamily < CHIP_FAMILY_R200) {
4401	    if (depthCpp == 2)
4402		depth_pattern = RADEON_SURF_TILE_DEPTH_16BPP;
4403	    else
4404		depth_pattern = RADEON_SURF_TILE_DEPTH_32BPP;
4405	} else if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
4406	    if (depthCpp == 2)
4407		depth_pattern = R300_SURF_TILE_COLOR_MACRO;
4408	    else
4409		depth_pattern = R300_SURF_TILE_COLOR_MACRO | R300_SURF_TILE_DEPTH_32BPP;
4410	} else {
4411	    if (depthCpp == 2)
4412		depth_pattern = R200_SURF_TILE_DEPTH_16BPP;
4413	    else
4414		depth_pattern = R200_SURF_TILE_DEPTH_32BPP;
4415	}
4416
4417	/* rv100 and probably the derivative igps don't have depth tiling on all the time? */
4418	if (info->dri->have3DWindows &&
4419	    (!((info->ChipFamily == CHIP_FAMILY_RV100) ||
4420	    (info->ChipFamily == CHIP_FAMILY_RS100) ||
4421	    (info->ChipFamily == CHIP_FAMILY_RS200)))) {
4422	    drm_radeon_surface_alloc_t drmsurfalloc;
4423	    drmsurfalloc.size = depthBufferSize;
4424	    drmsurfalloc.address = info->dri->depthOffset;
4425            if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
4426                drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 8) | depth_pattern;
4427            else
4428                drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 16) | depth_pattern;
4429	    retvalue = drmCommandWrite(info->dri->drmFD, DRM_RADEON_SURF_ALLOC,
4430		&drmsurfalloc, sizeof(drmsurfalloc));
4431	    if (retvalue < 0)
4432		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
4433		    "drm: could not allocate surface for depth buffer!\n");
4434	}
4435    }
4436    else
4437#endif
4438    {
4439	unsigned int surf_info = swap_pattern;
4440	unsigned char *RADEONMMIO = info->MMIO;
4441	/* we don't need anything like WaitForFifo, no? */
4442	if (info->tilingEnabled) {
4443	    if (IS_R300_VARIANT || IS_AVIVO_VARIANT)
4444		surf_info |= (width_bytes / 8) | color_pattern;
4445	    else
4446		surf_info |= (width_bytes / 16) | color_pattern;
4447	}
4448	OUTREG(RADEON_SURFACE0_INFO, surf_info);
4449	OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0);
4450	OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1);
4451/*	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4452		"surface0 set to %x, LB 0x%x UB 0x%x\n",
4453		surf_info, 0, bufferSize - 1024);*/
4454    }
4455
4456    /* Update surface images */
4457    if (info->ChipFamily < CHIP_FAMILY_R600)
4458        RADEONSaveSurfaces(pScrn, info->ModeReg);
4459}
4460
4461/* Read memory map */
4462static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
4463{
4464    RADEONInfoPtr  info       = RADEONPTR(pScrn);
4465    unsigned char *RADEONMMIO = info->MMIO;
4466
4467    radeon_read_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP, &save->mc_fb_location,
4468				   &save->mc_agp_location, &save->mc_agp_location_hi);
4469
4470    if (!IS_AVIVO_VARIANT) {
4471        save->display_base_addr  = INREG(RADEON_DISPLAY_BASE_ADDR);
4472        save->display2_base_addr = INREG(RADEON_DISPLAY2_BASE_ADDR);
4473        save->ov0_base_addr      = INREG(RADEON_OV0_BASE_ADDR);
4474    }
4475}
4476
4477/* Read palette data */
4478static void RADEONSavePalette(ScrnInfoPtr pScrn, int palID, RADEONSavePtr save)
4479{
4480    RADEONInfoPtr  info       = RADEONPTR(pScrn);
4481    unsigned char *RADEONMMIO = info->MMIO;
4482    int            i;
4483
4484    PAL_SELECT(palID);
4485    INPAL_START(0);
4486
4487    for (i = 0; i < 256; i++) {
4488	save->palette[palID][i] = INREG(RADEON_PALETTE_30_DATA);
4489    }
4490}
4491
4492static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
4493{
4494    RADEONInfoPtr  info       = RADEONPTR(pScrn);
4495    unsigned char *RADEONMMIO = info->MMIO;
4496    int            i;
4497
4498    if (restore->palette_saved[1]) {
4499	ErrorF("Restore Palette 2\n");
4500	PAL_SELECT(1);
4501	OUTPAL_START(0);
4502	for (i = 0; i < 256; i++) {
4503	    OUTREG(RADEON_PALETTE_30_DATA, restore->palette[1][i]);
4504	}
4505    }
4506    if (restore->palette_saved[0]) {
4507	ErrorF("Restore Palette 1\n");
4508	PAL_SELECT(0);
4509	OUTPAL_START(0);
4510	for (i = 0; i < 256; i++) {
4511	    OUTREG(RADEON_PALETTE_30_DATA, restore->palette[0][i]);
4512	}
4513    }
4514}
4515
4516static void
4517dce4_save_grph(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4518	       uint32_t offset)
4519{
4520    RADEONInfoPtr info = RADEONPTR(pScrn);
4521    unsigned char *RADEONMMIO = info->MMIO;
4522
4523    state->grph.enable = INREG(offset + EVERGREEN_GRPH_ENABLE);
4524    state->grph.control = INREG(offset + EVERGREEN_GRPH_CONTROL);
4525    state->grph.swap_control = INREG(offset + EVERGREEN_GRPH_SWAP_CONTROL);
4526    state->grph.prim_surf_addr = INREG(offset + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS);
4527    state->grph.sec_surf_addr = INREG(offset + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS);
4528    state->grph.pitch = INREG(offset + EVERGREEN_GRPH_PITCH);
4529    state->grph.prim_surf_addr_hi = INREG(offset + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH);
4530    state->grph.sec_surf_addr_hi = INREG(offset + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH);
4531    state->grph.x_offset = INREG(offset + EVERGREEN_GRPH_SURFACE_OFFSET_X);
4532    state->grph.y_offset = INREG(offset + EVERGREEN_GRPH_SURFACE_OFFSET_Y);
4533    state->grph.x_start = INREG(offset + EVERGREEN_GRPH_X_START);
4534    state->grph.y_start = INREG(offset + EVERGREEN_GRPH_Y_START);
4535    state->grph.x_end = INREG(offset + EVERGREEN_GRPH_X_END);
4536    state->grph.y_end = INREG(offset + EVERGREEN_GRPH_Y_END);
4537
4538    state->grph.desktop_height = INREG(offset + EVERGREEN_DESKTOP_HEIGHT);
4539    state->grph.viewport_start = INREG(offset + EVERGREEN_VIEWPORT_START);
4540    state->grph.viewport_size = INREG(offset + EVERGREEN_VIEWPORT_SIZE);
4541    state->grph.mode_data_format = INREG(offset + EVERGREEN_DATA_FORMAT);
4542}
4543
4544static void
4545dce4_restore_grph(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4546	       uint32_t offset)
4547{
4548    RADEONInfoPtr info = RADEONPTR(pScrn);
4549    unsigned char *RADEONMMIO = info->MMIO;
4550
4551    OUTREG(offset + EVERGREEN_GRPH_ENABLE, state->grph.enable);
4552    OUTREG(offset + EVERGREEN_GRPH_CONTROL, state->grph.control);
4553    OUTREG(offset + EVERGREEN_GRPH_SWAP_CONTROL, state->grph.swap_control);
4554    OUTREG(offset + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS, state->grph.prim_surf_addr);
4555    OUTREG(offset + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS, state->grph.sec_surf_addr);
4556    OUTREG(offset + EVERGREEN_GRPH_PITCH, state->grph.pitch);
4557    OUTREG(offset + EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, state->grph.prim_surf_addr_hi);
4558    OUTREG(offset + EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, state->grph.sec_surf_addr_hi);
4559    OUTREG(offset + EVERGREEN_GRPH_SURFACE_OFFSET_X, state->grph.x_offset);
4560    OUTREG(offset + EVERGREEN_GRPH_SURFACE_OFFSET_Y, state->grph.y_offset);
4561    OUTREG(offset + EVERGREEN_GRPH_X_START, state->grph.x_start);
4562    OUTREG(offset + EVERGREEN_GRPH_Y_START, state->grph.y_start);
4563    OUTREG(offset + EVERGREEN_GRPH_X_END, state->grph.x_end);
4564    OUTREG(offset + EVERGREEN_GRPH_Y_END, state->grph.y_end);
4565
4566    OUTREG(offset + EVERGREEN_DESKTOP_HEIGHT, state->grph.desktop_height);
4567    OUTREG(offset + EVERGREEN_VIEWPORT_START, state->grph.viewport_start);
4568    OUTREG(offset + EVERGREEN_VIEWPORT_SIZE, state->grph.viewport_size);
4569    OUTREG(offset + EVERGREEN_DATA_FORMAT, state->grph.mode_data_format);
4570}
4571
4572static uint32_t dce4_dac_regs[] = {
4573    0x6690, 0x6694, 0x66b0, 0x66cc, 0x66d0, 0x66d4, 0x66d8 };
4574
4575static uint32_t dce4_scl_regs[] = {
4576    0x6d08, 0x6d0c, 0x6d14, 0x6d1c };
4577
4578static uint32_t dce4_dig_regs[] = {
4579    0x7000, 0x7004, 0x7008, 0x700c, 0x7010, 0x7014,
4580    0x71f0, 0x71f4, 0x71f8, 0x71fc, 0x7200, 0x7204,
4581    0x7208, 0x720c, 0x7210, 0x7218, 0x721c, 0x7220,
4582    0x7230};
4583
4584static uint32_t dce4_crtc_regs[] = {
4585    0x6e00, 0x6e04, 0x6e08, 0x6e0c, 0x6e1c, 0x6e34, 0x6e38, 0x6e3c, 0x6e70, 0x6e74, 0x6e78};
4586
4587
4588#define DCE4_REG_SCL_NUM (sizeof(dce4_scl_regs)/sizeof(uint32_t))
4589#define DCE4_REG_CRTC_NUM (sizeof(dce4_crtc_regs)/sizeof(uint32_t))
4590#define DCE4_REG_DIG_NUM (sizeof(dce4_dig_regs)/sizeof(uint32_t))
4591#define DCE4_DAC_NUM (sizeof(dce4_dac_regs)/sizeof(uint32_t))
4592
4593
4594static void
4595dce4_save_crtc(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4596	       uint32_t offset)
4597{
4598    RADEONInfoPtr info = RADEONPTR(pScrn);
4599    unsigned char *RADEONMMIO = info->MMIO;
4600    int i;
4601
4602    for (i = 0; i < DCE4_REG_CRTC_NUM; i++)
4603        state->crtc[i] = INREG(offset + dce4_crtc_regs[i]);
4604}
4605
4606static void
4607dce4_restore_crtc(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4608		  uint32_t offset)
4609{
4610    RADEONInfoPtr info = RADEONPTR(pScrn);
4611    unsigned char *RADEONMMIO = info->MMIO;
4612    int i;
4613
4614    for (i = 0; i < DCE4_REG_CRTC_NUM; i++)
4615        OUTREG(offset + dce4_crtc_regs[i], state->crtc[i]);
4616}
4617
4618static void
4619dce4_save_scl(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4620	      uint32_t offset)
4621{
4622    RADEONInfoPtr info = RADEONPTR(pScrn);
4623    unsigned char *RADEONMMIO = info->MMIO;
4624    int i;
4625
4626    for (i = 0; i < DCE4_REG_SCL_NUM; i++)
4627        state->scl[i] = INREG(offset + dce4_scl_regs[i]);
4628}
4629
4630static void
4631dce4_restore_scl(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4632	      uint32_t offset)
4633{
4634    RADEONInfoPtr info = RADEONPTR(pScrn);
4635    unsigned char *RADEONMMIO = info->MMIO;
4636    int i;
4637
4638    for (i = 0; i < DCE4_REG_SCL_NUM; i++)
4639        OUTREG(offset + dce4_scl_regs[i], state->scl[i]);
4640}
4641
4642
4643static void
4644dce4_save_fmt(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4645	      uint32_t offset)
4646{
4647    RADEONInfoPtr info = RADEONPTR(pScrn);
4648    unsigned char *RADEONMMIO = info->MMIO;
4649    int i, index = 0;
4650
4651    for (i = 0x6fb4; i <= 0x6fd4; i += 4)
4652	state->fmt[index++] = INREG(offset + i);
4653}
4654
4655static void
4656dce4_restore_fmt(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4657	      uint32_t offset)
4658{
4659    RADEONInfoPtr info = RADEONPTR(pScrn);
4660    unsigned char *RADEONMMIO = info->MMIO;
4661    int i, index = 0;
4662
4663    for (i = 0x6fb4; i <= 0x6fd4; i += 4)
4664	OUTREG(offset + i, state->fmt[index++]);
4665}
4666
4667
4668static void
4669dce4_save_dig(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4670	      uint32_t offset)
4671{
4672    RADEONInfoPtr info = RADEONPTR(pScrn);
4673    unsigned char *RADEONMMIO = info->MMIO;
4674    int i;
4675
4676    for (i = 0; i < DCE4_REG_DIG_NUM; i++)
4677        state->dig[i] = INREG(offset + dce4_dig_regs[i]);
4678}
4679
4680static void
4681dce4_restore_dig(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4682	      uint32_t offset)
4683{
4684    RADEONInfoPtr info = RADEONPTR(pScrn);
4685    unsigned char *RADEONMMIO = info->MMIO;
4686    int i;
4687
4688    for (i = 0; i < DCE4_REG_DIG_NUM; i++)
4689        OUTREG(offset + dce4_dig_regs[i], state->dig[i]);
4690}
4691
4692
4693
4694static void dce4_save_block(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4695			    uint32_t offset)
4696{
4697    dce4_save_grph(pScrn, state, offset);
4698    dce4_save_crtc(pScrn, state, offset);
4699    dce4_save_scl(pScrn, state, offset);
4700    dce4_save_dig(pScrn, state, offset);
4701    dce4_save_fmt(pScrn, state, offset);
4702}
4703
4704static void dce4_restore_block(ScrnInfoPtr pScrn, struct dce4_main_block_state *state,
4705			       uint32_t offset)
4706{
4707    dce4_restore_grph(pScrn, state, offset);
4708    dce4_restore_crtc(pScrn, state, offset);
4709    dce4_restore_scl(pScrn, state, offset);
4710    dce4_restore_dig(pScrn, state, offset);
4711    dce4_restore_fmt(pScrn, state, offset);
4712}
4713
4714static void dce4_save_uniphy(ScrnInfoPtr pScrn, struct dce4_state *state, int index)
4715{
4716    RADEONInfoPtr info = RADEONPTR(pScrn);
4717    unsigned char *RADEONMMIO = info->MMIO;
4718    uint32_t uniphy_offset[6] = {0x0, 0x30, 0x60, 0x100, 0x130, 0x160 };
4719    int i, ri = 0;
4720    for (i = 0; i < 0x18; i+=4)
4721	state->uniphy[index][ri++] = INREG(0x6600 + uniphy_offset[index] + i);
4722}
4723
4724static void dce4_restore_uniphy(ScrnInfoPtr pScrn, struct dce4_state *state, int index)
4725{
4726    RADEONInfoPtr info = RADEONPTR(pScrn);
4727    unsigned char *RADEONMMIO = info->MMIO;
4728    uint32_t uniphy_offset[6] = {0x0, 0x30, 0x60, 0x100, 0x130, 0x160 };
4729    int i, ri = 0;
4730    for (i = 0; i <= 0x18; i+=4)
4731	OUTREG(0x6600 + uniphy_offset[index] + i, state->uniphy[index][ri++]);
4732}
4733
4734static void dce4_save_dig_regs(ScrnInfoPtr pScrn, struct dce4_state *state)
4735{
4736    RADEONInfoPtr info = RADEONPTR(pScrn);
4737    unsigned char *RADEONMMIO = info->MMIO;
4738    int i, ri = 0;
4739
4740    for (i = 0x6578; i <= 0x6598; i += 4)
4741	state->dig[ri++] = INREG(i);
4742    for (i = 0x65ac; i <= 0x65d8; i += 4)
4743	state->dig[ri++] = INREG(i);
4744}
4745
4746static void dce4_restore_dig_regs(ScrnInfoPtr pScrn, struct dce4_state *state)
4747{
4748    RADEONInfoPtr info = RADEONPTR(pScrn);
4749    unsigned char *RADEONMMIO = info->MMIO;
4750    int i, ri = 0;
4751
4752    for (i = 0x6578; i <= 0x6598; i += 4)
4753	OUTREG(i, state->dig[ri++]);
4754    for (i = 0x65ac; i <= 0x65d8; i += 4)
4755	OUTREG(i, state->dig[ri++]);
4756}
4757
4758static void dce4_save_pll_regs(ScrnInfoPtr pScrn, struct dce4_state *state)
4759{
4760    RADEONInfoPtr info = RADEONPTR(pScrn);
4761    unsigned char *RADEONMMIO = info->MMIO;
4762    int i, ri = 0;
4763
4764    for (i = 0x360; i <= 0x368; i += 4)
4765	state->vga_pll[0][ri++] = INREG(i);
4766
4767    ri = 0;
4768    for (i = 0x370; i <= 0x378; i += 4)
4769	state->vga_pll[1][ri++] = INREG(i);
4770
4771    ri = 0;
4772    for (i = 0x390; i <= 0x398; i += 4)
4773	state->vga_pll[2][ri++] = INREG(i);
4774
4775    ri = 0;
4776    for (i = 0x400; i <= 0x408; i += 4)
4777	state->pll[0][ri++] = INREG(i);
4778    for (i = 0x410; i <= 0x43c; i += 4)
4779	state->pll[0][ri++] = INREG(i);
4780
4781    ri = 0;
4782    for (i = 0x440; i <= 0x448; i += 4)
4783	state->pll[1][ri++] = INREG(i);
4784    for (i = 0x450; i <= 0x47c; i += 4)
4785	state->pll[1][ri++] = INREG(i);
4786
4787    ri = 0;
4788    for (i = 0x500; i <= 0x550; i += 0x10)
4789	state->pll_route[ri++] = INREG(i);
4790}
4791
4792static void dce4_restore_pll_regs(ScrnInfoPtr pScrn, struct dce4_state *state)
4793{
4794    RADEONInfoPtr info = RADEONPTR(pScrn);
4795    unsigned char *RADEONMMIO = info->MMIO;
4796    int i, ri = 0;
4797
4798    for (i = 0x360; i <= 0x368; i += 4)
4799	OUTREG(i, state->vga_pll[0][ri++]);
4800
4801    ri = 0;
4802    for (i = 0x370; i <= 0x378; i += 4)
4803	OUTREG(i, state->vga_pll[1][ri++]);
4804
4805    ri = 0;
4806    for (i = 0x390; i <= 0x398; i += 4)
4807	OUTREG(i, state->vga_pll[2][ri++]);
4808
4809    ri = 0;
4810    for (i = 0x400; i <= 0x408; i += 4)
4811	OUTREG(i, state->pll[0][ri++]);
4812    for (i = 0x410; i <= 0x43c; i += 4)
4813	OUTREG(i, state->pll[0][ri++]);
4814
4815    ri = 0;
4816    for (i = 0x440; i <= 0x448; i += 4)
4817	OUTREG(i, state->pll[1][ri++]);
4818    for (i = 0x450; i <= 0x47c; i += 4)
4819	OUTREG(i, state->pll[1][ri++]);
4820
4821    ri = 0;
4822    for (i = 0x500; i <= 0x550; i += 0x10)
4823	OUTREG(i, state->pll_route[ri++]);
4824}
4825
4826static void
4827dce4_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
4828{
4829    RADEONInfoPtr info = RADEONPTR(pScrn);
4830    unsigned char *RADEONMMIO = info->MMIO;
4831    struct dce4_state *state = &save->dce4;
4832    int i, j;
4833    uint32_t crtc_offset[] = {EVERGREEN_CRTC0_REGISTER_OFFSET,
4834			      EVERGREEN_CRTC1_REGISTER_OFFSET,
4835			      EVERGREEN_CRTC2_REGISTER_OFFSET,
4836			      EVERGREEN_CRTC3_REGISTER_OFFSET,
4837			      EVERGREEN_CRTC4_REGISTER_OFFSET,
4838			      EVERGREEN_CRTC5_REGISTER_OFFSET};
4839
4840    state->vga1_cntl = INREG(AVIVO_D1VGA_CONTROL);
4841    state->vga2_cntl = INREG(AVIVO_D2VGA_CONTROL);
4842    state->vga3_cntl = INREG(EVERGREEN_D3VGA_CONTROL);
4843    state->vga4_cntl = INREG(EVERGREEN_D4VGA_CONTROL);
4844    state->vga5_cntl = INREG(EVERGREEN_D5VGA_CONTROL);
4845    state->vga6_cntl = INREG(EVERGREEN_D6VGA_CONTROL);
4846    state->vga_render_control = INREG(AVIVO_VGA_RENDER_CONTROL);
4847
4848    dce4_save_pll_regs(pScrn, state);
4849    dce4_save_dig_regs(pScrn, state);
4850
4851    for (i = 0; i < 6; i++)
4852	dce4_save_block(pScrn, &state->block[i], crtc_offset[i]);
4853
4854    for (i = 0; i < 6; i++)
4855	dce4_save_uniphy(pScrn, state, i);
4856
4857    for (i = 0; i < 2; i++) {
4858	for (j = 0; j < DCE4_DAC_NUM; j++) {
4859	    uint32_t offset = i ? 0x100 : 0x0;
4860	    state->dac[i][j] = INREG(dce4_dac_regs[j] + offset);
4861	}
4862    }
4863}
4864
4865static void
4866dce4_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
4867{
4868    RADEONInfoPtr info = RADEONPTR(pScrn);
4869    unsigned char *RADEONMMIO = info->MMIO;
4870    struct dce4_state *state = &restore->dce4;
4871    int i, j;
4872    uint32_t crtc_offset[] = {EVERGREEN_CRTC0_REGISTER_OFFSET,
4873			      EVERGREEN_CRTC1_REGISTER_OFFSET,
4874			      EVERGREEN_CRTC2_REGISTER_OFFSET,
4875			      EVERGREEN_CRTC3_REGISTER_OFFSET,
4876			      EVERGREEN_CRTC4_REGISTER_OFFSET,
4877			      EVERGREEN_CRTC5_REGISTER_OFFSET};
4878
4879    OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
4880    OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);;
4881    OUTREG(EVERGREEN_D3VGA_CONTROL, state->vga3_cntl);
4882    OUTREG(EVERGREEN_D4VGA_CONTROL, state->vga4_cntl);
4883    OUTREG(EVERGREEN_D5VGA_CONTROL, state->vga5_cntl);
4884    OUTREG(EVERGREEN_D6VGA_CONTROL, state->vga6_cntl);
4885    OUTREG(AVIVO_VGA_RENDER_CONTROL, state->vga_render_control);
4886
4887    dce4_restore_dig_regs(pScrn, state);
4888    dce4_restore_pll_regs(pScrn, state);
4889    for (i = 0; i < 6; i++)
4890	dce4_restore_uniphy(pScrn, state, i);
4891
4892    for (i = 0; i < 6; i++)
4893	dce4_restore_block(pScrn, &state->block[i], crtc_offset[i]);
4894
4895    for (i = 0; i < 2; i++) {
4896	for (j = 0; j < DCE4_DAC_NUM; j++) {
4897	    uint32_t offset = i ? 0x100 : 0x0;
4898	    OUTREG(dce4_dac_regs[j] + offset, state->dac[i][j]);
4899	}
4900    }
4901}
4902
4903static void
4904avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
4905{
4906    RADEONInfoPtr info = RADEONPTR(pScrn);
4907    unsigned char *RADEONMMIO = info->MMIO;
4908    struct avivo_state *state = &save->avivo;
4909    int i, j;
4910
4911    //    state->vga_memory_base = INREG(AVIVO_VGA_MEMORY_BASE);
4912    //    state->vga_fb_start = INREG(AVIVO_VGA_FB_START);
4913    state->vga1_cntl = INREG(AVIVO_D1VGA_CONTROL);
4914    state->vga2_cntl = INREG(AVIVO_D2VGA_CONTROL);
4915    state->vga_render_control = INREG(AVIVO_VGA_RENDER_CONTROL);
4916
4917    state->crtc_master_en = INREG(AVIVO_DC_CRTC_MASTER_EN);
4918    state->crtc_tv_control = INREG(AVIVO_DC_CRTC_TV_CONTROL);
4919    state->dc_lb_memory_split = INREG(AVIVO_DC_LB_MEMORY_SPLIT);
4920
4921    state->pll[0].ref_div_src = INREG(AVIVO_EXT1_PPLL_REF_DIV_SRC);
4922    state->pll[0].ref_div = INREG(AVIVO_EXT1_PPLL_REF_DIV);
4923    state->pll[0].fb_div = INREG(AVIVO_EXT1_PPLL_FB_DIV);
4924    state->pll[0].post_div_src = INREG(AVIVO_EXT1_PPLL_POST_DIV_SRC);
4925    state->pll[0].post_div = INREG(AVIVO_EXT1_PPLL_POST_DIV);
4926    state->pll[0].ext_ppll_cntl = INREG(AVIVO_EXT1_PPLL_CNTL);
4927    state->pll[0].pll_cntl = INREG(AVIVO_P1PLL_CNTL);
4928    state->pll[0].int_ss_cntl = INREG(AVIVO_P1PLL_INT_SS_CNTL);
4929
4930    state->pll[1].ref_div_src = INREG(AVIVO_EXT1_PPLL_REF_DIV_SRC);
4931    state->pll[1].ref_div = INREG(AVIVO_EXT2_PPLL_REF_DIV);
4932    state->pll[1].fb_div = INREG(AVIVO_EXT2_PPLL_FB_DIV);
4933    state->pll[1].post_div_src = INREG(AVIVO_EXT2_PPLL_POST_DIV_SRC);
4934    state->pll[1].post_div = INREG(AVIVO_EXT2_PPLL_POST_DIV);
4935    state->pll[1].ext_ppll_cntl = INREG(AVIVO_EXT2_PPLL_CNTL);
4936    state->pll[1].pll_cntl = INREG(AVIVO_P2PLL_CNTL);
4937    state->pll[1].int_ss_cntl = INREG(AVIVO_P2PLL_INT_SS_CNTL);
4938
4939    state->vga25_ppll.ref_div_src = INREG(AVIVO_VGA25_PPLL_REF_DIV_SRC);
4940    state->vga25_ppll.ref_div = INREG(AVIVO_VGA25_PPLL_REF_DIV);
4941    state->vga25_ppll.fb_div = INREG(AVIVO_VGA25_PPLL_FB_DIV);
4942    state->vga25_ppll.post_div_src = INREG(AVIVO_VGA25_PPLL_POST_DIV_SRC);
4943    state->vga25_ppll.post_div = INREG(AVIVO_VGA25_PPLL_POST_DIV);
4944    state->vga25_ppll.pll_cntl = INREG(AVIVO_VGA25_PPLL_CNTL);
4945
4946    state->vga28_ppll.ref_div_src = INREG(AVIVO_VGA28_PPLL_REF_DIV_SRC);
4947    state->vga28_ppll.ref_div = INREG(AVIVO_VGA28_PPLL_REF_DIV);
4948    state->vga28_ppll.fb_div = INREG(AVIVO_VGA28_PPLL_FB_DIV);
4949    state->vga28_ppll.post_div_src = INREG(AVIVO_VGA28_PPLL_POST_DIV_SRC);
4950    state->vga28_ppll.post_div = INREG(AVIVO_VGA28_PPLL_POST_DIV);
4951    state->vga28_ppll.pll_cntl = INREG(AVIVO_VGA28_PPLL_CNTL);
4952
4953    state->vga41_ppll.ref_div_src = INREG(AVIVO_VGA41_PPLL_REF_DIV_SRC);
4954    state->vga41_ppll.ref_div = INREG(AVIVO_VGA41_PPLL_REF_DIV);
4955    state->vga41_ppll.fb_div = INREG(AVIVO_VGA41_PPLL_FB_DIV);
4956    state->vga41_ppll.post_div_src = INREG(AVIVO_VGA41_PPLL_POST_DIV_SRC);
4957    state->vga41_ppll.post_div = INREG(AVIVO_VGA41_PPLL_POST_DIV);
4958    state->vga41_ppll.pll_cntl = INREG(AVIVO_VGA41_PPLL_CNTL);
4959
4960    state->crtc[0].pll_source = INREG(AVIVO_PCLK_CRTC1_CNTL);
4961
4962    state->crtc[0].h_total = INREG(AVIVO_D1CRTC_H_TOTAL);
4963    state->crtc[0].h_blank_start_end = INREG(AVIVO_D1CRTC_H_BLANK_START_END);
4964    state->crtc[0].h_sync_a = INREG(AVIVO_D1CRTC_H_SYNC_A);
4965    state->crtc[0].h_sync_a_cntl = INREG(AVIVO_D1CRTC_H_SYNC_A_CNTL);
4966    state->crtc[0].h_sync_b = INREG(AVIVO_D1CRTC_H_SYNC_B);
4967    state->crtc[0].h_sync_b_cntl = INREG(AVIVO_D1CRTC_H_SYNC_B_CNTL);
4968
4969    state->crtc[0].v_total = INREG(AVIVO_D1CRTC_V_TOTAL);
4970    state->crtc[0].v_blank_start_end = INREG(AVIVO_D1CRTC_V_BLANK_START_END);
4971    state->crtc[0].v_sync_a = INREG(AVIVO_D1CRTC_V_SYNC_A);
4972    state->crtc[0].v_sync_a_cntl = INREG(AVIVO_D1CRTC_V_SYNC_A_CNTL);
4973    state->crtc[0].v_sync_b = INREG(AVIVO_D1CRTC_V_SYNC_B);
4974    state->crtc[0].v_sync_b_cntl = INREG(AVIVO_D1CRTC_V_SYNC_B_CNTL);
4975
4976    state->crtc[0].control = INREG(AVIVO_D1CRTC_CONTROL);
4977    state->crtc[0].blank_control = INREG(AVIVO_D1CRTC_BLANK_CONTROL);
4978    state->crtc[0].interlace_control = INREG(AVIVO_D1CRTC_INTERLACE_CONTROL);
4979    state->crtc[0].stereo_control = INREG(AVIVO_D1CRTC_STEREO_CONTROL);
4980
4981    state->crtc[0].cursor_control = INREG(AVIVO_D1CUR_CONTROL);
4982
4983    state->grph[0].enable = INREG(AVIVO_D1GRPH_ENABLE);
4984    state->grph[0].control = INREG(AVIVO_D1GRPH_CONTROL);
4985    state->grph[0].control = INREG(AVIVO_D1GRPH_CONTROL);
4986    state->grph[0].prim_surf_addr = INREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS);
4987    state->grph[0].sec_surf_addr = INREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS);
4988    state->grph[0].pitch = INREG(AVIVO_D1GRPH_PITCH);
4989    state->grph[0].x_offset = INREG(AVIVO_D1GRPH_SURFACE_OFFSET_X);
4990    state->grph[0].y_offset = INREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y);
4991    state->grph[0].x_start = INREG(AVIVO_D1GRPH_X_START);
4992    state->grph[0].y_start = INREG(AVIVO_D1GRPH_Y_START);
4993    state->grph[0].x_end = INREG(AVIVO_D1GRPH_X_END);
4994    state->grph[0].y_end = INREG(AVIVO_D1GRPH_Y_END);
4995
4996    state->grph[0].desktop_height = INREG(AVIVO_D1MODE_DESKTOP_HEIGHT);
4997    state->grph[0].viewport_start = INREG(AVIVO_D1MODE_VIEWPORT_START);
4998    state->grph[0].viewport_size = INREG(AVIVO_D1MODE_VIEWPORT_SIZE);
4999    state->grph[0].mode_data_format = INREG(AVIVO_D1MODE_DATA_FORMAT);
5000
5001    state->crtc[1].pll_source = INREG(AVIVO_PCLK_CRTC2_CNTL);
5002
5003    state->crtc[1].h_total = INREG(AVIVO_D2CRTC_H_TOTAL);
5004    state->crtc[1].h_blank_start_end = INREG(AVIVO_D2CRTC_H_BLANK_START_END);
5005    state->crtc[1].h_sync_a = INREG(AVIVO_D2CRTC_H_SYNC_A);
5006    state->crtc[1].h_sync_a_cntl = INREG(AVIVO_D2CRTC_H_SYNC_A_CNTL);
5007    state->crtc[1].h_sync_b = INREG(AVIVO_D2CRTC_H_SYNC_B);
5008    state->crtc[1].h_sync_b_cntl = INREG(AVIVO_D2CRTC_H_SYNC_B_CNTL);
5009
5010    state->crtc[1].v_total = INREG(AVIVO_D2CRTC_V_TOTAL);
5011    state->crtc[1].v_blank_start_end = INREG(AVIVO_D2CRTC_V_BLANK_START_END);
5012    state->crtc[1].v_sync_a = INREG(AVIVO_D2CRTC_V_SYNC_A);
5013    state->crtc[1].v_sync_a_cntl = INREG(AVIVO_D2CRTC_V_SYNC_A_CNTL);
5014    state->crtc[1].v_sync_b = INREG(AVIVO_D2CRTC_V_SYNC_B);
5015    state->crtc[1].v_sync_b_cntl = INREG(AVIVO_D2CRTC_V_SYNC_B_CNTL);
5016
5017    state->crtc[1].control = INREG(AVIVO_D2CRTC_CONTROL);
5018    state->crtc[1].blank_control = INREG(AVIVO_D2CRTC_BLANK_CONTROL);
5019    state->crtc[1].interlace_control = INREG(AVIVO_D2CRTC_INTERLACE_CONTROL);
5020    state->crtc[1].stereo_control = INREG(AVIVO_D2CRTC_STEREO_CONTROL);
5021
5022    state->crtc[1].cursor_control = INREG(AVIVO_D2CUR_CONTROL);
5023
5024    state->grph[1].enable = INREG(AVIVO_D2GRPH_ENABLE);
5025    state->grph[1].control = INREG(AVIVO_D2GRPH_CONTROL);
5026    state->grph[1].control = INREG(AVIVO_D2GRPH_CONTROL);
5027    state->grph[1].prim_surf_addr = INREG(AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS);
5028    state->grph[1].sec_surf_addr = INREG(AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS);
5029    state->grph[1].pitch = INREG(AVIVO_D2GRPH_PITCH);
5030    state->grph[1].x_offset = INREG(AVIVO_D2GRPH_SURFACE_OFFSET_X);
5031    state->grph[1].y_offset = INREG(AVIVO_D2GRPH_SURFACE_OFFSET_Y);
5032    state->grph[1].x_start = INREG(AVIVO_D2GRPH_X_START);
5033    state->grph[1].y_start = INREG(AVIVO_D2GRPH_Y_START);
5034    state->grph[1].x_end = INREG(AVIVO_D2GRPH_X_END);
5035    state->grph[1].y_end = INREG(AVIVO_D2GRPH_Y_END);
5036
5037    state->grph[1].desktop_height = INREG(AVIVO_D2MODE_DESKTOP_HEIGHT);
5038    state->grph[1].viewport_start = INREG(AVIVO_D2MODE_VIEWPORT_START);
5039    state->grph[1].viewport_size = INREG(AVIVO_D2MODE_VIEWPORT_SIZE);
5040    state->grph[1].mode_data_format = INREG(AVIVO_D2MODE_DATA_FORMAT);
5041
5042    if (IS_DCE3_VARIANT) {
5043	/* save DVOA regs */
5044	state->dvoa[0] = INREG(0x7080);
5045	state->dvoa[1] = INREG(0x7084);
5046	state->dvoa[2] = INREG(0x708c);
5047	state->dvoa[3] = INREG(0x7090);
5048	state->dvoa[4] = INREG(0x7094);
5049	state->dvoa[5] = INREG(0x70ac);
5050	state->dvoa[6] = INREG(0x70b0);
5051
5052	j = 0;
5053	/* save DAC regs */
5054	for (i = 0x7000; i <= 0x7040; i += 4) {
5055	    state->daca[j] = INREG(i);
5056	    state->dacb[j] = INREG(i + 0x100);
5057	    j++;
5058	}
5059	for (i = 0x7058; i <= 0x7060; i += 4) {
5060	    state->daca[j] = INREG(i);
5061	    state->dacb[j] = INREG(i + 0x100);
5062	    j++;
5063	}
5064	for (i = 0x7068; i <= 0x706c; i += 4) {
5065	    state->daca[j] = INREG(i);
5066	    state->dacb[j] = INREG(i + 0x100);
5067	    j++;
5068	}
5069	for (i = 0x7ef0; i <= 0x7ef8; i += 4) {
5070	    state->daca[j] = INREG(i);
5071	    state->dacb[j] = INREG(i + 0x100);
5072	    j++;
5073	}
5074	state->daca[j] = INREG(0x7050);
5075	state->dacb[j] = INREG(0x7050 + 0x100);
5076
5077	j = 0;
5078	/* save FMT regs */
5079	for (i = 0x6700; i <= 0x6744; i += 4) {
5080	    state->fmt1[j] = INREG(i);
5081	    state->fmt2[j] = INREG(i + 0x800);
5082	    j++;
5083	}
5084
5085	j = 0;
5086	/* save DIG regs */
5087	for (i = 0x75a0; i <= 0x75e0; i += 4) {
5088	    state->dig1[j] = INREG(i);
5089	    state->dig2[j] = INREG(i + 0x400);
5090	    j++;
5091	}
5092	for (i = 0x75e8; i <= 0x75ec; i += 4) {
5093	    state->dig1[j] = INREG(i);
5094	    state->dig2[j] = INREG(i + 0x400);
5095	    j++;
5096	}
5097
5098	j = 0;
5099	/* save HDMI regs */
5100	for (i = 0x7400; i <= 0x741c; i += 4) {
5101	    state->hdmi1[j] = INREG(i);
5102	    state->hdmi2[j] = INREG(i + 0x400);
5103	    j++;
5104	}
5105	for (i = 0x7430; i <= 0x74ec; i += 4) {
5106	    state->hdmi1[j] = INREG(i);
5107	    state->hdmi2[j] = INREG(i + 0x400);
5108	    j++;
5109	}
5110	state->hdmi1[j] = INREG(0x7428);
5111	state->hdmi2[j] = INREG(0x7828);
5112
5113	j = 0;
5114	/* save AUX regs */
5115	for (i = 0x7780; i <= 0x77b4; i += 4) {
5116	    state->aux_cntl1[j] = INREG(i);
5117	    state->aux_cntl2[j] = INREG(i + 0x040);
5118	    state->aux_cntl3[j] = INREG(i + 0x400);
5119	    state->aux_cntl4[j] = INREG(i + 0x440);
5120	    if (IS_DCE32_VARIANT) {
5121		state->aux_cntl5[j] = INREG(i + 0x500);
5122		state->aux_cntl6[j] = INREG(i + 0x540);
5123	    }
5124	    j++;
5125	}
5126
5127	j = 0;
5128	/* save UNIPHY regs */
5129	if (IS_DCE32_VARIANT) {
5130	    for (i = 0x7680; i <= 0x7690; i += 4) {
5131		state->uniphy1[j] = INREG(i);
5132		state->uniphy2[j] = INREG(i + 0x20);
5133		state->uniphy3[j] = INREG(i + 0x400);
5134		state->uniphy4[j] = INREG(i + 0x420);
5135		state->uniphy5[j] = INREG(i + 0x840);
5136		state->uniphy6[j] = INREG(i + 0x940);
5137		j++;
5138	    }
5139	    for (i = 0x7698; i <= 0x769c; i += 4) {
5140		state->uniphy1[j] = INREG(i);
5141		state->uniphy2[j] = INREG(i + 0x20);
5142		state->uniphy3[j] = INREG(i + 0x400);
5143		state->uniphy4[j] = INREG(i + 0x420);
5144		state->uniphy5[j] = INREG(i + 0x840);
5145		state->uniphy6[j] = INREG(i + 0x940);
5146		j++;
5147	    }
5148	} else {
5149	    for (i = 0x7ec0; i <= 0x7edc; i += 4) {
5150		state->uniphy1[j] = INREG(i);
5151		state->uniphy2[j] = INREG(i + 0x100);
5152		j++;
5153	    }
5154	}
5155	j = 0;
5156	/* save PHY,LINK regs */
5157	for (i = 0x7f20; i <= 0x7f34; i += 4) {
5158	    state->phy[j] = INREG(i);
5159	    j++;
5160	}
5161	for (i = 0x7f9c; i <= 0x7fa4; i += 4) {
5162	    state->phy[j] = INREG(i);
5163	    j++;
5164	}
5165	state->phy[j] = INREG(0x7f40);
5166
5167	j = 0;
5168	/* save LVTMA regs */
5169	for (i = 0x7f00; i <= 0x7f1c; i += 4) {
5170	    state->lvtma[j] = INREG(i);
5171	    j++;
5172	}
5173	for (i = 0x7f80; i <= 0x7f98; i += 4) {
5174	    state->lvtma[j] = INREG(i);
5175	    j++;
5176	}
5177    } else {
5178	j = 0;
5179	/* save DVOA regs */
5180	for (i = 0x7980; i <= 0x79bc; i += 4) {
5181	    state->dvoa[j] = INREG(i);
5182	    j++;
5183	}
5184
5185	j = 0;
5186	/* save DAC regs */
5187	for (i = 0x7800; i <= 0x782c; i += 4) {
5188	    state->daca[j] = INREG(i);
5189	    state->dacb[j] = INREG(i + 0x200);
5190	    j++;
5191	}
5192	for (i = 0x7834; i <= 0x7840; i += 4) {
5193	    state->daca[j] = INREG(i);
5194	    state->dacb[j] = INREG(i + 0x200);
5195	    j++;
5196	}
5197	for (i = 0x7850; i <= 0x7868; i += 4) {
5198	    state->daca[j] = INREG(i);
5199	    state->dacb[j] = INREG(i + 0x200);
5200	    j++;
5201	}
5202
5203	j = 0;
5204	/* save TMDSA regs */
5205	for (i = 0x7880; i <= 0x78e0; i += 4) {
5206	    state->tmdsa[j] = INREG(i);
5207	    j++;
5208	}
5209	for (i = 0x7904; i <= 0x7918; i += 4) {
5210	    state->tmdsa[j] = INREG(i);
5211	    j++;
5212	}
5213
5214	j = 0;
5215	/* save LVTMA regs */
5216	for (i = 0x7a80; i <= 0x7b18; i += 4) {
5217	    state->lvtma[j] = INREG(i);
5218	    j++;
5219	}
5220
5221	if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
5222	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
5223	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
5224	    j = 0;
5225	    /* save DDIA regs */
5226	    for (i = 0x7200; i <= 0x7290; i += 4) {
5227		state->ddia[j] = INREG(i);
5228		j++;
5229	    }
5230	}
5231    }
5232
5233    /* scalers */
5234    j = 0;
5235    for (i = 0x6578; i <= 0x65e4; i += 4) {
5236	state->d1scl[j] = INREG(i);
5237	state->d2scl[j] = INREG(i + 0x800);
5238	j++;
5239    }
5240    for (i = 0x6600; i <= 0x662c; i += 4) {
5241	state->d1scl[j] = INREG(i);
5242	state->d2scl[j] = INREG(i + 0x800);
5243	j++;
5244    }
5245    j = 0;
5246    for (i = 0x66e8; i <= 0x66fc; i += 4) {
5247	state->dxscl[j] = INREG(i);
5248	j++;
5249    }
5250    state->dxscl[6] = INREG(0x6e30);
5251    state->dxscl[7] = INREG(0x6e34);
5252
5253    if (state->crtc[0].control & AVIVO_CRTC_EN)
5254	info->crtc_on = TRUE;
5255
5256    if (state->crtc[1].control & AVIVO_CRTC_EN)
5257	info->crtc2_on = TRUE;
5258
5259}
5260
5261static void
5262avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
5263{
5264    RADEONInfoPtr info = RADEONPTR(pScrn);
5265    unsigned char *RADEONMMIO = info->MMIO;
5266    struct avivo_state *state = &restore->avivo;
5267    int i, j;
5268
5269    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "avivo_restore !\n");
5270
5271    /* Disable VGA control for now.. maybe needs to be changed */
5272    OUTREG(AVIVO_D1VGA_CONTROL, 0);
5273    OUTREG(AVIVO_D2VGA_CONTROL, 0);
5274
5275    /* Disable CRTCs */
5276    OUTREG(AVIVO_D1CRTC_CONTROL,
5277	   (INREG(AVIVO_D1CRTC_CONTROL) & ~0x300) | 0x01000000);
5278    OUTREG(AVIVO_D2CRTC_CONTROL,
5279	   (INREG(AVIVO_D2CRTC_CONTROL) & ~0x300) | 0x01000000);
5280    OUTREG(AVIVO_D1CRTC_CONTROL,
5281	   INREG(AVIVO_D1CRTC_CONTROL) & ~0x1);
5282    OUTREG(AVIVO_D2CRTC_CONTROL,
5283	   INREG(AVIVO_D2CRTC_CONTROL) & ~0x1);
5284    OUTREG(AVIVO_D1CRTC_CONTROL,
5285	   INREG(AVIVO_D1CRTC_CONTROL) | 0x100);
5286    OUTREG(AVIVO_D2CRTC_CONTROL,
5287	   INREG(AVIVO_D2CRTC_CONTROL) | 0x100);
5288
5289    /* Lock graph registers */
5290    OUTREG(AVIVO_D1GRPH_UPDATE, AVIVO_D1GRPH_UPDATE_LOCK);
5291    OUTREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, state->grph[0].prim_surf_addr);
5292    OUTREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS, state->grph[0].sec_surf_addr);
5293    OUTREG(AVIVO_D1GRPH_CONTROL, state->grph[0].control);
5294    OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_X, state->grph[0].x_offset);
5295    OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y, state->grph[0].y_offset);
5296    OUTREG(AVIVO_D1GRPH_X_START, state->grph[0].x_start);
5297    OUTREG(AVIVO_D1GRPH_Y_START, state->grph[0].y_start);
5298    OUTREG(AVIVO_D1GRPH_X_END, state->grph[0].x_end);
5299    OUTREG(AVIVO_D1GRPH_Y_END, state->grph[0].y_end);
5300    OUTREG(AVIVO_D1GRPH_PITCH, state->grph[0].pitch);
5301    OUTREG(AVIVO_D1GRPH_ENABLE, state->grph[0].enable);
5302    OUTREG(AVIVO_D1GRPH_UPDATE, 0);
5303
5304    OUTREG(AVIVO_D2GRPH_UPDATE, AVIVO_D1GRPH_UPDATE_LOCK);
5305    OUTREG(AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, state->grph[1].prim_surf_addr);
5306    OUTREG(AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS, state->grph[1].sec_surf_addr);
5307    OUTREG(AVIVO_D2GRPH_CONTROL, state->grph[1].control);
5308    OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_X, state->grph[1].x_offset);
5309    OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_Y, state->grph[1].y_offset);
5310    OUTREG(AVIVO_D2GRPH_X_START, state->grph[1].x_start);
5311    OUTREG(AVIVO_D2GRPH_Y_START, state->grph[1].y_start);
5312    OUTREG(AVIVO_D2GRPH_X_END, state->grph[1].x_end);
5313    OUTREG(AVIVO_D2GRPH_Y_END, state->grph[1].y_end);
5314    OUTREG(AVIVO_D2GRPH_PITCH, state->grph[1].pitch);
5315    OUTREG(AVIVO_D2GRPH_ENABLE, state->grph[1].enable);
5316    OUTREG(AVIVO_D2GRPH_UPDATE, 0);
5317
5318    /* Whack some mode regs too */
5319    OUTREG(AVIVO_D1SCL_UPDATE, AVIVO_D1SCL_UPDATE_LOCK);
5320    OUTREG(AVIVO_D1MODE_DESKTOP_HEIGHT, state->grph[0].desktop_height);
5321    OUTREG(AVIVO_D1MODE_VIEWPORT_START, state->grph[0].viewport_start);
5322    OUTREG(AVIVO_D1MODE_VIEWPORT_SIZE, state->grph[0].viewport_size);
5323    OUTREG(AVIVO_D1MODE_DATA_FORMAT, state->grph[0].mode_data_format);
5324    OUTREG(AVIVO_D1SCL_UPDATE, 0);
5325
5326    OUTREG(AVIVO_D2SCL_UPDATE, AVIVO_D1SCL_UPDATE_LOCK);
5327    OUTREG(AVIVO_D2MODE_DESKTOP_HEIGHT, state->grph[1].desktop_height);
5328    OUTREG(AVIVO_D2MODE_VIEWPORT_START, state->grph[1].viewport_start);
5329    OUTREG(AVIVO_D2MODE_VIEWPORT_SIZE, state->grph[1].viewport_size);
5330    OUTREG(AVIVO_D2MODE_DATA_FORMAT, state->grph[1].mode_data_format);
5331    OUTREG(AVIVO_D2SCL_UPDATE, 0);
5332
5333    /* Set the PLL */
5334    OUTREG(AVIVO_EXT1_PPLL_REF_DIV_SRC, state->pll[0].ref_div_src);
5335    OUTREG(AVIVO_EXT1_PPLL_REF_DIV, state->pll[0].ref_div);
5336    OUTREG(AVIVO_EXT1_PPLL_FB_DIV, state->pll[0].fb_div);
5337    OUTREG(AVIVO_EXT1_PPLL_POST_DIV_SRC, state->pll[0].post_div_src);
5338    OUTREG(AVIVO_EXT1_PPLL_POST_DIV, state->pll[0].post_div);
5339    OUTREG(AVIVO_EXT1_PPLL_CNTL, state->pll[0].ext_ppll_cntl);
5340    OUTREG(AVIVO_P1PLL_CNTL, state->pll[0].pll_cntl);
5341    OUTREG(AVIVO_P1PLL_INT_SS_CNTL, state->pll[0].int_ss_cntl);
5342
5343    OUTREG(AVIVO_EXT2_PPLL_REF_DIV_SRC, state->pll[1].ref_div_src);
5344    OUTREG(AVIVO_EXT2_PPLL_REF_DIV, state->pll[1].ref_div);
5345    OUTREG(AVIVO_EXT2_PPLL_FB_DIV, state->pll[1].fb_div);
5346    OUTREG(AVIVO_EXT2_PPLL_POST_DIV_SRC, state->pll[1].post_div_src);
5347    OUTREG(AVIVO_EXT2_PPLL_POST_DIV, state->pll[1].post_div);
5348    OUTREG(AVIVO_EXT2_PPLL_CNTL, state->pll[1].ext_ppll_cntl);
5349    OUTREG(AVIVO_P2PLL_CNTL, state->pll[1].pll_cntl);
5350    OUTREG(AVIVO_P2PLL_INT_SS_CNTL, state->pll[1].int_ss_cntl);
5351
5352    OUTREG(AVIVO_PCLK_CRTC1_CNTL, state->crtc[0].pll_source);
5353    OUTREG(AVIVO_PCLK_CRTC2_CNTL, state->crtc[1].pll_source);
5354
5355    /* Set the vga PLL */
5356    OUTREG(AVIVO_VGA25_PPLL_REF_DIV_SRC, state->vga25_ppll.ref_div_src);
5357    OUTREG(AVIVO_VGA25_PPLL_REF_DIV, state->vga25_ppll.ref_div);
5358    OUTREG(AVIVO_VGA25_PPLL_FB_DIV, state->vga25_ppll.fb_div);
5359    OUTREG(AVIVO_VGA25_PPLL_POST_DIV_SRC, state->vga25_ppll.post_div_src);
5360    OUTREG(AVIVO_VGA25_PPLL_POST_DIV, state->vga25_ppll.post_div);
5361    OUTREG(AVIVO_VGA25_PPLL_CNTL, state->vga25_ppll.pll_cntl);
5362
5363    OUTREG(AVIVO_VGA28_PPLL_REF_DIV_SRC, state->vga28_ppll.ref_div_src);
5364    OUTREG(AVIVO_VGA28_PPLL_REF_DIV, state->vga28_ppll.ref_div);
5365    OUTREG(AVIVO_VGA28_PPLL_FB_DIV, state->vga28_ppll.fb_div);
5366    OUTREG(AVIVO_VGA28_PPLL_POST_DIV_SRC, state->vga28_ppll.post_div_src);
5367    OUTREG(AVIVO_VGA28_PPLL_POST_DIV, state->vga28_ppll.post_div);
5368    OUTREG(AVIVO_VGA28_PPLL_CNTL, state->vga28_ppll.pll_cntl);
5369
5370    OUTREG(AVIVO_VGA41_PPLL_REF_DIV_SRC, state->vga41_ppll.ref_div_src);
5371    OUTREG(AVIVO_VGA41_PPLL_REF_DIV, state->vga41_ppll.ref_div);
5372    OUTREG(AVIVO_VGA41_PPLL_FB_DIV, state->vga41_ppll.fb_div);
5373    OUTREG(AVIVO_VGA41_PPLL_POST_DIV_SRC, state->vga41_ppll.post_div_src);
5374    OUTREG(AVIVO_VGA41_PPLL_POST_DIV, state->vga41_ppll.post_div);
5375    OUTREG(AVIVO_VGA41_PPLL_CNTL, state->vga41_ppll.pll_cntl);
5376
5377    /* Set the CRTC */
5378    OUTREG(AVIVO_D1CRTC_H_TOTAL, state->crtc[0].h_total);
5379    OUTREG(AVIVO_D1CRTC_H_BLANK_START_END, state->crtc[0].h_blank_start_end);
5380    OUTREG(AVIVO_D1CRTC_H_SYNC_A, state->crtc[0].h_sync_a);
5381    OUTREG(AVIVO_D1CRTC_H_SYNC_A_CNTL, state->crtc[0].h_sync_a_cntl);
5382    OUTREG(AVIVO_D1CRTC_H_SYNC_B, state->crtc[0].h_sync_b);
5383    OUTREG(AVIVO_D1CRTC_H_SYNC_B_CNTL, state->crtc[0].h_sync_b_cntl);
5384
5385    OUTREG(AVIVO_D1CRTC_V_TOTAL, state->crtc[0].v_total);
5386    OUTREG(AVIVO_D1CRTC_V_BLANK_START_END, state->crtc[0].v_blank_start_end);
5387    OUTREG(AVIVO_D1CRTC_V_SYNC_A, state->crtc[0].v_sync_a);
5388    OUTREG(AVIVO_D1CRTC_V_SYNC_A_CNTL, state->crtc[0].v_sync_a_cntl);
5389    OUTREG(AVIVO_D1CRTC_V_SYNC_B, state->crtc[0].v_sync_b);
5390    OUTREG(AVIVO_D1CRTC_V_SYNC_B_CNTL, state->crtc[0].v_sync_b_cntl);
5391
5392    OUTREG(AVIVO_D1CRTC_INTERLACE_CONTROL, state->crtc[0].interlace_control);
5393    OUTREG(AVIVO_D1CRTC_STEREO_CONTROL, state->crtc[0].stereo_control);
5394
5395    OUTREG(AVIVO_D1CUR_CONTROL, state->crtc[0].cursor_control);
5396
5397    /* XXX Fix scaler */
5398
5399    OUTREG(AVIVO_D2CRTC_H_TOTAL, state->crtc[1].h_total);
5400    OUTREG(AVIVO_D2CRTC_H_BLANK_START_END, state->crtc[1].h_blank_start_end);
5401    OUTREG(AVIVO_D2CRTC_H_SYNC_A, state->crtc[1].h_sync_a);
5402    OUTREG(AVIVO_D2CRTC_H_SYNC_A_CNTL, state->crtc[1].h_sync_a_cntl);
5403    OUTREG(AVIVO_D2CRTC_H_SYNC_B, state->crtc[1].h_sync_b);
5404    OUTREG(AVIVO_D2CRTC_H_SYNC_B_CNTL, state->crtc[1].h_sync_b_cntl);
5405
5406    OUTREG(AVIVO_D2CRTC_V_TOTAL, state->crtc[1].v_total);
5407    OUTREG(AVIVO_D2CRTC_V_BLANK_START_END, state->crtc[1].v_blank_start_end);
5408    OUTREG(AVIVO_D2CRTC_V_SYNC_A, state->crtc[1].v_sync_a);
5409    OUTREG(AVIVO_D2CRTC_V_SYNC_A_CNTL, state->crtc[1].v_sync_a_cntl);
5410    OUTREG(AVIVO_D2CRTC_V_SYNC_B, state->crtc[1].v_sync_b);
5411    OUTREG(AVIVO_D2CRTC_V_SYNC_B_CNTL, state->crtc[1].v_sync_b_cntl);
5412
5413    OUTREG(AVIVO_D2CRTC_INTERLACE_CONTROL, state->crtc[1].interlace_control);
5414    OUTREG(AVIVO_D2CRTC_STEREO_CONTROL, state->crtc[1].stereo_control);
5415
5416    OUTREG(AVIVO_D2CUR_CONTROL, state->crtc[1].cursor_control);
5417
5418    if (IS_DCE3_VARIANT) {
5419	/* DVOA regs */
5420	OUTREG(0x7080, state->dvoa[0]);
5421	OUTREG(0x7084, state->dvoa[1]);
5422	OUTREG(0x708c, state->dvoa[2]);
5423	OUTREG(0x7090, state->dvoa[3]);
5424	OUTREG(0x7094, state->dvoa[4]);
5425	OUTREG(0x70ac, state->dvoa[5]);
5426	OUTREG(0x70b0, state->dvoa[6]);
5427
5428	j = 0;
5429	/* DAC regs */
5430	for (i = 0x7000; i <= 0x7040; i += 4) {
5431	    OUTREG(i, state->daca[j]);
5432	    OUTREG((i + 0x100), state->dacb[j]);
5433	    j++;
5434	}
5435	for (i = 0x7058; i <= 0x7060; i += 4) {
5436	    OUTREG(i, state->daca[j]);
5437	    OUTREG((i + 0x100), state->dacb[j]);
5438	    j++;
5439	}
5440	for (i = 0x7068; i <= 0x706c; i += 4) {
5441	    OUTREG(i, state->daca[j]);
5442	    OUTREG((i + 0x100), state->dacb[j]);
5443	    j++;
5444	}
5445	for (i = 0x7ef0; i <= 0x7ef8; i += 4) {
5446	    OUTREG(i, state->daca[j]);
5447	    OUTREG((i + 0x100), state->dacb[j]);
5448	    j++;
5449	}
5450	OUTREG(0x7050, state->daca[j]);
5451	OUTREG((0x7050 + 0x100), state->dacb[j]);
5452
5453	j = 0;
5454	/* FMT regs */
5455	for (i = 0x6700; i <= 0x6744; i += 4) {
5456	    OUTREG(i, state->fmt1[j]);
5457	    OUTREG((i + 0x800), state->fmt2[j]);
5458	    j++;
5459	}
5460
5461	j = 0;
5462	/* DIG regs */
5463	for (i = 0x75a0; i <= 0x75e0; i += 4) {
5464	    OUTREG(i, state->dig1[j]);
5465	    OUTREG((i + 0x400), state->dig2[j]);
5466	    j++;
5467	}
5468	for (i = 0x75e8; i <= 0x75ec; i += 4) {
5469	    OUTREG(i, state->dig1[j]);
5470	    OUTREG((i + 0x400), state->dig2[j]);
5471	    j++;
5472	}
5473
5474	j = 0;
5475	/* HDMI regs */
5476	for (i = 0x7400; i <= 0x741c; i += 4) {
5477	    OUTREG(i, state->hdmi1[j]);
5478	    OUTREG((i + 0x400), state->hdmi2[j]);
5479	    j++;
5480	}
5481	for (i = 0x7430; i <= 0x74ec; i += 4) {
5482	    OUTREG(i, state->hdmi1[j]);
5483	    OUTREG((i + 0x400), state->hdmi2[j]);
5484	    j++;
5485	}
5486	OUTREG(0x7428, state->hdmi1[j]);
5487	OUTREG((0x7428 + 0x400), state->hdmi2[j]);
5488
5489	j = 0;
5490	/* save AUX regs */
5491	for (i = 0x7780; i <= 0x77b4; i += 4) {
5492	    OUTREG(i, state->aux_cntl1[j]);
5493	    OUTREG((i + 0x040), state->aux_cntl2[j]);
5494	    OUTREG((i + 0x400), state->aux_cntl3[j]);
5495	    OUTREG((i + 0x440), state->aux_cntl4[j]);
5496	    if (IS_DCE32_VARIANT) {
5497		OUTREG((i + 0x500), state->aux_cntl5[j]);
5498		OUTREG((i + 0x540), state->aux_cntl6[j]);
5499	    }
5500	    j++;
5501	}
5502
5503	j = 0;
5504	/* save UNIPHY regs */
5505	if (IS_DCE32_VARIANT) {
5506	    for (i = 0x7680; i <= 0x7690; i += 4) {
5507		OUTREG(i, state->uniphy1[j]);
5508		OUTREG((i + 0x20), state->uniphy2[j]);
5509		OUTREG((i + 0x400), state->uniphy3[j]);
5510		OUTREG((i + 0x420), state->uniphy4[j]);
5511		OUTREG((i + 0x840), state->uniphy5[j]);
5512		OUTREG((i + 0x940), state->uniphy6[j]);
5513		j++;
5514	    }
5515	    for (i = 0x7698; i <= 0x769c; i += 4) {
5516		OUTREG(i, state->uniphy1[j]);
5517		OUTREG((i + 0x20), state->uniphy2[j]);
5518		OUTREG((i + 0x400), state->uniphy3[j]);
5519		OUTREG((i + 0x420), state->uniphy4[j]);
5520		OUTREG((i + 0x840), state->uniphy5[j]);
5521		OUTREG((i + 0x940), state->uniphy6[j]);
5522		j++;
5523	    }
5524	} else {
5525	    for (i = 0x7ec0; i <= 0x7edc; i += 4) {
5526		OUTREG(i, state->uniphy1[j]);
5527		OUTREG((i + 0x100), state->uniphy2[j]);
5528		j++;
5529	    }
5530	}
5531	j = 0;
5532	/* save PHY,LINK regs */
5533	for (i = 0x7f20; i <= 0x7f34; i += 4) {
5534	    OUTREG(i, state->phy[j]);
5535	    j++;
5536	}
5537	for (i = 0x7f9c; i <= 0x7fa4; i += 4) {
5538	    OUTREG(i, state->phy[j]);
5539	    j++;
5540	}
5541	state->phy[j] = INREG(0x7f40);
5542
5543	j = 0;
5544	/* save LVTMA regs */
5545	for (i = 0x7f00; i <= 0x7f1c; i += 4) {
5546	    OUTREG(i, state->lvtma[j]);
5547	    j++;
5548	}
5549	for (i = 0x7f80; i <= 0x7f98; i += 4) {
5550	    OUTREG(i, state->lvtma[j]);
5551	    j++;
5552	}
5553    } else {
5554	j = 0;
5555	/* DVOA regs */
5556	for (i = 0x7980; i <= 0x79bc; i += 4) {
5557	    OUTREG(i, state->dvoa[j]);
5558	    j++;
5559	}
5560
5561	j = 0;
5562	/* DAC regs */ /* -- MIGHT NEED ORDERING FIX & DELAYS -- */
5563	for (i = 0x7800; i <= 0x782c; i += 4) {
5564	    OUTREG(i, state->daca[j]);
5565	    OUTREG((i + 0x200), state->dacb[j]);
5566	    j++;
5567	}
5568	for (i = 0x7834; i <= 0x7840; i += 4) {
5569	    OUTREG(i, state->daca[j]);
5570	    OUTREG((i + 0x200), state->dacb[j]);
5571	    j++;
5572	}
5573	for (i = 0x7850; i <= 0x7868; i += 4) {
5574	    OUTREG(i, state->daca[j]);
5575	    OUTREG((i + 0x200), state->dacb[j]);
5576	    j++;
5577	}
5578
5579	j = 0;
5580	/* TMDSA regs */
5581	for (i = 0x7880; i <= 0x78e0; i += 4) {
5582	    OUTREG(i, state->tmdsa[j]);
5583	    j++;
5584	}
5585	for (i = 0x7904; i <= 0x7918; i += 4) {
5586	    OUTREG(i, state->tmdsa[j]);
5587	    j++;
5588	}
5589
5590	j = 0;
5591	/* LVTMA regs */
5592	for (i = 0x7a80; i <= 0x7b18; i += 4) {
5593	    OUTREG(i, state->lvtma[j]);
5594	    j++;
5595	}
5596
5597	/* DDIA regs */
5598	if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
5599	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
5600	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
5601	    j = 0;
5602	    for (i = 0x7200; i <= 0x7290; i += 4) {
5603		OUTREG(i, state->ddia[j]);
5604		j++;
5605	    }
5606	}
5607    }
5608
5609    /* scalers */
5610    j = 0;
5611    for (i = 0x6578; i <= 0x65e4; i += 4) {
5612	OUTREG(i, state->d1scl[j]);
5613	OUTREG((i + 0x800), state->d2scl[j]);
5614	j++;
5615    }
5616    for (i = 0x6600; i <= 0x662c; i += 4) {
5617	OUTREG(i, state->d1scl[j]);
5618	OUTREG((i + 0x800), state->d2scl[j]);
5619	j++;
5620    }
5621    j = 0;
5622    for (i = 0x66e8; i <= 0x66fc; i += 4) {
5623	OUTREG(i, state->dxscl[j]);
5624	j++;
5625    }
5626    OUTREG(0x6e30, state->dxscl[6]);
5627    OUTREG(0x6e34, state->dxscl[7]);
5628
5629    /* Enable CRTCs */
5630    if (state->crtc[0].control & 1) {
5631	    OUTREG(AVIVO_D1CRTC_CONTROL, 0x01000101);
5632	    INREG(AVIVO_D1CRTC_CONTROL);
5633	    OUTREG(AVIVO_D1CRTC_CONTROL, 0x00010101);
5634    }
5635    if (state->crtc[1].control & 1) {
5636	    OUTREG(AVIVO_D2CRTC_CONTROL, 0x01000101);
5637	    INREG(AVIVO_D2CRTC_CONTROL);
5638	    OUTREG(AVIVO_D2CRTC_CONTROL, 0x00010101);
5639    }
5640
5641    /* Where should that go ? */
5642    OUTREG(AVIVO_DC_CRTC_TV_CONTROL, state->crtc_tv_control);
5643    OUTREG(AVIVO_DC_LB_MEMORY_SPLIT, state->dc_lb_memory_split);
5644
5645    /* Need fixing too ? */
5646    OUTREG(AVIVO_D1CRTC_BLANK_CONTROL, state->crtc[0].blank_control);
5647    OUTREG(AVIVO_D2CRTC_BLANK_CONTROL, state->crtc[1].blank_control);
5648
5649    /* Dbl check */
5650    OUTREG(AVIVO_VGA_RENDER_CONTROL, state->vga_render_control);
5651    OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
5652    OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
5653
5654    /* Should only enable outputs here */
5655}
5656
5657static void avivo_restore_vga_regs(ScrnInfoPtr pScrn, RADEONSavePtr restore)
5658{
5659    RADEONInfoPtr info = RADEONPTR(pScrn);
5660    unsigned char *RADEONMMIO = info->MMIO;
5661    struct avivo_state *state = &restore->avivo;
5662
5663    OUTREG(AVIVO_VGA_RENDER_CONTROL, state->vga_render_control);
5664    OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
5665    OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
5666}
5667
5668static void dce4_restore_vga_regs(ScrnInfoPtr pScrn, RADEONSavePtr restore)
5669{
5670    RADEONInfoPtr info = RADEONPTR(pScrn);
5671    unsigned char *RADEONMMIO = info->MMIO;
5672    struct dce4_state *state = &restore->dce4;
5673
5674    OUTREG(AVIVO_VGA_RENDER_CONTROL, state->vga_render_control);
5675    OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
5676    OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
5677    OUTREG(EVERGREEN_D3VGA_CONTROL, state->vga3_cntl);
5678    OUTREG(EVERGREEN_D4VGA_CONTROL, state->vga4_cntl);
5679    OUTREG(EVERGREEN_D5VGA_CONTROL, state->vga5_cntl);
5680    OUTREG(EVERGREEN_D6VGA_CONTROL, state->vga6_cntl);
5681}
5682
5683
5684static void
5685RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
5686{
5687    RADEONInfoPtr  info       = RADEONPTR(pScrn);
5688    unsigned char *RADEONMMIO = info->MMIO;
5689
5690    if (info->ChipFamily >= CHIP_FAMILY_R600) {
5691	OUTREG(R600_BIOS_0_SCRATCH, restore->bios_0_scratch);
5692	OUTREG(R600_BIOS_1_SCRATCH, restore->bios_1_scratch);
5693	OUTREG(R600_BIOS_2_SCRATCH, restore->bios_2_scratch);
5694	OUTREG(R600_BIOS_3_SCRATCH, restore->bios_3_scratch);
5695	OUTREG(R600_BIOS_4_SCRATCH, restore->bios_4_scratch);
5696	OUTREG(R600_BIOS_5_SCRATCH, restore->bios_5_scratch);
5697	OUTREG(R600_BIOS_6_SCRATCH, restore->bios_6_scratch);
5698	OUTREG(R600_BIOS_7_SCRATCH, restore->bios_7_scratch);
5699    } else {
5700	OUTREG(RADEON_BIOS_0_SCRATCH, restore->bios_0_scratch);
5701	OUTREG(RADEON_BIOS_1_SCRATCH, restore->bios_1_scratch);
5702	OUTREG(RADEON_BIOS_2_SCRATCH, restore->bios_2_scratch);
5703	OUTREG(RADEON_BIOS_3_SCRATCH, restore->bios_3_scratch);
5704	OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
5705	OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch);
5706	OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch);
5707	OUTREG(RADEON_BIOS_7_SCRATCH, restore->bios_7_scratch);
5708    }
5709}
5710
5711static void
5712RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
5713{
5714    RADEONInfoPtr  info       = RADEONPTR(pScrn);
5715    unsigned char *RADEONMMIO = info->MMIO;
5716
5717    if (info->ChipFamily >= CHIP_FAMILY_R600) {
5718	save->bios_0_scratch       = INREG(R600_BIOS_0_SCRATCH);
5719	save->bios_1_scratch       = INREG(R600_BIOS_1_SCRATCH);
5720	save->bios_2_scratch       = INREG(R600_BIOS_2_SCRATCH);
5721	save->bios_3_scratch       = INREG(R600_BIOS_3_SCRATCH);
5722	save->bios_4_scratch       = INREG(R600_BIOS_4_SCRATCH);
5723	save->bios_5_scratch       = INREG(R600_BIOS_5_SCRATCH);
5724	save->bios_6_scratch       = INREG(R600_BIOS_6_SCRATCH);
5725	save->bios_7_scratch       = INREG(R600_BIOS_7_SCRATCH);
5726    } else {
5727	save->bios_0_scratch       = INREG(RADEON_BIOS_0_SCRATCH);
5728	save->bios_1_scratch       = INREG(RADEON_BIOS_1_SCRATCH);
5729	save->bios_2_scratch       = INREG(RADEON_BIOS_2_SCRATCH);
5730	save->bios_3_scratch       = INREG(RADEON_BIOS_3_SCRATCH);
5731	save->bios_4_scratch       = INREG(RADEON_BIOS_4_SCRATCH);
5732	save->bios_5_scratch       = INREG(RADEON_BIOS_5_SCRATCH);
5733	save->bios_6_scratch       = INREG(RADEON_BIOS_6_SCRATCH);
5734	save->bios_7_scratch       = INREG(RADEON_BIOS_7_SCRATCH);
5735    }
5736}
5737
5738void radeon_save_palette_on_demand(ScrnInfoPtr pScrn, int palID)
5739{
5740    RADEONInfoPtr  info       = RADEONPTR(pScrn);
5741    RADEONSavePtr  save       = info->SavedReg;
5742
5743    if (save->palette_saved[palID] == TRUE)
5744        return;
5745
5746    if (!IS_AVIVO_VARIANT)
5747        RADEONSavePalette(pScrn, palID, save);
5748
5749    save->palette_saved[palID] = TRUE;
5750}
5751
5752/* Save everything needed to restore the original VC state */
5753static void RADEONSave(ScrnInfoPtr pScrn)
5754{
5755    RADEONInfoPtr  info       = RADEONPTR(pScrn);
5756    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
5757    unsigned char *RADEONMMIO = info->MMIO;
5758    RADEONSavePtr  save       = info->SavedReg;
5759
5760    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
5761		   "RADEONSave\n");
5762
5763#ifdef WITH_VGAHW
5764    if (info->VGAAccess) {
5765	vgaHWPtr hwp = VGAHWPTR(pScrn);
5766
5767	vgaHWUnlock(hwp);
5768# if defined(__powerpc__)
5769	/* temporary hack to prevent crashing on PowerMacs when trying to
5770	 * read VGA fonts and colormap, will find a better solution
5771	 * in the future. TODO: Check if there's actually some VGA stuff
5772	 * setup in the card at all !!
5773	 */
5774	vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
5775# else
5776	/* Save only mode * & fonts */
5777	vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
5778# endif
5779	vgaHWLock(hwp);
5780    }
5781#endif
5782
5783    if (IS_DCE4_VARIANT) {
5784	RADEONSaveMemMapRegisters(pScrn, save);
5785	dce4_save(pScrn, save);
5786	//XXX
5787    } else if (IS_AVIVO_VARIANT) {
5788	RADEONSaveMemMapRegisters(pScrn, save);
5789	avivo_save(pScrn, save);
5790    } else {
5791	save->dp_datatype      = INREG(RADEON_DP_DATATYPE);
5792	save->rbbm_soft_reset  = INREG(RADEON_RBBM_SOFT_RESET);
5793	save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
5794	RADEONPllErrataAfterIndex(info);
5795
5796	RADEONSaveMemMapRegisters(pScrn, save);
5797	RADEONSaveCommonRegisters(pScrn, save);
5798	RADEONSavePLLRegisters(pScrn, save);
5799	RADEONSaveCrtcRegisters(pScrn, save);
5800	RADEONSaveFPRegisters(pScrn, save);
5801	RADEONSaveDACRegisters(pScrn, save);
5802	/* Palette saving is done on demand now */
5803
5804	if (pRADEONEnt->HasCRTC2) {
5805	    RADEONSaveCrtc2Registers(pScrn, save);
5806	    RADEONSavePLL2Registers(pScrn, save);
5807	}
5808	if (info->InternalTVOut)
5809	    RADEONSaveTVRegisters(pScrn, save);
5810    }
5811
5812    if (info->ChipFamily < CHIP_FAMILY_R600)
5813        RADEONSaveSurfaces(pScrn, save);
5814
5815}
5816
5817/* Restore the original (text) mode */
5818static void RADEONRestore(ScrnInfoPtr pScrn)
5819{
5820    RADEONInfoPtr  info       = RADEONPTR(pScrn);
5821    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
5822    unsigned char *RADEONMMIO = info->MMIO;
5823    RADEONSavePtr  restore    = info->SavedReg;
5824    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
5825    xf86CrtcPtr crtc;
5826
5827    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
5828		   "RADEONRestore\n");
5829
5830#if X_BYTE_ORDER == X_BIG_ENDIAN
5831    if (info->ChipFamily < CHIP_FAMILY_R600) {
5832	RADEONWaitForFifo(pScrn, 1);
5833	OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
5834    }
5835#endif
5836
5837    RADEONBlank(pScrn);
5838
5839    if (IS_DCE4_VARIANT) {
5840	RADEONRestoreMemMapRegisters(pScrn, restore);
5841	dce4_restore(pScrn, restore);
5842	//XXX
5843    } else if (IS_AVIVO_VARIANT) {
5844	RADEONRestoreMemMapRegisters(pScrn, restore);
5845	avivo_restore(pScrn, restore);
5846    } else {
5847	OUTREG(RADEON_RBBM_SOFT_RESET,  restore->rbbm_soft_reset);
5848	OUTREG(RADEON_DP_DATATYPE,      restore->dp_datatype);
5849	OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl);
5850	OUTREG(RADEON_GRPH2_BUFFER_CNTL, restore->grph2_buffer_cntl);
5851
5852	if (!info->IsSecondary) {
5853	    RADEONRestoreMemMapRegisters(pScrn, restore);
5854	    RADEONRestoreCommonRegisters(pScrn, restore);
5855
5856	    RADEONRestorePalette(pScrn, restore);
5857	    if (pRADEONEnt->HasCRTC2) {
5858		RADEONRestoreCrtc2Registers(pScrn, restore);
5859		RADEONRestorePLL2Registers(pScrn, restore);
5860	    }
5861
5862	    RADEONRestoreCrtcRegisters(pScrn, restore);
5863	    RADEONRestorePLLRegisters(pScrn, restore);
5864	    RADEONRestoreRMXRegisters(pScrn, restore);
5865	    RADEONRestoreFPRegisters(pScrn, restore);
5866	    RADEONRestoreFP2Registers(pScrn, restore);
5867	    RADEONRestoreLVDSRegisters(pScrn, restore);
5868
5869	    if (info->InternalTVOut)
5870		RADEONRestoreTVRegisters(pScrn, restore);
5871	}
5872
5873	OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
5874	RADEONPllErrataAfterIndex(info);
5875
5876	RADEONRestoreBIOSRegisters(pScrn, restore);
5877    }
5878
5879
5880#if 1
5881    /* Temp fix to "solve" VT switch problems.  When switching VTs on
5882     * some systems, the console can either hang or the fonts can be
5883     * corrupted.  This hack solves the problem 99% of the time.  A
5884     * correct fix is being worked on.
5885     */
5886    usleep(100000);
5887#endif
5888
5889    if (info->ChipFamily < CHIP_FAMILY_R600)
5890	RADEONRestoreSurfaces(pScrn, restore);
5891
5892    /* need to make sure we don't enable a crtc by accident or we may get a hang */
5893    if (pRADEONEnt->HasCRTC2 && !info->IsSecondary) {
5894	if (info->crtc2_on && xf86_config->num_crtc > 1) {
5895	    crtc = xf86_config->crtc[1];
5896	    radeon_do_crtc_dpms(crtc, DPMSModeOn);
5897	}
5898    }
5899    if (info->crtc_on) {
5900	crtc = xf86_config->crtc[0];
5901	radeon_do_crtc_dpms(crtc, DPMSModeOn);
5902    }
5903
5904#ifdef WITH_VGAHW
5905    if (info->VGAAccess) {
5906       vgaHWPtr hwp = VGAHWPTR(pScrn);
5907       vgaHWUnlock(hwp);
5908# if defined(__powerpc__)
5909       /* Temporary hack to prevent crashing on PowerMacs when trying to
5910	* write VGA fonts, will find a better solution in the future
5911	*/
5912       vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
5913# else
5914       vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
5915# endif
5916       vgaHWLock(hwp);
5917    }
5918#endif
5919
5920    /* to restore console mode, DAC registers should be set after every other registers are set,
5921     * otherwise,we may get blank screen
5922     */
5923    if (IS_DCE4_VARIANT)
5924        dce4_restore_vga_regs(pScrn, restore);
5925    else if (IS_AVIVO_VARIANT)
5926	avivo_restore_vga_regs(pScrn, restore);
5927    else {
5928	RADEONRestoreDACRegisters(pScrn, restore);
5929    }
5930#if 0
5931    RADEONWaitForVerticalSync(pScrn);
5932#endif
5933}
5934
5935static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode)
5936{
5937    ScrnInfoPtr  pScrn = xf86ScreenToScrn(pScreen);
5938    Bool         unblank;
5939
5940    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
5941		   "RADEONSaveScreen(%d)\n", mode);
5942
5943    unblank = xf86IsUnblank(mode);
5944    if (unblank) SetTimeSinceLastInputEvent();
5945
5946    if ((pScrn != NULL) && pScrn->vtSema) {
5947	if (unblank)
5948	    RADEONUnblank(pScrn);
5949	else
5950	    RADEONBlank(pScrn);
5951    }
5952    return TRUE;
5953}
5954
5955Bool RADEONSwitchMode(SWITCH_MODE_ARGS_DECL)
5956{
5957    SCRN_INFO_PTR(arg);
5958    RADEONInfoPtr  info        = RADEONPTR(pScrn);
5959    Bool           tilingOld   = info->tilingEnabled;
5960    Bool           ret;
5961#ifdef XF86DRI
5962    Bool           CPStarted   = info->cp->CPStarted;
5963
5964    if (CPStarted) {
5965	DRILock(pScrn->pScreen, 0);
5966	RADEONCP_STOP(pScrn, info);
5967    }
5968#endif
5969
5970    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
5971		   "RADEONSwitchMode() !n");
5972
5973    if (info->allowColorTiling) {
5974        info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
5975#ifdef XF86DRI
5976	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
5977	    drm_radeon_sarea_t *pSAREAPriv;
5978	  if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
5979  	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
5980			 "[drm] failed changing tiling status\n");
5981	    pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
5982	    info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
5983	}
5984#endif
5985    }
5986
5987    if (info->accelOn)
5988        RADEON_SYNC(info, pScrn);
5989
5990    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
5991
5992    if (info->tilingEnabled != tilingOld) {
5993	/* need to redraw front buffer, I guess this can be considered a hack ? */
5994	xf86EnableDisableFBAccess(arg, FALSE);
5995	RADEONChangeSurfaces(pScrn);
5996	xf86EnableDisableFBAccess(arg, TRUE);
5997	/* xf86SetRootClip would do, but can't access that here */
5998    }
5999
6000    if (info->accelOn) {
6001        RADEON_SYNC(info, pScrn);
6002	if (info->ChipFamily < CHIP_FAMILY_R600)
6003	    RADEONEngineRestore(pScrn);
6004    }
6005
6006#ifdef XF86DRI
6007    if (CPStarted) {
6008	RADEONCP_START(pScrn, info);
6009	DRIUnlock(pScrn->pScreen);
6010    }
6011#endif
6012
6013    /* reset ecp for overlay */
6014    info->ecp_div = -1;
6015
6016    return ret;
6017}
6018
6019#ifdef X_XF86MiscPassMessage
6020Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
6021                                   const char* msgval, char** retmsg)
6022{
6023    ErrorF("RADEONHandleMessage(%d, \"%s\", \"%s\", retmsg)\n", scrnIndex,
6024		    msgtype, msgval);
6025    *retmsg = "";
6026    return 0;
6027}
6028#endif
6029
6030#ifndef HAVE_XF86MODEBANDWIDTH
6031/** Calculates the memory bandwidth (in MiB/sec) of a mode. */
6032_X_HIDDEN unsigned int
6033xf86ModeBandwidth(DisplayModePtr mode, int depth)
6034{
6035    float a_active, a_total, active_percent, pixels_per_second;
6036    int bytes_per_pixel = (depth + 7) / 8;
6037
6038    if (!mode->HTotal || !mode->VTotal || !mode->Clock)
6039	return 0;
6040
6041    a_active = mode->HDisplay * mode->VDisplay;
6042    a_total = mode->HTotal * mode->VTotal;
6043    active_percent = a_active / a_total;
6044    pixels_per_second = active_percent * mode->Clock * 1000.0;
6045
6046    return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024));
6047}
6048#endif
6049
6050/* Used to disallow modes that are not supported by the hardware */
6051ModeStatus RADEONValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
6052                                     Bool verbose, int flag)
6053{
6054    SCRN_INFO_PTR(arg);
6055    RADEONInfoPtr info = RADEONPTR(pScrn);
6056    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
6057
6058    /*
6059     * RN50 has effective maximum mode bandwidth of about 300MiB/s.
6060     * XXX should really do this for all chips by properly computing
6061     * memory bandwidth and an overhead factor.
6062     */
6063    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
6064	if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 300)
6065	    return MODE_BANDWIDTH;
6066    }
6067
6068    /* There are problems with double scan mode at high clocks
6069     * They're likely related PLL and display buffer settings.
6070     * Disable these modes for now.
6071     */
6072    if (mode->Flags & V_DBLSCAN) {
6073	if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
6074	    return MODE_CLOCK_RANGE;
6075    }
6076    return MODE_OK;
6077}
6078
6079/* Adjust viewport into virtual desktop such that (0,0) in viewport
6080 * space is (x,y) in virtual space.
6081 */
6082void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool crtc2)
6083{
6084    RADEONInfoPtr  info       = RADEONPTR(pScrn);
6085    unsigned char *RADEONMMIO = info->MMIO;
6086    int            Base, reg, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
6087#ifdef XF86DRI
6088    drm_radeon_sarea_t *pSAREAPriv;
6089    XF86DRISAREAPtr pSAREA;
6090#endif
6091
6092#if 0 /* Verbose */
6093    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6094		   "RADEONDoAdjustFrame(%d,%d,%d)\n", x, y, clone);
6095#endif
6096
6097    Base = pScrn->fbOffset;
6098
6099  /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
6100     drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
6101     flickering when scrolling vertically in a virtual screen, possibly because crtc will
6102     pick up the new offset value at the end of each scanline, but the new offset_cntl value
6103     only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
6104     OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
6105    if (crtc2) {
6106	reg = RADEON_CRTC2_OFFSET;
6107	regcntl = RADEON_CRTC2_OFFSET_CNTL;
6108	xytilereg = R300_CRTC2_TILE_X0_Y0;
6109    } else {
6110	reg = RADEON_CRTC_OFFSET;
6111	regcntl = RADEON_CRTC_OFFSET_CNTL;
6112	xytilereg = R300_CRTC_TILE_X0_Y0;
6113    }
6114    crtcoffsetcntl = INREG(regcntl) & ~0xf;
6115#if 0
6116    /* try to get rid of flickering when scrolling at least for 2d */
6117#ifdef XF86DRI
6118    if (!info->dri->have3DWindows)
6119#endif
6120    crtcoffsetcntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
6121#endif
6122    if (info->tilingEnabled) {
6123        if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
6124	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
6125	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
6126	 * Makes tiling MUCH easier.
6127	 */
6128             crtcxytile = x | (y << 16);
6129             Base &= ~0x7ff;
6130         } else {
6131             int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
6132             /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
6133             int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
6134             Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
6135             crtcoffsetcntl = crtcoffsetcntl | (y % 16);
6136         }
6137    }
6138    else {
6139       int offset = y * info->CurrentLayout.displayWidth + x;
6140       switch (info->CurrentLayout.pixel_code) {
6141       case 15:
6142       case 16: offset *= 2; break;
6143       case 24: offset *= 3; break;
6144       case 32: offset *= 4; break;
6145       }
6146       Base += offset;
6147    }
6148
6149    Base &= ~7;                 /* 3 lower bits are always 0 */
6150
6151#ifdef XF86DRI
6152    if (info->directRenderingInited) {
6153	/* note cannot use pScrn->pScreen since this is unitialized when called from
6154	   RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
6155        /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
6156	 *** pageflipping!
6157	 ***/
6158	pSAREAPriv = DRIGetSAREAPrivate(xf86ScrnToScreen(pScrn));
6159	/* can't get at sarea in a semi-sane way? */
6160	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
6161
6162	if (crtc2) {
6163	    pSAREAPriv->crtc2_base = Base;
6164	}
6165	else {
6166	    pSAREA->frame.x = (Base  / info->CurrentLayout.pixel_bytes)
6167		% info->CurrentLayout.displayWidth;
6168	    pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
6169		/ info->CurrentLayout.displayWidth;
6170	    pSAREA->frame.width = pScrn->frameX1 - x + 1;
6171	    pSAREA->frame.height = pScrn->frameY1 - y + 1;
6172	}
6173
6174	if (pSAREAPriv->pfCurrentPage == 1) {
6175	    Base += info->dri->backOffset - info->dri->frontOffset;
6176	}
6177    }
6178#endif
6179
6180    if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
6181	OUTREG(xytilereg, crtcxytile);
6182    } else {
6183	OUTREG(regcntl, crtcoffsetcntl);
6184    }
6185
6186    OUTREG(reg, Base);
6187}
6188
6189void RADEONAdjustFrame(ADJUST_FRAME_ARGS_DECL)
6190{
6191    SCRN_INFO_PTR(arg);
6192    RADEONInfoPtr  info       = RADEONPTR(pScrn);
6193    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
6194    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
6195    xf86OutputPtr  output = config->output[config->compat_output];
6196    xf86CrtcPtr	crtc = output->crtc;
6197
6198    /* not handled */
6199    if (IS_AVIVO_VARIANT)
6200	return;
6201
6202#ifdef XF86DRI
6203    if (info->cp->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
6204#endif
6205
6206    if (info->accelOn)
6207        RADEON_SYNC(info, pScrn);
6208
6209    if (crtc && crtc->enabled) {
6210	if (crtc == pRADEONEnt->pCrtc[0])
6211	    RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
6212	else
6213	    RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, TRUE);
6214	crtc->x = output->initial_x + x;
6215	crtc->y = output->initial_y + y;
6216    }
6217
6218
6219#ifdef XF86DRI
6220	if (info->cp->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
6221#endif
6222}
6223
6224/* Called when VT switching back to the X server.  Reinitialize the
6225 * video mode.
6226 */
6227Bool RADEONEnterVT(VT_FUNC_ARGS_DECL)
6228{
6229    SCRN_INFO_PTR(arg);
6230    RADEONInfoPtr  info  = RADEONPTR(pScrn);
6231    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
6232    int i;
6233
6234    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6235		   "RADEONEnterVT\n");
6236
6237    if (!radeon_card_posted(pScrn)) { /* Softboot V_BIOS */
6238	if (info->IsAtomBios) {
6239	    rhdAtomASICInit(info->atomBIOS);
6240	} else {
6241	    xf86Int10InfoPtr pInt;
6242
6243	    pInt = xf86InitInt10 (info->pEnt->index);
6244	    if (pInt) {
6245		pInt->num = 0xe6;
6246		xf86ExecX86int10 (pInt);
6247		xf86FreeInt10 (pInt);
6248	    } else {
6249		RADEONGetBIOSInitTableOffsets(pScrn);
6250		RADEONPostCardFromBIOSTables(pScrn);
6251	    }
6252	}
6253    }
6254
6255    /* Makes sure the engine is idle before doing anything */
6256    RADEONWaitForIdleMMIO(pScrn);
6257
6258    RADEONPMEnterVT(pScrn);
6259
6260    for (i = 0; i < config->num_crtc; i++)
6261	radeon_crtc_modeset_ioctl(config->crtc[i], TRUE);
6262
6263    pScrn->vtSema = TRUE;
6264
6265    /* Clear the framebuffer */
6266    memset(info->FB + pScrn->fbOffset, 0,
6267           pScrn->virtualY * pScrn->displayWidth * info->CurrentLayout.pixel_bytes);
6268
6269    if (!xf86SetDesiredModes(pScrn))
6270	return FALSE;
6271
6272    if (info->ChipFamily < CHIP_FAMILY_R600)
6273        RADEONRestoreSurfaces(pScrn, info->ModeReg);
6274#ifdef XF86DRI
6275    if (info->directRenderingEnabled) {
6276	if (info->cardType == CARD_PCIE &&
6277	    info->dri->pKernelDRMVersion->version_minor >= 19 &&
6278	    info->FbSecureSize) {
6279#if X_BYTE_ORDER == X_BIG_ENDIAN
6280	    unsigned char *RADEONMMIO = info->MMIO;
6281	    unsigned int sctrl = INREG(RADEON_SURFACE_CNTL);
6282
6283	    /* we need to backup the PCIE GART TABLE from fb memory */
6284	    OUTREG(RADEON_SURFACE_CNTL, 0);
6285#endif
6286	    memcpy(info->FB + info->dri->pciGartOffset, info->dri->pciGartBackup, info->dri->pciGartSize);
6287#if X_BYTE_ORDER == X_BIG_ENDIAN
6288	    OUTREG(RADEON_SURFACE_CNTL, sctrl);
6289#endif
6290	}
6291
6292	/* get the DRI back into shape after resume */
6293	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
6294	RADEONDRIResume(pScrn->pScreen);
6295	RADEONAdjustMemMapRegisters(pScrn, info->ModeReg);
6296
6297    }
6298#endif
6299    /* this will get XVideo going again, but only if XVideo was initialised
6300       during server startup (hence the info->adaptor if). */
6301    if (info->adaptor)
6302	RADEONResetVideo(pScrn);
6303
6304    if (info->accelOn && (info->ChipFamily < CHIP_FAMILY_R600))
6305	RADEONEngineRestore(pScrn);
6306
6307    if (info->accelOn && info->accel_state)
6308	info->accel_state->XInited3D = FALSE;
6309
6310#ifdef XF86DRI
6311    if (info->directRenderingEnabled) {
6312        if (info->ChipFamily >= CHIP_FAMILY_R600)
6313		R600LoadShaders(pScrn);
6314	RADEONCP_START(pScrn, info);
6315	DRIUnlock(pScrn->pScreen);
6316    }
6317#endif
6318    if (IS_R500_3D || IS_R300_3D)
6319	radeon_load_bicubic_texture(pScrn);
6320
6321    return TRUE;
6322}
6323
6324/* Called when VT switching away from the X server.  Restore the
6325 * original text mode.
6326 */
6327void RADEONLeaveVT(VT_FUNC_ARGS_DECL)
6328{
6329    SCRN_INFO_PTR(arg);
6330    RADEONInfoPtr  info  = RADEONPTR(pScrn);
6331    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
6332    int i;
6333
6334    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6335		   "RADEONLeaveVT\n");
6336#ifdef XF86DRI
6337    if (RADEONPTR(pScrn)->directRenderingInited) {
6338
6339	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
6340	DRILock(pScrn->pScreen, 0);
6341	RADEONCP_STOP(pScrn, info);
6342
6343        if (info->cardType == CARD_PCIE &&
6344	    info->dri->pKernelDRMVersion->version_minor >= 19 &&
6345	    info->FbSecureSize) {
6346#if X_BYTE_ORDER == X_BIG_ENDIAN
6347	    unsigned char *RADEONMMIO = info->MMIO;
6348	    unsigned int sctrl = INREG(RADEON_SURFACE_CNTL);
6349
6350            /* we need to backup the PCIE GART TABLE from fb memory */
6351	    OUTREG(RADEON_SURFACE_CNTL, 0);
6352#endif
6353            memcpy(info->dri->pciGartBackup, (info->FB + info->dri->pciGartOffset), info->dri->pciGartSize);
6354#if X_BYTE_ORDER == X_BIG_ENDIAN
6355	    OUTREG(RADEON_SURFACE_CNTL, sctrl);
6356#endif
6357        }
6358
6359	/* Make sure 3D clients will re-upload textures to video RAM */
6360	if (info->dri->textureSize) {
6361	    drm_radeon_sarea_t *pSAREAPriv =
6362		(drm_radeon_sarea_t*)DRIGetSAREAPrivate(pScrn->pScreen);
6363	    struct drm_tex_region *list = pSAREAPriv->tex_list[0];
6364	    int age = ++pSAREAPriv->tex_age[0];
6365
6366	    i = 0;
6367
6368	    do {
6369		list[i].age = age;
6370		i = list[i].next;
6371	    } while (i != 0);
6372	}
6373    }
6374#endif
6375
6376
6377    for (i = 0; i < config->num_crtc; i++) {
6378	xf86CrtcPtr crtc = config->crtc[i];
6379	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
6380
6381	radeon_crtc->initialized = FALSE;
6382
6383#ifndef HAVE_FREE_SHADOW
6384	if (crtc->rotatedPixmap || crtc->rotatedData) {
6385	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
6386					crtc->rotatedData);
6387	    crtc->rotatedPixmap = NULL;
6388	    crtc->rotatedData = NULL;
6389	}
6390#endif
6391    }
6392
6393#ifdef HAVE_FREE_SHADOW
6394    xf86RotateFreeShadow(pScrn);
6395#endif
6396
6397    xf86_hide_cursors (pScrn);
6398
6399    RADEONPMLeaveVT(pScrn);
6400
6401    RADEONRestore(pScrn);
6402
6403    for (i = 0; i < config->num_crtc; i++)
6404	radeon_crtc_modeset_ioctl(config->crtc[i], FALSE);
6405
6406    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6407		   "Ok, leaving now...\n");
6408}
6409
6410/* Called at the end of each server generation.  Restore the original
6411 * text mode, unmap video memory, and unwrap and call the saved
6412 * CloseScreen function.
6413 */
6414static Bool RADEONCloseScreen(CLOSE_SCREEN_ARGS_DECL)
6415{
6416    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
6417    RADEONInfoPtr  info  = RADEONPTR(pScrn);
6418    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
6419    int i;
6420
6421    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6422		   "RADEONCloseScreen\n");
6423
6424    RADEONPMFini(pScrn);
6425
6426    /* Mark acceleration as stopped or we might try to access the engine at
6427     * wrong times, especially if we had DRI, after DRI has been stopped
6428     */
6429    info->accelOn = FALSE;
6430
6431    for (i = 0; i < config->num_crtc; i++) {
6432	xf86CrtcPtr crtc = config->crtc[i];
6433	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
6434
6435	radeon_crtc->initialized = FALSE;
6436    }
6437
6438#ifdef XF86DRI
6439#ifdef DAMAGE
6440    if (info->dri && info->dri->pDamage) {
6441	PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
6442
6443	DamageUnregister(&pPix->drawable, info->dri->pDamage);
6444	DamageDestroy(info->dri->pDamage);
6445	info->dri->pDamage = NULL;
6446    }
6447#endif
6448
6449    RADEONDRIStop(pScreen);
6450#endif
6451
6452#ifdef USE_XAA
6453    if(!info->useEXA && info->accel_state->RenderTex) {
6454        xf86FreeOffscreenLinear(info->accel_state->RenderTex);
6455        info->accel_state->RenderTex = NULL;
6456    }
6457#endif /* USE_XAA */
6458
6459    if (pScrn->vtSema) {
6460	RADEONRestore(pScrn);
6461    }
6462
6463    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6464		   "Disposing accel...\n");
6465#ifdef USE_EXA
6466    if (info->accel_state->exa) {
6467	exaDriverFini(pScreen);
6468	free(info->accel_state->exa);
6469	info->accel_state->exa = NULL;
6470    }
6471#endif /* USE_EXA */
6472#ifdef USE_XAA
6473    if (!info->useEXA) {
6474	if (info->accel_state->accel)
6475		XAADestroyInfoRec(info->accel_state->accel);
6476	info->accel_state->accel = NULL;
6477
6478	if (info->accel_state->scratch_save)
6479	    free(info->accel_state->scratch_save);
6480	info->accel_state->scratch_save = NULL;
6481    }
6482#endif /* USE_XAA */
6483
6484    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6485		   "Disposing cursor info\n");
6486    if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
6487    info->cursor = NULL;
6488
6489    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6490		   "Unmapping memory\n");
6491    RADEONUnmapMem(pScrn);
6492
6493    pScrn->vtSema = FALSE;
6494
6495    xf86ClearPrimInitDone(info->pEnt->index);
6496
6497    pScreen->BlockHandler = info->BlockHandler;
6498    pScreen->CloseScreen = info->CloseScreen;
6499    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
6500}
6501
6502void RADEONFreeScreen(FREE_SCREEN_ARGS_DECL)
6503{
6504    SCRN_INFO_PTR(arg);
6505    RADEONInfoPtr  info  = RADEONPTR(pScrn);
6506
6507    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
6508		   "RADEONFreeScreen\n");
6509
6510    /* when server quits at PreInit, we don't need do this anymore*/
6511    if (!info) return;
6512
6513#ifdef WITH_VGAHW
6514    if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
6515	vgaHWFreeHWRec(pScrn);
6516#endif
6517    RADEONFreeRec(pScrn);
6518}
6519