diff options
Diffstat (limited to 'src/r128_driver.c')
-rw-r--r-- | src/r128_driver.c | 3676 |
1 files changed, 0 insertions, 3676 deletions
diff --git a/src/r128_driver.c b/src/r128_driver.c deleted file mode 100644 index d990610c..00000000 --- a/src/r128_driver.c +++ /dev/null @@ -1,3676 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.79 2003/08/23 15:02:54 dawes Exp $ */ -/* - * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, - * Precision Insight, Inc., Cedar Park, Texas, and - * VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX - * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Authors: - * Rickard E. Faith <faith@valinux.com> - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * - * Credits: - * - * Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for - * providing source code to their 3.3.x Rage 128 driver. Portions of - * this file are based on the initialization code for that driver. - * - * References: - * - * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical - * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April - * 1999. - * - * RAGE 128 Software Development Manual (Technical Reference Manual P/N - * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. - * - * This server does not yet support these XFree86 4.0 features: - * DDC1 & DDC2 - * shadowfb - * overlay planes - * - * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. - */ - - - /* Driver data structures */ -#include "r128.h" -#include "r128_probe.h" -#include "r128_reg.h" -#include "r128_version.h" - -#ifdef XF86DRI -#define _XF86DRI_SERVER_ -#include "r128_dri.h" -#include "r128_common.h" -#include "r128_sarea.h" -#endif - -#include "fb.h" - - /* colormap initialization */ -#include "micmap.h" - - /* X and server generic header files */ -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86PciInfo.h" -#include "xf86RAC.h" -#include "xf86Resources.h" -#include "xf86cmap.h" -#include "xf86xv.h" -#include "vbe.h" - - /* fbdevhw & vgahw */ -#include "fbdevhw.h" -#include "vgaHW.h" -#include "dixstruct.h" - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#define USE_CRT_ONLY 0 - - /* Forward definitions for driver functions */ -static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool R128SaveScreen(ScreenPtr pScreen, int mode); -static void R128Save(ScrnInfoPtr pScrn); -static void R128Restore(ScrnInfoPtr pScrn); -static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); -static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn, - int PowerManagementMode, int flags); -static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn, - int PowerManagementMode, int flags); - -typedef enum { - OPTION_NOACCEL, - OPTION_SW_CURSOR, - OPTION_DAC_6BIT, - OPTION_DAC_8BIT, -#ifdef XF86DRI - OPTION_XV_DMA, - OPTION_IS_PCI, - OPTION_CCE_PIO, - OPTION_NO_SECURITY, - OPTION_USEC_TIMEOUT, - OPTION_AGP_MODE, - OPTION_AGP_SIZE, - OPTION_RING_SIZE, - OPTION_BUFFER_SIZE, - OPTION_PAGE_FLIP, -#endif -#if USE_CRT_ONLY - /* FIXME: Disable CRTOnly until it is tested */ - OPTION_CRT, -#endif - OPTION_DISPLAY, - OPTION_PANEL_WIDTH, - OPTION_PANEL_HEIGHT, - OPTION_PROG_FP_REGS, - OPTION_FBDEV, - OPTION_VIDEO_KEY, - OPTION_SHOW_CACHE -} R128Opts; - -const OptionInfoRec R128Options[] = { - { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE }, -#ifdef XF86DRI - { OPTION_XV_DMA, "DMAForXv", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CCE_PIO, "CCEPIOMode", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_NO_SECURITY, "CCENoSecurity", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_USEC_TIMEOUT, "CCEusecTimeout", OPTV_INTEGER, {0}, FALSE }, - { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, - { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE }, -#endif - { OPTION_DISPLAY, "Display", OPTV_STRING, {0}, FALSE }, - { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, - { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, - { OPTION_PROG_FP_REGS, "ProgramFPRegs", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, - { OPTION_SHOW_CACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE } -}; - -R128RAMRec R128RAM[] = { /* Memory Specifications - From RAGE 128 Software Development - Manual (Technical Reference Manual P/N - SDK-G04000 Rev 0.01), page 3-21. */ - { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, - { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, - { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, - { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, -}; - -static const char *vgahwSymbols[] = { - "vgaHWFreeHWRec", - "vgaHWGetHWRec", - "vgaHWGetIndex", - "vgaHWLock", - "vgaHWRestore", - "vgaHWSave", - "vgaHWUnlock", - NULL -}; - -static const char *fbdevHWSymbols[] = { - "fbdevHWInit", - "fbdevHWUseBuildinMode", - "fbdevHWGetLineLength", - "fbdevHWGetVidmem", - - "fbdevHWDPMSSet", - - /* colormap */ - "fbdevHWLoadPalette", - - /* ScrnInfo hooks */ - "fbdevHWAdjustFrame", - "fbdevHWEnterVT", - "fbdevHWLeaveVT", - "fbdevHWModeInit", - "fbdevHWRestore", - "fbdevHWSave", - "fbdevHWSwitchMode", - "fbdevHWValidMode", - - "fbdevHWMapMMIO", - "fbdevHWMapVidmem", - "fbdevHWUnmapMMIO", - "fbdevHWUnmapVidmem", - - NULL -}; - -static const char *ddcSymbols[] = { - "xf86PrintEDID", - "xf86DoEDID_DDC1", - "xf86DoEDID_DDC2", - NULL -}; - -static const char *i2cSymbols[] = { - "xf86CreateI2CBusRec", - "xf86I2CBusInit", - NULL -}; - -static const char *fbSymbols[] = { - "fbPictureInit", - "fbScreenInit", - NULL -}; - -static const char *xaaSymbols[] = { - "XAACreateInfoRec", - "XAADestroyInfoRec", - "XAAInit", - NULL -}; - -static const char *ramdacSymbols[] = { - "xf86CreateCursorInfoRec", - "xf86DestroyCursorInfoRec", - "xf86InitCursor", - NULL -}; - -#ifdef XF86DRI -static const char *drmSymbols[] = { - "drmAddBufs", - "drmAddMap", - "drmAgpAcquire", - "drmAgpAlloc", - "drmAgpBase", - "drmAgpBind", - "drmAgpDeviceId", - "drmAgpEnable", - "drmAgpFree", - "drmAgpGetMode", - "drmAgpRelease", - "drmAgpUnbind", - "drmAgpVendorId", - "drmAvailable", - "drmCommandNone", - "drmCommandRead", - "drmCommandWrite", - "drmCommandWriteRead", - "drmCtlInstHandler", - "drmCtlUninstHandler", - "drmFreeBufs", - "drmFreeVersion", - "drmGetInterruptFromBusID", - "drmGetLibVersion", - "drmGetVersion", - "drmMap", - "drmMapBufs", - "drmDMA", - "drmScatterGatherAlloc", - "drmScatterGatherFree", - "drmUnmap", - "drmUnmapBufs", - NULL -}; - -static const char *driSymbols[] = { - "DRICloseScreen", - "DRICreateInfoRec", - "DRIDestroyInfoRec", - "DRIFinishScreenInit", - "DRIGetDeviceInfo", - "DRIGetSAREAPrivate", - "DRILock", - "DRIQueryVersion", - "DRIScreenInit", - "DRIUnlock", - "GlxSetVisualConfigs", - "DRICreatePCIBusID", - NULL -}; - -static const char *driShadowFBSymbols[] = { - "ShadowFBInit", - NULL -}; -#endif - -static const char *vbeSymbols[] = { - "VBEInit", - "vbeDoEDID", - "vbeFree", - NULL -}; - -static const char *int10Symbols[] = { - "xf86InitInt10", - "xf86FreeInt10", - "xf86int10Addr", - NULL -}; - -void R128LoaderRefSymLists(void) -{ - /* - * Tell the loader about symbols from other modules that this module might - * refer to. - */ - xf86LoaderRefSymLists(vgahwSymbols, - fbSymbols, - xaaSymbols, - ramdacSymbols, -#ifdef XF86DRI - drmSymbols, - driSymbols, - driShadowFBSymbols, -#endif - fbdevHWSymbols, - int10Symbols, - vbeSymbols, - /* ddcsymbols, */ - i2cSymbols, - /* shadowSymbols, */ - NULL); -} - -/* Allocate our private R128InfoRec. */ -static Bool R128GetRec(ScrnInfoPtr pScrn) -{ - if (pScrn->driverPrivate) return TRUE; - - pScrn->driverPrivate = xnfcalloc(sizeof(R128InfoRec), 1); - return TRUE; -} - -/* Free our private R128InfoRec. */ -static void R128FreeRec(ScrnInfoPtr pScrn) -{ - if (!pScrn || !pScrn->driverPrivate) return; - xfree(pScrn->driverPrivate); - pScrn->driverPrivate = NULL; -} - -/* Memory map the MMIO region. Used during pre-init and by R128MapMem, - below. */ -static Bool R128MapMMIO(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (info->FBDev) { - info->MMIO = fbdevHWMapMMIO(pScrn); - } else { - info->MMIO = xf86MapPciMem(pScrn->scrnIndex, - VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, - info->PciTag, - info->MMIOAddr, - R128_MMIOSIZE); - } - - if (!info->MMIO) return FALSE; - return TRUE; -} - -/* Unmap the MMIO region. Used during pre-init and by R128UnmapMem, - below. */ -static Bool R128UnmapMMIO(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (info->FBDev) - fbdevHWUnmapMMIO(pScrn); - else { - xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE); - } - info->MMIO = NULL; - return TRUE; -} - -/* Memory map the frame buffer. Used by R128MapMem, below. */ -static Bool R128MapFB(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (info->FBDev) { - info->FB = fbdevHWMapVidmem(pScrn); - } else { - info->FB = xf86MapPciMem(pScrn->scrnIndex, - VIDMEM_FRAMEBUFFER, - info->PciTag, - info->LinearAddr, - info->FbMapSize); - } - - if (!info->FB) return FALSE; - return TRUE; -} - -/* Unmap the frame buffer. Used by R128UnmapMem, below. */ -static Bool R128UnmapFB(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (info->FBDev) - fbdevHWUnmapVidmem(pScrn); - else - xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); - info->FB = NULL; - return TRUE; -} - -/* Memory map the MMIO region and the frame buffer. */ -static Bool R128MapMem(ScrnInfoPtr pScrn) -{ - if (!R128MapMMIO(pScrn)) return FALSE; - if (!R128MapFB(pScrn)) { - R128UnmapMMIO(pScrn); - return FALSE; - } - return TRUE; -} - -/* Unmap the MMIO region and the frame buffer. */ -static Bool R128UnmapMem(ScrnInfoPtr pScrn) -{ - if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE; - return TRUE; -} - -/* Read PLL information */ -unsigned R128INPLL(ScrnInfoPtr pScrn, int addr) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); - return INREG(R128_CLOCK_CNTL_DATA); -} - -#if 0 -/* Read PAL information (only used for debugging). */ -static int R128INPAL(int idx) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTREG(R128_PALETTE_INDEX, idx << 16); - return INREG(R128_PALETTE_DATA); -} -#endif - -/* Wait for vertical sync. */ -void R128WaitForVerticalSync(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int i; - - OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); - for (i = 0; i < R128_TIMEOUT; i++) { - if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; - } -} - -/* Blank screen. */ -static void R128Blank(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - if(info->isDFP) - OUTREGP(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, ~R128_FP_BLANK_DIS); - else - OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS); -} - -/* Unblank screen. */ -static void R128Unblank(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - if(info->isDFP) - OUTREGP(R128_FP_GEN_CNTL, 0, ~R128_FP_BLANK_DIS); - else - OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS); -} - -/* Compute log base 2 of val. */ -int R128MinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - -/* Compute n/d with rounding. */ -static int R128Div(int n, int d) -{ - return (n + (d / 2)) / d; -} - -/* Read the Video BIOS block and the FP registers (if applicable). */ -static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) -{ - R128InfoPtr info = R128PTR(pScrn); - int i; - int FPHeader = 0; - -#define R128_BIOS8(v) (info->VBIOS[v]) -#define R128_BIOS16(v) (info->VBIOS[v] | \ - (info->VBIOS[(v) + 1] << 8)) -#define R128_BIOS32(v) (info->VBIOS[v] | \ - (info->VBIOS[(v) + 1] << 8) | \ - (info->VBIOS[(v) + 2] << 16) | \ - (info->VBIOS[(v) + 3] << 24)) - - if (!(info->VBIOS = xalloc(R128_VBIOS_SIZE))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Cannot allocate space for hold Video BIOS!\n"); - return FALSE; - } - - if (pInt10) { - info->BIOSAddr = pInt10->BIOSseg << 4; - (void)memcpy(info->VBIOS, xf86int10Addr(pInt10, info->BIOSAddr), - R128_VBIOS_SIZE); - } else { - xf86ReadPciBIOS(0, info->PciTag, 0, info->VBIOS, R128_VBIOS_SIZE); - if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS not detected in PCI space!\n"); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Attempting to read Video BIOS from legacy ISA space!\n"); - info->BIOSAddr = 0x000c0000; - xf86ReadDomainMemory(info->PciTag, info->BIOSAddr, R128_VBIOS_SIZE, info->VBIOS); - } - } - if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { - info->BIOSAddr = 0x00000000; - xfree(info->VBIOS); - info->VBIOS = NULL; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS not found!\n"); - } - - if (info->VBIOS && info->HasPanelRegs) { - info->FPBIOSstart = 0; - - /* FIXME: There should be direct access to the start of the FP info - tables, but until we find out where that offset is stored, we - must search for the ATI signature string: "M3 ". */ - for (i = 4; i < R128_VBIOS_SIZE-8; i++) { - if (R128_BIOS8(i) == 'M' && - R128_BIOS8(i+1) == '3' && - R128_BIOS8(i+2) == ' ' && - R128_BIOS8(i+3) == ' ' && - R128_BIOS8(i+4) == ' ' && - R128_BIOS8(i+5) == ' ' && - R128_BIOS8(i+6) == ' ' && - R128_BIOS8(i+7) == ' ') { - FPHeader = i-2; - break; - } - } - - if (!FPHeader) return TRUE; - - /* Assume that only one panel is attached and supported */ - for (i = FPHeader+20; i < FPHeader+84; i += 2) { - if (R128_BIOS16(i) != 0) { - info->FPBIOSstart = R128_BIOS16(i); - break; - } - } - if (!info->FPBIOSstart) return TRUE; - - if (!info->PanelXRes) - info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25); - if (!info->PanelYRes) - info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", - info->PanelXRes, info->PanelYRes); - - info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); - for (i = 1; i <= 24; i++) - ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i)); - ErrorF("\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); - i = R128_BIOS16(info->FPBIOSstart+29); - if (i & 1) ErrorF("Color, "); - else ErrorF("Monochrome, "); - if (i & 2) ErrorF("Dual(split), "); - else ErrorF("Single, "); - switch ((i >> 2) & 0x3f) { - case 0: ErrorF("STN"); break; - case 1: ErrorF("TFT"); break; - case 2: ErrorF("Active STN"); break; - case 3: ErrorF("EL"); break; - case 4: ErrorF("Plasma"); break; - default: ErrorF("UNKNOWN"); break; - } - ErrorF("\n"); - if (R128_BIOS8(info->FPBIOSstart+61) & 1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); - } else { - /* FIXME: Add Non-LVDS flat pael support */ - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Non-LVDS panel interface detected! " - "This support is untested and may not " - "function properly\n"); - } - } - - if (!info->PanelXRes || !info->PanelYRes) { - info->HasPanelRegs = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Can't determine panel dimensions, and none specified. \ - Disabling programming of FP registers.\n"); - } - - return TRUE; -} - -/* Read PLL parameters from BIOS block. Default to typical values if there - is no BIOS. */ -static Bool R128GetPLLParameters(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - R128PLLPtr pll = &info->pll; - -#if defined(__powerpc__) || defined(__alpha__) - /* there is no bios under Linux PowerPC but Open Firmware - does set up the PLL registers properly and we can use - those to calculate xclk and find the reference divider */ - - unsigned x_mpll_ref_fb_div; - unsigned xclk_cntl; - unsigned Nx, M; - unsigned PostDivSet[] = {0, 1, 2, 4, 8, 3, 6, 12}; - - /* Assume REF clock is 2950 (in units of 10khz) */ - /* and that all pllclk must be between 125 Mhz and 250Mhz */ - pll->reference_freq = 2950; - pll->min_pll_freq = 12500; - pll->max_pll_freq = 25000; - - /* need to memory map the io to use INPLL since it - has not been done yet at this point in the startup */ - R128MapMMIO(pScrn); - x_mpll_ref_fb_div = INPLL(pScrn, R128_X_MPLL_REF_FB_DIV); - xclk_cntl = INPLL(pScrn, R128_XCLK_CNTL) & 0x7; - pll->reference_div = - INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK; - /* unmap it again */ - R128UnmapMMIO(pScrn); - - Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8; - M = (x_mpll_ref_fb_div & 0x0000FF); - - pll->xclk = R128Div((2 * Nx * pll->reference_freq), - (M * PostDivSet[xclk_cntl])); - -#else /* !defined(__powerpc__) */ - - if (!info->VBIOS) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS not detected, using default PLL parameters!\n"); - /* These probably aren't going to work for - the card you are using. Specifically, - reference freq can be 29.50MHz, - 28.63MHz, or 14.32MHz. YMMV. */ - pll->reference_freq = 2950; - pll->reference_div = 65; - pll->min_pll_freq = 12500; - pll->max_pll_freq = 25000; - pll->xclk = 10300; - } else { - CARD16 bios_header = R128_BIOS16(0x48); - CARD16 pll_info_block = R128_BIOS16(bios_header + 0x30); - R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n", - bios_header, pll_info_block)); - - pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e); - pll->reference_div = R128_BIOS16(pll_info_block + 0x10); - pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12); - pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16); - pll->xclk = R128_BIOS16(pll_info_block + 0x08); - } -#endif /* __powerpc__ */ - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", - pll->reference_freq, - pll->reference_div, - pll->min_pll_freq, - pll->max_pll_freq, - pll->xclk); - - return TRUE; -} - -/* This is called by R128PreInit to set up the default visual. */ -static Bool R128PreInitVisual(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (!xf86SetDepthBpp(pScrn, 0, 0, 0, (Support24bppFb - | Support32bppFb - | SupportConvert32to24 - ))) - return FALSE; - - switch (pScrn->depth) { - case 8: - case 15: - case 16: - case 24: - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported by %s driver\n", - pScrn->depth, R128_DRIVER_NAME); - return FALSE; - } - - xf86PrintDepthBpp(pScrn); - - info->fifo_slots = 0; - info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); - info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; - info->CurrentLayout.depth = pScrn->depth; - info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; - info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 - ? pScrn->bitsPerPixel - : pScrn->depth); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", - pScrn->depth, - info->CurrentLayout.pixel_bytes, - info->CurrentLayout.pixel_bytes > 1 ? "s" : "", - info->pix24bpp); - - - if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - - if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Default visual (%s) is not supported at depth %d\n", - xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); - return FALSE; - } - return TRUE; - -} - -/* This is called by R128PreInit to handle all color weight issues. */ -static Bool R128PreInitWeight(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - /* Save flag for 6 bit DAC to use for - setting CRTC registers. Otherwise use - an 8 bit DAC, even if xf86SetWeight sets - pScrn->rgbBits to some value other than - 8. */ - info->dac6bits = FALSE; - if (pScrn->depth > 8) { - rgb defaultWeight = { 0, 0, 0 }; - if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; - } else { - pScrn->rgbBits = 8; - if (xf86ReturnOptValBool(info->Options, OPTION_DAC_6BIT, FALSE)) { - pScrn->rgbBits = 6; - info->dac6bits = TRUE; - } - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d bits per RGB (%d bit DAC)\n", - pScrn->rgbBits, info->dac6bits ? 6 : 8); - - return TRUE; - -} - -/* This is called by R128PreInit to handle config file overrides for things - like chipset and memory regions. Also determine memory size and type. - If memory type ever needs an override, put it in this routine. */ -static Bool R128PreInitConfig(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - EntityInfoPtr pEnt = info->pEnt; - GDevPtr dev = pEnt->device; - int offset = 0; /* RAM Type */ - MessageType from; - - /* Chipset */ - from = X_PROBED; - if (dev->chipset && *dev->chipset) { - info->Chipset = xf86StringToToken(R128Chipsets, dev->chipset); - from = X_CONFIG; - } else if (dev->chipID >= 0) { - info->Chipset = dev->chipID; - from = X_CONFIG; - } else { - info->Chipset = info->PciInfo->chipType; - } - pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset); - - if (!pScrn->chipset) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ChipID 0x%04x is not recognized\n", info->Chipset); - return FALSE; - } - - if (info->Chipset < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Chipset \"%s\" is not recognized\n", pScrn->chipset); - return FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, from, - "Chipset: \"%s\" (ChipID = 0x%04x)\n", - pScrn->chipset, - info->Chipset); - - /* Framebuffer */ - - from = X_PROBED; - info->LinearAddr = info->PciInfo->memBase[0] & 0xfc000000; - pScrn->memPhysBase = info->LinearAddr; - if (dev->MemBase) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Linear address override, using 0x%08x instead of 0x%08x\n", - dev->MemBase, - info->LinearAddr); - info->LinearAddr = dev->MemBase; - from = X_CONFIG; - } else if (!info->LinearAddr) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid linear framebuffer address\n"); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, from, - "Linear framebuffer at 0x%08lx\n", info->LinearAddr); - - /* MMIO registers */ - from = X_PROBED; - info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; - if (dev->IOBase) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MMIO address override, using 0x%08x instead of 0x%08x\n", - dev->IOBase, - info->MMIOAddr); - info->MMIOAddr = dev->IOBase; - from = X_CONFIG; - } else if (!info->MMIOAddr) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, from, - "MMIO registers at 0x%08lx\n", info->MMIOAddr); - - /* BIOS */ - from = X_PROBED; - info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; - if (dev->BiosBase) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS address override, using 0x%08x instead of 0x%08x\n", - dev->BiosBase, - info->BIOSAddr); - info->BIOSAddr = dev->BiosBase; - from = X_CONFIG; - } - if (info->BIOSAddr) { - xf86DrvMsg(pScrn->scrnIndex, from, - "BIOS at 0x%08lx\n", info->BIOSAddr); - } - - /* Flat panel (part 1) */ - if (xf86GetOptValBool(info->Options, OPTION_PROG_FP_REGS, - &info->HasPanelRegs)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Turned flat panel register programming %s\n", - info->HasPanelRegs ? "on" : "off"); - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "\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"); - } else { - info->isDFP = FALSE; - info->isPro2 = FALSE; - switch (info->Chipset) { - /* R128 Pro and Pro2 can have DFP, we will deal with it. - No support for dual-head/xinerama yet. - M3 can also have DFP, no support for now */ - case PCI_CHIP_RAGE128TF: - case PCI_CHIP_RAGE128TL: - case PCI_CHIP_RAGE128TR: - /* FIXME: RAGE128 TS/TT/TU are assumed to be PRO2 as all 6 chips came - * out at the same time, so are of the same family likely. - * This requires confirmation however to be fully correct. - * Mike A. Harris <mharris@redhat.com> - */ - case PCI_CHIP_RAGE128TS: - case PCI_CHIP_RAGE128TT: - case PCI_CHIP_RAGE128TU: info->isPro2 = TRUE; - /* FIXME: RAGE128 P[ABCEGHIJKLMNOQSTUVWX] are assumed to have DFP - * capability, as the comment at the top suggests. - * This requires confirmation however to be fully correct. - * Mike A. Harris <mharris@redhat.com> - */ - case PCI_CHIP_RAGE128PA: - case PCI_CHIP_RAGE128PB: - case PCI_CHIP_RAGE128PC: - case PCI_CHIP_RAGE128PE: - case PCI_CHIP_RAGE128PG: - case PCI_CHIP_RAGE128PH: - case PCI_CHIP_RAGE128PI: - case PCI_CHIP_RAGE128PJ: - case PCI_CHIP_RAGE128PK: - case PCI_CHIP_RAGE128PL: - case PCI_CHIP_RAGE128PM: - case PCI_CHIP_RAGE128PN: - case PCI_CHIP_RAGE128PO: - case PCI_CHIP_RAGE128PQ: - case PCI_CHIP_RAGE128PS: - case PCI_CHIP_RAGE128PT: - case PCI_CHIP_RAGE128PU: - case PCI_CHIP_RAGE128PV: - case PCI_CHIP_RAGE128PW: - case PCI_CHIP_RAGE128PX: - - case PCI_CHIP_RAGE128PD: - case PCI_CHIP_RAGE128PF: - case PCI_CHIP_RAGE128PP: - case PCI_CHIP_RAGE128PR: info->isDFP = TRUE; break; - - case PCI_CHIP_RAGE128LE: - case PCI_CHIP_RAGE128LF: - case PCI_CHIP_RAGE128MF: - case PCI_CHIP_RAGE128ML: info->HasPanelRegs = TRUE; break; - case PCI_CHIP_RAGE128RE: - case PCI_CHIP_RAGE128RF: - case PCI_CHIP_RAGE128RG: - case PCI_CHIP_RAGE128RK: - case PCI_CHIP_RAGE128RL: - case PCI_CHIP_RAGE128SM: - /* FIXME: RAGE128 S[EFGHKLN] are assumed to be like the SM above as - * all of them are listed as "Rage 128 4x" in ATI docs. - * This requires confirmation however to be fully correct. - * Mike A. Harris <mharris@redhat.com> - */ - case PCI_CHIP_RAGE128SE: - case PCI_CHIP_RAGE128SF: - case PCI_CHIP_RAGE128SG: - case PCI_CHIP_RAGE128SH: - case PCI_CHIP_RAGE128SK: - case PCI_CHIP_RAGE128SL: - case PCI_CHIP_RAGE128SN: - default: info->HasPanelRegs = FALSE; break; - } - } - - /* Read registers used to determine options */ - from = X_PROBED; - R128MapMMIO(pScrn); - R128MMIO = info->MMIO; - - if (info->FBDev) - pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; - else - pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024; - - info->MemCntl = INREG(R128_MEM_CNTL); - info->BusCntl = INREG(R128_BUS_CNTL); - - /* On non-flat panel systems, the default is to display to the CRT, - and on flat panel systems, the default is to display to the flat - panel unless the user explicity chooses otherwise using the "Display" - config file setting. BIOS_5_SCRATCH holds the display device on flat - panel systems only. */ - if (info->HasPanelRegs) { - char *Display = xf86GetOptValString(info->Options, OPTION_DISPLAY); - - if (info->FBDev) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Option \"Display\" ignored " - "(framebuffer device determines display type)\n"); - else if (!Display || !xf86NameCmp(Display, "FP")) - info->BIOSDisplay = R128_BIOS_DISPLAY_FP; - else if (!xf86NameCmp(Display, "BIOS")) - info->BIOSDisplay = INREG8(R128_BIOS_5_SCRATCH); - else if (!xf86NameCmp(Display, "Mirror")) - info->BIOSDisplay = R128_BIOS_DISPLAY_FP_CRT; - else if (!xf86NameCmp(Display, "CRT")) - info->BIOSDisplay = R128_BIOS_DISPLAY_CRT; - else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unsupported type \"%s\" specified for Option \"Display\".\n" - "\tSupported types are: " - "\"BIOS\", \"Mirror\", \"CRT\" and \"FP\"\n", Display); - return FALSE; - } - } else { - info->BIOSDisplay = R128_BIOS_DISPLAY_CRT; - } - - R128MMIO = NULL; - R128UnmapMMIO(pScrn); - - /* RAM */ - switch (info->MemCntl & 0x3) { - case 0: /* SDR SGRAM 1:1 */ - switch (info->Chipset) { - case PCI_CHIP_RAGE128TF: - case PCI_CHIP_RAGE128TL: - case PCI_CHIP_RAGE128TR: - case PCI_CHIP_RAGE128LE: - case PCI_CHIP_RAGE128LF: - case PCI_CHIP_RAGE128MF: - case PCI_CHIP_RAGE128ML: - case PCI_CHIP_RAGE128RE: - case PCI_CHIP_RAGE128RF: - case PCI_CHIP_RAGE128RG: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */ - case PCI_CHIP_RAGE128RK: - case PCI_CHIP_RAGE128RL: - case PCI_CHIP_RAGE128SM: - default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ - } - break; - case 1: offset = 2; break; /* 64-bit SDR SGRAM 2:1 */ - case 2: offset = 3; break; /* 64-bit DDR SGRAM */ - default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ - } - info->ram = &R128RAM[offset]; - - if (dev->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Video RAM override, using %d kB instead of %d kB\n", - dev->videoRam, - pScrn->videoRam); - from = X_CONFIG; - pScrn->videoRam = dev->videoRam; - } - pScrn->videoRam &= ~1023; - info->FbMapSize = pScrn->videoRam * 1024; - xf86DrvMsg(pScrn->scrnIndex, from, - "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); - - /* Flat panel (part 2) */ - switch (info->BIOSDisplay) { - case R128_BIOS_DISPLAY_FP: - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using flat panel for display\n"); - break; - case R128_BIOS_DISPLAY_CRT: - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using external CRT for display\n"); - break; - case R128_BIOS_DISPLAY_FP_CRT: - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using both flat panel and external CRT " - "for display\n"); - break; - } - - if (info->HasPanelRegs) { - /* Panel width/height overrides */ - info->PanelXRes = 0; - info->PanelYRes = 0; - if (xf86GetOptValInteger(info->Options, - OPTION_PANEL_WIDTH, &(info->PanelXRes))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Flat panel width: %d\n", info->PanelXRes); - } - if (xf86GetOptValInteger(info->Options, - OPTION_PANEL_HEIGHT, &(info->PanelYRes))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Flat panel height: %d\n", info->PanelYRes); - } - } - -#ifdef XF86DRI - /* DMA for Xv */ - info->DMAForXv = xf86ReturnOptValBool(info->Options, OPTION_XV_DMA, FALSE); - if (info->DMAForXv) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Will try to use DMA for Xv image transfers\n"); - } - - /* AGP/PCI */ - if (xf86ReturnOptValBool(info->Options, OPTION_IS_PCI, FALSE)) { - info->IsPCI = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n"); - } else { - switch (info->Chipset) { - case PCI_CHIP_RAGE128LE: - case PCI_CHIP_RAGE128RE: - case PCI_CHIP_RAGE128RK: - case PCI_CHIP_RAGE128PD: - case PCI_CHIP_RAGE128PR: - case PCI_CHIP_RAGE128PP: info->IsPCI = TRUE; break; - case PCI_CHIP_RAGE128LF: - case PCI_CHIP_RAGE128MF: - case PCI_CHIP_RAGE128ML: - case PCI_CHIP_RAGE128PF: - case PCI_CHIP_RAGE128RF: - case PCI_CHIP_RAGE128RG: - case PCI_CHIP_RAGE128RL: - case PCI_CHIP_RAGE128SM: - case PCI_CHIP_RAGE128TF: - case PCI_CHIP_RAGE128TL: - case PCI_CHIP_RAGE128TR: - /* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are - * believed to be AGP, but need confirmation. <mharris@redhat.com> - */ - case PCI_CHIP_RAGE128PA: - case PCI_CHIP_RAGE128PB: - case PCI_CHIP_RAGE128PC: - case PCI_CHIP_RAGE128PE: - case PCI_CHIP_RAGE128PG: - case PCI_CHIP_RAGE128PH: - case PCI_CHIP_RAGE128PI: - case PCI_CHIP_RAGE128PJ: - case PCI_CHIP_RAGE128PK: - case PCI_CHIP_RAGE128PL: - case PCI_CHIP_RAGE128PM: - case PCI_CHIP_RAGE128PN: - case PCI_CHIP_RAGE128PO: - case PCI_CHIP_RAGE128PQ: - case PCI_CHIP_RAGE128PS: - case PCI_CHIP_RAGE128PT: - case PCI_CHIP_RAGE128PU: - case PCI_CHIP_RAGE128PV: - case PCI_CHIP_RAGE128PW: - case PCI_CHIP_RAGE128PX: - case PCI_CHIP_RAGE128TS: - case PCI_CHIP_RAGE128TT: - case PCI_CHIP_RAGE128TU: - case PCI_CHIP_RAGE128SE: - case PCI_CHIP_RAGE128SF: - case PCI_CHIP_RAGE128SG: - case PCI_CHIP_RAGE128SH: - case PCI_CHIP_RAGE128SK: - case PCI_CHIP_RAGE128SL: - case PCI_CHIP_RAGE128SN: - default: info->IsPCI = FALSE; break; - } - } -#endif - - return TRUE; -} - -static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) -{ - R128InfoPtr info = R128PTR(pScrn); - vbeInfoPtr pVbe; - - if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; - xf86LoaderReqSymLists(ddcSymbols, NULL); - -#if defined(__powerpc__) || defined(__alpha__) - /* Int10 is broken on PPC and some Alphas */ - return TRUE; -#else - if (xf86LoadSubModule(pScrn, "vbe")) { - xf86LoaderReqSymLists(vbeSymbols,NULL); - pVbe = VBEInit(pInt10,info->pEnt->index); - if (!pVbe) return FALSE; - xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); - vbeFree(pVbe); - return TRUE; - } else - return FALSE; -#endif -} - -/* This is called by R128PreInit to initialize gamma correction. */ -static Bool R128PreInitGamma(ScrnInfoPtr pScrn) -{ - Gamma zeros = { 0.0, 0.0, 0.0 }; - - if (!xf86SetGamma(pScrn, zeros)) return FALSE; - return TRUE; -} - -static void -R128I2CGetBits(I2CBusPtr b, int *Clock, int *data) -{ - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - unsigned long val; - unsigned char *R128MMIO = info->MMIO; - - /* Get the result. */ - val = INREG(info->DDCReg); - *Clock = (val & R128_GPIO_MONID_Y_3) != 0; - *data = (val & R128_GPIO_MONID_Y_0) != 0; - -} - -static void -R128I2CPutBits(I2CBusPtr b, int Clock, int data) -{ - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - unsigned long val; - unsigned char *R128MMIO = info->MMIO; - - val = INREG(info->DDCReg) - & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3); - val |= (Clock ? 0:R128_GPIO_MONID_EN_3); - val |= (data ? 0:R128_GPIO_MONID_EN_0); - OUTREG(info->DDCReg, val); -} - - -static Bool -R128I2cInit(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - if ( xf86LoadSubModule(pScrn, "i2c") ) - xf86LoaderReqSymLists(i2cSymbols,NULL); - else{ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to load i2c module\n"); - return FALSE; - } - - info->pI2CBus = xf86CreateI2CBusRec(); - if(!info->pI2CBus) return FALSE; - - info->pI2CBus->BusName = "DDC"; - info->pI2CBus->scrnIndex = pScrn->scrnIndex; - info->DDCReg = R128_GPIO_MONID; - info->pI2CBus->I2CPutBits = R128I2CPutBits; - info->pI2CBus->I2CGetBits = R128I2CGetBits; - info->pI2CBus->AcknTimeout = 5; - - if (!xf86I2CBusInit(info->pI2CBus)) { - return FALSE; - } - return TRUE; -} - -/* return TRUE is a DFP is indeed connected to a DVI port */ -static Bool R128GetDFPInfo(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - int i; - xf86MonPtr MonInfo = NULL; - xf86MonPtr ddc; - unsigned char *R128MMIO = info->MMIO; - - if(!R128I2cInit(pScrn)){ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I2C initialization failed!\n"); - } - - OUTREG(info->DDCReg, (INREG(info->DDCReg) - | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3)); - - OUTREG(info->DDCReg, INREG(info->DDCReg) - & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3)); - - MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus); - if(!MonInfo) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No DFP detected\n"); - return FALSE; - } - xf86SetDDCproperties(pScrn, MonInfo); - ddc = pScrn->monitor->DDC; - - for(i=0; i<4; i++) - { - if(ddc->det_mon[i].type == 0) - { - info->PanelXRes = - ddc->det_mon[i].section.d_timings.h_active; - info->PanelYRes = - ddc->det_mon[i].section.d_timings.v_active; - - info->HOverPlus = - ddc->det_mon[i].section.d_timings.h_sync_off; - info->HSyncWidth = - ddc->det_mon[i].section.d_timings.h_sync_width; - info->HBlank = - ddc->det_mon[i].section.d_timings.h_blanking; - info->VOverPlus = - ddc->det_mon[i].section.d_timings.v_sync_off; - info->VSyncWidth = - ddc->det_mon[i].section.d_timings.v_sync_width; - info->VBlank = - ddc->det_mon[i].section.d_timings.v_blanking; - } - } - return TRUE; -} - - -static void R128SetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag) -{ - int i; - xf86MonPtr ddc = pScrn->monitor->DDC; - if(flag) /*HSync*/ - { - for(i=0; i<4; i++) - { - if(ddc->det_mon[i].type == DS_RANGES) - { - pScrn->monitor->nHsync = 1; - pScrn->monitor->hsync[0].lo = - ddc->det_mon[i].section.ranges.min_h; - pScrn->monitor->hsync[0].hi = - ddc->det_mon[i].section.ranges.max_h; - return; - } - } - /*if no sync ranges detected in detailed timing table, - let's try to derive them from supported VESA modes - Are we doing too much here!!!? - **/ - i = 0; - if(ddc->timings1.t1 & 0x02) /*800x600@56*/ - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 35.2; - i++; - } - if(ddc->timings1.t1 & 0x04) /*640x480@75*/ - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 37.5; - i++; - } - if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01)) - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 37.9; - i++; - } - if(ddc->timings1.t2 & 0x40) - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 46.9; - i++; - } - if((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08)) - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 48.1; - i++; - } - if(ddc->timings1.t2 & 0x04) - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 56.5; - i++; - } - if(ddc->timings1.t2 & 0x02) - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 60.0; - i++; - } - if(ddc->timings1.t2 & 0x01) - { - pScrn->monitor->hsync[i].lo = - pScrn->monitor->hsync[i].hi = 64.0; - i++; - } - pScrn->monitor->nHsync = i; - } - else /*Vrefresh*/ - { - for(i=0; i<4; i++) - { - if(ddc->det_mon[i].type == DS_RANGES) - { - pScrn->monitor->nVrefresh = 1; - pScrn->monitor->vrefresh[0].lo = - ddc->det_mon[i].section.ranges.min_v; - pScrn->monitor->vrefresh[0].hi = - ddc->det_mon[i].section.ranges.max_v; - return; - } - } - i = 0; - if(ddc->timings1.t1 & 0x02) /*800x600@56*/ - { - pScrn->monitor->vrefresh[i].lo = - pScrn->monitor->vrefresh[i].hi = 56; - i++; - } - if((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08)) - { - pScrn->monitor->vrefresh[i].lo = - pScrn->monitor->vrefresh[i].hi = 60; - i++; - } - if(ddc->timings1.t2 & 0x04) - { - pScrn->monitor->vrefresh[i].lo = - pScrn->monitor->vrefresh[i].hi = 70; - i++; - } - if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80)) - { - pScrn->monitor->vrefresh[i].lo = - pScrn->monitor->vrefresh[i].hi = 72; - i++; - } - if((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40) - || (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01)) - { - pScrn->monitor->vrefresh[i].lo = - pScrn->monitor->vrefresh[i].hi = 75; - i++; - } - pScrn->monitor->nVrefresh = i; - } -} - -/*********** - xfree's xf86ValidateModes routine deosn't work well with DFPs - here is our own validation routine. All modes between - 640<=XRes<=MaxRes and 480<=YRes<=MaxYRes will be permitted. - NOTE: RageProII doesn't support rmx, can only work with the - standard modes the monitor can support (scale). -************/ - -static int R128ValidateFPModes(ScrnInfoPtr pScrn) -{ - int i, j, count=0, width, height; - R128InfoPtr info = R128PTR(pScrn); - DisplayModePtr last = NULL, new = NULL, first = NULL; - xf86MonPtr ddc; - - /* Free any allocated modes during configuration. We don't need them*/ - while (pScrn->modes) - { - xf86DeleteMode(&pScrn->modes, pScrn->modes); - } - while (pScrn->modePool) - { - xf86DeleteMode(&pScrn->modePool, pScrn->modePool); - } - - pScrn->virtualX = pScrn->display->virtualX; - pScrn->virtualY = pScrn->display->virtualY; - - /* If no mode specified in config, we use native resolution*/ - if(!pScrn->display->modes[0]) - { - pScrn->display->modes[0] = xnfalloc(16); - sprintf(pScrn->display->modes[0], "%dx%d", - info->PanelXRes, info->PanelYRes); - } - - for(i=0; pScrn->display->modes[i] != NULL; i++) - { - if (sscanf(pScrn->display->modes[i], "%dx%d", &width, &height) == 2) - { - - if(width < 640 || width > info->PanelXRes || - height < 480 || height > info->PanelYRes) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode %s is out of range.\n" - "Valid mode should be between 640x480-%dx%d\n", - pScrn->display->modes[i], info->PanelXRes, info->PanelYRes); - continue; - } - - new = xnfcalloc(1, sizeof(DisplayModeRec)); - new->prev = last; - new->name = xnfalloc(strlen(pScrn->display->modes[i]) + 1); - strcpy(new->name, pScrn->display->modes[i]); - new->HDisplay = new->CrtcHDisplay = width; - new->VDisplay = new->CrtcVDisplay = height; - - ddc = pScrn->monitor->DDC; - for(j=0; j<DET_TIMINGS; j++) - { - /*We use native mode clock only*/ - if(ddc->det_mon[j].type == 0){ - new->Clock = ddc->det_mon[j].section.d_timings.clock / 1000; - break; - } - } - - if(new->prev) new->prev->next = new; - last = new; - if(!first) first = new; - pScrn->display->virtualX = - pScrn->virtualX = MAX(pScrn->virtualX, width); - pScrn->display->virtualY = - pScrn->virtualY = MAX(pScrn->virtualY, height); - count++; - } - else - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Mode name %s is invalid\n", pScrn->display->modes[i]); - continue; - } - } - - if(last) - { - last->next = first; - first->prev = last; - pScrn->modes = first; - - /*FIXME: May need to validate line pitch here*/ - { - int dummy = 0; - switch(pScrn->depth / 8) - { - case 1: - dummy = 128 - pScrn->virtualX % 128; - break; - case 2: - dummy = 32 - pScrn->virtualX % 32; - break; - case 3: - case 4: - dummy = 16 - pScrn->virtualX % 16; - } - pScrn->displayWidth = pScrn->virtualX + dummy; - } - - } - - return count; -} - - -/* This is called by R128PreInit to validate modes and compute parameters - for all of the valid modes. */ -static Bool R128PreInitModes(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - ClockRangePtr clockRanges; - int modesFound; - - if(info->isDFP) { - R128MapMem(pScrn); - info->BIOSDisplay = R128_BIOS_DISPLAY_FP; - /* validate if DFP really connected. */ - if(!R128GetDFPInfo(pScrn)) { - info->isDFP = FALSE; - info->BIOSDisplay = R128_BIOS_DISPLAY_CRT; - } else if(!info->isPro2) { - /* RageProII doesn't support rmx, we can't use native-mode - stretching for other non-native modes. It will rely on - whatever VESA modes monitor can support. */ - modesFound = R128ValidateFPModes(pScrn); - if(modesFound < 1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid mode found for this DFP/LCD\n"); - R128UnmapMem(pScrn); - return FALSE; - - } - } - R128UnmapMem(pScrn); - } - - if(!info->isDFP || info->isPro2) { - /* Get mode information */ - pScrn->progClock = TRUE; - clockRanges = xnfcalloc(sizeof(*clockRanges), 1); - clockRanges->next = NULL; - clockRanges->minClock = info->pll.min_pll_freq; - clockRanges->maxClock = info->pll.max_pll_freq * 10; - clockRanges->clockIndex = -1; - if (info->HasPanelRegs || info->isDFP) { - clockRanges->interlaceAllowed = FALSE; - clockRanges->doubleScanAllowed = FALSE; - } else { - clockRanges->interlaceAllowed = TRUE; - clockRanges->doubleScanAllowed = TRUE; - } - - if(pScrn->monitor->DDC) { - /*if we still don't know sync range yet, let's try EDID. - Note that, since we can have dual heads, the Xconfigurator - may not be able to probe both monitors correctly through - vbe probe function (R128ProbeDDC). Here we provide an - additional way to auto-detect sync ranges if they haven't - been added to XF86Config manually. - **/ - if(pScrn->monitor->nHsync <= 0) - R128SetSyncRangeFromEdid(pScrn, 1); - if(pScrn->monitor->nVrefresh <= 0) - R128SetSyncRangeFromEdid(pScrn, 0); - } - - modesFound = xf86ValidateModes(pScrn, - pScrn->monitor->Modes, - pScrn->display->modes, - clockRanges, - NULL, /* linePitches */ - 8 * 64, /* minPitch */ - 8 * 1024, /* maxPitch */ - 8 * 64, /* pitchInc */ - 128, /* minHeight */ - 2048, /* maxHeight */ - pScrn->display->virtualX, - pScrn->display->virtualY, - info->FbMapSize, - LOOKUP_BEST_REFRESH); - - if (modesFound < 1 && info->FBDev) { - fbdevHWUseBuildinMode(pScrn); - pScrn->displayWidth = fbdevHWGetLineLength(pScrn)/(pScrn->bitsPerPixel/8); - modesFound = 1; - } - - if (modesFound == -1) return FALSE; - xf86PruneDriverModes(pScrn); - if (!modesFound || !pScrn->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - return FALSE; - } - xf86SetCrtcForModes(pScrn, 0); - } - /* Set DPI */ - pScrn->currentMode = pScrn->modes; - xf86PrintModes(pScrn); - - xf86SetDpi(pScrn, 0, 0); - - /* Get ScreenInit function */ - if (!xf86LoadSubModule(pScrn, "fb")) return FALSE; - xf86LoaderReqSymLists(fbSymbols, NULL); - - info->CurrentLayout.displayWidth = pScrn->displayWidth; - info->CurrentLayout.mode = pScrn->currentMode; - - return TRUE; -} - -/* This is called by R128PreInit to initialize the hardware cursor. */ -static Bool R128PreInitCursor(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { - if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; - xf86LoaderReqSymLists(ramdacSymbols, NULL); - } - return TRUE; -} - -/* This is called by R128PreInit to initialize hardware acceleration. */ -static Bool R128PreInitAccel(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { - if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE; - xf86LoaderReqSymLists(xaaSymbols, NULL); - } - return TRUE; -} - -static Bool R128PreInitInt10(ScrnInfoPtr pScrn, xf86Int10InfoPtr *ppInt10) -{ - R128InfoPtr info = R128PTR(pScrn); -#if 1 && !defined(__alpha__) - /* int10 is broken on some Alphas */ - if (xf86LoadSubModule(pScrn, "int10")) { - xf86LoaderReqSymLists(int10Symbols, NULL); - xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); - *ppInt10 = xf86InitInt10(info->pEnt->index); - } -#endif - return TRUE; -} - -#ifdef XF86DRI -static Bool R128PreInitDRI(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (xf86ReturnOptValBool(info->Options, OPTION_CCE_PIO, FALSE)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n"); - info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; - } else { - info->CCEMode = R128_DEFAULT_CCE_BM_MODE; - } - - if (xf86ReturnOptValBool(info->Options, OPTION_NO_SECURITY, FALSE)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "WARNING!!! CCE Security checks disabled!!! **********\n"); - info->CCESecure = FALSE; - } else { - info->CCESecure = TRUE; - } - - info->agpMode = R128_DEFAULT_AGP_MODE; - info->agpSize = R128_DEFAULT_AGP_SIZE; - info->ringSize = R128_DEFAULT_RING_SIZE; - info->bufSize = R128_DEFAULT_BUFFER_SIZE; - info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; - - info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; - - if (!info->IsPCI) { - if (xf86GetOptValInteger(info->Options, - OPTION_AGP_MODE, &(info->agpMode))) { - if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal AGP Mode: %d\n", info->agpMode); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using AGP %dx mode\n", info->agpMode); - } - - if (xf86GetOptValInteger(info->Options, - OPTION_AGP_SIZE, (int *)&(info->agpSize))) { - switch (info->agpSize) { - case 4: - case 8: - case 16: - case 32: - case 64: - case 128: - case 256: - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal AGP size: %d MB\n", info->agpSize); - return FALSE; - } - } - - if (xf86GetOptValInteger(info->Options, - OPTION_RING_SIZE, &(info->ringSize))) { - if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal ring buffer size: %d MB\n", - info->ringSize); - return FALSE; - } - } - - if (xf86GetOptValInteger(info->Options, - OPTION_BUFFER_SIZE, &(info->bufSize))) { - if (info->bufSize < 1 || info->bufSize >= (int)info->agpSize) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal vertex/indirect buffers size: %d MB\n", - info->bufSize); - return FALSE; - } - if (info->bufSize > 2) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal vertex/indirect buffers size: %d MB\n", - info->bufSize); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Clamping vertex/indirect buffers size to 2 MB\n"); - info->bufSize = 2; - } - } - - if (info->ringSize + info->bufSize + info->agpTexSize > - (int)info->agpSize) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Buffers are too big for requested AGP space\n"); - return FALSE; - } - - info->agpTexSize = info->agpSize - (info->ringSize + info->bufSize); - } - - if (xf86GetOptValInteger(info->Options, OPTION_USEC_TIMEOUT, - &(info->CCEusecTimeout))) { - /* This option checked by the R128 DRM kernel module */ - } - - if (!xf86LoadSubModule(pScrn, "shadowfb")) { - info->allowPageFlip = 0; - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't load shadowfb module:\n"); - } else { - xf86LoaderReqSymLists(driShadowFBSymbols, NULL); - - info->allowPageFlip = xf86ReturnOptValBool(info->Options, - OPTION_PAGE_FLIP, - FALSE); - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n", - info->allowPageFlip ? "en" : "dis"); - - return TRUE; -} -#endif - -static void -R128ProbeDDC(ScrnInfoPtr pScrn, int indx) -{ - vbeInfoPtr pVbe; - if (xf86LoadSubModule(pScrn, "vbe")) { - pVbe = VBEInit(NULL,indx); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } -} - -/* R128PreInit is called once at server startup. */ -Bool R128PreInit(ScrnInfoPtr pScrn, int flags) -{ - R128InfoPtr info; - xf86Int10InfoPtr pInt10 = NULL; - - R128TRACE(("R128PreInit\n")); - - if (pScrn->numEntities != 1) return FALSE; - - if (!R128GetRec(pScrn)) return FALSE; - - info = R128PTR(pScrn); - - info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (info->pEnt->location.type != BUS_PCI) goto fail; - - if (flags & PROBE_DETECT) { - R128ProbeDDC(pScrn, info->pEnt->index); - return TRUE; - } - - if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; - xf86LoaderReqSymLists(vgahwSymbols, NULL); - if (!vgaHWGetHWRec(pScrn)) { - R128FreeRec(pScrn); - return FALSE; - } - - info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); - info->PciTag = pciTag(info->PciInfo->bus, - info->PciInfo->device, - info->PciInfo->func); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "PCI bus %d card %d func %d\n", - info->PciInfo->bus, - info->PciInfo->device, - info->PciInfo->func); - - if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; - if (xf86SetOperatingState(resVga, info->pEnt->index, ResUnusedOpr)) goto fail; - - pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR; - pScrn->monitor = pScrn->confScreen->monitor; - - if (!R128PreInitVisual(pScrn)) goto fail; - - /* We can't do this until we have a - pScrn->display. */ - xf86CollectOptions(pScrn, NULL); - if (!(info->Options = xalloc(sizeof(R128Options)))) goto fail; - memcpy(info->Options, R128Options, sizeof(R128Options)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); - - if (!R128PreInitWeight(pScrn)) goto fail; - - if(xf86GetOptValInteger(info->Options, OPTION_VIDEO_KEY, &(info->videoKey))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", - info->videoKey); - } else { - info->videoKey = 0x1E; - } - - if (xf86ReturnOptValBool(info->Options, OPTION_SHOW_CACHE, FALSE)) { - info->showCache = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n"); - } - - if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) { - info->FBDev = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using framebuffer device\n"); - } - - if (info->FBDev) { - /* check for linux framebuffer device */ - if (!xf86LoadSubModule(pScrn, "fbdevhw")) return FALSE; - xf86LoaderReqSymLists(fbdevHWSymbols, NULL); - if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) return FALSE; - pScrn->SwitchMode = fbdevHWSwitchMode; - pScrn->AdjustFrame = fbdevHWAdjustFrame; - pScrn->ValidMode = fbdevHWValidMode; - } - - if (!info->FBDev) - if (!R128PreInitInt10(pScrn, &pInt10)) goto fail; - - if (!R128PreInitConfig(pScrn)) goto fail; - - if (!R128GetBIOSParameters(pScrn, pInt10)) goto fail; - - if (!R128GetPLLParameters(pScrn)) goto fail; - - /* Don't fail on this one */ - R128PreInitDDC(pScrn, pInt10); - - if (!R128PreInitGamma(pScrn)) goto fail; - - if (!R128PreInitModes(pScrn)) goto fail; - - if (!R128PreInitCursor(pScrn)) goto fail; - - if (!R128PreInitAccel(pScrn)) goto fail; - -#ifdef XF86DRI - if (!R128PreInitDRI(pScrn)) goto fail; -#endif - - /* Free the video bios (if applicable) */ - if (info->VBIOS) { - xfree(info->VBIOS); - info->VBIOS = NULL; - } - - /* Free int10 info */ - if (pInt10) - xf86FreeInt10(pInt10); - - xf86DrvMsg(pScrn->scrnIndex, X_NOTICE, - "For information on using the multimedia capabilities\n of this" - " adapter, please see http://gatos.sf.net.\n"); - - return TRUE; - - fail: - /* Pre-init failed. */ - - /* Free the video bios (if applicable) */ - if (info->VBIOS) { - xfree(info->VBIOS); - info->VBIOS = NULL; - } - - /* Free int10 info */ - if (pInt10) - xf86FreeInt10(pInt10); - - vgaHWFreeHWRec(pScrn); - R128FreeRec(pScrn); - return FALSE; -} - -/* Load a palette. */ -static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors, - int *indices, LOCO *colors, VisualPtr pVisual) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int i; - int idx; - unsigned char r, g, b; - - /* Select palette 0 (main CRTC) if using FP-enabled chip */ - if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0); - - if (info->CurrentLayout.depth == 15) { - /* 15bpp mode. This sends 32 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - g = colors[idx].green; - b = colors[idx].blue; - OUTPAL(idx * 8, r, g, b); - } - } - else if (info->CurrentLayout.depth == 16) { - /* 16bpp mode. This sends 64 values. */ - /* There are twice as many green values as - there are values for red and blue. So, - we take each red and blue pair, and - combine it with each of the two green - values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx / 2].red; - g = colors[idx].green; - b = colors[idx / 2].blue; - OUTPAL(idx * 4, r, g, b); - } - } - else { - /* 8bpp mode. This sends 256 values. */ - for (i = 0; i < numColors; i++) { - idx = indices[i]; - r = colors[idx].red; - b = colors[idx].blue; - g = colors[idx].green; - OUTPAL(idx, r, g, b); - } - } -} - -static void -R128BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) -{ - ScreenPtr pScreen = screenInfo.screens[i]; - ScrnInfoPtr pScrn = xf86Screens[i]; - R128InfoPtr info = R128PTR(pScrn); - -#ifdef XF86DRI - if (info->directRenderingEnabled) - FLUSH_RING(); -#endif - - pScreen->BlockHandler = info->BlockHandler; - (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); - pScreen->BlockHandler = R128BlockHandler; - - if(info->VideoTimerCallback) { - (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds); - } -} - -/* Called at the start of each server generation. */ -Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - R128InfoPtr info = R128PTR(pScrn); - BoxRec MemBox; - int y2; - - R128TRACE(("R128ScreenInit %x %d\n", pScrn->memPhysBase, pScrn->fbOffset)); - -#ifdef XF86DRI - /* Turn off the CCE for now. */ - info->CCEInUse = FALSE; - info->indirectBuffer = NULL; -#endif - - if (!R128MapMem(pScrn)) return FALSE; - pScrn->fbOffset = 0; -#ifdef XF86DRI - info->fbX = 0; - info->fbY = 0; - info->frontOffset = 0; - info->frontPitch = pScrn->displayWidth; -#endif - - info->PaletteSavedOnVT = FALSE; - - R128Save(pScrn); - if (info->FBDev) { - if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; - } else { - if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE; - } - - R128SaveScreen(pScreen, SCREEN_SAVER_ON); - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - /* Visual setup */ - miClearVisualTypes(); - if (!miSetVisualTypes(pScrn->depth, - miGetDefaultVisualMask(pScrn->depth), - pScrn->rgbBits, - pScrn->defaultVisual)) return FALSE; - miSetPixmapDepths (); - -#ifdef XF86DRI - /* Setup DRI after visuals have been - established, but before fbScreenInit is - called. fbScreenInit will eventually - call the driver's InitGLXVisuals call - back. */ - { - /* FIXME: When we move to dynamic allocation of back and depth - buffers, we will want to revisit the following check for 3 - times the virtual size of the screen below. */ - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); - int maxy = info->FbMapSize / width_bytes; - - if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { - xf86DrvMsg(scrnIndex, X_WARNING, - "Acceleration disabled, not initializing the DRI\n"); - info->directRenderingEnabled = FALSE; - } else if (maxy <= pScrn->virtualY * 3) { - xf86DrvMsg(scrnIndex, X_WARNING, - "Static buffer allocation failed -- " - "need at least %d kB video memory\n", - (pScrn->displayWidth * pScrn->virtualY * - info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); - info->directRenderingEnabled = FALSE; - } else { - info->directRenderingEnabled = R128DRIScreenInit(pScreen); - } - } -#endif - - if (!fbScreenInit (pScreen, info->FB, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, - pScrn->bitsPerPixel)) - return FALSE; - - xf86SetBlackWhitePixels(pScreen); - - if (pScrn->bitsPerPixel > 8) { - VisualPtr visual; - - visual = pScreen->visuals + pScreen->numVisuals; - while (--visual >= pScreen->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrn->offset.red; - visual->offsetGreen = pScrn->offset.green; - visual->offsetBlue = pScrn->offset.blue; - visual->redMask = pScrn->mask.red; - visual->greenMask = pScrn->mask.green; - visual->blueMask = pScrn->mask.blue; - } - } - } - - /* must be after RGB order fixed */ - fbPictureInit (pScreen, 0, 0); - - /* Memory manager setup */ -#ifdef XF86DRI - if (info->directRenderingEnabled) { - FBAreaPtr fbarea; - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); - int cpp = info->CurrentLayout.pixel_bytes; - int bufferSize = pScrn->virtualY * width_bytes; - int l, total; - int scanlines; - - switch (info->CCEMode) { - case R128_DEFAULT_CCE_PIO_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); - break; - case R128_DEFAULT_CCE_BM_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); - break; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB AGP aperture\n", info->agpSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for the ring buffer\n", info->ringSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for AGP textures\n", info->agpTexSize); - - /* Try for front, back, depth, and two framebuffers worth of - * pixmap cache. Should be enough for a fullscreen background - * image plus some leftovers. - */ - info->textureSize = info->FbMapSize - 5 * bufferSize; - - /* If that gives us less than half the available memory, let's - * be greedy and grab some more. Sorry, I care more about 3D - * performance than playing nicely, and you'll get around a full - * framebuffer's worth of pixmap cache anyway. - */ - if (info->textureSize < (int)info->FbMapSize / 2) { - info->textureSize = info->FbMapSize - 4 * bufferSize; - } - - if (info->textureSize > 0) { - l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); - if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; - } else { - info->textureSize = 0; - } - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - total = info->FbMapSize - info->textureSize; - scanlines = total / width_bytes; - if (scanlines > 8191) scanlines = 8191; - - /* Recalculate the texture offset and size to accomodate any - * rounding to a whole number of scanlines. - */ - info->textureOffset = scanlines * width_bytes; - - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - MemBox.y2 = scanlines; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } - - /* Allocate the shared back buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved back buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->backX = fbarea->box.x1; - info->backY = fbarea->box.y1; - info->backOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->backPitch = pScrn->displayWidth; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); - info->backX = -1; - info->backY = -1; - info->backOffset = -1; - info->backPitch = -1; - } - - /* Allocate the shared depth buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY + 1, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->depthX = fbarea->box.x1; - info->depthY = fbarea->box.y1; - info->depthOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->depthPitch = pScrn->displayWidth; - info->spanOffset = ((fbarea->box.y2 - 1) * width_bytes + - fbarea->box.x1 * cpp); - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth span from (%d,%d) offset 0x%x\n", - fbarea->box.x1, fbarea->box.y2 - 1, info->spanOffset); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); - info->depthX = -1; - info->depthY = -1; - info->depthOffset = -1; - info->depthPitch = -1; - info->spanOffset = -1; - } - - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - } - else -#endif - { - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - y2 = (info->FbMapSize - / (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes)); - /* The acceleration engine uses 14 bit - signed coordinates, so we can't have any - drawable caches beyond this region. */ - if (y2 > 8191) y2 = 8191; - MemBox.y2 = y2; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - FBAreaPtr fbarea; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, - 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } - } - - /* Acceleration setup */ - if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) { - if (R128AccelInit(pScreen)) { - xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); - info->accelOn = TRUE; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Acceleration initialization failed\n"); - xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); - info->accelOn = FALSE; - } - } else { - xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); - info->accelOn = FALSE; - } - - /* DGA setup */ - R128DGAInit(pScreen); - - /* Backing store setup */ - miInitializeBackingStore(pScreen); - xf86SetBackingStore(pScreen); - - /* Set Silken Mouse */ - xf86SetSilkenMouse(pScreen); - - /* Cursor setup */ - miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - - /* Hardware cursor setup */ - if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) { - if (R128CursorInit(pScreen)) { - int width, height; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using hardware cursor (scanline %d)\n", - info->cursor_start / pScrn->displayWidth); - if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, - 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } else { - xf86DrvMsg(scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); - } - } else { - info->cursor_start = 0; - xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); - } - - /* Colormap setup */ - if (!miCreateDefColormap(pScreen)) return FALSE; - if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, - (info->FBDev ? fbdevHWLoadPalette : - R128LoadPalette), NULL, - CMAP_PALETTED_TRUECOLOR - | CMAP_RELOAD_ON_MODE_SWITCH -#if 0 /* This option messes up text mode! (eich@suse.de) */ - | CMAP_LOAD_EVEN_IF_OFFSCREEN -#endif - )) return FALSE; - - /* DPMS setup - FIXME: also for mirror mode in non-fbdev case? - Michel */ - if (info->FBDev) - xf86DPMSInit(pScreen, fbdevHWDPMSSet, 0); - else { - if (!info->HasPanelRegs || info->BIOSDisplay == R128_BIOS_DISPLAY_CRT) - xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0); - else if (info->HasPanelRegs || info->BIOSDisplay == R128_BIOS_DISPLAY_FP) - xf86DPMSInit(pScreen, R128DisplayPowerManagementSetLCD, 0); - } - - R128InitVideo(pScreen); - - /* Provide SaveScreen */ - pScreen->SaveScreen = R128SaveScreen; - - /* Wrap CloseScreen */ - info->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = R128CloseScreen; - - /* Note unused options */ - if (serverGeneration == 1) - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - -#ifdef XF86DRI - /* DRI finalization */ - if (info->directRenderingEnabled) { - /* Now that mi, fb, drm and others have - done their thing, complete the DRI - setup. */ - info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen); - } - if (info->directRenderingEnabled) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); - } -#endif - - info->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = R128BlockHandler; - - return TRUE; -} - -/* Write common registers (initialized to 0). */ -static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl | R128_FP_BLANK_DIS); - - OUTREG(R128_OVR_CLR, restore->ovr_clr); - OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); - OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); - OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); - OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); - OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); - OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); - OUTREG(R128_VIPH_CONTROL, restore->viph_control); - OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); - OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); - OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); - OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); - OUTREG(R128_BUS_CNTL, restore->bus_cntl); - OUTREG(R128_CONFIG_CNTL, restore->config_cntl); -} - -/* Write CRTC registers. */ -static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTREG(R128_CRTC_GEN_CNTL, restore->crtc_gen_cntl); - - OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl, - R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS); - - OUTREGP(R128_DAC_CNTL, restore->dac_cntl, - R128_DAC_RANGE_CNTL | R128_DAC_BLANKING); - - OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); - OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); - OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); - OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); - OUTREG(R128_CRTC_OFFSET, restore->crtc_offset); - OUTREG(R128_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); - OUTREG(R128_CRTC_PITCH, restore->crtc_pitch); -} - -/* Write flat panel registers */ -static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - CARD32 tmp; - - - /*OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);*/ - OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); - OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); - OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); - OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); - OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); - OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); - OUTREG(R128_TMDS_CRC, restore->tmds_crc); - OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); - OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(CARD32)R128_FP_BLANK_DIS); - - if(info->isDFP) return; - - tmp = INREG(R128_LVDS_GEN_CNTL); - if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == - (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { - OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - } else { - if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { - OUTREG(R128_LVDS_GEN_CNTL, - restore->lvds_gen_cntl & (CARD32)~R128_LVDS_BLON); - usleep(R128PTR(pScrn)->PanelPwrDly * 1000); - OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - } else { - OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON); - usleep(R128PTR(pScrn)->PanelPwrDly * 1000); - OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - } - } -} - -static void R128PLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) -{ - while (INPLL(pScrn, R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R); -} - -static void R128PLLWriteUpdate(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTPLLP(pScrn, R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff); -} - -/* Write PLL registers. */ -static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff); - - OUTPLLP(pScrn, - R128_PPLL_CNTL, - R128_PPLL_RESET - | R128_PPLL_ATOMIC_UPDATE_EN - | R128_PPLL_VGA_ATOMIC_UPDATE_EN, - 0xffff); - - R128PLLWaitForReadUpdateComplete(pScrn); - OUTPLLP(pScrn, R128_PPLL_REF_DIV, - restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK); - R128PLLWriteUpdate(pScrn); - - R128PLLWaitForReadUpdateComplete(pScrn); - OUTPLLP(pScrn, R128_PPLL_DIV_3, - restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK); - R128PLLWriteUpdate(pScrn); - OUTPLLP(pScrn, R128_PPLL_DIV_3, - restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK); - R128PLLWriteUpdate(pScrn); - - R128PLLWaitForReadUpdateComplete(pScrn); - OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl); - R128PLLWriteUpdate(pScrn); - - OUTPLLP(pScrn, R128_PPLL_CNTL, 0, ~R128_PPLL_RESET); - - R128TRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", - restore->ppll_ref_div, - restore->ppll_div_3, - restore->htotal_cntl, - INPLL(pScrn, R128_PPLL_CNTL))); - R128TRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", - restore->ppll_ref_div & R128_PPLL_REF_DIV_MASK, - restore->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, - (restore->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16)); -} - -/* Write DDA registers. */ -static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - OUTREG(R128_DDA_CONFIG, restore->dda_config); - OUTREG(R128_DDA_ON_OFF, restore->dda_on_off); -} - -/* Write palette data. */ -static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int i; - - if (!restore->palette_valid) return; - - /* Select palette 0 (main CRTC) if using FP-enabled chip */ - if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0); - - OUTPAL_START(0); - for (i = 0; i < 256; i++) OUTPAL_NEXT_CARD32(restore->palette[i]); -} - -/* Write out state to define a new video mode. */ -static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore) -{ - R128InfoPtr info = R128PTR(pScrn); - - R128TRACE(("R128RestoreMode(%p)\n", restore)); - R128RestoreCommonRegisters(pScrn, restore); - R128RestoreCrtcRegisters(pScrn, restore); - if (!(info->HasPanelRegs) || info->BIOSDisplay == R128_BIOS_DISPLAY_CRT){ - R128RestorePLLRegisters(pScrn, restore); - } - R128RestoreDDARegisters(pScrn, restore); - if (info->HasPanelRegs || info->isDFP) - R128RestoreFPRegisters(pScrn, restore); - - R128RestorePalette(pScrn, restore); -} - -/* Read common registers. */ -static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - save->ovr_clr = INREG(R128_OVR_CLR); - save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); - save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); - save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); - save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); - save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); - save->subpic_cntl = INREG(R128_SUBPIC_CNTL); - save->viph_control = INREG(R128_VIPH_CONTROL); - save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); - save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); - save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); - save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); - save->bus_cntl = INREG(R128_BUS_CNTL); - save->config_cntl = INREG(R128_CONFIG_CNTL); -} - -/* Read CRTC registers. */ -static void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); - save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); - save->dac_cntl = INREG(R128_DAC_CNTL); - save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); - save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); - save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); - save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); - save->crtc_offset = INREG(R128_CRTC_OFFSET); - save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); - save->crtc_pitch = INREG(R128_CRTC_PITCH); -} - -/* Read flat panel registers */ -static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); - save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); - save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); - save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); - save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); - save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); - save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); - save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); - save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); - save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); - save->tmds_crc = INREG(R128_TMDS_CRC); - save->tmds_transmitter_cntl = INREG(R128_TMDS_TRANSMITTER_CNTL); -} - -/* Read PLL registers. */ -static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save) -{ - save->ppll_ref_div = INPLL(pScrn, R128_PPLL_REF_DIV); - save->ppll_div_3 = INPLL(pScrn, R128_PPLL_DIV_3); - save->htotal_cntl = INPLL(pScrn, R128_HTOTAL_CNTL); - - R128TRACE(("Read: 0x%08x 0x%08x 0x%08x\n", - save->ppll_ref_div, - save->ppll_div_3, - save->htotal_cntl)); - R128TRACE(("Read: rd=%d, fd=%d, pd=%d\n", - save->ppll_ref_div & R128_PPLL_REF_DIV_MASK, - save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, - (save->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16)); -} - -/* Read DDA registers. */ -static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - - save->dda_config = INREG(R128_DDA_CONFIG); - save->dda_on_off = INREG(R128_DDA_ON_OFF); -} - -/* Read palette data. */ -static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int i; - - /* Select palette 0 (main CRTC) if using FP-enabled chip */ - if (info->HasPanelRegs || info->isDFP) PAL_SELECT(0); - - INPAL_START(0); - for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); - save->palette_valid = TRUE; -} - -/* Save state that defines current video mode. */ -static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save) -{ - R128TRACE(("R128SaveMode(%p)\n", save)); - - R128SaveCommonRegisters(pScrn, save); - R128SaveCrtcRegisters(pScrn, save); - if (R128PTR(pScrn)->HasPanelRegs || R128PTR(pScrn)->isDFP) - R128SaveFPRegisters(pScrn, save); - R128SavePLLRegisters(pScrn, save); - R128SaveDDARegisters(pScrn, save); - R128SavePalette(pScrn, save); - - R128TRACE(("R128SaveMode returns %p\n", save)); -} - -/* Save everything needed to restore the original VC state. */ -static void R128Save(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - R128SavePtr save = &info->SavedReg; - vgaHWPtr hwp = VGAHWPTR(pScrn); - - R128TRACE(("R128Save\n")); - if (info->FBDev) { - fbdevHWSave(pScrn); - return; - } - vgaHWUnlock(hwp); - vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); /* save mode, fonts, cmap */ - vgaHWLock(hwp); - - R128SaveMode(pScrn, save); - - save->dp_datatype = INREG(R128_DP_DATATYPE); - save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); - save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); - save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); - save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); -} - -/* Restore the original (text) mode. */ -static void R128Restore(ScrnInfoPtr pScrn) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - R128SavePtr restore = &info->SavedReg; - vgaHWPtr hwp = VGAHWPTR(pScrn); - - R128TRACE(("R128Restore\n")); - if (info->FBDev) { - fbdevHWRestore(pScrn); - return; - } - - R128Blank(pScrn); - OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); - OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); - OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); - OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); - OUTREG(R128_DP_DATATYPE, restore->dp_datatype); - - R128RestoreMode(pScrn, restore); - vgaHWUnlock(hwp); - vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); - vgaHWLock(hwp); - - R128WaitForVerticalSync(pScrn); - R128Unblank(pScrn); -} - -/* Define common registers for requested video mode. */ -static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info) -{ - save->ovr_clr = 0; - save->ovr_wid_left_right = 0; - save->ovr_wid_top_bottom = 0; - save->ov0_scale_cntl = 0; - save->mpp_tb_config = 0; - save->mpp_gp_config = 0; - save->subpic_cntl = 0; - save->viph_control = 0; - save->i2c_cntl_1 = 0; -#ifdef XF86DRI - save->gen_int_cntl = info->gen_int_cntl; -#else - save->gen_int_cntl = 0; -#endif - save->cap0_trig_cntl = 0; - save->cap1_trig_cntl = 0; - save->bus_cntl = info->BusCntl; - /* - * If bursts are enabled, turn on discards and aborts - */ - if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST)) - save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; -} - -/* Define CRTC registers for requested video mode. */ -static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, - DisplayModePtr mode, R128InfoPtr info) -{ - int format; - int hsync_start; - int hsync_wid; - int hsync_fudge; - int vsync_wid; - int bytpp; - int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; - int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 }; - int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; - - switch (info->CurrentLayout.pixel_code) { - case 4: format = 1; bytpp = 0; break; - case 8: format = 2; bytpp = 1; break; - case 15: format = 3; bytpp = 2; break; /* 555 */ - case 16: format = 4; bytpp = 2; break; /* 565 */ - case 24: format = 5; bytpp = 3; break; /* RGB */ - case 32: format = 6; bytpp = 4; break; /* xRGB */ - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unsupported pixel depth (%d)\n", - info->CurrentLayout.bitsPerPixel); - return FALSE; - } - R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); - - switch (info->BIOSDisplay) { - case R128_BIOS_DISPLAY_FP: - hsync_fudge = hsync_fudge_fp[format-1]; - break; - case R128_BIOS_DISPLAY_FP_CRT: - hsync_fudge = hsync_fudge_fp_crt[format-1]; - break; - case R128_BIOS_DISPLAY_CRT: - default: - hsync_fudge = hsync_fudge_default[format-1]; - break; - } - - save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN - | R128_CRTC_EN - | (format << 8) - | ((mode->Flags & V_DBLSCAN) - ? R128_CRTC_DBL_SCAN_EN - : 0) - | ((mode->Flags & V_INTERLACE) - ? R128_CRTC_INTERLACE_EN - : 0) - | ((mode->Flags & V_CSYNC) - ? R128_CRTC_CSYNC_EN - : 0)); - - save->crtc_ext_cntl = R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN; - save->dac_cntl = (R128_DAC_MASK_ALL - | R128_DAC_VGA_ADR_EN - | (info->dac6bits ? 0 : R128_DAC_8BIT_EN)); - - - if(info->isDFP && !info->isPro2) - { - if(info->PanelXRes < mode->CrtcHDisplay) - mode->HDisplay = mode->CrtcHDisplay = info->PanelXRes; - if(info->PanelYRes < mode->CrtcVDisplay) - mode->VDisplay = mode->CrtcVDisplay = info->PanelYRes; - mode->CrtcHTotal = mode->CrtcHDisplay + info->HBlank; - mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlus; - mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidth; - mode->CrtcVTotal = mode->CrtcVDisplay + info->VBlank; - mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlus; - mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidth; - } - - save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) - | (((mode->CrtcHDisplay / 8) - 1) << 16)); - - hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; - if (!hsync_wid) hsync_wid = 1; - if (hsync_wid > 0x3f) hsync_wid = 0x3f; - - hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; - - save->crtc_h_sync_strt_wid = ((hsync_start & 0xfff) - | (hsync_wid << 16) - | ((mode->Flags & V_NHSYNC) - ? R128_CRTC_H_SYNC_POL - : 0)); - -#if 1 - /* This works for double scan mode. */ - save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) - | ((mode->CrtcVDisplay - 1) << 16)); -#else - /* This is what cce/nbmode.c example code - does -- is this correct? */ - save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) - | ((mode->CrtcVDisplay - * ((mode->Flags & V_DBLSCAN) ? 2 : 1) - 1) - << 16)); -#endif - - vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; - if (!vsync_wid) vsync_wid = 1; - if (vsync_wid > 0x1f) vsync_wid = 0x1f; - - save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) - | (vsync_wid << 16) - | ((mode->Flags & V_NVSYNC) - ? R128_CRTC_V_SYNC_POL - : 0)); - save->crtc_offset = 0; - save->crtc_offset_cntl = 0; - save->crtc_pitch = info->CurrentLayout.displayWidth / 8; - - R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", - save->crtc_pitch, pScrn->virtualX, info->CurrentLayout.displayWidth)); - -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* Change the endianness of the aperture */ - switch (info->CurrentLayout.pixel_code) { - case 15: - case 16: save->config_cntl |= APER_0_BIG_ENDIAN_16BPP_SWAP; break; - case 32: save->config_cntl |= APER_0_BIG_ENDIAN_32BPP_SWAP; break; - default: break; - } -#endif - - return TRUE; -} - -/* Define CRTC registers for requested video mode. */ -static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, - DisplayModePtr mode, R128InfoPtr info) -{ - int xres = mode->CrtcHDisplay; - int yres = mode->CrtcVDisplay; - float Hratio, Vratio; - - if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT) { - save->crtc_ext_cntl |= R128_CRTC_CRT_ON; - save->crtc2_gen_cntl = 0; - save->fp_gen_cntl = orig->fp_gen_cntl; - save->fp_gen_cntl &= ~(R128_FP_FPON | - R128_FP_CRTC_USE_SHADOW_VEND | - R128_FP_CRTC_HORZ_DIV2_EN | - R128_FP_CRTC_HOR_CRT_DIV2_DIS | - R128_FP_USE_SHADOW_EN); - save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 | - R128_FP_CRTC_DONT_SHADOW_VPAR); - save->fp_panel_cntl = orig->fp_panel_cntl & (CARD32)~R128_FP_DIGON; - save->lvds_gen_cntl = orig->lvds_gen_cntl & - (CARD32)~(R128_LVDS_ON | R128_LVDS_BLON); - return; - } - - if (xres > info->PanelXRes) xres = info->PanelXRes; - if (yres > info->PanelYRes) yres = info->PanelYRes; - - Hratio = (float)xres/(float)info->PanelXRes; - Vratio = (float)yres/(float)info->PanelYRes; - - save->fp_horz_stretch = - (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5)) - & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) | - (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE | - R128_HORZ_FP_LOOP_STRETCH | - R128_HORZ_STRETCH_RESERVED))); - save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN; - save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO; - if (xres == info->PanelXRes) - save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE); - else - save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE); - - save->fp_vert_stretch = - (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5)) - & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) | - (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE | - R128_VERT_STRETCH_RESERVED))); - save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN; - if (yres == info->PanelYRes) - save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND); - else - save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND); - - save->fp_gen_cntl = (orig->fp_gen_cntl & - (CARD32)~(R128_FP_SEL_CRTC2 | - R128_FP_CRTC_USE_SHADOW_VEND | - R128_FP_CRTC_HORZ_DIV2_EN | - R128_FP_CRTC_HOR_CRT_DIV2_DIS | - R128_FP_USE_SHADOW_EN)); - - save->fp_panel_cntl = orig->fp_panel_cntl; - save->lvds_gen_cntl = orig->lvds_gen_cntl; - save->tmds_crc = orig->tmds_crc; - - /* Disable CRT output by disabling CRT output and setting the CRT - DAC to use CRTC2, which we set to 0's. In the future, we will - want to use the dual CRTC capabilities of the R128 to allow both - the flat panel and external CRT to either simultaneously display - the same image or display two different images. */ - - if(!info->isDFP){ - if (info->BIOSDisplay == R128_BIOS_DISPLAY_FP_CRT) { - save->crtc_ext_cntl |= R128_CRTC_CRT_ON; - } else { - save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON; - save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2; - save->crtc2_gen_cntl = 0; - } - } - - /* WARNING: Be careful about turning on the flat panel */ - if(info->isDFP){ - save->fp_gen_cntl = orig->fp_gen_cntl; - - save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND | - R128_FP_CRTC_USE_SHADOW_ROWCUR | - R128_FP_CRTC_HORZ_DIV2_EN | - R128_FP_CRTC_HOR_CRT_DIV2_DIS | - R128_FP_CRT_SYNC_SEL | - R128_FP_USE_SHADOW_EN); - - save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON); - save->fp_gen_cntl |= (R128_FP_FPON | R128_FP_TDMS_EN | - R128_FP_CRTC_DONT_SHADOW_VPAR | R128_FP_CRTC_DONT_SHADOW_HEND); - save->tmds_transmitter_cntl = (orig->tmds_transmitter_cntl - & ~(CARD32)R128_TMDS_PLLRST) | R128_TMDS_PLLEN; - } - else - save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON); - - save->fp_crtc_h_total_disp = save->crtc_h_total_disp; - save->fp_crtc_v_total_disp = save->crtc_v_total_disp; - save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; - save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; -} - -/* Define PLL registers for requested video mode. */ -static void R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save, - R128PLLPtr pll, double dot_clock) -{ - unsigned long freq = dot_clock * 100; - struct { - int divider; - int bitvalue; - } *post_div, - post_divs[] = { - /* From RAGE 128 VR/RAGE 128 GL Register - Reference Manual (Technical Reference - Manual P/N RRG-G04100-C Rev. 0.04), page - 3-17 (PLL_DIV_[3:0]). */ - { 1, 0 }, /* VCLK_SRC */ - { 2, 1 }, /* VCLK_SRC/2 */ - { 4, 2 }, /* VCLK_SRC/4 */ - { 8, 3 }, /* VCLK_SRC/8 */ - - { 3, 4 }, /* VCLK_SRC/3 */ - /* bitvalue = 5 is reserved */ - { 6, 6 }, /* VCLK_SRC/6 */ - { 12, 7 }, /* VCLK_SRC/12 */ - { 0, 0 } - }; - - if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; - if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; - - for (post_div = &post_divs[0]; post_div->divider; ++post_div) { - save->pll_output_freq = post_div->divider * freq; - if (save->pll_output_freq >= pll->min_pll_freq - && save->pll_output_freq <= pll->max_pll_freq) break; - } - - save->dot_clock_freq = freq; - save->feedback_div = R128Div(pll->reference_div * save->pll_output_freq, - pll->reference_freq); - save->post_div = post_div->divider; - - R128TRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", - save->dot_clock_freq, - save->pll_output_freq, - save->feedback_div, - save->post_div)); - - save->ppll_ref_div = pll->reference_div; - save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); - save->htotal_cntl = 0; - -} - -/* Define DDA registers for requested video mode. */ -static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save, - R128PLLPtr pll, R128InfoPtr info, - DisplayModePtr mode) -{ - int DisplayFifoWidth = 128; - int DisplayFifoDepth = 32; - int XclkFreq; - int VclkFreq; - int XclksPerTransfer; - int XclksPerTransferPrecise; - int UseablePrecision; - int Roff; - int Ron; - - XclkFreq = pll->xclk; - - VclkFreq = R128Div(pll->reference_freq * save->feedback_div, - pll->reference_div * save->post_div); - - if(info->isDFP && !info->isPro2){ - if(info->PanelXRes != mode->CrtcHDisplay) - VclkFreq = (VclkFreq * mode->CrtcHDisplay)/info->PanelXRes; - } - - XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth, - VclkFreq * (info->CurrentLayout.pixel_bytes * 8)); - - UseablePrecision = R128MinBits(XclksPerTransfer) + 1; - - XclksPerTransferPrecise = R128Div((XclkFreq * DisplayFifoWidth) - << (11 - UseablePrecision), - VclkFreq * (info->CurrentLayout.pixel_bytes * 8)); - - Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4); - - Ron = (4 * info->ram->MB - + 3 * MAX(info->ram->Trcd - 2, 0) - + 2 * info->ram->Trp - + info->ram->Twr - + info->ram->CL - + info->ram->Tr2w - + XclksPerTransfer) << (11 - UseablePrecision); - - if (Ron + info->ram->Rloop >= Roff) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "(Ron = %d) + (Rloop = %d) >= (Roff = %d)\n", - Ron, info->ram->Rloop, Roff); - return FALSE; - } - - save->dda_config = (XclksPerTransferPrecise - | (UseablePrecision << 16) - | (info->ram->Rloop << 20)); - - save->dda_on_off = (Ron << 16) | Roff; - - R128TRACE(("XclkFreq = %d; VclkFreq = %d; per = %d, %d (useable = %d)\n", - XclkFreq, - VclkFreq, - XclksPerTransfer, - XclksPerTransferPrecise, - UseablePrecision)); - R128TRACE(("Roff = %d, Ron = %d, Rloop = %d\n", - Roff, Ron, info->ram->Rloop)); - - return TRUE; -} - - -#if 0 -/* Define initial palette for requested video mode. This doesn't do - anything for XFree86 4.0. */ -static void R128InitPalette(R128SavePtr save) -{ - save->palette_valid = FALSE; -} -#endif - -/* Define registers for a requested video mode. */ -static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save) -{ - R128InfoPtr info = R128PTR(pScrn); - double dot_clock = mode->Clock/1000.0; - -#if R128_DEBUG - ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", - mode->name, - dot_clock, - - mode->HDisplay, - mode->HSyncStart, - mode->HSyncEnd, - mode->HTotal, - - mode->VDisplay, - mode->VSyncStart, - mode->VSyncEnd, - mode->VTotal, - pScrn->depth, - pScrn->bitsPerPixel); - if (mode->Flags & V_DBLSCAN) ErrorF(" D"); - if (mode->Flags & V_CSYNC) ErrorF(" C"); - if (mode->Flags & V_INTERLACE) ErrorF(" I"); - if (mode->Flags & V_PHSYNC) ErrorF(" +H"); - if (mode->Flags & V_NHSYNC) ErrorF(" -H"); - if (mode->Flags & V_PVSYNC) ErrorF(" +V"); - if (mode->Flags & V_NVSYNC) ErrorF(" -V"); - ErrorF("\n"); - ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", - mode->name, - dot_clock, - - mode->CrtcHDisplay, - mode->CrtcHSyncStart, - mode->CrtcHSyncEnd, - mode->CrtcHTotal, - - mode->CrtcVDisplay, - mode->CrtcVSyncStart, - mode->CrtcVSyncEnd, - mode->CrtcVTotal, - pScrn->depth, - pScrn->bitsPerPixel); - if (mode->Flags & V_DBLSCAN) ErrorF(" D"); - if (mode->Flags & V_CSYNC) ErrorF(" C"); - if (mode->Flags & V_INTERLACE) ErrorF(" I"); - if (mode->Flags & V_PHSYNC) ErrorF(" +H"); - if (mode->Flags & V_NHSYNC) ErrorF(" -H"); - if (mode->Flags & V_PVSYNC) ErrorF(" +V"); - if (mode->Flags & V_NVSYNC) ErrorF(" -V"); - ErrorF("\n"); -#endif - - info->Flags = mode->Flags; - - R128InitCommonRegisters(save, info); - if (!R128InitCrtcRegisters(pScrn, save, mode, info)) return FALSE; - if (info->HasPanelRegs || info->isDFP) - R128InitFPRegisters(&info->SavedReg, save, mode, info); - if(dot_clock > 0){ - R128InitPLLRegisters(pScrn, save, &info->pll, dot_clock); - if (!R128InitDDARegisters(pScrn, save, &info->pll, info, mode)) - return FALSE; - } - else{ - save->ppll_ref_div = info->SavedReg.ppll_ref_div; - save->ppll_div_3 = info->SavedReg.ppll_div_3; - save->htotal_cntl = info->SavedReg.htotal_cntl; - save->dda_config = info->SavedReg.dda_config; - save->dda_on_off = info->SavedReg.dda_on_off; - } - - R128TRACE(("R128Init returns %p\n", save)); - return TRUE; -} - -/* Initialize a new mode. */ -static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - R128InfoPtr info = R128PTR(pScrn); - - if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE; - /* FIXME? DRILock/DRIUnlock here? */ - pScrn->vtSema = TRUE; - R128Blank(pScrn); - R128RestoreMode(pScrn, &info->ModeReg); - R128Unblank(pScrn); - - info->CurrentLayout.mode = mode; - - return TRUE; -} - -static Bool R128SaveScreen(ScreenPtr pScreen, int mode) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - Bool unblank; - - unblank = xf86IsUnblank(mode); - if (unblank) - SetTimeSinceLastInputEvent(); - - if ((pScrn != NULL) && pScrn->vtSema) { - if (unblank) - R128Unblank(pScrn); - else - R128Blank(pScrn); - } - return TRUE; -} - -Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) -{ - return R128ModeInit(xf86Screens[scrnIndex], mode); -} - -/* Used to disallow modes that are not supported by the hardware. */ -int R128ValidMode(int scrnIndex, DisplayModePtr mode, - Bool verbose, int flag) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - - if(info->isDFP) { - if(info->PanelXRes < mode->CrtcHDisplay || - info->PanelYRes < mode->CrtcVDisplay) - return MODE_NOMODE; - else - return MODE_OK; - } - - if (info->HasPanelRegs) { - if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; - if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; - } - - if (info->HasPanelRegs && - info->BIOSDisplay != R128_BIOS_DISPLAY_CRT && - info->VBIOS) { - int i; - for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) { - int j = R128_BIOS16(i); - - if (mode->CrtcHDisplay == R128_BIOS16(j) && - mode->CrtcVDisplay == R128_BIOS16(j+2)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Modifying mode according to VBIOS: %ix%i [pclk %.1f MHz] for FP to: ", - mode->CrtcHDisplay,mode->CrtcVDisplay, - (float)mode->Clock/1000); - - /* Assume we are using expanded mode */ - if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5); - else j += 9; - - mode->Clock = (CARD32)R128_BIOS16(j) * 10; - - mode->HDisplay = mode->CrtcHDisplay = - ((R128_BIOS16(j+10) & 0x01ff)+1)*8; - mode->HSyncStart = mode->CrtcHSyncStart = - ((R128_BIOS16(j+12) & 0x01ff)+1)*8; - mode->HSyncEnd = mode->CrtcHSyncEnd = - mode->CrtcHSyncStart + (R128_BIOS8(j+14) & 0x1f); - mode->HTotal = mode->CrtcHTotal = - ((R128_BIOS16(j+8) & 0x01ff)+1)*8; - - mode->VDisplay = mode->CrtcVDisplay = - (R128_BIOS16(j+17) & 0x07ff)+1; - mode->VSyncStart = mode->CrtcVSyncStart = - (R128_BIOS16(j+19) & 0x07ff)+1; - mode->VSyncEnd = mode->CrtcVSyncEnd = - mode->CrtcVSyncStart + ((R128_BIOS16(j+19) >> 11) & 0x1f); - mode->VTotal = mode->CrtcVTotal = - (R128_BIOS16(j+15) & 0x07ff)+1; - xf86ErrorF("%ix%i [pclk %.1f MHz]\n", - mode->CrtcHDisplay,mode->CrtcVDisplay, - (float)mode->Clock/1000); - - return MODE_OK; - } - } - xf86DrvMsgVerb(5,pScrn->scrnIndex, X_INFO, - "Mode rejected for FP %ix%i [pclk: %.1f] " - "(not listed in VBIOS)\n", - mode->CrtcHDisplay, mode->CrtcVDisplay, - mode->Clock / 1000); - return MODE_NOMODE; - } - - return MODE_OK; -} - -/* Adjust viewport into virtual desktop such that (0,0) in viewport space - is (x,y) in virtual space. */ -void R128AdjustFrame(int scrnIndex, int x, int y, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int Base; - - if(info->showCache && y && pScrn->vtSema) - y += pScrn->virtualY - 1; - - Base = y * info->CurrentLayout.displayWidth + x; - - switch (info->CurrentLayout.pixel_code) { - case 15: - case 16: Base *= 2; break; - case 24: Base *= 3; break; - case 32: Base *= 4; break; - } - - Base &= ~7; /* 3 lower bits are always 0 */ - - if (info->CurrentLayout.pixel_code == 24) - Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */ - - OUTREG(R128_CRTC_OFFSET, Base); -} - -/* Called when VT switching back to the X server. Reinitialize the video - mode. */ -Bool R128EnterVT(int scrnIndex, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - - R128TRACE(("R128EnterVT\n")); - if (info->FBDev) { - if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE; - } else - if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE; - if (info->accelOn) - R128EngineInit(pScrn); - -#ifdef XF86DRI - if (info->directRenderingEnabled) { - if (info->irq) { - /* Need to make sure interrupts are enabled */ - unsigned char *R128MMIO = info->MMIO; - OUTREG(R128_GEN_INT_CNTL, info->gen_int_cntl); - } - R128CCE_START(pScrn, info); - DRIUnlock(pScrn->pScreen); - } -#endif - - info->PaletteSavedOnVT = FALSE; - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - return TRUE; -} - -/* Called when VT switching away from the X server. Restore the original - text mode. */ -void R128LeaveVT(int scrnIndex, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - R128SavePtr save = &info->ModeReg; - - R128TRACE(("R128LeaveVT\n")); -#ifdef XF86DRI - if (info->directRenderingEnabled) { - DRILock(pScrn->pScreen, 0); - R128CCE_STOP(pScrn, info); - } -#endif - R128SavePalette(pScrn, save); - info->PaletteSavedOnVT = TRUE; - if (info->FBDev) - fbdevHWLeaveVT(scrnIndex,flags); - else - R128Restore(pScrn); -} - - -/* Called at the end of each server generation. Restore the original text - mode, unmap video memory, and unwrap and call the saved CloseScreen - function. */ -static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - R128InfoPtr info = R128PTR(pScrn); - - R128TRACE(("R128CloseScreen\n")); - -#ifdef XF86DRI - /* Disable direct rendering */ - if (info->directRenderingEnabled) { - R128DRICloseScreen(pScreen); - info->directRenderingEnabled = FALSE; - } -#endif - - if (pScrn->vtSema) { - R128Restore(pScrn); - R128UnmapMem(pScrn); - } - - if (info->accel) XAADestroyInfoRec(info->accel); - info->accel = NULL; - - if (info->scratch_save) xfree(info->scratch_save); - info->scratch_save = NULL; - - if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); - info->cursor = NULL; - - if (info->DGAModes) xfree(info->DGAModes); - info->DGAModes = NULL; - - if (info->adaptor) { - xfree(info->adaptor->pPortPrivates[0].ptr); - xf86XVFreeVideoAdaptorRec(info->adaptor); - info->adaptor = NULL; - } - - pScrn->vtSema = FALSE; - - pScreen->BlockHandler = info->BlockHandler; - pScreen->CloseScreen = info->CloseScreen; - return (*pScreen->CloseScreen)(scrnIndex, pScreen); -} - -void R128FreeScreen(int scrnIndex, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - - R128TRACE(("R128FreeScreen\n")); - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(pScrn); - R128FreeRec(pScrn); -} - -/* Sets VESA Display Power Management Signaling (DPMS) Mode. */ -static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn, - int PowerManagementMode, int flags) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int mask = (R128_CRTC_DISPLAY_DIS - | R128_CRTC_HSYNC_DIS - | R128_CRTC_VSYNC_DIS); - - switch (PowerManagementMode) { - case DPMSModeOn: - /* Screen: On; HSync: On, VSync: On */ - OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask); - break; - case DPMSModeStandby: - /* Screen: Off; HSync: Off, VSync: On */ - OUTREGP(R128_CRTC_EXT_CNTL, - R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask); - break; - case DPMSModeSuspend: - /* Screen: Off; HSync: On, VSync: Off */ - OUTREGP(R128_CRTC_EXT_CNTL, - R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask); - break; - case DPMSModeOff: - /* Screen: Off; HSync: Off, VSync: Off */ - OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask); - break; - } -} - -static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on); - -static void R128DisplayPowerManagementSetLCD(ScrnInfoPtr pScrn, - int PowerManagementMode, int flags) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - int mask = R128_LVDS_DISPLAY_DIS; - - switch (PowerManagementMode) { - case DPMSModeOn: - /* Screen: On; HSync: On, VSync: On */ - OUTREGP(R128_LVDS_GEN_CNTL, 0, ~mask); - r128_set_backlight_enable(pScrn, 1); - break; - case DPMSModeStandby: - /* Fall through */ - case DPMSModeSuspend: - /* Fall through */ - break; - case DPMSModeOff: - /* Screen: Off; HSync: Off, VSync: Off */ - OUTREGP(R128_LVDS_GEN_CNTL, mask, ~mask); - r128_set_backlight_enable(pScrn, 0); - break; - } -} - -static int r128_set_backlight_enable(ScrnInfoPtr pScrn, int on) -{ - R128InfoPtr info = R128PTR(pScrn); - unsigned char *R128MMIO = info->MMIO; - unsigned int lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); - - lvds_gen_cntl |= (/*R128_LVDS_BL_MOD_EN |*/ R128_LVDS_BLON); - if (on) { - lvds_gen_cntl |= R128_LVDS_DIGON; - if (!lvds_gen_cntl & R128_LVDS_ON) { - lvds_gen_cntl &= ~R128_LVDS_BLON; - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl); - (void)INREG(R128_LVDS_GEN_CNTL); - usleep(10000); - lvds_gen_cntl |= R128_LVDS_BLON; - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl); - } -#if 0 - lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK; - lvds_gen_cntl |= (0xFF /* backlight_conv[level] */ << - R128_LVDS_BL_MOD_LEVEL_SHIFT); -#endif - lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_EN); - lvds_gen_cntl &= ~R128_LVDS_DISPLAY_DIS; - } else { -#if 0 - lvds_gen_cntl &= ~R128_LVDS_BL_MOD_LEVEL_MASK; - lvds_gen_cntl |= (0xFF /* backlight_conv[0] */ << - R128_LVDS_BL_MOD_LEVEL_SHIFT); -#endif - lvds_gen_cntl |= R128_LVDS_DISPLAY_DIS; - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl); - usleep(10); - lvds_gen_cntl &= ~(R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON - | R128_LVDS_DIGON); - } - - OUTREG(R128_LVDS_GEN_CNTL, lvds_gen_cntl); - - return 0; - } |