Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
      3  *                      Precision Insight, Inc., Cedar Park, Texas, and
      4  *                      VA Linux Systems Inc., Fremont, California.
      5  *
      6  * All Rights Reserved.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining
      9  * a copy of this software and associated documentation files (the
     10  * "Software"), to deal in the Software without restriction, including
     11  * without limitation on the rights to use, copy, modify, merge,
     12  * publish, distribute, sublicense, and/or sell copies of the Software,
     13  * and to permit persons to whom the Software is furnished to do so,
     14  * subject to the following conditions:
     15  *
     16  * The above copyright notice and this permission notice (including the
     17  * next paragraph) shall be included in all copies or substantial
     18  * portions of the Software.
     19  *
     20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     23  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX
     24  * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     27  * OTHER DEALINGS IN THE SOFTWARE.
     28  */
     29 
     30 #ifdef HAVE_CONFIG_H
     31 #include "config.h"
     32 #endif
     33 
     34 /*
     35  * Authors:
     36  *   Rickard E. Faith <faith (at) valinux.com>
     37  *   Kevin E. Martin <martin (at) valinux.com>
     38  *   Gareth Hughes <gareth (at) valinux.com>
     39  *
     40  * Credits:
     41  *
     42  *   Thanks to Alan Hourihane <alanh (at) fairlite.demon..co.uk> and SuSE for
     43  *   providing source code to their 3.3.x Rage 128 driver.  Portions of
     44  *   this file are based on the initialization code for that driver.
     45  *
     46  * References:
     47  *
     48  *   RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical
     49  *   Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April
     50  *   1999.
     51  *
     52  *   RAGE 128 Software Development Manual (Technical Reference Manual P/N
     53  *   SDK-G04000 Rev. 0.01), ATI Technologies: June 1999.
     54  *
     55  * This server does not yet support these XFree86 4.0 features:
     56  *   DDC1 & DDC2
     57  *   shadowfb
     58  *   overlay planes
     59  *
     60  * Modified by Marc Aurele La France <tsi (at) xfree86.org> for ATI driver merge.
     61  *
     62  * Dualhead support - Alex Deucher <agd5f (at) yahoo.com>
     63  */
     64 
     65 #include <string.h>
     66 #include <stdio.h>
     67 
     68 				/* Driver data structures */
     69 #include "r128.h"
     70 #include "r128_probe.h"
     71 #include "r128_reg.h"
     72 #include "r128_version.h"
     73 #include "xf86Priv.h"
     74 
     75 #ifdef HAVE_DEV_WSCONS_WSCONSIO_H
     76 #include <sys/time.h>
     77 #include <sys/ioctl.h>
     78 #include <dev/wscons/wsconsio.h>
     79 #endif
     80 
     81 #ifdef R128DRI
     82 #define _XF86DRI_SERVER_
     83 #include "r128_dri.h"
     84 #include "r128_common.h"
     85 #include "r128_sarea.h"
     86 #endif
     87 
     88 				/* colormap initialization */
     89 #include "micmap.h"
     90 
     91 				/* X and server generic header files */
     92 #include "xf86.h"
     93 #include "xf86_OSproc.h"
     94 #include "xf86RandR12.h"
     95 #include "xf86cmap.h"
     96 #include "xf86xv.h"
     97 #include "vbe.h"
     98 #include "xf86Priv.h"
     99 #include "xf86Privstr.h"
    100 
    101 				/* fbdevhw & vgahw */
    102 #ifdef WITH_VGAHW
    103 #include "vgaHW.h"
    104 #endif
    105 
    106 #ifndef AVOID_FBDEV
    107 #include "fbdevhw.h"
    108 #endif
    109 
    110 #include "dixstruct.h"
    111 
    112 				/* DPMS support. */
    113 #ifdef HAVE_XEXTPROTO_71
    114 #include <X11/extensions/dpmsconst.h>
    115 #else
    116 #define DPMS_SERVER
    117 #include <X11/extensions/dpms.h>
    118 #endif
    119 
    120 static Bool R128CloseScreen(ScreenPtr pScreen);
    121 static Bool R128SaveScreen(ScreenPtr pScreen, int mode);
    122 static void R128Save(ScrnInfoPtr pScrn);
    123 static void R128Restore(ScrnInfoPtr pScrn);
    124 
    125 typedef enum {
    126   OPTION_NOACCEL,
    127 #ifndef AVOID_FBDEV
    128   OPTION_FBDEV,
    129 #endif
    130   OPTION_DAC_6BIT,
    131   OPTION_VGA_ACCESS,
    132   OPTION_SHOW_CACHE,
    133   OPTION_SW_CURSOR,
    134   OPTION_VIDEO_KEY,
    135   OPTION_PANEL_WIDTH,
    136   OPTION_PANEL_HEIGHT,
    137   OPTION_PROG_FP_REGS,
    138 #ifdef R128DRI
    139   OPTION_XV_DMA,
    140   OPTION_IS_PCI,
    141   OPTION_CCE_PIO,
    142   OPTION_NO_SECURITY,
    143   OPTION_USEC_TIMEOUT,
    144   OPTION_AGP_MODE,
    145   OPTION_AGP_SIZE,
    146   OPTION_RING_SIZE,
    147   OPTION_BUFFER_SIZE,
    148   OPTION_PAGE_FLIP,
    149 #endif
    150   OPTION_ACCELMETHOD,
    151   OPTION_RENDERACCEL
    152 } R128Opts;
    153 
    154 static const OptionInfoRec R128Options[] = {
    155 { OPTION_NOACCEL,      "NoAccel",          OPTV_BOOLEAN, {0}, FALSE },
    156 #ifndef AVOID_FBDEV
    157 { OPTION_FBDEV,        "UseFBDev",         OPTV_BOOLEAN, {0}, FALSE },
    158 #endif
    159 { OPTION_DAC_6BIT,     "Dac6Bit",          OPTV_BOOLEAN, {0}, FALSE },
    160 { OPTION_VGA_ACCESS,   "VGAAccess",        OPTV_BOOLEAN, {0}, TRUE  },
    161 { OPTION_SHOW_CACHE,   "ShowCache",        OPTV_BOOLEAN, {0}, FALSE },
    162 { OPTION_SW_CURSOR,    "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
    163 { OPTION_VIDEO_KEY,    "VideoKey",         OPTV_INTEGER, {0}, FALSE },
    164 { OPTION_PANEL_WIDTH,  "PanelWidth",       OPTV_INTEGER, {0}, FALSE },
    165 { OPTION_PANEL_HEIGHT, "PanelHeight",      OPTV_INTEGER, {0}, FALSE },
    166 { OPTION_PROG_FP_REGS, "ProgramFPRegs",    OPTV_BOOLEAN, {0}, FALSE },
    167 #ifdef R128DRI
    168   { OPTION_XV_DMA,       "DMAForXv",         OPTV_BOOLEAN, {0}, FALSE },
    169   { OPTION_IS_PCI,       "ForcePCIMode",     OPTV_BOOLEAN, {0}, FALSE },
    170   { OPTION_CCE_PIO,      "CCEPIOMode",       OPTV_BOOLEAN, {0}, FALSE },
    171   { OPTION_NO_SECURITY,  "CCENoSecurity",    OPTV_BOOLEAN, {0}, FALSE },
    172   { OPTION_USEC_TIMEOUT, "CCEusecTimeout",   OPTV_INTEGER, {0}, FALSE },
    173   { OPTION_AGP_MODE,     "AGPMode",          OPTV_INTEGER, {0}, FALSE },
    174   { OPTION_AGP_SIZE,     "AGPSize",          OPTV_INTEGER, {0}, FALSE },
    175   { OPTION_RING_SIZE,    "RingSize",         OPTV_INTEGER, {0}, FALSE },
    176   { OPTION_BUFFER_SIZE,  "BufferSize",       OPTV_INTEGER, {0}, FALSE },
    177   { OPTION_PAGE_FLIP,    "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
    178 #endif
    179   { OPTION_ACCELMETHOD,  "AccelMethod",      OPTV_STRING,  {0}, FALSE },
    180   { OPTION_RENDERACCEL,  "RenderAccel",      OPTV_BOOLEAN, {0}, FALSE },
    181   { -1,                  NULL,               OPTV_NONE,    {0}, FALSE }
    182 };
    183 
    184 const OptionInfoRec *R128OptionsWeak(void) { return R128Options; }
    185 
    186 R128RAMRec R128RAM[] = {        /* Memory Specifications
    187 				   From RAGE 128 Software Development
    188 				   Manual (Technical Reference Manual P/N
    189 				   SDK-G04000 Rev 0.01), page 3-21.  */
    190     { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" },
    191     { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" },
    192     { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" },
    193     { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" },
    194 };
    195 
    196 extern _X_EXPORT int gR128EntityIndex;
    197 
    198 int getR128EntityIndex(void)
    199 {
    200     return gR128EntityIndex;
    201 }
    202 
    203 R128EntPtr R128EntPriv(ScrnInfoPtr pScrn)
    204 {
    205     DevUnion     *pPriv;
    206     R128InfoPtr  info   = R128PTR(pScrn);
    207     pPriv = xf86GetEntityPrivate(info->pEnt->index,
    208                                  getR128EntityIndex());
    209     return pPriv->ptr;
    210 }
    211 
    212 /* Allocate our private R128InfoRec. */
    213 static Bool R128GetRec(ScrnInfoPtr pScrn)
    214 {
    215     if (pScrn->driverPrivate) return TRUE;
    216 
    217     pScrn->driverPrivate = XNFcallocarray(1, sizeof(R128InfoRec));
    218     return TRUE;
    219 }
    220 
    221 /* Free our private R128InfoRec. */
    222 static void R128FreeRec(ScrnInfoPtr pScrn)
    223 {
    224     if (!pScrn || !pScrn->driverPrivate) return;
    225     free(pScrn->driverPrivate);
    226     pScrn->driverPrivate = NULL;
    227 }
    228 
    229 /* Memory map the MMIO region.  Used during pre-init and by R128MapMem,
    230    below. */
    231 static Bool R128MapMMIO(ScrnInfoPtr pScrn)
    232 {
    233     R128InfoPtr info          = R128PTR(pScrn);
    234 
    235 #ifndef AVOID_FBDEV
    236     if (info->FBDev) {
    237 	info->MMIO = fbdevHWMapMMIO(pScrn);
    238     } else
    239 #endif
    240     {
    241 #ifndef XSERVER_LIBPCIACCESS
    242 	info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
    243 				   VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
    244 				   info->PciTag,
    245 				   info->MMIOAddr,
    246 				   R128_MMIOSIZE);
    247         if (!info->MMIO) return FALSE;
    248 #else
    249 	int err = pci_device_map_range(info->PciInfo,
    250 				       info->MMIOAddr,
    251 				       R128_MMIOSIZE,
    252 				       PCI_DEV_MAP_FLAG_WRITABLE,
    253 				       &info->MMIO);
    254 
    255 	if (err) {
    256 	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
    257                         "Unable to map MMIO aperture. %s (%d)\n",
    258                         strerror (err), err);
    259 	    return FALSE;
    260 	}
    261 #endif
    262     }
    263 
    264     return TRUE;
    265 }
    266 
    267 /* Unmap the MMIO region.  Used during pre-init and by R128UnmapMem,
    268    below. */
    269 static Bool R128UnmapMMIO(ScrnInfoPtr pScrn)
    270 {
    271     R128InfoPtr info          = R128PTR(pScrn);
    272 
    273 #ifndef AVOID_FBDEV
    274     if (info->FBDev)
    275 	fbdevHWUnmapMMIO(pScrn);
    276     else
    277 #endif
    278     {
    279 #ifndef XSERVER_LIBPCIACCESS
    280 	xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE);
    281 #else
    282 	pci_device_unmap_range(info->PciInfo, info->MMIO, R128_MMIOSIZE);
    283 #endif
    284     }
    285     info->MMIO = NULL;
    286     return TRUE;
    287 }
    288 
    289 /* Memory map the frame buffer.  Used by R128MapMem, below. */
    290 static Bool R128MapFB(ScrnInfoPtr pScrn)
    291 {
    292     R128InfoPtr info          = R128PTR(pScrn);
    293 
    294 #ifndef AVOID_FBDEV
    295     if (info->FBDev) {
    296 	info->FB = fbdevHWMapVidmem(pScrn);
    297     } else
    298 #endif
    299     {
    300 #ifndef XSERVER_LIBPCIACCESS
    301 	info->FB = xf86MapPciMem(pScrn->scrnIndex,
    302 				 VIDMEM_FRAMEBUFFER,
    303 				 info->PciTag,
    304 				 info->LinearAddr,
    305 				 info->FbMapSize);
    306 #else
    307 	int err = pci_device_map_range(info->PciInfo,
    308 				       info->LinearAddr,
    309 				       info->FbMapSize,
    310 				       PCI_DEV_MAP_FLAG_WRITABLE |
    311 				       PCI_DEV_MAP_FLAG_WRITE_COMBINE,
    312 				       &info->FB);
    313 
    314 	if (err) {
    315 	    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
    316                         "Unable to map FB aperture. %s (%d)\n",
    317                         strerror (err), err);
    318 	    return FALSE;
    319 	}
    320 #endif
    321     }
    322 
    323     if (!info->FB) return FALSE;
    324     return TRUE;
    325 }
    326 
    327 /* Unmap the frame buffer.  Used by R128UnmapMem, below. */
    328 static Bool R128UnmapFB(ScrnInfoPtr pScrn)
    329 {
    330     R128InfoPtr info          = R128PTR(pScrn);
    331 
    332 #ifndef AVOID_FBDEV
    333     if (info->FBDev)
    334 	fbdevHWUnmapVidmem(pScrn);
    335     else
    336 #endif
    337 #ifndef XSERVER_LIBPCIACCESS
    338 	xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
    339 #else
    340 	pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize);
    341 #endif
    342     info->FB = NULL;
    343     return TRUE;
    344 }
    345 
    346 /* Memory map the MMIO region and the frame buffer. */
    347 static Bool R128MapMem(ScrnInfoPtr pScrn)
    348 {
    349     if (!R128MapMMIO(pScrn)) return FALSE;
    350     if (!R128MapFB(pScrn)) {
    351 	R128UnmapMMIO(pScrn);
    352 	return FALSE;
    353     }
    354     return TRUE;
    355 }
    356 
    357 /* Unmap the MMIO region and the frame buffer. */
    358 static Bool R128UnmapMem(ScrnInfoPtr pScrn)
    359 {
    360     if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE;
    361     return TRUE;
    362 }
    363 
    364 /* Read PLL information */
    365 unsigned R128INPLL(ScrnInfoPtr pScrn, int addr)
    366 {
    367     R128InfoPtr   info      = R128PTR(pScrn);
    368     unsigned char *R128MMIO = info->MMIO;
    369 
    370     OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x3f);
    371     return INREG(R128_CLOCK_CNTL_DATA);
    372 }
    373 
    374 #if 0
    375 /* Read PAL information (only used for debugging). */
    376 static int R128INPAL(int idx)
    377 {
    378     R128InfoPtr   info      = R128PTR(pScrn);
    379     unsigned char *R128MMIO = info->MMIO;
    380 
    381     OUTREG(R128_PALETTE_INDEX, idx << 16);
    382     return INREG(R128_PALETTE_DATA);
    383 }
    384 #endif
    385 
    386 /* Wait for vertical sync. */
    387 void R128WaitForVerticalSync(ScrnInfoPtr pScrn)
    388 {
    389     R128InfoPtr   info      = R128PTR(pScrn);
    390     unsigned char *R128MMIO = info->MMIO;
    391     int           i;
    392 
    393     OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK);
    394     for (i = 0; i < R128_TIMEOUT; i++) {
    395 	if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break;
    396     }
    397 }
    398 
    399 /* Compute log base 2 of val. */
    400 int R128MinBits(int val)
    401 {
    402     int bits;
    403 
    404     if (!val) return 1;
    405     for (bits = 0; val; val >>= 1, ++bits);
    406     return bits;
    407 }
    408 
    409 /* Finds the first output using a given crtc. */
    410 xf86OutputPtr R128FirstOutput(xf86CrtcPtr crtc)
    411 {
    412     ScrnInfoPtr pScrn = crtc->scrn;
    413     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    414     xf86OutputPtr output = xf86_config->output[0];
    415     int o;
    416 
    417     for (o = 0; o < xf86_config->num_output; o++) {
    418         output = xf86_config->output[o];
    419         if (output->crtc == crtc) break;
    420     }
    421 
    422     return output;
    423 }
    424 
    425 /* Read the Video BIOS block. */
    426 static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
    427 {
    428     R128InfoPtr info = R128PTR(pScrn);
    429 
    430 #ifdef XSERVER_LIBPCIACCESS
    431     int size = info->PciInfo->rom_size > R128_VBIOS_SIZE ? info->PciInfo->rom_size : R128_VBIOS_SIZE;
    432     info->VBIOS = malloc(size);
    433 #else
    434     info->VBIOS = malloc(R128_VBIOS_SIZE);
    435 #endif
    436 
    437     if (!info->VBIOS) {
    438 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    439 		   "Cannot allocate space for hold Video BIOS!\n");
    440 	return FALSE;
    441     }
    442 
    443     if (pInt10) {
    444 	info->BIOSAddr = pInt10->BIOSseg << 4;
    445 	(void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr),
    446 		     R128_VBIOS_SIZE);
    447     } else {
    448 #ifdef XSERVER_LIBPCIACCESS
    449 	if (pci_device_read_rom(info->PciInfo, info->VBIOS)) {
    450 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    451 		       "Failed to read PCI ROM!\n");
    452 	}
    453 #else
    454 	xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE);
    455 	if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
    456 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    457 		       "Video BIOS not detected in PCI space!\n");
    458 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    459 		       "Attempting to read Video BIOS from legacy ISA space!\n");
    460 	    info->BIOSAddr = 0x000c0000;
    461 	    xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS);
    462 	}
    463 #endif
    464     }
    465     if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
    466 	info->BIOSAddr = 0x00000000;
    467 	free(info->VBIOS);
    468 	info->VBIOS = NULL;
    469 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    470 		   "Video BIOS not found!\n");
    471     }
    472 
    473     return TRUE;
    474 }
    475 
    476 /* Read the FP parameters if an LVDS panel is expected. */
    477 void R128GetPanelInfoFromBIOS(xf86OutputPtr output)
    478 {
    479     ScrnInfoPtr pScrn = output->scrn;
    480     R128InfoPtr info  = R128PTR(pScrn);
    481     R128OutputPrivatePtr r128_output = output->driver_private;
    482     int FPHeader = 0;
    483     int i;
    484 
    485     r128_output->PanelPwrDly = 200;
    486     xf86GetOptValInteger(info->Options, OPTION_PANEL_WIDTH,  &(r128_output->PanelXRes));
    487     xf86GetOptValInteger(info->Options, OPTION_PANEL_HEIGHT, &(r128_output->PanelYRes));
    488 
    489     if (!info->VBIOS) goto fallback;
    490     info->FPBIOSstart = 0;
    491 
    492     /* FIXME: There should be direct access to the start of the FP info
    493      * tables, but until we find out where that offset is stored, we
    494      * must search for the ATI signature string: "M3      ".
    495      */
    496     for (i = 4; i < R128_VBIOS_SIZE - 8; i++) {
    497         if (R128_BIOS8(i)     == 'M' &&
    498             R128_BIOS8(i + 1) == '3' &&
    499             R128_BIOS8(i + 2) == ' ' &&
    500             R128_BIOS8(i + 3) == ' ' &&
    501             R128_BIOS8(i + 4) == ' ' &&
    502             R128_BIOS8(i + 5) == ' ' &&
    503             R128_BIOS8(i + 6) == ' ' &&
    504             R128_BIOS8(i + 7) == ' ') {
    505             FPHeader = i - 2;
    506             break;
    507         }
    508     }
    509 
    510     if (!FPHeader) goto fallback;
    511 
    512     /* Assume that only one panel is attached and supported */
    513     for (i = FPHeader + 20; i < FPHeader + 84; i += 2) {
    514         if (R128_BIOS16(i) != 0) {
    515             info->FPBIOSstart = R128_BIOS16(i);
    516             break;
    517         }
    518     }
    519 
    520 #ifndef AVOID_FBDEV
    521     if (!info->FPBIOSstart) return;
    522 #endif
    523 
    524     if (!r128_output->PanelXRes)
    525         r128_output->PanelXRes = R128_BIOS16(info->FPBIOSstart + 25);
    526     if (!r128_output->PanelYRes)
    527         r128_output->PanelYRes = R128_BIOS16(info->FPBIOSstart + 27);
    528     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",
    529                r128_output->PanelXRes, r128_output->PanelYRes);
    530 
    531     r128_output->PanelPwrDly = R128_BIOS8(info->FPBIOSstart + 56);
    532 
    533     if (!r128_output->PanelXRes || !r128_output->PanelYRes) {
    534         info->HasPanelRegs = FALSE;
    535         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    536 		   "Can't determine panel dimensions, and none specified.\n"
    537 		   "\tDisabling programming of FP registers.\n");
    538     }
    539 
    540     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");
    541     for (i = 1; i <= 24; i++)
    542         ErrorF("%c", R128_BIOS8(info->FPBIOSstart + i));
    543 
    544     ErrorF("\n");
    545 
    546     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");
    547     i = R128_BIOS16(info->FPBIOSstart + 29);
    548     if (i & 1) ErrorF("Color, ");
    549     else       ErrorF("Monochrome, ");
    550     if (i & 2) ErrorF("Dual(split), ");
    551     else       ErrorF("Single, ");
    552 
    553     switch ((i >> 2) & 0x3f) {
    554     case 0:  ErrorF("STN");        break;
    555     case 1:  ErrorF("TFT");        break;
    556     case 2:  ErrorF("Active STN"); break;
    557     case 3:  ErrorF("EL");         break;
    558     case 4:  ErrorF("Plasma");     break;
    559     default: ErrorF("UNKNOWN");    break;
    560     }
    561 
    562     ErrorF("\n");
    563 
    564     if (R128_BIOS8(info->FPBIOSstart + 61) & 1) {
    565         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");
    566     } else {
    567         /* FIXME: Add Non-LVDS flat panel support */
    568         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    569                    "Non-LVDS panel interface detected!  "
    570                    "This support is untested and may not "
    571                    "function properly\n");
    572     }
    573     return;
    574 
    575 fallback:
    576 #ifdef WSDISPLAYIO_GINFO
    577     if ((!r128_output->PanelXRes || !r128_output->PanelYRes) &&
    578         (info->HaveWSDisplay)) {
    579 	/*
    580 	 * we may not be on x86 so check wsdisplay for panel dimensions
    581 	 * this assumes that the r128 is the console, although that should
    582 	 * be the case in the vast majority of cases where an LCD is hooked up
    583 	 * directly
    584 	 * We should probably just check the relevant registers but I'm not
    585 	 * sure they're available at this point.
    586 	 */
    587 	struct wsdisplay_fbinfo fbinfo;
    588 
    589 	if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GINFO, &fbinfo) == 0) {
    590 	    r128_output->PanelXRes = fbinfo.width;
    591 	    r128_output->PanelYRes = fbinfo.height;
    592 	}
    593     }
    594 #endif
    595     return;
    596 }
    597 
    598 /* Read PLL parameters from BIOS block.  Default to typical values if there
    599    is no BIOS. */
    600 static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
    601 {
    602     R128InfoPtr   info = R128PTR(pScrn);
    603     R128PLLPtr    pll  = &info->pll;
    604 
    605 #if defined(__powerpc__) || defined(__alpha__)
    606     /* there is no bios under Linux PowerPC but Open Firmware
    607        does set up the PLL registers properly and we can use
    608        those to calculate xclk and find the reference divider */
    609 
    610     unsigned x_mpll_ref_fb_div;
    611     unsigned xclk_cntl;
    612     unsigned Nx, M;
    613     unsigned PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12};
    614 
    615     /* Assume REF clock is 2950 (in units of 10khz) */
    616     /* and that all pllclk must be between 125 Mhz and 250Mhz */
    617     pll->reference_freq = 2950;
    618     pll->min_pll_freq   = 12500;
    619     pll->max_pll_freq   = 25000;
    620 
    621     x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV);
    622     xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7;
    623     pll->reference_div =
    624 	INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK;
    625 
    626     Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8;
    627     M =  (x_mpll_ref_fb_div & 0x0000FF);
    628 
    629     pll->xclk =  R128Div((2 * Nx * pll->reference_freq),
    630 			 (M * PostDivSet[xclk_cntl]));
    631 
    632 #else /* !defined(__powerpc__) */
    633 
    634     if (!info->VBIOS) {
    635 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    636 		   "Video BIOS not detected, using default PLL parameters!\n");
    637 				/* These probably aren't going to work for
    638 				   the card you are using.  Specifically,
    639 				   reference freq can be 29.50MHz,
    640 				   28.63MHz, or 14.32MHz.  YMMV. */
    641 	pll->reference_freq = 2950;
    642 	pll->reference_div  = 65;
    643 	pll->min_pll_freq   = 12500;
    644 	pll->max_pll_freq   = 25000;
    645 	pll->xclk           = 10300;
    646     } else {
    647 	uint16_t bios_header    = R128_BIOS16(0x48);
    648 	uint16_t pll_info_block = R128_BIOS16(bios_header + 0x30);
    649     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    650                         "Header at 0x%04x; PLL Information at 0x%04x\n",
    651                         bios_header, pll_info_block));
    652 
    653 	pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e);
    654 	pll->reference_div  = R128_BIOS16(pll_info_block + 0x10);
    655 	pll->min_pll_freq   = R128_BIOS32(pll_info_block + 0x12);
    656 	pll->max_pll_freq   = R128_BIOS32(pll_info_block + 0x16);
    657 	pll->xclk           = R128_BIOS16(pll_info_block + 0x08);
    658     }
    659 #endif /* __powerpc__ */
    660 
    661     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    662 	       "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n",
    663 	       pll->reference_freq,
    664 	       pll->reference_div,
    665 	       pll->min_pll_freq,
    666 	       pll->max_pll_freq,
    667 	       pll->xclk);
    668 
    669     return TRUE;
    670 }
    671 
    672 /* This is called by R128PreInit to set up the default visual. */
    673 static Bool R128PreInitVisual(ScrnInfoPtr pScrn)
    674 {
    675     if (!xf86SetDepthBpp(pScrn, 0, 0, 0, (Support24bppFb
    676 					  | Support32bppFb
    677 					  | SupportConvert32to24
    678 					  )))
    679 	return FALSE;
    680 
    681     switch (pScrn->depth) {
    682     case 8:
    683     case 15:
    684     case 16:
    685     case 24:
    686 	break;
    687     default:
    688 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    689 		   "Given depth (%d) is not supported by %s driver\n",
    690 		   pScrn->depth, R128_DRIVER_NAME);
    691 	return FALSE;
    692     }
    693 
    694     xf86PrintDepthBpp(pScrn);
    695 
    696     if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE;
    697 
    698     if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
    699 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    700 		   "Default visual (%s) is not supported at depth %d\n",
    701 		   xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
    702 	return FALSE;
    703     }
    704     return TRUE;
    705 
    706 }
    707 
    708 /* This is called by R128PreInit to handle all color weight issues. */
    709 static Bool R128PreInitWeight(ScrnInfoPtr pScrn)
    710 {
    711     R128InfoPtr info          = R128PTR(pScrn);
    712     rgb defaultWeight = { 0, 0, 0 };
    713 
    714     /*
    715      * Save flag for 6 bit DAC to use for setting CRTC registers.
    716      * Otherwise use an 8 bit DAC, even if xf86SetWeight sets
    717      * pScrn->rgbBits to some value other than 8.
    718      */
    719     if (pScrn->depth <= 8) {
    720         if (info->dac6bits) {
    721             pScrn->rgbBits = 6;
    722         } else {
    723             pScrn->rgbBits = 8;
    724         }
    725     } else {
    726         info->dac6bits = FALSE;
    727         pScrn->rgbBits = 8;
    728     }
    729 
    730     if (pScrn->depth > 8) {
    731         if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE;
    732     }
    733 
    734     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    735                "Using %d bits per RGB (%d bit DAC)\n",
    736                pScrn->rgbBits, info->dac6bits ? 6 : 8);
    737 
    738     return TRUE;
    739 }
    740 
    741 /* This is called by R128PreInit to handle config file overrides for things
    742    like chipset and memory regions.  Also determine memory size and type.
    743    If memory type ever needs an override, put it in this routine. */
    744 static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
    745 {
    746     R128InfoPtr   info      = R128PTR(pScrn);
    747     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
    748     unsigned char *R128MMIO = info->MMIO;
    749     EntityInfoPtr pEnt      = info->pEnt;
    750     GDevPtr       dev       = pEnt->device;
    751     int           offset    = 0;        /* RAM Type */
    752     MessageType   from;
    753 
    754 				/* Chipset */
    755     from = X_PROBED;
    756     if (dev->chipset && *dev->chipset) {
    757 	info->Chipset  = xf86StringToToken(R128Chipsets, dev->chipset);
    758 	from           = X_CONFIG;
    759     } else if (dev->chipID >= 0) {
    760 	info->Chipset  = dev->chipID;
    761 	from           = X_CONFIG;
    762     } else {
    763 	info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
    764     }
    765     pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset);
    766 
    767     if (!pScrn->chipset) {
    768 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    769 		   "ChipID 0x%04x is not recognized\n", info->Chipset);
    770 	return FALSE;
    771     }
    772 
    773     if (info->Chipset < 0) {
    774 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    775 		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
    776 	return FALSE;
    777     }
    778 
    779     xf86DrvMsg(pScrn->scrnIndex, from,
    780 	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
    781 	       pScrn->chipset,
    782 	       info->Chipset);
    783 
    784 				/* Framebuffer */
    785 
    786     from             = X_PROBED;
    787     info->LinearAddr = PCI_REGION_BASE(info->PciInfo, 0, REGION_MEM) & 0xfc000000;
    788     pScrn->memPhysBase = info->LinearAddr;
    789     if (dev->MemBase) {
    790 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    791 		   "Linear address override, using 0x%08lx instead of 0x%08lx\n",
    792 		   dev->MemBase,
    793 		   info->LinearAddr);
    794 	info->LinearAddr = dev->MemBase;
    795 	from             = X_CONFIG;
    796     } else if (!info->LinearAddr) {
    797 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    798 		   "No valid linear framebuffer address\n");
    799 	return FALSE;
    800     }
    801     xf86DrvMsg(pScrn->scrnIndex, from,
    802 	       "Linear framebuffer at 0x%08lx\n", info->LinearAddr);
    803 
    804 				/* MMIO registers */
    805     from             = X_PROBED;
    806     info->MMIOAddr   = PCI_REGION_BASE(info->PciInfo, 2, REGION_MEM) & 0xffffff00;
    807     if (dev->IOBase) {
    808 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    809 		   "MMIO address override, using 0x%08lx instead of 0x%08lx\n",
    810 		   dev->IOBase,
    811 		   info->MMIOAddr);
    812 	info->MMIOAddr = dev->IOBase;
    813 	from           = X_CONFIG;
    814     } else if (!info->MMIOAddr) {
    815 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n");
    816 	return FALSE;
    817     }
    818     xf86DrvMsg(pScrn->scrnIndex, from,
    819 	       "MMIO registers at 0x%08lx\n", info->MMIOAddr);
    820 
    821 #ifndef XSERVER_LIBPCIACCESS
    822 				/* BIOS */
    823     from              = X_PROBED;
    824     info->BIOSAddr    = info->PciInfo->biosBase & 0xfffe0000;
    825     if (info->BIOSAddr) {
    826 	xf86DrvMsg(pScrn->scrnIndex, from,
    827 		   "BIOS at 0x%08lx\n", info->BIOSAddr);
    828     }
    829 #endif
    830 
    831 				/* Flat panel (part 1) */
    832     if (xf86GetOptValBool(info->Options, OPTION_PROG_FP_REGS,
    833 			  &info->HasPanelRegs)) {
    834 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
    835 		   "Turned flat panel register programming %s\n",
    836 		   info->HasPanelRegs ? "on" : "off");
    837 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    838 		   "\n\nWARNING: Forcing the driver to use/not use the flat panel registers\nmight damage your flat panel.  Use at your *OWN* *RISK*.\n\n");
    839     } else {
    840         info->isDFP = FALSE;
    841         info->isPro2 = FALSE;
    842         pR128Ent->HasCRTC2 = FALSE;
    843 	switch (info->Chipset) {
    844 	/* R128 Pro and Pro2 can have DFP, we will deal with it.
    845 	   No support for dual-head/xinerama yet.
    846            M3 can also have DFP, no support for now */
    847 	case PCI_CHIP_RAGE128TF:
    848 	case PCI_CHIP_RAGE128TL:
    849 	case PCI_CHIP_RAGE128TR:
    850 	/* FIXME: RAGE128 TS/TT/TU are assumed to be PRO2 as all 6 chips came
    851 	 *        out at the same time, so are of the same family likely.
    852 	 *        This requires confirmation however to be fully correct.
    853 	 *        Mike A. Harris <mharris (at) redhat.com>
    854 	 */
    855 	case PCI_CHIP_RAGE128TS:
    856 	case PCI_CHIP_RAGE128TT:
    857 	case PCI_CHIP_RAGE128TU: info->isPro2 = TRUE;
    858 	/* FIXME: RAGE128 P[ABCEGHIJKLMNOQSTUVWX] are assumed to have DFP
    859 	 *        capability, as the comment at the top suggests.
    860 	 *        This requires confirmation however to be fully correct.
    861 	 *        Mike A. Harris <mharris (at) redhat.com>
    862 	 */
    863 	case PCI_CHIP_RAGE128PA:
    864 	case PCI_CHIP_RAGE128PB:
    865 	case PCI_CHIP_RAGE128PC:
    866 	case PCI_CHIP_RAGE128PE:
    867 	case PCI_CHIP_RAGE128PG:
    868 	case PCI_CHIP_RAGE128PH:
    869 	case PCI_CHIP_RAGE128PI:
    870 	case PCI_CHIP_RAGE128PJ:
    871 	case PCI_CHIP_RAGE128PK:
    872 	case PCI_CHIP_RAGE128PL:
    873 	case PCI_CHIP_RAGE128PM:
    874 	case PCI_CHIP_RAGE128PN:
    875 	case PCI_CHIP_RAGE128PO:
    876 	case PCI_CHIP_RAGE128PQ:
    877 	case PCI_CHIP_RAGE128PS:
    878 	case PCI_CHIP_RAGE128PT:
    879 	case PCI_CHIP_RAGE128PU:
    880 	case PCI_CHIP_RAGE128PV:
    881 	case PCI_CHIP_RAGE128PW:
    882 	case PCI_CHIP_RAGE128PX:
    883 
    884 	case PCI_CHIP_RAGE128PD:
    885 	case PCI_CHIP_RAGE128PF:
    886 	case PCI_CHIP_RAGE128PP:
    887 	case PCI_CHIP_RAGE128PR: info->isDFP = TRUE; break;
    888 
    889 	case PCI_CHIP_RAGE128LE:
    890 	case PCI_CHIP_RAGE128LF:
    891 	case PCI_CHIP_RAGE128MF:
    892 	case PCI_CHIP_RAGE128ML:
    893 			info->HasPanelRegs = TRUE;
    894 			info->isDFP = TRUE;
    895 			/* which chips support dualhead? */
    896 			pR128Ent->HasCRTC2 = TRUE;
    897 			break;
    898 	case PCI_CHIP_RAGE128RE:
    899 	case PCI_CHIP_RAGE128RF:
    900 	case PCI_CHIP_RAGE128RG:
    901 	case PCI_CHIP_RAGE128RK:
    902 	case PCI_CHIP_RAGE128RL:
    903 	case PCI_CHIP_RAGE128SM:
    904 	/* FIXME: RAGE128 S[EFGHKLN] are assumed to be like the SM above as
    905 	 *        all of them are listed as "Rage 128 4x" in ATI docs.
    906 	 *        This requires confirmation however to be fully correct.
    907 	 *        Mike A. Harris <mharris (at) redhat.com>
    908 	 */
    909 	case PCI_CHIP_RAGE128SE:
    910 	case PCI_CHIP_RAGE128SF:
    911 	case PCI_CHIP_RAGE128SG:
    912 	case PCI_CHIP_RAGE128SH:
    913 	case PCI_CHIP_RAGE128SK:
    914 	case PCI_CHIP_RAGE128SL:
    915 	case PCI_CHIP_RAGE128SN:
    916 	default:                 info->HasPanelRegs = FALSE; break;
    917 	}
    918     }
    919 
    920 				/* Read registers used to determine options */
    921     from                      = X_PROBED;
    922     if (!R128MapMMIO(pScrn)) return FALSE;
    923     R128MMIO                  = info->MMIO;
    924 
    925 #ifndef AVOID_FBDEV
    926     if (info->FBDev)
    927 	pScrn->videoRam       = fbdevHWGetVidmem(pScrn) / 1024;
    928     else
    929 #endif
    930 	pScrn->videoRam       = INREG(R128_CONFIG_MEMSIZE) / 1024;
    931 
    932     info->MemCntl             = INREG(R128_MEM_CNTL);
    933     info->BusCntl             = INREG(R128_BUS_CNTL);
    934 
    935 				/* RAM */
    936     switch (info->MemCntl & 0x3) {
    937     case 0:                     /* SDR SGRAM 1:1 */
    938 	switch (info->Chipset) {
    939 	case PCI_CHIP_RAGE128TF:
    940 	case PCI_CHIP_RAGE128TL:
    941 	case PCI_CHIP_RAGE128TR:
    942 	case PCI_CHIP_RAGE128LE:
    943 	case PCI_CHIP_RAGE128LF:
    944 	case PCI_CHIP_RAGE128MF:
    945 	case PCI_CHIP_RAGE128ML:
    946 	case PCI_CHIP_RAGE128RE:
    947 	case PCI_CHIP_RAGE128RF:
    948 	case PCI_CHIP_RAGE128RG: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */
    949 	case PCI_CHIP_RAGE128RK:
    950 	case PCI_CHIP_RAGE128RL:
    951 	case PCI_CHIP_RAGE128SM:
    952 	default:                 offset = 1; break; /*  64-bit SDR SGRAM 1:1 */
    953 	}
    954 	break;
    955     case 1:                      offset = 2; break; /*  64-bit SDR SGRAM 2:1 */
    956     case 2:                      offset = 3; break; /*  64-bit DDR SGRAM     */
    957     default:                     offset = 1; break; /*  64-bit SDR SGRAM 1:1 */
    958     }
    959     info->ram = &R128RAM[offset];
    960 
    961     if (dev->videoRam) {
    962 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    963 		   "Video RAM override, using %d kB instead of %d kB\n",
    964 		   dev->videoRam,
    965 		   pScrn->videoRam);
    966 	from             = X_CONFIG;
    967 	pScrn->videoRam  = dev->videoRam;
    968     }
    969 
    970     xf86DrvMsg(pScrn->scrnIndex, from,
    971 	       "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
    972 
    973     pScrn->videoRam  &= ~1023;
    974     info->FbMapSize  = pScrn->videoRam * 1024;
    975 
    976 #ifdef R128DRI
    977     /* AGP/PCI */
    978     if (!info->IsPCI) {
    979 	switch (info->Chipset) {
    980 	case PCI_CHIP_RAGE128LE:
    981 	case PCI_CHIP_RAGE128RE:
    982 	case PCI_CHIP_RAGE128RK:
    983 	case PCI_CHIP_RAGE128PD:
    984 	case PCI_CHIP_RAGE128PR:
    985 	case PCI_CHIP_RAGE128PP: info->IsPCI = TRUE;  break;
    986 	case PCI_CHIP_RAGE128LF:
    987 	case PCI_CHIP_RAGE128MF:
    988 	case PCI_CHIP_RAGE128ML:
    989 	case PCI_CHIP_RAGE128PF:
    990 	case PCI_CHIP_RAGE128RF:
    991 	case PCI_CHIP_RAGE128RG:
    992 	case PCI_CHIP_RAGE128RL:
    993 	case PCI_CHIP_RAGE128SM:
    994 	case PCI_CHIP_RAGE128TF:
    995 	case PCI_CHIP_RAGE128TL:
    996 	case PCI_CHIP_RAGE128TR:
    997 	/* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are
    998 	 * believed to be AGP, but need confirmation. <mharris (at) redhat.com>
    999 	 */
   1000 	case PCI_CHIP_RAGE128PA:
   1001 	case PCI_CHIP_RAGE128PB:
   1002 	case PCI_CHIP_RAGE128PC:
   1003 	case PCI_CHIP_RAGE128PE:
   1004 	case PCI_CHIP_RAGE128PG:
   1005 	case PCI_CHIP_RAGE128PH:
   1006 	case PCI_CHIP_RAGE128PI:
   1007 	case PCI_CHIP_RAGE128PJ:
   1008 	case PCI_CHIP_RAGE128PK:
   1009 	case PCI_CHIP_RAGE128PL:
   1010 	case PCI_CHIP_RAGE128PM:
   1011 	case PCI_CHIP_RAGE128PN:
   1012 	case PCI_CHIP_RAGE128PO:
   1013 	case PCI_CHIP_RAGE128PQ:
   1014 	case PCI_CHIP_RAGE128PS:
   1015 	case PCI_CHIP_RAGE128PT:
   1016 	case PCI_CHIP_RAGE128PU:
   1017 	case PCI_CHIP_RAGE128PV:
   1018 	case PCI_CHIP_RAGE128PW:
   1019 	case PCI_CHIP_RAGE128PX:
   1020 	case PCI_CHIP_RAGE128TS:
   1021 	case PCI_CHIP_RAGE128TT:
   1022 	case PCI_CHIP_RAGE128TU:
   1023 	case PCI_CHIP_RAGE128SE:
   1024 	case PCI_CHIP_RAGE128SF:
   1025 	case PCI_CHIP_RAGE128SG:
   1026 	case PCI_CHIP_RAGE128SH:
   1027 	case PCI_CHIP_RAGE128SK:
   1028 	case PCI_CHIP_RAGE128SL:
   1029 	case PCI_CHIP_RAGE128SN:
   1030 	default:                 info->IsPCI = FALSE; break;
   1031 	}
   1032     }
   1033 #endif
   1034 
   1035     return TRUE;
   1036 }
   1037 
   1038 static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
   1039 {
   1040 #if !defined(__powerpc__) && !defined(__alpha__) && !defined(__sparc__)
   1041     R128InfoPtr   info = R128PTR(pScrn);
   1042     vbeInfoPtr pVbe;
   1043 #endif
   1044 
   1045     if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE;
   1046     if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE;
   1047 
   1048 #if defined(__powerpc__) || defined(__alpha__) || defined(__sparc__)
   1049     /* Int10 is broken on PPC and some Alphas */
   1050     return TRUE;
   1051 #else
   1052     if (xf86LoadSubModule(pScrn, "vbe")) {
   1053 	pVbe = VBEInit(pInt10,info->pEnt->index);
   1054 	if (!pVbe) return FALSE;
   1055         xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL)));
   1056 	vbeFree(pVbe);
   1057 	return TRUE;
   1058     } else
   1059 	return FALSE;
   1060 #endif
   1061 }
   1062 
   1063 /* This is called by R128PreInit to initialize gamma correction. */
   1064 static Bool R128PreInitGamma(ScrnInfoPtr pScrn)
   1065 {
   1066     Gamma zeros = { 0.0, 0.0, 0.0 };
   1067 
   1068     if (!xf86SetGamma(pScrn, zeros)) return FALSE;
   1069     return TRUE;
   1070 }
   1071 
   1072 /* This is called by R128PreInit to initialize the hardware cursor. */
   1073 static Bool R128PreInitCursor(ScrnInfoPtr pScrn)
   1074 {
   1075     R128InfoPtr   info = R128PTR(pScrn);
   1076 
   1077     if (!info->swCursor) {
   1078 	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
   1079     }
   1080     return TRUE;
   1081 }
   1082 
   1083 static Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10)
   1084 {
   1085     R128InfoPtr   info = R128PTR(pScrn);
   1086 #if !defined(__powerpc__) && !defined(__alpha__)
   1087     /* int10 is broken on some Alphas and powerpc */
   1088     if (xf86LoadSubModule(pScrn, "int10")) {
   1089 	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
   1090 	*ppInt10 = xf86InitInt10(info->pEnt->index);
   1091     }
   1092 #endif
   1093     return TRUE;
   1094 }
   1095 
   1096 #ifdef R128DRI
   1097 static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
   1098 {
   1099     R128InfoPtr   info = R128PTR(pScrn);
   1100 
   1101     info->agpMode        = R128_DEFAULT_AGP_MODE;
   1102     info->agpSize        = R128_DEFAULT_AGP_SIZE;
   1103     info->ringSize       = R128_DEFAULT_RING_SIZE;
   1104     info->bufSize        = R128_DEFAULT_BUFFER_SIZE;
   1105     info->agpTexSize     = R128_DEFAULT_AGP_TEX_SIZE;
   1106 
   1107     info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT;
   1108 
   1109     if (!info->IsPCI) {
   1110 	if (xf86GetOptValInteger(info->Options,
   1111 				 OPTION_AGP_MODE, &(info->agpMode))) {
   1112 	    if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) {
   1113 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1114 			   "Illegal AGP Mode: %d\n", info->agpMode);
   1115 		return FALSE;
   1116 	    }
   1117 	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1118 		       "Using AGP %dx mode\n", info->agpMode);
   1119 	}
   1120 
   1121 	if (xf86GetOptValInteger(info->Options,
   1122 				 OPTION_AGP_SIZE, (int *)&(info->agpSize))) {
   1123 	    switch (info->agpSize) {
   1124 	    case 4:
   1125 	    case 8:
   1126 	    case 16:
   1127 	    case 32:
   1128 	    case 64:
   1129 	    case 128:
   1130 	    case 256:
   1131 		break;
   1132 	    default:
   1133 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1134 			   "Illegal AGP size: %d MB\n", info->agpSize);
   1135 		return FALSE;
   1136 	    }
   1137 	}
   1138 
   1139 	if (xf86GetOptValInteger(info->Options,
   1140 				 OPTION_RING_SIZE, &(info->ringSize))) {
   1141 	    if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) {
   1142 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1143 			   "Illegal ring buffer size: %d MB\n",
   1144 			   info->ringSize);
   1145 		return FALSE;
   1146 	    }
   1147 	}
   1148 
   1149 	if (xf86GetOptValInteger(info->Options,
   1150 				 OPTION_BUFFER_SIZE, &(info->bufSize))) {
   1151 	    if (info->bufSize < 1 || info->bufSize >= (int)info->agpSize) {
   1152 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1153 			   "Illegal vertex/indirect buffers size: %d MB\n",
   1154 			   info->bufSize);
   1155 		return FALSE;
   1156 	    }
   1157 	    if (info->bufSize > 2) {
   1158 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1159 			   "Illegal vertex/indirect buffers size: %d MB\n",
   1160 			   info->bufSize);
   1161 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1162 			   "Clamping vertex/indirect buffers size to 2 MB\n");
   1163 		info->bufSize = 2;
   1164 	    }
   1165 	}
   1166 
   1167 	if (info->ringSize + info->bufSize + info->agpTexSize >
   1168 	    (int)info->agpSize) {
   1169 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1170 		       "Buffers are too big for requested AGP space\n");
   1171 	    return FALSE;
   1172 	}
   1173 
   1174 	info->agpTexSize = info->agpSize - (info->ringSize + info->bufSize);
   1175     }
   1176 
   1177     if (xf86GetOptValInteger(info->Options, OPTION_USEC_TIMEOUT,
   1178 			     &(info->CCEusecTimeout))) {
   1179 	/* This option checked by the R128 DRM kernel module */
   1180     }
   1181 
   1182     if (!xf86LoadSubModule(pScrn, "shadowfb")) {
   1183 	info->allowPageFlip = 0;
   1184 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1185 		   "Couldn't load shadowfb module:\n");
   1186     } else {
   1187 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
   1188 						   OPTION_PAGE_FLIP,
   1189 						   FALSE);
   1190     }
   1191 
   1192     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n",
   1193 	       info->allowPageFlip ? "en" : "dis");
   1194 
   1195     return TRUE;
   1196 }
   1197 #endif
   1198 
   1199 static Bool R128PreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
   1200 {
   1201     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
   1202     int found = 0;
   1203     int i;
   1204 
   1205     if (!R128GetBIOSParameters(pScrn, pInt10))
   1206         return FALSE;
   1207 
   1208     if (!R128GetPLLParameters(pScrn))
   1209         return FALSE;
   1210 
   1211     if (!R128AllocateControllers(pScrn))
   1212         return FALSE;
   1213 
   1214     if (!R128SetupConnectors(pScrn))
   1215         return FALSE;
   1216 
   1217     for (i = 0; i < config->num_output; i++) {
   1218         xf86OutputPtr output = config->output[i];
   1219 
   1220         output->status = (*output->funcs->detect) (output);
   1221         if (output->status == XF86OutputStatusConnected)
   1222             found++;
   1223     }
   1224     return !!found;
   1225 }
   1226 
   1227 static void
   1228 r128UMSOption(ScrnInfoPtr pScrn)
   1229 {
   1230     R128InfoPtr      info = R128PTR(pScrn);
   1231 
   1232     info->dac6bits = xf86ReturnOptValBool(info->Options,
   1233                                             OPTION_DAC_6BIT, FALSE);
   1234 
   1235 #ifndef AVOID_FBDEV
   1236 #ifdef __powerpc__
   1237     if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, TRUE))
   1238 #else
   1239     if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE))
   1240 #endif
   1241     {
   1242         info->FBDev = TRUE;
   1243         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1244                     "Using framebuffer device.\n");
   1245     }
   1246 #endif
   1247 
   1248     /* By default, don't access VGA IOs on PowerPC or SPARC. */
   1249 #if defined(__powerpc__) || defined(__sparc__) || !defined(WITH_VGAHW)
   1250     info->VGAAccess = FALSE;
   1251 #else
   1252     info->VGAAccess = TRUE;
   1253 #endif
   1254 
   1255 #ifdef WITH_VGAHW
   1256     xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS,
   1257                         &info->VGAAccess);
   1258     if (info->VGAAccess) {
   1259        if (!xf86LoadSubModule(pScrn, "vgahw"))
   1260            info->VGAAccess = FALSE;
   1261         else {
   1262             if (!vgaHWGetHWRec(pScrn))
   1263                info->VGAAccess = FALSE;
   1264        }
   1265 
   1266        if (!info->VGAAccess) {
   1267            xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
   1268                        "Loading VGA module failed, trying to "
   1269                        "run without it.\n");
   1270        }
   1271     } else
   1272            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1273                        "VGAAccess option set to FALSE, VGA "
   1274                        "module load skipped.\n");
   1275     if (info->VGAAccess) {
   1276         vgaHWSetStdFuncs(VGAHWPTR(pScrn));
   1277         vgaHWGetIOBase(VGAHWPTR(pScrn));
   1278     }
   1279 #else
   1280     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1281                 "VGAHW support not compiled, VGA "
   1282                 "module load skipped.\n");
   1283 #endif
   1284 
   1285     if (xf86ReturnOptValBool(info->Options,
   1286                                 OPTION_SHOW_CACHE, FALSE)) {
   1287         info->showCache = TRUE;
   1288         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1289                     "ShowCache enabled.\n");
   1290     }
   1291 
   1292     if (xf86ReturnOptValBool(info->Options,
   1293                                 OPTION_SW_CURSOR, FALSE)) {
   1294         info->swCursor = TRUE;
   1295         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1296                     "Software cursor requested.\n");
   1297     }
   1298 
   1299     if(xf86GetOptValInteger(info->Options,
   1300                             OPTION_VIDEO_KEY, &info->videoKey)) {
   1301         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1302                     "Video key set to 0x%x.\n", info->videoKey);
   1303     } else {
   1304         info->videoKey = 0x1E;
   1305     }
   1306 
   1307 #ifdef R128DRI
   1308     /* DMA for Xv */
   1309     info->DMAForXv = xf86ReturnOptValBool(info->Options,
   1310                                             OPTION_XV_DMA, FALSE);
   1311     if (info->DMAForXv) {
   1312         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1313                    "Will try to use DMA for Xv image transfers.\n");
   1314     }
   1315 
   1316     /* Force PCI Mode */
   1317     info->IsPCI = xf86ReturnOptValBool(info->Options,
   1318                                         OPTION_IS_PCI, FALSE);
   1319     if (info->IsPCI) {
   1320         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1321                     "Forced into PCI only mode.\n");
   1322     }
   1323 
   1324     if (xf86ReturnOptValBool(info->Options, OPTION_CCE_PIO, FALSE)) {
   1325         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1326                     "Forcing CCE into PIO mode.\n");
   1327         info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
   1328     } else {
   1329         info->CCEMode = R128_DEFAULT_CCE_BM_MODE;
   1330     }
   1331 
   1332     if (xf86ReturnOptValBool(info->Options, OPTION_NO_SECURITY, FALSE)) {
   1333         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
   1334                     "WARNING!!! CCE Security checks disabled!!!\n");
   1335         info->CCESecure = FALSE;
   1336     } else {
   1337         info->CCESecure = TRUE;
   1338     }
   1339 
   1340 
   1341 #endif
   1342 }
   1343 
   1344 static void
   1345 r128AcquireOption(ScrnInfoPtr pScrn)
   1346 {
   1347     R128InfoPtr      info = R128PTR(pScrn);
   1348 #ifdef USE_EXA
   1349     char *optstr;
   1350 #endif
   1351 
   1352     if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
   1353         info->noAccel = TRUE;
   1354     }
   1355 
   1356 #ifdef USE_EXA
   1357     if (!info->noAccel) {
   1358         optstr = (char *) xf86GetOptValString(info->Options,
   1359                                                 OPTION_ACCELMETHOD);
   1360         if (optstr) {
   1361             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1362                         "AccelMethod option found.\n");
   1363             if (xf86NameCmp(optstr, "EXA") == 0) {
   1364                 info->useEXA = TRUE;
   1365                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1366                             "AccelMethod is set to EXA, turning "
   1367                             "EXA on.\n");
   1368             }
   1369         }
   1370 
   1371 #ifdef RENDER
   1372         info->RenderAccel = xf86ReturnOptValBool(info->Options,
   1373                                                     OPTION_RENDERACCEL,
   1374                                                     TRUE);
   1375         if (info->RenderAccel)
   1376             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1377                         "Acceleration of RENDER operations will be "
   1378                         "enabled upon successful loading of DRI and "
   1379                         "EXA.\n");
   1380 #endif
   1381     }
   1382 #endif
   1383 
   1384     r128UMSOption(pScrn);
   1385 }
   1386 
   1387 static Bool R128CRTCResize(ScrnInfoPtr pScrn, int width, int height)
   1388 {
   1389     pScrn->virtualX = width;
   1390     pScrn->virtualY = height;
   1391     return TRUE;
   1392 }
   1393 
   1394 static const xf86CrtcConfigFuncsRec R128CRTCResizeFuncs = {
   1395     R128CRTCResize
   1396 };
   1397 
   1398 static Bool R128LegacyMS(ScrnInfoPtr pScrn)
   1399 {
   1400     R128InfoPtr      info = R128PTR(pScrn);
   1401     xf86Int10InfoPtr pInt10 = NULL;
   1402     Bool ret = FALSE;
   1403 
   1404 #ifndef AVOID_FBDEV
   1405     if (info->FBDev) {
   1406         /* check for linux framebuffer device */
   1407         if (!xf86LoadSubModule(pScrn, "fbdevhw")) goto exit;
   1408         if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) goto exit;
   1409         pScrn->SwitchMode    = fbdevHWSwitchModeWeak();
   1410         pScrn->AdjustFrame   = fbdevHWAdjustFrameWeak();
   1411         pScrn->ValidMode     = fbdevHWValidModeWeak();
   1412     } else {
   1413 #endif /* !AVOID_FBDEV */
   1414         if (!R128PreInitInt10(pScrn, &pInt10)) goto exit;
   1415 #ifndef AVOID_FBDEV
   1416     }
   1417 #endif /* !AVOID_FBDEV */
   1418 
   1419     if (!R128PreInitConfig(pScrn)) goto freeInt10;
   1420 
   1421     xf86CrtcSetSizeRange(pScrn, 320, 200, 4096, 4096);
   1422 
   1423     if (!R128PreInitCursor(pScrn)) goto freeInt10;
   1424 
   1425     /* Don't fail on this one */
   1426     info->DDC = R128PreInitDDC(pScrn, pInt10);
   1427 
   1428     if (!R128PreInitControllers(pScrn, pInt10)) goto freeInt10;
   1429 
   1430 #ifdef R128DRI
   1431     if (!R128PreInitDRI(pScrn)) goto freeInt10;
   1432 #endif
   1433 
   1434     ret = TRUE;
   1435 freeInt10:
   1436     /* Free int10 info */
   1437     if (pInt10) {
   1438         xf86FreeInt10(pInt10);
   1439     }
   1440 
   1441 exit:
   1442     return ret;
   1443 }
   1444 
   1445 static void
   1446 R128PreInitAccel(ScrnInfoPtr pScrn)
   1447 {
   1448     R128InfoPtr      info = R128PTR(pScrn);
   1449 #ifdef USE_EXA
   1450     int errmaj, errmin;
   1451 #endif
   1452 
   1453     if (!info->noAccel) {
   1454         if (info->useEXA) {
   1455 #ifdef USE_EXA
   1456             info->exaReq.majorversion = EXA_VERSION_MAJOR;
   1457             info->exaReq.minorversion = EXA_VERSION_MINOR;
   1458 
   1459             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1460                         "Loading EXA module...\n");
   1461             if (LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
   1462                                 &info->exaReq, &errmaj, &errmin)) {
   1463                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1464                             "Loading EXA module.\n");
   1465             } else {
   1466                 LoaderErrorMsg(NULL, "exa", errmaj, errmin);
   1467             }
   1468 #endif
   1469         }
   1470 
   1471         if ((!info->useEXA) ||
   1472             ((info->useEXA) && (!info->accelOn))) {
   1473         }
   1474     }
   1475 }
   1476 
   1477 /* R128PreInit is called once at server startup. */
   1478 Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
   1479 {
   1480     R128InfoPtr      info;
   1481 #ifdef WSDISPLAYIO_GET_BUSID
   1482     struct wsdisplayio_bus_id bid;
   1483 #endif
   1484 
   1485     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1486                         "%s\n", __func__));
   1487 
   1488     if (flags & PROBE_DETECT) {
   1489         return TRUE;
   1490     }
   1491 
   1492     pScrn->monitor = pScrn->confScreen->monitor;
   1493 
   1494     if (!R128PreInitVisual(pScrn)) {
   1495         return FALSE;
   1496     }
   1497 
   1498     if (!R128PreInitGamma(pScrn)) {
   1499         return FALSE;
   1500     }
   1501 
   1502     if (pScrn->numEntities != 1) return FALSE;
   1503 
   1504     if (!R128GetRec(pScrn)) return FALSE;
   1505 
   1506     info                = R128PTR(pScrn);
   1507     info->SwitchingMode = FALSE;
   1508     info->MMIO          = NULL;
   1509 
   1510     info->pEnt          = xf86GetEntityInfo(pScrn->entityList[0]);
   1511     if (info->pEnt->location.type != BUS_PCI) goto fail;
   1512 
   1513     info->PciInfo       = xf86GetPciInfoForEntity(info->pEnt->index);
   1514 
   1515     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1516 	       "PCI bus %d card %d func %d\n",
   1517 	       PCI_DEV_BUS(info->PciInfo),
   1518 	       PCI_DEV_DEV(info->PciInfo),
   1519 	       PCI_DEV_FUNC(info->PciInfo));
   1520 
   1521 #ifdef WSDISPLAYIO_GET_BUSID
   1522     /* now check if this is the console */
   1523     info->HaveWSDisplay = FALSE;
   1524     info->HaveBacklightControl = FALSE;
   1525     if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GET_BUSID, &bid) != -1) {
   1526     	if ((bid.bus_type == WSDISPLAYIO_BUS_PCI) &&
   1527     	    (bid.ubus.pci.bus == PCI_DEV_BUS(info->PciInfo)) &&
   1528     	    (bid.ubus.pci.device == PCI_DEV_DEV(info->PciInfo)) &&
   1529     	    (bid.ubus.pci.function == PCI_DEV_FUNC(info->PciInfo))) {
   1530     	    	struct wsdisplay_param p;
   1531     	    	info->HaveWSDisplay = TRUE;
   1532 
   1533 #ifdef WSDISPLAYIO_PARAM_BACKLIGHT
   1534     	    	/* now see if we have hacklight control */
   1535     	    	p.param = WSDISPLAYIO_PARAM_BACKLIGHT;
   1536 		if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, &p) != -1) {
   1537 		    info->HaveBacklightControl = TRUE;
   1538 		}
   1539 #endif
   1540     	}
   1541     }
   1542 #endif
   1543 
   1544 #ifndef XSERVER_LIBPCIACCESS
   1545     info->PciTag        = pciTag(PCI_DEV_BUS(info->PciInfo),
   1546 				PCI_DEV_DEV(info->PciInfo),
   1547 				PCI_DEV_FUNC(info->PciInfo));
   1548 
   1549     if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail;
   1550     if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail;
   1551 
   1552     pScrn->racMemFlags  = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
   1553 #endif
   1554 
   1555     info->fifo_slots  = 0;
   1556     info->pix24bpp    = xf86GetBppFromDepth(pScrn, pScrn->depth);
   1557     info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
   1558     info->CurrentLayout.depth        = pScrn->depth;
   1559     info->CurrentLayout.pixel_bytes  = pScrn->bitsPerPixel / 8;
   1560     info->CurrentLayout.pixel_code   = (pScrn->bitsPerPixel != 16
   1561                                        ? pScrn->bitsPerPixel
   1562                                        : pScrn->depth);
   1563 
   1564     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1565            "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n",
   1566            pScrn->depth,
   1567            info->CurrentLayout.pixel_bytes,
   1568            info->CurrentLayout.pixel_bytes > 1 ? "s" : "",
   1569            info->pix24bpp);
   1570 
   1571 				/* We can't do this until we have a
   1572 				   pScrn->display. */
   1573     xf86CollectOptions(pScrn, NULL);
   1574     if (!(info->Options = malloc(sizeof(R128Options))))    goto fail;
   1575     memcpy(info->Options, R128Options, sizeof(R128Options));
   1576     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
   1577 
   1578     info->noAccel = FALSE;
   1579     info->accelOn = FALSE;
   1580 
   1581     info->useEXA = FALSE;
   1582 #ifdef USE_EXA
   1583     info->useEXA = TRUE;
   1584 #endif
   1585 
   1586     info->swCursor = FALSE;
   1587 
   1588     r128AcquireOption(pScrn);
   1589 
   1590     if (!R128PreInitWeight(pScrn))    goto fail;
   1591 
   1592     /* Allocate an xf86CrtcConfig */
   1593     xf86CrtcConfigInit(pScrn, &R128CRTCResizeFuncs);
   1594 
   1595     R128LegacyMS(pScrn);
   1596 
   1597     if (!xf86InitialConfiguration(pScrn, TRUE)) {
   1598         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
   1599         goto fail;
   1600     }
   1601     pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
   1602 
   1603     /* Set display resolution */
   1604     xf86SetDpi(pScrn, 0, 0);
   1605 
   1606     /* Get ScreenInit function */
   1607     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
   1608 
   1609     R128PreInitAccel(pScrn);
   1610 
   1611     info->CurrentLayout.displayWidth = pScrn->displayWidth;
   1612 
   1613     if (!xf86RandR12PreInit(pScrn)) {
   1614         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
   1615         goto fail;
   1616     }
   1617 
   1618     if (pScrn->modes == NULL) {
   1619         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
   1620         goto fail;
   1621     }
   1622 
   1623 				/* Free the video bios (if applicable) */
   1624     if (info->VBIOS) {
   1625 	free(info->VBIOS);
   1626 	info->VBIOS = NULL;
   1627     }
   1628 
   1629     if (info->MMIO) R128UnmapMMIO(pScrn);
   1630     info->MMIO = NULL;
   1631 
   1632     return TRUE;
   1633 
   1634   fail:
   1635 				/* Pre-init failed. */
   1636 
   1637 				/* Free the video bios (if applicable) */
   1638     if (info->VBIOS) {
   1639 	free(info->VBIOS);
   1640 	info->VBIOS = NULL;
   1641     }
   1642 
   1643 #ifdef WITH_VGAHW
   1644     if (info->VGAAccess)
   1645            vgaHWFreeHWRec(pScrn);
   1646 #endif
   1647 
   1648     if (info->MMIO) R128UnmapMMIO(pScrn);
   1649     info->MMIO = NULL;
   1650 
   1651     R128FreeRec(pScrn);
   1652     return FALSE;
   1653 }
   1654 
   1655 /* Load a palette. */
   1656 static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors,
   1657 			    int *indices, LOCO *colors, VisualPtr pVisual)
   1658 {
   1659     R128InfoPtr   info      = R128PTR(pScrn);
   1660     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
   1661     int i, j;
   1662     int c, index;
   1663     uint16_t lut_r[256], lut_g[256], lut_b[256];
   1664 
   1665     for (c = 0; c < xf86_config->num_crtc; c++) {
   1666         xf86CrtcPtr crtc = xf86_config->crtc[c];
   1667         R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
   1668 
   1669         for (i = 0 ; i < 256; i++) {
   1670             lut_r[i] = r128_crtc->lut_r[i] << 8;
   1671             lut_g[i] = r128_crtc->lut_g[i] << 8;
   1672             lut_b[i] = r128_crtc->lut_b[i] << 8;
   1673         }
   1674 
   1675         switch (info->CurrentLayout.depth) {
   1676         case 15:
   1677             for (i = 0; i < numColors; i++) {
   1678                 index = indices[i];
   1679                 for (j = 0; j < 8; j++) {
   1680                     lut_r[index * 8 + j] = colors[index].red << 8;
   1681                     lut_g[index * 8 + j] = colors[index].green << 8;
   1682                     lut_b[index * 8 + j] = colors[index].blue << 8;
   1683                 }
   1684             }
   1685         case 16:
   1686             for (i = 0; i < numColors; i++) {
   1687                 index = indices[i];
   1688 
   1689                 /* XXX: The old version of R128LoadPalette did not do this and
   1690                  * the old version of RADEONLoadPalette has a comment asking why.
   1691                  */
   1692                 if (i <= 31) {
   1693                     for (j = 0; j < 8; j++) {
   1694                         lut_r[index * 8 + j] = colors[index].red << 8;
   1695                         lut_b[index * 8 + j] = colors[index].blue << 8;
   1696                     }
   1697                 }
   1698 
   1699                 for (j = 0; j < 4; j++) {
   1700                     lut_g[index * 4 + j] = colors[index].green << 8;
   1701                 }
   1702             }
   1703         default:
   1704             for (i = 0; i < numColors; i++) {
   1705                 index = indices[i];
   1706                 lut_r[index] = colors[index].red << 8;
   1707                 lut_g[index] = colors[index].green << 8;
   1708                 lut_b[index] = colors[index].blue << 8;
   1709             }
   1710             break;
   1711         }
   1712 
   1713         /* Make the change through RandR */
   1714 #ifdef RANDR_12_INTERFACE
   1715         if (crtc->randr_crtc)
   1716             RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
   1717         else
   1718 #endif
   1719         crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
   1720     }
   1721 }
   1722 
   1723 static void
   1724 R128BlockHandler(BLOCKHANDLER_ARGS_DECL)
   1725 {
   1726     ScrnInfoPtr pScrn   = xf86ScreenToScrn(pScreen);
   1727     R128InfoPtr info    = R128PTR(pScrn);
   1728 
   1729 #ifdef R128DRI
   1730     if (info->directRenderingEnabled)
   1731         FLUSH_RING();
   1732 #endif
   1733 
   1734     pScreen->BlockHandler = info->BlockHandler;
   1735     (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
   1736     pScreen->BlockHandler = R128BlockHandler;
   1737 
   1738     if(info->VideoTimerCallback) {
   1739         (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
   1740     }
   1741 }
   1742 
   1743 /* Called at the start of each server generation. */
   1744 Bool R128ScreenInit(ScreenPtr pScreen, int argc, char **argv)
   1745 {
   1746     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   1747     R128InfoPtr info   = R128PTR(pScrn);
   1748     BoxRec      MemBox;
   1749     int width_bytes = (pScrn->displayWidth *
   1750                         info->CurrentLayout.pixel_bytes);
   1751     int scanlines;
   1752     int total = info->FbMapSize;
   1753     FBAreaPtr fbarea = NULL;
   1754 #ifdef R128DRI
   1755     int cpp = info->CurrentLayout.pixel_bytes;
   1756     int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
   1757 #ifdef USE_EXA
   1758     ExaOffscreenArea*     osArea = NULL;
   1759 #endif /* USE_EXA */
   1760 #endif /* R128DRI */
   1761 
   1762     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1763                         "%s %lx %lx\n",
   1764                         __func__,
   1765                         pScrn->memPhysBase, pScrn->fbOffset));
   1766 
   1767 #ifdef R128DRI
   1768 				/* Turn off the CCE for now. */
   1769     info->CCEInUse     = FALSE;
   1770     info->indirectBuffer = NULL;
   1771 #endif
   1772 
   1773     if (!R128MapMem(pScrn)) return FALSE;
   1774     pScrn->fbOffset    = 0;
   1775     //if(info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
   1776 #ifdef R128DRI
   1777     info->fbX          = 0;
   1778     info->fbY          = 0;
   1779     info->frontOffset  = 0;
   1780     info->frontPitch   = pScrn->displayWidth;
   1781 #endif
   1782 
   1783     info->PaletteSavedOnVT = FALSE;
   1784 
   1785     R128Save(pScrn);
   1786 
   1787 				/* Visual setup */
   1788     miClearVisualTypes();
   1789     if (!miSetVisualTypes(pScrn->depth,
   1790 			  miGetDefaultVisualMask(pScrn->depth),
   1791 			  pScrn->rgbBits,
   1792 			  pScrn->defaultVisual)) return FALSE;
   1793     miSetPixmapDepths ();
   1794 
   1795 #ifdef R128DRI
   1796 				/* Setup DRI after visuals have been
   1797 				   established, but before fbScreenInit is
   1798 				   called. */
   1799     {
   1800 	/* FIXME: When we move to dynamic allocation of back and depth
   1801 	   buffers, we will want to revisit the following check for 3
   1802 	   times the virtual size of the screen below. */
   1803 	int maxy        = info->FbMapSize / width_bytes;
   1804 
   1805         if (info->noAccel) {
   1806 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
   1807 		       "Acceleration disabled, not initializing the DRI\n");
   1808 	    info->directRenderingEnabled = FALSE;
   1809 	} else if (maxy <= pScrn->virtualY * 3) {
   1810 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
   1811 		       "Static buffer allocation failed -- "
   1812 		       "need at least %d kB video memory\n",
   1813 		       (pScrn->displayWidth * pScrn->virtualY *
   1814 			info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
   1815 	    info->directRenderingEnabled = FALSE;
   1816 	} else {
   1817             info->directRenderingEnabled = R128DRIScreenInit(pScreen);
   1818 	}
   1819     }
   1820 #endif
   1821 
   1822     if (!fbScreenInit (pScreen, info->FB,
   1823 		       pScrn->virtualX, pScrn->virtualY,
   1824 		       pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
   1825 		       pScrn->bitsPerPixel))
   1826 	return FALSE;
   1827 
   1828     xf86SetBlackWhitePixels(pScreen);
   1829 
   1830     if (pScrn->bitsPerPixel > 8) {
   1831 	VisualPtr visual;
   1832 
   1833 	visual = pScreen->visuals + pScreen->numVisuals;
   1834 	while (--visual >= pScreen->visuals) {
   1835 	    if ((visual->class | DynamicClass) == DirectColor) {
   1836 		visual->offsetRed   = pScrn->offset.red;
   1837 		visual->offsetGreen = pScrn->offset.green;
   1838 		visual->offsetBlue  = pScrn->offset.blue;
   1839 		visual->redMask     = pScrn->mask.red;
   1840 		visual->greenMask   = pScrn->mask.green;
   1841 		visual->blueMask    = pScrn->mask.blue;
   1842 	    }
   1843 	}
   1844     }
   1845 
   1846     /* must be after RGB order fixed */
   1847     fbPictureInit (pScreen, 0, 0);
   1848 
   1849 				/* Memory manager setup */
   1850 #ifdef R128DRI
   1851     if (info->directRenderingEnabled) {
   1852 	int bufferSize = pScrn->virtualY * width_bytes;
   1853 	int l;
   1854 
   1855 	switch (info->CCEMode) {
   1856 	case R128_DEFAULT_CCE_PIO_MODE:
   1857 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n");
   1858 	    break;
   1859 	case R128_DEFAULT_CCE_BM_MODE:
   1860 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n");
   1861 	    break;
   1862 	default:
   1863 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n");
   1864 	    break;
   1865 	}
   1866 
   1867 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1868 		   "Using %d MB AGP aperture\n", info->agpSize);
   1869 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1870 		   "Using %d MB for the ring buffer\n", info->ringSize);
   1871 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1872 		   "Using %d MB for vertex/indirect buffers\n", info->bufSize);
   1873 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1874 		   "Using %d MB for AGP textures\n", info->agpTexSize);
   1875 
   1876 	/* Try for front, back, depth, and two framebuffers worth of
   1877 	 * pixmap cache.  Should be enough for a fullscreen background
   1878 	 * image plus some leftovers.
   1879 	 */
   1880 	info->textureSize = info->FbMapSize - 5 * bufferSize;
   1881 
   1882 	/* If that gives us less than half the available memory, let's
   1883 	 * be greedy and grab some more.  Sorry, I care more about 3D
   1884 	 * performance than playing nicely, and you'll get around a full
   1885 	 * framebuffer's worth of pixmap cache anyway.
   1886 	 */
   1887 	if (info->textureSize < (int)info->FbMapSize / 2) {
   1888 	    info->textureSize = info->FbMapSize - 4 * bufferSize;
   1889 	}
   1890 
   1891 	if (info->textureSize > 0) {
   1892 	    l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS);
   1893 	    if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY;
   1894 
   1895 	    /* Round the texture size up to the nearest whole number of
   1896 	     * texture regions.  Again, be greedy about this, don't
   1897 	     * round down.
   1898 	     */
   1899 	    info->log2TexGran = l;
   1900 	    info->textureSize = (info->textureSize >> l) << l;
   1901 	} else {
   1902 	    info->textureSize = 0;
   1903 	}
   1904 
   1905 	/* Set a minimum usable local texture heap size.  This will fit
   1906 	 * two 256x256x32bpp textures.
   1907 	 */
   1908 	if (info->textureSize < 512 * 1024) {
   1909 	    info->textureOffset = 0;
   1910 	    info->textureSize = 0;
   1911 	}
   1912 
   1913         total = info->FbMapSize - info->textureSize;
   1914     }
   1915 #endif /* R128DRI */
   1916 
   1917     scanlines = total / width_bytes;
   1918     if (scanlines > 8191) scanlines = 8191;
   1919 
   1920 #ifdef R128DRI
   1921     if (info->directRenderingEnabled)
   1922         /*
   1923          * Recalculate the texture offset and size to accommodate any
   1924          * rounding to a whole number of scanlines.
   1925          */
   1926         info->textureOffset = scanlines * width_bytes;
   1927 #endif /* R128DRI */
   1928 
   1929     MemBox.x1 = 0;
   1930     MemBox.y1 = 0;
   1931     MemBox.x2 = pScrn->displayWidth;
   1932     MemBox.y2 = scanlines;
   1933 
   1934     if (!info->useEXA) {
   1935         if (!xf86InitFBManager(pScreen, &MemBox)) {
   1936             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1937                        "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
   1938                        MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
   1939             return FALSE;
   1940         } else {
   1941             int width, height;
   1942 
   1943             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1944                        "Memory manager initialized to (%d,%d) (%d,%d)\n",
   1945                        MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
   1946             if ((fbarea = xf86AllocateOffscreenArea(pScreen,
   1947                                                     pScrn->displayWidth,
   1948                                                     2, 0, NULL, NULL, NULL))) {
   1949                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1950                            "Reserved area from (%d,%d) to (%d,%d)\n",
   1951                            fbarea->box.x1, fbarea->box.y1,
   1952                            fbarea->box.x2, fbarea->box.y2);
   1953             } else {
   1954                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve area\n");
   1955             }
   1956             if (xf86QueryLargestOffscreenArea(pScreen, &width,
   1957                                               &height, 0, 0, 0)) {
   1958                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1959                            "Largest offscreen area available: %d x %d\n",
   1960                            width, height);
   1961             }
   1962 
   1963             if (!info->noAccel) {
   1964                 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1965                            "Acceleration disabled.\n");
   1966             }
   1967         }
   1968     }
   1969 #ifdef USE_EXA
   1970     else {
   1971         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1972                     "Filling in EXA memory info\n");
   1973 
   1974 
   1975         /*
   1976          * Don't give EXA the true full memory size, because
   1977          * the textureSize sized chunk on the end is handled
   1978          * by DRI.
   1979          */
   1980         if (R128EXAInit(pScreen, total)) {
   1981             info->accelOn = TRUE;
   1982             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1983                         "EXA Acceleration enabled.\n");
   1984         } else {
   1985             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   1986                         "EXA Acceleration initialization "
   1987                         "failed.\n");
   1988             xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   1989                         "Acceleration disabled.\n");
   1990         }
   1991     }
   1992 #endif
   1993 
   1994 #ifdef R128DRI
   1995     if (info->directRenderingEnabled) {
   1996 				/* Allocate the shared back buffer */
   1997 	if(!info->useEXA) {
   1998 	    fbarea = xf86AllocateOffscreenArea(pScreen,
   1999 					       pScrn->virtualX,
   2000 					       pScrn->virtualY,
   2001 					       32, NULL, NULL, NULL);
   2002 
   2003 	    if (fbarea) {
   2004 		x1 = fbarea->box.x1;
   2005 		x2 = fbarea->box.x2;
   2006 		y1 = fbarea->box.y1;
   2007 		y2 = fbarea->box.y2;
   2008 	    }
   2009 	}
   2010 #ifdef USE_EXA
   2011 	else {
   2012 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2013 		       "Actually trying an EXA allocation...\n");
   2014 	    osArea = exaOffscreenAlloc(pScreen,
   2015 				       pScrn->virtualY * width_bytes,
   2016 				       32, TRUE, NULL, NULL);
   2017 
   2018 	    if (osArea) {
   2019 		x1 = osArea->offset % width_bytes;
   2020 		x2 = (osArea->offset + osArea->size) % width_bytes;
   2021 		y1 = osArea->offset / width_bytes;
   2022 		y2 = (osArea->offset + osArea->size) / width_bytes;
   2023 
   2024 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Went swimmingly...\n");
   2025 	    }
   2026 	}
   2027 #endif
   2028 
   2029 	if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) {
   2030 	    /* info->backOffset = y1 * width_bytes + x1 * cpp; */
   2031 	    info->backOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16);
   2032 	    info->backX = info->backOffset % width_bytes;
   2033 	    info->backY = info->backOffset / width_bytes;
   2034 	    info->backPitch = pScrn->displayWidth;
   2035 
   2036 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2037 		       "Reserved back buffer from (%d,%d) to (%d,%d) offset: %x\n",
   2038 		       x1, y1,
   2039 		       x2, y2, info->backOffset);
   2040 	} else {
   2041 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve back buffer\n");
   2042 	    info->backX = -1;
   2043 	    info->backY = -1;
   2044 	    info->backOffset = -1;
   2045 	    info->backPitch = -1;
   2046 	}
   2047 
   2048 				/* Allocate the shared depth buffer */
   2049 	if(!info->useEXA) {
   2050 	    fbarea = xf86AllocateOffscreenArea(pScreen,
   2051 					       pScrn->virtualX,
   2052 					       pScrn->virtualY + 1,
   2053 					       32, NULL, NULL, NULL);
   2054 	    if (fbarea) {
   2055 		x1 = fbarea->box.x1;
   2056 		x2 = fbarea->box.x2;
   2057 		y1 = fbarea->box.y1;
   2058 		y2 = fbarea->box.y2;
   2059 	    }
   2060 	}
   2061 #ifdef USE_EXA
   2062 	else {
   2063 	    osArea = exaOffscreenAlloc(pScreen,
   2064 				       (pScrn->virtualY + 1) * width_bytes,
   2065 				       32, TRUE, NULL, NULL);
   2066 
   2067 	    if (osArea) {
   2068 		x1 = osArea->offset % width_bytes;
   2069 		x2 = (osArea->offset + osArea->size) % width_bytes;
   2070 		y1 = osArea->offset / width_bytes;
   2071 		y2 = (osArea->offset + osArea->size) / width_bytes;
   2072 	    }
   2073 	}
   2074 #endif
   2075 
   2076 	if ((!info->useEXA && fbarea) || (info->useEXA && osArea)) {
   2077 	    /* info->depthOffset = y1 * width_bytes + x1 * cpp; */
   2078 	    info->depthOffset = R128_ALIGN(y1 * width_bytes + x1 * cpp, 16);
   2079 	    info->depthX = info->depthOffset % width_bytes;
   2080 	    info->depthY = info->depthOffset / width_bytes;
   2081 	    info->depthPitch = pScrn->displayWidth;
   2082 	    info->spanOffset = (y2 - 1) * width_bytes + x1 * cpp;
   2083 
   2084 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2085 		       "Reserved depth buffer from (%d,%d) to (%d,%d) offset: %x\n",
   2086 		       x1, y1,
   2087 		       x2, y2, info->depthOffset);
   2088 
   2089 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2090 		       "Reserved depth span from (%d,%d) offset 0x%x\n",
   2091 		       x1, y2 - 1, info->spanOffset);
   2092 	} else {
   2093 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to reserve depth buffer\n");
   2094 	    info->depthX = -1;
   2095 	    info->depthY = -1;
   2096 	    info->depthOffset = -1;
   2097 	    info->depthPitch = -1;
   2098 	    info->spanOffset = -1;
   2099 	}
   2100 
   2101 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2102 		   "Reserved %d kb for textures at offset 0x%x\n",
   2103 		   info->textureSize/1024, info->textureOffset);
   2104     }
   2105 #endif /* R128DRI */
   2106 
   2107     pScrn->vtSema = TRUE;
   2108     /* xf86CrtcRotate accesses pScrn->pScreen */
   2109     pScrn->pScreen = pScreen;
   2110 
   2111 #ifndef AVOID_FBDEV
   2112     if (info->FBDev) {
   2113 	if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
   2114     } else {
   2115 #endif
   2116 	if (!xf86SetDesiredModes(pScrn)) return FALSE;
   2117 #ifndef AVOID_FBDEV
   2118     }
   2119 #endif
   2120 
   2121     R128SaveScreen(pScreen, SCREEN_SAVER_ON);
   2122     //pScrn->AdjustFrame(pScrn, pScrn->frameX0, pScrn->frameY0);
   2123 
   2124 				/* DGA setup */
   2125 #ifdef XFreeXDGA
   2126     xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset);
   2127 #endif
   2128 
   2129 				/* Backing store setup */
   2130     xf86SetBackingStore(pScreen);
   2131 
   2132 				/* Set Silken Mouse */
   2133     xf86SetSilkenMouse(pScreen);
   2134 
   2135 				/* Cursor setup */
   2136     miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
   2137 
   2138 				/* Hardware cursor setup */
   2139     if (!info->swCursor) {
   2140 	if (R128CursorInit(pScreen)) {
   2141 	    int width, height;
   2142 
   2143 	    if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
   2144 					      0, 0, 0)) {
   2145 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2146 			   "Largest offscreen area available: %d x %d\n",
   2147 			   width, height);
   2148 	    }
   2149 	} else {
   2150 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
   2151 		       "Hardware cursor initialization failed\n");
   2152 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
   2153 	}
   2154     } else {
   2155 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using software cursor\n");
   2156     }
   2157 
   2158     /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */
   2159 #ifndef AVOID_FBDEV
   2160     if (info->FBDev)
   2161 	xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0);
   2162     else
   2163 #endif
   2164         xf86DPMSInit(pScreen, xf86DPMSSet, 0);
   2165 
   2166     R128InitVideo(pScreen);
   2167 
   2168 				/* Provide SaveScreen */
   2169     pScreen->SaveScreen  = R128SaveScreen;
   2170 
   2171 				/* Wrap CloseScreen */
   2172     info->CloseScreen    = pScreen->CloseScreen;
   2173     pScreen->CloseScreen = R128CloseScreen;
   2174 
   2175 				/* Note unused options */
   2176     if (serverGeneration == 1)
   2177 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
   2178 
   2179 #ifdef R128DRI
   2180 				/* DRI finalization */
   2181     if (info->directRenderingEnabled) {
   2182 				/* Now that mi, fb, drm and others have
   2183 				   done their thing, complete the DRI
   2184 				   setup. */
   2185 	info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen);
   2186     }
   2187     if (info->directRenderingEnabled) {
   2188 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
   2189     } else {
   2190 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
   2191 		   "Direct rendering disabled\n");
   2192     }
   2193 #endif
   2194 
   2195     info->BlockHandler = pScreen->BlockHandler;
   2196     pScreen->BlockHandler = R128BlockHandler;
   2197 
   2198     if (!xf86CrtcScreenInit(pScreen)) return FALSE;
   2199 
   2200 				/* Colormap setup */
   2201     if (!miCreateDefColormap(pScreen)) return FALSE;
   2202     if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
   2203 			     (
   2204 #ifndef AVOID_FBDEV
   2205 			     info->FBDev ? fbdevHWLoadPaletteWeak() :
   2206 #endif
   2207 			     R128LoadPalette), NULL,
   2208 			     CMAP_PALETTED_TRUECOLOR
   2209 			     | CMAP_RELOAD_ON_MODE_SWITCH
   2210 #if 0 /* This option messes up text mode! (eich (at) suse.de) */
   2211 			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
   2212 #endif
   2213 			     )) return FALSE;
   2214 
   2215     return TRUE;
   2216 }
   2217 
   2218 /* Write common registers (initialized to 0). */
   2219 void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
   2220 {
   2221     R128InfoPtr   info      = R128PTR(pScrn);
   2222     unsigned char *R128MMIO = info->MMIO;
   2223 
   2224     OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl | R128_FP_BLANK_DIS);
   2225 
   2226     OUTREG(R128_OVR_CLR,              restore->ovr_clr);
   2227     OUTREG(R128_OVR_WID_LEFT_RIGHT,   restore->ovr_wid_left_right);
   2228     OUTREG(R128_OVR_WID_TOP_BOTTOM,   restore->ovr_wid_top_bottom);
   2229     OUTREG(R128_OV0_SCALE_CNTL,       restore->ov0_scale_cntl);
   2230     OUTREG(R128_MPP_TB_CONFIG,        restore->mpp_tb_config );
   2231     OUTREG(R128_MPP_GP_CONFIG,        restore->mpp_gp_config );
   2232     OUTREG(R128_SUBPIC_CNTL,          restore->subpic_cntl);
   2233     OUTREG(R128_VIPH_CONTROL,         restore->viph_control);
   2234     OUTREG(R128_I2C_CNTL_1,           restore->i2c_cntl_1);
   2235     OUTREG(R128_GEN_INT_CNTL,         restore->gen_int_cntl);
   2236     OUTREG(R128_CAP0_TRIG_CNTL,       restore->cap0_trig_cntl);
   2237     OUTREG(R128_CAP1_TRIG_CNTL,       restore->cap1_trig_cntl);
   2238     OUTREG(R128_BUS_CNTL,             restore->bus_cntl);
   2239     OUTREG(R128_CONFIG_CNTL,          restore->config_cntl);
   2240 }
   2241 
   2242 /* Write RMX registers */
   2243 void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
   2244 {
   2245     R128InfoPtr   info      = R128PTR(pScrn);
   2246     unsigned char *R128MMIO = info->MMIO;
   2247 
   2248     OUTREG(R128_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
   2249     OUTREG(R128_FP_VERT_STRETCH,      restore->fp_vert_stretch);
   2250     OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
   2251     OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
   2252     OUTREG(R128_FP_H_SYNC_STRT_WID,   restore->fp_h_sync_strt_wid);
   2253     OUTREG(R128_FP_V_SYNC_STRT_WID,   restore->fp_v_sync_strt_wid);
   2254 }
   2255 
   2256 /* Write flat panel registers */
   2257 void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
   2258 {
   2259     R128InfoPtr   info      = R128PTR(pScrn);
   2260     unsigned char *R128MMIO = info->MMIO;
   2261 
   2262     OUTREG(R128_TMDS_CRC,              restore->tmds_crc);
   2263     OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl);
   2264     OUTREG(R128_FP_PANEL_CNTL,         restore->fp_panel_cntl);
   2265     OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(uint32_t)R128_FP_BLANK_DIS);
   2266 }
   2267 
   2268 /* Write LVDS registers */
   2269 void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
   2270 {
   2271     R128InfoPtr   info      = R128PTR(pScrn);
   2272     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
   2273     unsigned char *R128MMIO = info->MMIO;
   2274     uint32_t      tmp;
   2275 
   2276     xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
   2277     R128OutputPrivatePtr r128_output = output->driver_private;
   2278 
   2279     tmp = INREG(R128_LVDS_GEN_CNTL);
   2280     if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
   2281 	(restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) {
   2282 	OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
   2283     } else {
   2284 	if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
   2285 	    OUTREG(R128_LVDS_GEN_CNTL,
   2286 		   restore->lvds_gen_cntl & (uint32_t)~R128_LVDS_BLON);
   2287 	    usleep(r128_output->PanelPwrDly * 1000);
   2288 	    OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
   2289 	} else {
   2290 	    OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);
   2291 	    usleep(r128_output->PanelPwrDly * 1000);
   2292 	    OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
   2293 	}
   2294     }
   2295 }
   2296 
   2297 /* Write DDA registers. */
   2298 void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
   2299 {
   2300     R128InfoPtr   info      = R128PTR(pScrn);
   2301     unsigned char *R128MMIO = info->MMIO;
   2302 
   2303     OUTREG(R128_DDA_CONFIG, restore->dda_config);
   2304     OUTREG(R128_DDA_ON_OFF, restore->dda_on_off);
   2305 }
   2306 
   2307 /* Write DDA registers. */
   2308 void R128RestoreDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr restore)
   2309 {
   2310     R128InfoPtr   info      = R128PTR(pScrn);
   2311     unsigned char *R128MMIO = info->MMIO;
   2312 
   2313     OUTREG(R128_DDA2_CONFIG, restore->dda2_config);
   2314     OUTREG(R128_DDA2_ON_OFF, restore->dda2_on_off);
   2315 }
   2316 
   2317 /* Read common registers. */
   2318 static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
   2319 {
   2320     R128InfoPtr   info      = R128PTR(pScrn);
   2321     unsigned char *R128MMIO = info->MMIO;
   2322 
   2323     save->ovr_clr            = INREG(R128_OVR_CLR);
   2324     save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT);
   2325     save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM);
   2326     save->ov0_scale_cntl     = INREG(R128_OV0_SCALE_CNTL);
   2327     save->mpp_tb_config      = INREG(R128_MPP_TB_CONFIG);
   2328     save->mpp_gp_config      = INREG(R128_MPP_GP_CONFIG);
   2329     save->subpic_cntl        = INREG(R128_SUBPIC_CNTL);
   2330     save->viph_control       = INREG(R128_VIPH_CONTROL);
   2331     save->i2c_cntl_1         = INREG(R128_I2C_CNTL_1);
   2332     save->gen_int_cntl       = INREG(R128_GEN_INT_CNTL);
   2333     save->cap0_trig_cntl     = INREG(R128_CAP0_TRIG_CNTL);
   2334     save->cap1_trig_cntl     = INREG(R128_CAP1_TRIG_CNTL);
   2335     save->bus_cntl           = INREG(R128_BUS_CNTL);
   2336     save->config_cntl        = INREG(R128_CONFIG_CNTL);
   2337 }
   2338 
   2339 /* Read CRTC registers. */
   2340 static void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
   2341 {
   2342     R128InfoPtr   info      = R128PTR(pScrn);
   2343     unsigned char *R128MMIO = info->MMIO;
   2344 
   2345     save->crtc_gen_cntl        = INREG(R128_CRTC_GEN_CNTL);
   2346     save->crtc_ext_cntl        = INREG(R128_CRTC_EXT_CNTL);
   2347     save->dac_cntl             = INREG(R128_DAC_CNTL);
   2348     save->crtc_h_total_disp    = INREG(R128_CRTC_H_TOTAL_DISP);
   2349     save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID);
   2350     save->crtc_v_total_disp    = INREG(R128_CRTC_V_TOTAL_DISP);
   2351     save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID);
   2352     save->crtc_offset          = INREG(R128_CRTC_OFFSET);
   2353     save->crtc_offset_cntl     = INREG(R128_CRTC_OFFSET_CNTL);
   2354     save->crtc_pitch           = INREG(R128_CRTC_PITCH);
   2355 }
   2356 
   2357 /* Read flat panel registers */
   2358 static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
   2359 {
   2360     R128InfoPtr   info      = R128PTR(pScrn);
   2361     unsigned char *R128MMIO = info->MMIO;
   2362 
   2363     save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP);
   2364     save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP);
   2365     save->fp_gen_cntl          = INREG(R128_FP_GEN_CNTL);
   2366     save->fp_h_sync_strt_wid   = INREG(R128_FP_H_SYNC_STRT_WID);
   2367     save->fp_horz_stretch      = INREG(R128_FP_HORZ_STRETCH);
   2368     save->fp_panel_cntl        = INREG(R128_FP_PANEL_CNTL);
   2369     save->fp_v_sync_strt_wid   = INREG(R128_FP_V_SYNC_STRT_WID);
   2370     save->fp_vert_stretch      = INREG(R128_FP_VERT_STRETCH);
   2371     save->lvds_gen_cntl        = INREG(R128_LVDS_GEN_CNTL);
   2372     save->tmds_crc             = INREG(R128_TMDS_CRC);
   2373     save->tmds_transmitter_cntl = INREG(R128_TMDS_TRANSMITTER_CNTL);
   2374 }
   2375 
   2376 /* Read CRTC2 registers. */
   2377 static void R128SaveCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
   2378 {
   2379     R128InfoPtr info        = R128PTR(pScrn);
   2380     unsigned char *R128MMIO = info->MMIO;
   2381 
   2382     save->crtc2_gen_cntl        = INREG(R128_CRTC2_GEN_CNTL);
   2383     save->crtc2_h_total_disp    = INREG(R128_CRTC2_H_TOTAL_DISP);
   2384     save->crtc2_h_sync_strt_wid = INREG(R128_CRTC2_H_SYNC_STRT_WID);
   2385     save->crtc2_v_total_disp    = INREG(R128_CRTC2_V_TOTAL_DISP);
   2386     save->crtc2_v_sync_strt_wid = INREG(R128_CRTC2_V_SYNC_STRT_WID);
   2387     save->crtc2_offset          = INREG(R128_CRTC2_OFFSET);
   2388     save->crtc2_offset_cntl     = INREG(R128_CRTC2_OFFSET_CNTL);
   2389     save->crtc2_pitch           = INREG(R128_CRTC2_PITCH);
   2390 }
   2391 
   2392 /* Read PLL registers. */
   2393 static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save)
   2394 {
   2395     save->ppll_ref_div         = INPLL(pScrn, R128_PPLL_REF_DIV);
   2396     save->ppll_div_3           = INPLL(pScrn, R128_PPLL_DIV_3);
   2397     save->ppll_div_0           = INPLL(pScrn, R128_PPLL_DIV_0);
   2398     save->htotal_cntl          = INPLL(pScrn, R128_HTOTAL_CNTL);
   2399 
   2400     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2401                         "Read: 0x%08x 0x%08x 0x%08x\n",
   2402                         save->ppll_ref_div,
   2403                         save->ppll_div_3,
   2404                         save->htotal_cntl));
   2405     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2406                         "Read: rd=%d, fd=%d, pd=%d\n",
   2407                         save->ppll_ref_div & R128_PPLL_REF_DIV_MASK,
   2408                         save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK,
   2409                         (save->ppll_div_3 &
   2410                                 R128_PPLL_POST3_DIV_MASK) >> 16));
   2411 }
   2412 
   2413 /* Read PLL2 registers. */
   2414 static void R128SavePLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
   2415 {
   2416     save->p2pll_ref_div        = INPLL(pScrn, R128_P2PLL_REF_DIV);
   2417     save->p2pll_div_0          = INPLL(pScrn, R128_P2PLL_DIV_0);
   2418     save->htotal_cntl2         = INPLL(pScrn, R128_HTOTAL2_CNTL);
   2419 
   2420     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2421                         "Read: 0x%08x 0x%08x 0x%08x\n",
   2422                         save->p2pll_ref_div,
   2423                         save->p2pll_div_0,
   2424                         save->htotal_cntl2));
   2425     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2426                         "Read: rd=%d, fd=%d, pd=%d\n",
   2427                         save->p2pll_ref_div & R128_P2PLL_REF_DIV_MASK,
   2428                         save->p2pll_div_0 & R128_P2PLL_FB0_DIV_MASK,
   2429                         (save->p2pll_div_0 &
   2430                                 R128_P2PLL_POST0_DIV_MASK) >> 16));
   2431 }
   2432 
   2433 /* Read DDA registers. */
   2434 static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save)
   2435 {
   2436     R128InfoPtr   info      = R128PTR(pScrn);
   2437     unsigned char *R128MMIO = info->MMIO;
   2438 
   2439     save->dda_config           = INREG(R128_DDA_CONFIG);
   2440     save->dda_on_off           = INREG(R128_DDA_ON_OFF);
   2441 }
   2442 
   2443 /* Read DDA2 registers. */
   2444 static void R128SaveDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save)
   2445 {
   2446     R128InfoPtr   info      = R128PTR(pScrn);
   2447     unsigned char *R128MMIO = info->MMIO;
   2448 
   2449     save->dda2_config           = INREG(R128_DDA2_CONFIG);
   2450     save->dda2_on_off           = INREG(R128_DDA2_ON_OFF);
   2451 }
   2452 
   2453 /* Read palette data. */
   2454 static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save)
   2455 {
   2456     R128InfoPtr   info      = R128PTR(pScrn);
   2457     unsigned char *R128MMIO = info->MMIO;
   2458     int           i;
   2459 
   2460     PAL_SELECT(1);
   2461     INPAL_START(0);
   2462     for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
   2463     PAL_SELECT(0);
   2464     INPAL_START(0);
   2465     for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
   2466     save->palette_valid = TRUE;
   2467 }
   2468 
   2469 /* Save state that defines current video mode. */
   2470 static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save)
   2471 {
   2472     R128InfoPtr   info      = R128PTR(pScrn);
   2473     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
   2474 
   2475     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2476                         "%s(%p)\n", __func__, save));
   2477 
   2478     R128SaveCommonRegisters(pScrn, save);
   2479     R128SaveCrtcRegisters(pScrn, save);
   2480     R128SavePLLRegisters(pScrn, save);
   2481     R128SaveDDARegisters(pScrn, save);
   2482     if (pR128Ent->HasCRTC2) {
   2483         R128SaveCrtc2Registers(pScrn, save);
   2484         R128SavePLL2Registers(pScrn, save);
   2485         R128SaveDDA2Registers(pScrn, save);
   2486     }
   2487     if (info->HasPanelRegs) {
   2488         R128SaveFPRegisters(pScrn, save);
   2489     }
   2490     R128SavePalette(pScrn, save);
   2491 
   2492     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2493                         "%s returns %p\n", __func__, save));
   2494 }
   2495 
   2496 /* Save everything needed to restore the original VC state. */
   2497 static void R128Save(ScrnInfoPtr pScrn)
   2498 {
   2499     R128InfoPtr   info      = R128PTR(pScrn);
   2500     unsigned char *R128MMIO = info->MMIO;
   2501     R128SavePtr   save      = &info->SavedReg;
   2502 
   2503 #ifndef AVOID_FBDEV
   2504     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2505                         "%s\n", __func__));
   2506     if (info->FBDev) {
   2507 	fbdevHWSave(pScrn);
   2508 	return;
   2509     }
   2510 #endif
   2511 
   2512 #ifdef WITH_VGAHW
   2513     if (info->VGAAccess) {
   2514         vgaHWPtr hwp = VGAHWPTR(pScrn);
   2515 
   2516         vgaHWUnlock(hwp);
   2517 # if defined(__powerpc__)
   2518         /* temporary hack to prevent crashing on PowerMacs when trying to
   2519          * read VGA fonts and colormap, will find a better solution
   2520          * in the future. TODO: Check if there's actually some VGA stuff
   2521          * setup in the card at all !!
   2522          */
   2523         vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
   2524 # else
   2525         /* Save mode * & fonts & cmap */
   2526         vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
   2527 # endif
   2528         vgaHWLock(hwp);
   2529     }
   2530 #endif
   2531 
   2532     save->dp_datatype      = INREG(R128_DP_DATATYPE);
   2533     save->gen_reset_cntl   = INREG(R128_GEN_RESET_CNTL);
   2534     save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
   2535     save->amcgpio_en_reg   = INREG(R128_AMCGPIO_EN_REG);
   2536     save->amcgpio_mask     = INREG(R128_AMCGPIO_MASK);
   2537 
   2538     R128SaveMode(pScrn, save);
   2539 }
   2540 
   2541 /* Restore the original (text) mode. */
   2542 static void R128Restore(ScrnInfoPtr pScrn)
   2543 {
   2544     R128InfoPtr   info      = R128PTR(pScrn);
   2545     R128EntPtr    pR128Ent  = R128EntPriv(pScrn);
   2546     unsigned char *R128MMIO = info->MMIO;
   2547     R128SavePtr   restore   = &info->SavedReg;
   2548 
   2549 #ifndef AVOID_FBDEV
   2550     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2551                         "%s\n", __func__));
   2552     if (info->FBDev) {
   2553 	fbdevHWRestore(pScrn);
   2554 	return;
   2555     }
   2556 #endif
   2557     R128Blank(pScrn);
   2558 
   2559     OUTREG(R128_AMCGPIO_MASK,     restore->amcgpio_mask);
   2560     OUTREG(R128_AMCGPIO_EN_REG,   restore->amcgpio_en_reg);
   2561     OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
   2562     OUTREG(R128_GEN_RESET_CNTL,   restore->gen_reset_cntl);
   2563     OUTREG(R128_DP_DATATYPE,      restore->dp_datatype);
   2564 
   2565     R128RestoreCommonRegisters(pScrn, restore);
   2566     if (pR128Ent->HasCRTC2) {
   2567         R128RestoreDDA2Registers(pScrn, restore);
   2568         R128RestoreCrtc2Registers(pScrn, restore);
   2569         R128RestorePLL2Registers(pScrn, restore);
   2570     }
   2571     R128RestoreDDARegisters(pScrn, restore);
   2572     R128RestoreCrtcRegisters(pScrn, restore);
   2573     R128RestorePLLRegisters(pScrn, restore);
   2574     R128RestoreDACRegisters(pScrn, restore);
   2575     R128RestoreRMXRegisters(pScrn, restore);
   2576     R128RestoreFPRegisters(pScrn, restore);
   2577     R128RestoreLVDSRegisters(pScrn, restore);
   2578 
   2579     OUTREG(R128_AMCGPIO_MASK,     restore->amcgpio_mask);
   2580     OUTREG(R128_AMCGPIO_EN_REG,   restore->amcgpio_en_reg);
   2581     OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
   2582     OUTREG(R128_GEN_RESET_CNTL,   restore->gen_reset_cntl);
   2583     OUTREG(R128_DP_DATATYPE,      restore->dp_datatype);
   2584 
   2585 #ifdef WITH_VGAHW
   2586     if (info->VGAAccess) {
   2587         vgaHWPtr hwp = VGAHWPTR(pScrn);
   2588         vgaHWUnlock(hwp);
   2589 # if defined(__powerpc__)
   2590         /* Temporary hack to prevent crashing on PowerMacs when trying to
   2591          * write VGA fonts, will find a better solution in the future
   2592          */
   2593         vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
   2594 # else
   2595         vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
   2596 # endif
   2597         vgaHWLock(hwp);
   2598     }
   2599 #endif
   2600 
   2601     R128WaitForVerticalSync(pScrn);
   2602     R128Unblank(pScrn);
   2603 }
   2604 
   2605 /* Define common registers for requested video mode. */
   2606 void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info)
   2607 {
   2608     save->ovr_clr            = 0;
   2609     save->ovr_wid_left_right = 0;
   2610     save->ovr_wid_top_bottom = 0;
   2611     save->ov0_scale_cntl     = 0;
   2612     save->mpp_tb_config      = 0;
   2613     save->mpp_gp_config      = 0;
   2614     save->subpic_cntl        = 0;
   2615     save->viph_control       = 0;
   2616     save->i2c_cntl_1         = 0;
   2617 #ifdef R128DRI
   2618     save->gen_int_cntl       = info->gen_int_cntl;
   2619 #else
   2620     save->gen_int_cntl       = 0;
   2621 #endif
   2622     save->cap0_trig_cntl     = 0;
   2623     save->cap1_trig_cntl     = 0;
   2624     save->bus_cntl           = info->BusCntl;
   2625     /*
   2626      * If bursts are enabled, turn on discards and aborts
   2627      */
   2628     if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST))
   2629 	save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN;
   2630 }
   2631 
   2632 /* Define RMX registers for the requested video mode. */
   2633 void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save,
   2634                           xf86OutputPtr output, DisplayModePtr mode)
   2635 {
   2636     R128OutputPrivatePtr r128_output = output->driver_private;
   2637 
   2638     int   xres = mode->CrtcHDisplay;
   2639     int   yres = mode->CrtcVDisplay;
   2640     float Hratio, Vratio;
   2641 
   2642     save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
   2643     save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
   2644     save->fp_h_sync_strt_wid   = save->crtc_h_sync_strt_wid;
   2645     save->fp_v_sync_strt_wid   = save->crtc_v_sync_strt_wid;
   2646 
   2647     if (r128_output->MonType != MT_DFP && r128_output->MonType != MT_LCD)
   2648         return;
   2649 
   2650     if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) {
   2651         xres = r128_output->PanelXRes;
   2652         yres = r128_output->PanelYRes;
   2653 
   2654         Hratio = 1.0;
   2655         Vratio = 1.0;
   2656     } else {
   2657         if (xres > r128_output->PanelXRes) xres = r128_output->PanelXRes;
   2658         if (yres > r128_output->PanelYRes) yres = r128_output->PanelYRes;
   2659 
   2660         Hratio = (float)xres/(float)r128_output->PanelXRes;
   2661         Vratio = (float)yres/(float)r128_output->PanelYRes;
   2662     }
   2663 
   2664     save->fp_horz_stretch =
   2665 	(((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
   2666 	   & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) |
   2667        (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE |
   2668                                  R128_HORZ_FP_LOOP_STRETCH |
   2669                                  R128_HORZ_STRETCH_RESERVED)));
   2670     save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
   2671     save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO;
   2672     if (xres == r128_output->PanelXRes)
   2673          save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
   2674     else
   2675          save->fp_horz_stretch |=  (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
   2676 
   2677     save->fp_vert_stretch =
   2678 	(((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5))
   2679 	   & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) |
   2680 	 (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
   2681 				   R128_VERT_STRETCH_RESERVED)));
   2682     save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
   2683     if (yres == r128_output->PanelYRes)
   2684         save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
   2685     else
   2686         save->fp_vert_stretch |=  (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
   2687 }
   2688 
   2689 /* Define flat panel registers for the requested video mode. */
   2690 void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
   2691 {
   2692     xf86CrtcPtr crtc = output->crtc;
   2693     R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
   2694 
   2695     /* WARNING: Be careful about turning on the flat panel */
   2696     save->fp_gen_cntl            = orig->fp_gen_cntl;
   2697     save->fp_panel_cntl          = orig->fp_panel_cntl;
   2698     save->tmds_transmitter_cntl  = orig->tmds_transmitter_cntl;
   2699     save->tmds_crc               = orig->tmds_crc;
   2700 
   2701     if (r128_crtc->crtc_id)
   2702         save->fp_gen_cntl       |=   R128_FP_SEL_CRTC2;
   2703     else
   2704         save->fp_gen_cntl       &=  ~R128_FP_SEL_CRTC2;
   2705 
   2706     save->fp_gen_cntl           &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
   2707                                      R128_FP_CRTC_USE_SHADOW_ROWCUR |
   2708                                      R128_FP_CRTC_HORZ_DIV2_EN |
   2709                                      R128_FP_CRTC_HOR_CRT_DIV2_DIS |
   2710                                      R128_FP_CRT_SYNC_SEL |
   2711                                      R128_FP_USE_SHADOW_EN);
   2712 
   2713     save->fp_gen_cntl           |=  (R128_FP_CRTC_DONT_SHADOW_VPAR |
   2714                                      R128_FP_CRTC_DONT_SHADOW_HEND);
   2715 
   2716     save->fp_panel_cntl         |=  (R128_FP_DIGON | R128_FP_BLON);
   2717     save->tmds_transmitter_cntl &=  ~R128_TMDS_PLLRST;
   2718     save->tmds_transmitter_cntl |=   R128_TMDS_PLLEN;
   2719 }
   2720 
   2721 /* Define LVDS registers for the requested video mode. */
   2722 void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save, xf86OutputPtr output)
   2723 {
   2724     xf86CrtcPtr crtc = output->crtc;
   2725     R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
   2726 
   2727     save->lvds_gen_cntl      =  orig->lvds_gen_cntl;
   2728 
   2729     if (r128_crtc->crtc_id)
   2730         save->lvds_gen_cntl |=  R128_LVDS_SEL_CRTC2;
   2731     else
   2732         save->lvds_gen_cntl &= ~R128_LVDS_SEL_CRTC2;
   2733 }
   2734 
   2735 #if 0
   2736 /* Define initial palette for requested video mode.  This doesn't do
   2737    anything for XFree86 4.0. */
   2738 static void R128InitPalette(R128SavePtr save)
   2739 {
   2740     save->palette_valid = FALSE;
   2741 }
   2742 #endif
   2743 
   2744 static Bool R128SaveScreen(ScreenPtr pScreen, int mode)
   2745 {
   2746     ScrnInfoPtr   pScrn = xf86ScreenToScrn(pScreen);
   2747     Bool unblank;
   2748 
   2749     unblank = xf86IsUnblank(mode);
   2750     if (unblank)
   2751 	SetTimeSinceLastInputEvent();
   2752 
   2753     if ((pScrn != NULL) && pScrn->vtSema) {
   2754 	if (unblank)
   2755 		R128Unblank(pScrn);
   2756 	else
   2757 		R128Blank(pScrn);
   2758     }
   2759     return TRUE;
   2760 }
   2761 
   2762 /*
   2763  * SwitchMode() doesn't work right on crtc2 on some laptops.
   2764  * The workaround is to switch the mode, then switch to another VT, then
   2765  * switch back. --AGD
   2766  */
   2767 Bool R128SwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
   2768 {
   2769     R128InfoPtr info        = R128PTR(pScrn);
   2770     Bool ret;
   2771 
   2772     info->SwitchingMode = TRUE;
   2773     ret = xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
   2774     info->SwitchingMode = FALSE;
   2775     return ret;
   2776 }
   2777 
   2778 ModeStatus R128DoValidMode(xf86OutputPtr output, DisplayModePtr mode, int flags)
   2779 {
   2780     ScrnInfoPtr pScrn = output->scrn;
   2781     R128InfoPtr info  = R128PTR(pScrn);
   2782     R128OutputPrivatePtr r128_output = output->driver_private;
   2783     int i, j;
   2784 
   2785     if (r128_output->MonType == MT_CRT)
   2786         return MODE_OK;
   2787 
   2788     if (r128_output->MonType == MT_DFP || r128_output->MonType == MT_LCD) {
   2789 	if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
   2790 	if (mode->Flags & V_DBLSCAN)   return MODE_NO_DBLESCAN;
   2791     }
   2792 
   2793     if (r128_output->MonType == MT_LCD && info->VBIOS) {
   2794 	for (i = info->FPBIOSstart + 64; R128_BIOS16(i) != 0; i += 2) {
   2795 	    j = R128_BIOS16(i);
   2796 
   2797 	    if (mode->CrtcHDisplay == R128_BIOS16(j) &&
   2798 		mode->CrtcVDisplay == R128_BIOS16(j + 2)) {
   2799 		if ((flags & MODECHECK_FINAL) == MODECHECK_FINAL) {
   2800 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2801 			       "Modifying mode according to VBIOS: %ix%i [pclk %.1f MHz] for FP to: ",
   2802 			       mode->CrtcHDisplay, mode->CrtcVDisplay,
   2803 			       (float)mode->Clock / 1000);
   2804 
   2805 		    /* Assume we are using expanded mode */
   2806 		    if (R128_BIOS16(j + 5)) j  = R128_BIOS16(j + 5);
   2807 		    else                    j += 9;
   2808 
   2809 		    mode->Clock = (uint32_t)R128_BIOS16(j) * 10;
   2810 
   2811 		    mode->HDisplay   = mode->CrtcHDisplay   =
   2812 			((R128_BIOS16(j + 10) & 0x01ff) + 1) * 8;
   2813 		    mode->HSyncStart = mode->CrtcHSyncStart =
   2814 			((R128_BIOS16(j + 12) & 0x01ff) + 1) * 8;
   2815 		    mode->HSyncEnd   = mode->CrtcHSyncEnd   =
   2816 			mode->CrtcHSyncStart + (R128_BIOS8(j + 14) & 0x1f);
   2817 		    mode->HTotal     = mode->CrtcHTotal     =
   2818 			((R128_BIOS16(j + 8)  & 0x01ff) + 1) * 8;
   2819 
   2820 		    mode->VDisplay   = mode->CrtcVDisplay   =
   2821 			(R128_BIOS16(j + 17) & 0x07ff) + 1;
   2822 		    mode->VSyncStart = mode->CrtcVSyncStart =
   2823 			(R128_BIOS16(j + 19) & 0x07ff) + 1;
   2824 		    mode->VSyncEnd   = mode->CrtcVSyncEnd   =
   2825 			mode->CrtcVSyncStart + ((R128_BIOS16(j + 19) >> 11) & 0x1f);
   2826 		    mode->VTotal     = mode->CrtcVTotal     =
   2827 			(R128_BIOS16(j + 15) & 0x07ff) + 1;
   2828 		    xf86ErrorF("%ix%i [pclk %.1f MHz]\n",
   2829 			       mode->CrtcHDisplay,mode->CrtcVDisplay,
   2830 			       (float)mode->Clock/ 1000);
   2831 		}
   2832 		return MODE_OK;
   2833 	    }
   2834 	}
   2835 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5,
   2836 		       "Mode rejected for FP %ix%i [pclk: %.1f] "
   2837 		       "(not listed in VBIOS)\n",
   2838 		       mode->CrtcHDisplay, mode->CrtcVDisplay,
   2839 		       (float)mode->Clock / 1000);
   2840 	return MODE_NOMODE;
   2841     }
   2842 
   2843     return MODE_OK;
   2844 }
   2845 
   2846 /* Used to disallow modes that are not supported by the hardware. */
   2847 ModeStatus R128ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
   2848                                    Bool verbose, int flags)
   2849 {
   2850     R128EntPtr  pR128Ent = R128EntPriv(pScrn);
   2851     xf86OutputPtr output = R128FirstOutput(pR128Ent->pCrtc[0]);
   2852 
   2853     return R128DoValidMode(output, mode, flags);
   2854 }
   2855 
   2856 /* Adjust viewport into virtual desktop such that (0,0) in viewport space
   2857    is (x,y) in virtual space. */
   2858 void R128AdjustFrame(ScrnInfoPtr pScrn, int x, int y)
   2859 {
   2860     R128InfoPtr   info      = R128PTR(pScrn);
   2861     unsigned char *R128MMIO = info->MMIO;
   2862     int           Base;
   2863 
   2864     if(info->showCache && y && pScrn->vtSema)
   2865         y += pScrn->virtualY - 1;
   2866 
   2867     Base = y * info->CurrentLayout.displayWidth + x;
   2868 
   2869     switch (info->CurrentLayout.pixel_code) {
   2870     case 15:
   2871     case 16: Base *= 2; break;
   2872     case 24: Base *= 3; break;
   2873     case 32: Base *= 4; break;
   2874     }
   2875 
   2876     Base &= ~7;                 /* 3 lower bits are always 0 */
   2877 
   2878     if (info->CurrentLayout.pixel_code == 24)
   2879 	Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */
   2880 
   2881     OUTREG(R128_CRTC_OFFSET, Base);
   2882 }
   2883 
   2884 /* Called when VT switching back to the X server.  Reinitialize the video
   2885    mode. */
   2886 Bool R128EnterVT(ScrnInfoPtr pScrn)
   2887 {
   2888     R128InfoPtr info  = R128PTR(pScrn);
   2889 
   2890     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2891                         "%s\n", __func__));
   2892 
   2893     pScrn->vtSema = TRUE;
   2894 #ifndef AVOID_FBDEV
   2895     if (info->FBDev) {
   2896         if (!fbdevHWEnterVT(pScrn)) return FALSE;
   2897     } else {
   2898 #endif
   2899 	if (!xf86SetDesiredModes(pScrn)) return FALSE;
   2900 #ifndef AVOID_FBDEV
   2901     }
   2902 #endif
   2903 
   2904     if (info->accelOn)
   2905 	R128EngineInit(pScrn);
   2906 
   2907 #ifdef R128DRI
   2908     if (info->directRenderingEnabled) {
   2909 	if (info->irq) {
   2910 	    /* Need to make sure interrupts are enabled */
   2911 	    unsigned char *R128MMIO = info->MMIO;
   2912 	    OUTREG(R128_GEN_INT_CNTL, info->gen_int_cntl);
   2913 	}
   2914 	R128CCE_START(pScrn, info);
   2915 	DRIUnlock(pScrn->pScreen);
   2916     }
   2917 #endif
   2918 
   2919     info->PaletteSavedOnVT = FALSE;
   2920     //pScrn->AdjustFrame(pScrn, pScrn->frameX0, pScrn->frameY0);
   2921 
   2922     return TRUE;
   2923 }
   2924 
   2925 /* Called when VT switching away from the X server.  Restore the original
   2926    text mode. */
   2927 void R128LeaveVT(ScrnInfoPtr pScrn)
   2928 {
   2929     R128InfoPtr info  = R128PTR(pScrn);
   2930     R128SavePtr save  = &info->ModeReg;
   2931 
   2932     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2933                         "%s\n", __func__));
   2934 #ifdef R128DRI
   2935     if (info->directRenderingEnabled) {
   2936 	DRILock(pScrn->pScreen, 0);
   2937 	R128CCE_STOP(pScrn, info);
   2938     }
   2939 #ifdef USE_EXA
   2940     if (info->useEXA)
   2941         info->state_2d.composite_setup = FALSE;
   2942 #endif
   2943 #endif
   2944     R128SavePalette(pScrn, save);
   2945     info->PaletteSavedOnVT = TRUE;
   2946 #ifndef AVOID_FBDEV
   2947     if (info->FBDev)
   2948         fbdevHWLeaveVT(pScrn);
   2949     else
   2950 #endif
   2951         R128Restore(pScrn);
   2952 }
   2953 
   2954 
   2955 /* Called at the end of each server generation.  Restore the original text
   2956    mode, unmap video memory, and unwrap and call the saved CloseScreen
   2957    function.  */
   2958 static Bool R128CloseScreen(ScreenPtr pScreen)
   2959 {
   2960     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   2961     R128InfoPtr info  = R128PTR(pScrn);
   2962 
   2963     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   2964                         "%s\n", __func__));
   2965 
   2966 #ifdef R128DRI
   2967 				/* Disable direct rendering */
   2968     if (info->directRenderingEnabled) {
   2969 	R128DRICloseScreen(pScreen);
   2970 	info->directRenderingEnabled = FALSE;
   2971     }
   2972 #endif
   2973 
   2974     if (pScrn->vtSema) {
   2975 	R128Restore(pScrn);
   2976 	R128UnmapMem(pScrn);
   2977     }
   2978 
   2979 #ifdef USE_EXA
   2980     if (info->useEXA) {
   2981 	exaDriverFini(pScreen);
   2982 	free(info->ExaDriver);
   2983     }
   2984 #endif
   2985 
   2986     if (info->scratch_save)      free(info->scratch_save);
   2987     info->scratch_save           = NULL;
   2988 
   2989     if (info->adaptor) {
   2990         free(info->adaptor->pPortPrivates[0].ptr);
   2991 	xf86XVFreeVideoAdaptorRec(info->adaptor);
   2992 	info->adaptor = NULL;
   2993     }
   2994 
   2995     pScrn->vtSema = FALSE;
   2996 
   2997     pScreen->BlockHandler = info->BlockHandler;
   2998     pScreen->CloseScreen = info->CloseScreen;
   2999     return (*pScreen->CloseScreen)(pScreen);
   3000 }
   3001 
   3002 void R128FreeScreen(ScrnInfoPtr pScrn)
   3003 {
   3004     R128InfoPtr   info      = R128PTR(pScrn);
   3005 
   3006     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
   3007                         "%s\n", __func__));
   3008     if (info == NULL)
   3009 	return;
   3010 #ifdef WITH_VGAHW
   3011     if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
   3012 	vgaHWFreeHWRec(pScrn);
   3013 #endif
   3014     R128FreeRec(pScrn);
   3015 }
   3016