diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 15 | ||||
-rw-r--r-- | src/binding.h | 254 | ||||
-rw-r--r-- | src/client.h | 68 | ||||
-rw-r--r-- | src/clientlx.c | 832 | ||||
-rw-r--r-- | src/mga.h | 215 | ||||
-rw-r--r-- | src/mga_2064_crtc.c | 942 | ||||
-rw-r--r-- | src/mga_2064_output.c | 196 | ||||
-rw-r--r-- | src/mga_bios.c | 10 | ||||
-rw-r--r-- | src/mga_dac3026.c | 833 | ||||
-rw-r--r-- | src/mga_dac3026.h | 30 | ||||
-rw-r--r-- | src/mga_dacG.c | 999 | ||||
-rw-r--r-- | src/mga_dacG.h | 12 | ||||
-rw-r--r-- | src/mga_dh.c | 451 | ||||
-rw-r--r-- | src/mga_dri.c | 86 | ||||
-rw-r--r-- | src/mga_driver.c | 1738 | ||||
-rw-r--r-- | src/mga_esc.c | 795 | ||||
-rw-r--r-- | src/mga_g450pll.c | 61 | ||||
-rw-r--r-- | src/mga_g_crtc.c | 904 | ||||
-rw-r--r-- | src/mga_g_crtc2.c | 388 | ||||
-rw-r--r-- | src/mga_g_output.c | 526 | ||||
-rw-r--r-- | src/mga_halmod.c | 42 | ||||
-rw-r--r-- | src/mga_macros.h | 18 | ||||
-rw-r--r-- | src/mga_merge.c | 975 | ||||
-rw-r--r-- | src/mga_merge.h | 19 | ||||
-rw-r--r-- | src/mga_reg.h | 20 | ||||
-rw-r--r-- | src/mga_vga.c | 94 |
26 files changed, 3473 insertions, 7050 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 17211bb..61c2b26 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,33 +30,30 @@ mga_drv_ladir = @moduledir@/drivers mga_drv_la_LIBADD = $(noinst_LTLIBRARIES) mga_drv_la_SOURCES = \ - binding.h \ - client.h \ - clientlx.c \ mga_arc.c \ mga_bios.c \ mga_common.h \ mga_dac3026.c \ mga_dacG.c \ mga_dga.c \ - mga_dh.c \ mga_driver.c \ - mga_esc.c \ mga_g450pll.c \ mga.h \ - mga_halmod.c \ mga_hwcurs.c \ mga_macros.h \ mga_maven.h \ - mga_merge.c \ - mga_merge.h \ mgareg_flags.h \ mga_reg.h \ mga_sarea.h \ mga_shadow.c \ mga_ucode.h \ mga_vga.c \ - mga_video.c + mga_video.c \ + mga_2064_crtc.c \ + mga_2064_output.c \ + mga_g_crtc.c \ + mga_g_crtc2.c \ + mga_g_output.c if DRI mga_drv_la_SOURCES += \ diff --git a/src/binding.h b/src/binding.h deleted file mode 100644 index 6dcd1e9..0000000 --- a/src/binding.h +++ /dev/null @@ -1,254 +0,0 @@ -/************************************************************************************** - - @doc MGA MGA_STRUCT - - @module MGA Structures | Structure of The MGA Layer - @normal Copyright © 1997, Matrox Graphics Inc. - - All Rights Reserved. - - @head3 MGA Structures | - @index struct | MGA_STRUCT - - @end - -***************************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/HALlib/binding.h,v 1.3 2000/10/24 22:45:08 dawes Exp $ */ - -#ifndef _BINDING -#define _BINDING - -#ifndef _INTERNALBINDING - -#define BINDING_NOERROR 0x00000000 -#define BINDING_ERROR 0x90000000 -#define FAR -#define DECL - -typedef void VOID; -typedef void FAR *LPVOID; -typedef void FAR *LPBOARDHANDLE; - -typedef long LONG; -typedef unsigned long ULONG; -typedef unsigned long FLONG; -typedef unsigned long FAR *LPULONG; - -typedef char CHAR; -typedef unsigned char UCHAR; -typedef unsigned char FAR*LPUCHAR; - -typedef struct TAGCLIENTTABLE{ - ULONG (DECL *ClientReadConfigSpaceByte )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientReadConfigSpaceDword )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientWriteConfigSpaceByte )(LPVOID , ULONG, UCHAR); - ULONG (DECL *ClientWriteConfigSpaceDword )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientOpenRegisterBase )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientCloseRegisterBase )(LPVOID ); - ULONG (DECL *ClientReadRegisterByte )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientReadRegisterDword )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientWriteRegisterByte )(LPVOID , ULONG, UCHAR); - ULONG (DECL *ClientWriteRegisterDword )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientOpenMemoryBase )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientCloseMemoryBase )(LPVOID ); - ULONG (DECL *ClientReadMemoryByte )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientReadMemoryDword )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientWriteMemoryByte )(LPVOID , ULONG, UCHAR); - ULONG (DECL *ClientWriteMemoryDword )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientOpenSystemDevice )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientCloseSystemDevice )(LPVOID ); - ULONG (DECL *ClientReadSystemDeviceByte )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientReadSystemDeviceDword )(LPVOID , ULONG, LPVOID ); - ULONG (DECL *ClientWriteSystemDeviceByte )(LPVOID , ULONG, UCHAR); - ULONG (DECL *ClientWriteSystemDeviceDword )(LPVOID , ULONG, ULONG); - ULONG (DECL *ClientWait )(LPVOID , ULONG); - ULONG (DECL *ClientGetBiosInfo ) (LPVOID, LPVOID, LPVOID); - ULONG (DECL *ClientReadDDCEdid ) (LPVOID, LPVOID, ULONG); -#ifdef DEBUG - ULONG (DECL *ClientDebug ) (LPVOID, ULONG, LPVOID, ULONG, LPVOID); -#endif -} CLIENTTABLE, FAR *LPCLIENTTABLE; - -#endif /* _INTERNALBINDING */ - -/*************************************************************************************************** - MGAHWINFO STRUCTURE - *************************************************************************************************** - @struct MGAHWINFO | Public MGA Board Information - @field OUT ULONG | ulCapsFirstOutput | Capabilities of firts output - @flag Bit 0 | Analog output supported on primary CRTC - @flag Bit 1 | Digital output supported on primary CRTC - @flag Bit 2 | TV output supported on primary CRTC - @flag Bit 3 | Analog output supported on second CRTC - @flag Bit 4 | Digital output supported on second CRTC - @flag Bit 5 | TV output supported on second CRTC - @flag Bit 6 | VGA output supported - @field OUT ULONG | ulCapsSecondOutput | Capabilities of second output - @flag Bit 0 | Analog output supported on primary CRTC - @flag Bit 1 | Digital output supported on primary CRTC - @flag Bit 2 | TV output supported on primary CRTC - @flag Bit 3 | Analog output supported on second CRTC - @flag Bit 4 | Digital output supported on second CRTC - @flag Bit 5 | TV output supported on second CRTC - @flag Bit 6 | VGA output supported - @field OUT ULONG | ulVideoMemory | Total number of video memory in bytes - @end - **************************************************************************************************/ -typedef struct TAGMGAHWINFO { - ULONG ulCapsFirstOutput; - ULONG ulCapsSecondOutput; - ULONG ulVideoMemory; -} MGAHWINFO, FAR *LPMGAHWINFO; - -/*************************************************************************************************** - MGAMODEINFO STRUCTURE - *************************************************************************************************** - @struct MGAMODEINFO | Mode Information - @field IN FLONG | flOutput | Where we want to apply this parameters - @flag Bit 0 | Use second CRTC - @flag Bit 1 | Use primary analog output - @flag Bit 2 | Use secondary analog output - @flag Bit 3 | Use primary digital output - @flag Bit 4 | Use secondary digital output - @flag Bit 5 | Force a particular frame buffer pitch - @flag Bit 6 | Force a particular display origin - @flag Bit 7-31 | Reserved - @field IN ULONG | ulDispWidth | Display Width in pixels - @field IN ULONG | ulDispHeight | Display Height in pixels - @field IN ULONG | ulDeskWidth | Desktop Width in pixels - @field IN ULONG | ulDeskHeight | Desktop Height in pixels - @field IN OUT ULONG | ulFBPitch | Frame Buffer Pitch in pixel - @field IN ULONG | ulBpp | Bits Per Pixels and input format - @flag lower 16 bit | Bits per pixel - <nl><tab> 8, 15, 16, 24 or 32 - @flag upper 16 bit | Input format - <nl><tab> 0 RGB - <nl><tab> 1 RGBA - <nl><tab> 2 YcbCr 4:2:0 3 Planes - <nl><tab> 3 YcbCr 4:2:0 4 Planes - <nl><tab> 4 YcbCr 4:2:2-UYVY - <nl><tab> 5 YcbCr 4:2:2-YUY2 - <nl><tab> 6-10 none interleave mode - <nl><tab> 6 NI RGBA - <nl><tab> 7 NI YcbCr 4:2:0 3 Planes - <nl><tab> 8 NI YcbCr 4:2:0 4 Planes - <nl><tab> 9 NI YcbCr 4:2:2-UYVY - <nl><tab> 10 NI YcbCr 4:2:2-YUY2 - @field IN ULONG | ulZoom | Zoom factor - @flag 1x (1), 2x (2) or 4x (4)| - @field IN OUT FLONG | flSignalMode | Signal Mode - @flag Bit 0 | Interlace (0 : Non-interlace / 1: Interlace) - @flag Bit 1 | Overscan (0 : No Overscan / 1 : Overscan) - @flag Bit 2 | Horizontal Sync Polarity (0 : Negative / 1 : Positive) - @flag Bit 3 | Vertical Sync Polarity (0 : Negative / 1 : Positive) - @flag Bit 4-7 | Standard TV output - <nl><tab>000 - PAL B G H - <nl><tab>001 - NTSC M - <nl><tab>010..111 - Reserved - @flag Bit 8-31 | Reserved for future use - @field IN OUT ULONG | ulRefreshRate | Vertical Refresh Rate in Hz - @field IN OUT ULONG | ulHorizRate | Horizontal Refresh Rate in KHz - @field IN OUT ULONG | ulPixClock | Pixel Clock in kHz - @field IN OUT ULONG | ulHFPorch | Horizontal front porch in pixels - @field IN OUT ULONG | ulHSync | Horizontal Sync in pixels - @field IN OUT ULONG | ulHBPorch | Horizontal back porch in pixels - @field IN OUT ULONG | ulVFPorch | Vertical front porch in lines - @field IN OUT ULONG | ulVSync | Vertical Sync in lines - @field IN OUT ULONG | ulVBPorch | Vertical back Porch in lines - @field IN OUT ULONG | ulDisplayOrg | Origin of the display Offset(pixels) - @field IN OUT ULONG | ulDstOrg | Origin of the drawing Offset in the frame (pixels) - @field IN OUT ULONG | ulPanXGran | Panning in X granularity in pixel - @field IN OUT ULONG | ulPanYGran | Panning in Y granularity in pixel - @field IN OUT ULONG | ulTVStandard | TV Standard - @field IN OUT ULONG | ulCableType | Cable Type - @end - **************************************************************************************************/ -typedef struct TAGMAGMODEINFO { - FLONG flOutput; /* Where we want to apply this parameters */ - ULONG ulDispWidth; /* Display Width in pixels */ - ULONG ulDispHeight; /* Display Height in pixels */ - ULONG ulDeskWidth; /* Desktop Width in pixels */ - ULONG ulDeskHeight; /* Desktop Height in pixels */ - ULONG ulFBPitch; /* Frame Buffer Pitch in pixel */ - ULONG ulBpp; /* Bits Per Pixels / input format */ - ULONG ulZoom; /* Zoom factor */ - FLONG flSignalMode; /* Signal Mode */ - ULONG ulRefreshRate; /* Vertical Refresh Rate in Hz */ - ULONG ulHorizRate; /* Horizontal Refresh Rate in KHz */ - ULONG ulPixClock; /* Pixel Clock in kHz */ - ULONG ulHFPorch; /* Horizontal front porch in pixels */ - ULONG ulHSync; /* Horizontal Sync in pixels */ - ULONG ulHBPorch; /* Horizontal back porch in pixels */ - ULONG ulVFPorch; /* Vertical front porch in lines */ - ULONG ulVSync; /* Vertical Sync in lines */ - ULONG ulVBPorch; /* Vertical back Porch in lines */ - ULONG ulDisplayOrg; /* Origin of the display Offset(bytes) */ - ULONG ulDstOrg; /* Origin of the drawing Offset in the frame (bytes) */ - ULONG ulPanXGran; /* Panning in X granularity in pixel */ - ULONG ulPanYGran; /* Panning in Y granularity in pixel */ - ULONG ulTVStandard; /* TV Standard */ - ULONG ulCableType; /* Cable Type */ -} MGAMODEINFO, FAR *LPMGAMODEINFO; - -#define MGAHWINFOCAPS_CRTC1_ANALOG 1L -#define MGAHWINFOCAPS_CRTC1_DIGITAL (1L << 1) -#define MGAHWINFOCAPS_CRTC1_TV (1L << 2) -#define MGAHWINFOCAPS_CRTC2_ANALOG (1L << 3) -#define MGAHWINFOCAPS_CRTC2_DIGITAL (1L << 4) -#define MGAHWINFOCAPS_CRTC2_TV (1L << 5) -#define MGAHWINFOCAPS_OUTPUT_VGA (1L << 6) -#define MGAHWINFOCAPS_CRTC2 (MGAHWINFOCAPS_CRTC2_ANALOG | MGAHWINFOCAPS_CRTC2_DIGITAL | MGAHWINFOCAPS_CRTC2_TV) -#define MGAHWINFOCAPS_OUTPUT_ANALOG (MGAHWINFOCAPS_CRTC1_ANALOG | MGAHWINFOCAPS_CRTC2_ANALOG) -#define MGAHWINFOCAPS_OUTPUT_DIGITAL (MGAHWINFOCAPS_CRTC1_DIGITAL | MGAHWINFOCAPS_CRTC2_DIGITAL) -#define MGAHWINFOCAPS_OUTPUT_TV (MGAHWINFOCAPS_CRTC1_TV | MGAHWINFOCAPS_CRTC2_TV) - -#define MGAMODEINFO_SECOND_CRTC 1L -#define MGAMODEINFO_ANALOG1 (1L << 1) -#define MGAMODEINFO_ANALOG2 (1L << 2) -#define MGAMODEINFO_DIGITAL1 (1L << 3) -#define MGAMODEINFO_DIGITAL2 (1L << 4) -#define MGAMODEINFO_FORCE_PITCH (1L << 5) -#define MGAMODEINFO_FORCE_DISPLAYORG (1L << 6) -#define MGAMODEINFO_TV (1L << 7) -#define MGAMODEINFO_TESTONLY 0x80000000 - -/* Cable Type */ -#define TV_YC_COMPOSITE 0 -#define TV_SCART_RGB 1 -#define TV_SCART_COMPOSITE 2 -#define TV_SCART_TYPE2 3 - -/* TV Standard */ - -#define TV_PAL 0 -#define TV_NTSC 1 - -#if defined(__cplusplus) - extern "C" { -#endif - -ULONG MGACloseLibrary(LPBOARDHANDLE pBoard); -ULONG MGAValidateMode(LPBOARDHANDLE pBoard, LPMGAMODEINFO pMgaModeInfo); -ULONG MGAValidateVideoParameters(LPBOARDHANDLE pBoard, LPMGAMODEINFO pMgaModeInfo); -ULONG MGASetMode(LPBOARDHANDLE pBoard, LPMGAMODEINFO pMgaModeInfo); -ULONG MGASetTVMode(LPBOARDHANDLE pBoard, LPMGAMODEINFO pMgaModeInfo); -ULONG MGASetVgaMode(LPBOARDHANDLE pBoard); -ULONG MGASaveVgaState(LPBOARDHANDLE pBoard); -ULONG MGARestoreVgaState(LPBOARDHANDLE pBoard); -ULONG MGAInitHardware(LPBOARDHANDLE pBoard); -ULONG MGAGetVideoParameters(LPBOARDHANDLE pBoard, LPMGAMODEINFO pMgaModeInfo, ULONG ulRefresh); -ULONG MGAGetHardwareInfo(LPBOARDHANDLE pBoard, LPMGAHWINFO pMgaHwInfo); -LPVOID MGAGetClientPointer(LPBOARDHANDLE pBoard); -ULONG MGAOpenLibrary(LPBOARDHANDLE pBoard, LPVOID lpClient, ULONG ulClientSize); -ULONG MGAGetBOARDHANDLESize(void); -ULONG MGASetTVStandard(LPBOARDHANDLE pBoard, ULONG ulTVStandard); -ULONG MGASetTVCableType(LPBOARDHANDLE pBoard, ULONG ulCableType); -ULONG HALSetDisplayStart(LPBOARDHANDLE pBoard, ULONG x, ULONG y, ULONG crtc); - -#if defined(__cplusplus) - } -#endif - -#endif /* _BINDING */ - - diff --git a/src/client.h b/src/client.h deleted file mode 100644 index 8348b64..0000000 --- a/src/client.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _CLIENT -#define _CLIENT - -#include "binding.h" - -#if defined(__cplusplus) - extern "C" { -#endif - -typedef void* LPBIOSREGS; -#define ASSERT_HANDLER(pBoard) - -typedef struct TAGCLIENTDATA -{ - ULONG ulFrameBufferBase; - ULONG ulRegisterBase; - pointer pMga; -} CLIENTDATA, *LPCLIENTDATA; - -extern ULONG DECL ClientReadConfigSpaceByte(LPBOARDHANDLE, ULONG, LPUCHAR); -extern ULONG DECL ClientReadConfigSpaceDword(LPBOARDHANDLE , ULONG, LPULONG ); -extern ULONG DECL ClientWriteConfigSpaceByte (LPBOARDHANDLE , ULONG, UCHAR); -extern ULONG DECL ClientWriteConfigSpaceDword(LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientOpenRegisterBase(LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientCloseRegisterBase (LPBOARDHANDLE ); -extern ULONG DECL ClientReadRegisterByte(LPBOARDHANDLE , ULONG, LPUCHAR ); -extern ULONG DECL ClientReadRegisterDword(LPBOARDHANDLE , ULONG, LPULONG ); -extern ULONG DECL ClientWriteRegisterByte (LPBOARDHANDLE , ULONG, UCHAR); -extern ULONG DECL ClientWriteRegisterDword(LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientOpenMemoryBase(LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientCloseMemoryBase(LPBOARDHANDLE ); -extern ULONG DECL ClientReadMemoryByte(LPBOARDHANDLE , ULONG, LPUCHAR ); -extern ULONG DECL ClientReadMemoryDword (LPBOARDHANDLE , ULONG, LPULONG ); -extern ULONG DECL ClientWriteMemoryByte(LPBOARDHANDLE , ULONG, UCHAR); -extern ULONG DECL ClientWriteMemoryDword (LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientOpenSystemDevice (LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientCloseSystemDevice (LPBOARDHANDLE ); -extern ULONG DECL ClientReadSystemDeviceByte(LPBOARDHANDLE , ULONG, LPUCHAR ); -extern ULONG DECL ClientReadSystemDeviceDword(LPBOARDHANDLE , ULONG, LPULONG ); -extern ULONG DECL ClientWriteSystemDeviceByte(LPBOARDHANDLE , ULONG, UCHAR); -extern ULONG DECL ClientWriteSystemDeviceDword (LPBOARDHANDLE , ULONG, ULONG); -extern ULONG DECL ClientWait (LPBOARDHANDLE , ULONG); -extern ULONG DECL ClientLocateFirstTwisterOfQuad(ULONG); -extern ULONG DECL ClientSearchDevNode(ULONG, UCHAR, UCHAR); -extern ULONG DECL ClientGetBiosInfo(LPBOARDHANDLE, LPUCHAR, LPULONG ); -extern ULONG DECL ClientDebug (LPBOARDHANDLE , ULONG, LPUCHAR, ULONG, LPVOID); -extern ULONG DECL ClientCallBiosInt10(LPBOARDHANDLE, LPBIOSREGS); -extern ULONG DECL ClientReadDDCEdid(LPBOARDHANDLE, LPUCHAR, ULONG); -extern ULONG DECL ClientCustomCall(LPBOARDHANDLE, ULONG, LPVOID, LPVOID); -extern ULONG DECL ClientApplyEpromPatch(LPBOARDHANDLE); -extern ULONG DECL ClientDetectHostInterface(LPBOARDHANDLE, LPULONG); -extern ULONG DECL ClientHSLPatchFunction(LPBOARDHANDLE, ULONG, ULONG, LPUCHAR); -extern ULONG DECL InitClientFunctions(LPBOARDHANDLE, ULONG); -extern ULONG DECL ClientInitTimeBase(LPBOARDHANDLE); -extern ULONG DECL ClientOpenDMABase(LPBOARDHANDLE, ULONG, ULONG); -extern ULONG DECL ClientReadDMAByte(LPBOARDHANDLE, ULONG, LPUCHAR); -extern ULONG DECL ClientReadBIOS(LPBOARDHANDLE, ULONG, ULONG, ULONG, ULONG, LPUCHAR); -extern ULONG DECL ClientWriteBIOS(LPBOARDHANDLE, ULONG, ULONG, ULONG, ULONG); - -#if defined(__cplusplus) - } -#endif - -#define ESC_CUSTOM_SET_FUNCTION_PTR 0x80000200 -#define ESC_CUSTOM_GET_FUNCTION_PTR 0x80000201 -#define ESC_CUSTOM_PATCH_HSL 0x80000202 - -#endif diff --git a/src/clientlx.c b/src/clientlx.c deleted file mode 100644 index 306d3ed..0000000 --- a/src/clientlx.c +++ /dev/null @@ -1,832 +0,0 @@ -/******************************************************************************\ - - clientlx.c - - Copyright © 1997, Matrox Graphics Inc. - - All Rights Reserved. - -\******************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86_OSproc.h" -#include "xf86Pci.h" -#include "client.h" -#include "mga.h" - -CLIENTTABLE ClientFunctions = { - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadConfigSpaceByte, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadConfigSpaceDword, - (ULONG (DECL *)(LPVOID,ULONG,UCHAR)) ClientWriteConfigSpaceByte, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientWriteConfigSpaceDword, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientOpenRegisterBase, - (ULONG (DECL *)(LPVOID)) ClientCloseRegisterBase, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadRegisterByte, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadRegisterDword, - (ULONG (DECL *)(LPVOID,ULONG,UCHAR)) ClientWriteRegisterByte, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientWriteRegisterDword, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientOpenMemoryBase, - (ULONG (DECL *)(LPVOID)) ClientCloseMemoryBase, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadMemoryByte, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadMemoryDword, - (ULONG (DECL *)(LPVOID,ULONG,UCHAR)) ClientWriteMemoryByte, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientWriteMemoryDword, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientOpenSystemDevice, - (ULONG (DECL *)(LPVOID)) ClientCloseSystemDevice, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadSystemDeviceByte, - (ULONG (DECL *)(LPVOID,ULONG,LPVOID)) ClientReadSystemDeviceDword, - (ULONG (DECL *)(LPVOID,ULONG,UCHAR)) ClientWriteSystemDeviceByte, - (ULONG (DECL *)(LPVOID,ULONG,ULONG)) ClientWriteSystemDeviceDword, - (ULONG (DECL *)(LPVOID,ULONG)) ClientWait, - (ULONG (DECL *)(LPVOID,LPVOID,LPVOID)) ClientGetBiosInfo, - (ULONG (DECL *)(LPVOID,LPVOID,ULONG)) ClientReadDDCEdid -}; - -/******************************************************************************\ - - Function : ClientReadConfigSpaceByte - - Description : Read a Byte from the configuration space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specifib board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR *pucByte | pointer to a byte that will receive - the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadConfigSpaceByte(LPBOARDHANDLE pBoard, ULONG ulOffset, - UCHAR *pucByte) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - MGAPtr pMga = (MGAPtr)pClientStruct->pMga; - - ASSERT_HANDLER(pBoard); - - *pucByte = pciReadByte(pMga->PciTag,ulOffset); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientReadConfigSpaceDword - - Description : Read a Dword from the configuration space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG *pulDword | Dword to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadConfigSpaceDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG *pulDword) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - MGAPtr pMga = (MGAPtr)pClientStruct->pMga; - - ASSERT_HANDLER(pBoard); - - *pulDword = pciReadLong(pMga->PciTag,ulOffset); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientWriteConfigSpaceByte - - Description : Write a Byte from the configuration space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR ucByte | Byte to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteConfigSpaceByte(LPBOARDHANDLE pBoard, ULONG ulOffset, - UCHAR ucByte) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - MGAPtr pMga = (MGAPtr)pClientStruct->pMga; - - ASSERT_HANDLER(pBoard); - - pciWriteByte(pMga->PciTag,ulOffset, ucByte); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientWriteConfigSpaceDword - - Description : Write a Dword from the configuration space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG ulDword | Dword containing the data to be written - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteConfigSpaceDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG ulDword) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - MGAPtr pMga = (MGAPtr)pClientStruct->pMga; - - ASSERT_HANDLER(pBoard); - - pciWriteLong(pMga->PciTag,ulOffset, ulDword); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientOpenRegisterBase - - Description : Map the register base for future call to ClientReadRegisterX - and ClientWriteRegisterX. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulAddress | Physical address of the Register aperture - ULONG ulSize | Size in Byte of the Register Aperture - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientOpenRegisterBase(LPBOARDHANDLE pBoard, ULONG ulAddress, ULONG ulSize) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - MGAPtr pMga = (MGAPtr)pClientStruct->pMga; - - ASSERT_HANDLER(pBoard); - - pClientStruct->ulRegisterBase = (ULONG) pMga->IOBase; - - return 0; -} - - -/******************************************************************************\ - - Function : ClientCloseRegisterBase - - Description : Unmap the register base address and free resources needed - to address it. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientCloseRegisterBase(LPBOARDHANDLE pBoard) -{ - ASSERT_HANDLER(pBoard); - return 0; -} - - -/******************************************************************************\ - - Function : ClientReadRegisterByte - - Description : Read a byte from the Register space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure. - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR *pucByte | pointer to the byte that will receive - the data. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadRegisterByte(LPBOARDHANDLE pBoard, ULONG ulOffset, - UCHAR *pucByte) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *pucByte = *((UCHAR *)(pClientStruct->ulRegisterBase + ulOffset)); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientReadRegisterDword - - Description : Read a Dword from the Register space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG *pulDword | pointer to the dword that will receive - the data. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadRegisterDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG *pulDword) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *pulDword = *((ULONG *)(pClientStruct->ulRegisterBase + ulOffset)); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientWriteRegisterByte - - Description : Write a Byte from the Register space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR ucByte | CHAR to receive the data. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteRegisterByte(LPBOARDHANDLE pBoard, ULONG ulOffset, - UCHAR ucByte) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *((UCHAR *)(pClientStruct->ulRegisterBase + ulOffset)) = ucByte; - - return 0; -} - - -/******************************************************************************\ - - Function : ClientWriteRegisterSpaceDword - - Description : Write a Dword from the Register space. - - I/O Desc. : LPBOARDHANDLE *| pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG ulDword | Dword to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteRegisterDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG ulDword) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *((ULONG *)(pClientStruct->ulRegisterBase + ulOffset)) = ulDword; - - return 0; -} - - -/******************************************************************************\ - - Function : ClientOpenMemoryBase - - Description : Map the Memory base for future call to ClientReadMemoryX - and ClientWriteMemoryX. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulAddress | Physical address of the Register aperture - ULONG ulSize | Size in Byte of the Register Aperture - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientOpenMemoryBase(LPBOARDHANDLE pBoard, ULONG ulAddress, ULONG ulSize) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - MGAPtr pMga = (MGAPtr) pClientStruct->pMga; - - ASSERT_HANDLER(pBoard); - - pClientStruct->ulFrameBufferBase = (ULONG) pMga->FbBase; - - return 0; -} - - -/******************************************************************************\ - - Function : ClientCloseMemoryBase - - Description : Unmap the Frame Buffer aperture and free resources - needed to address it. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientCloseMemoryBase(LPBOARDHANDLE pBoard) -{ - ASSERT_HANDLER(pBoard); - return 0; -} - - -/******************************************************************************\ - - Function : ClientReadMemoryByte - - Description : Read a Byte from the Frame Buffer space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR *ucByte | CHAR to receive the data - - Return Val : ULONG -\******************************************************************************/ -ULONG ClientReadMemoryByte(LPBOARDHANDLE pBoard, ULONG ulOffset, UCHAR *pucByte) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *pucByte = *((UCHAR *)(pClientStruct->ulFrameBufferBase + ulOffset)); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientReadMemoryDword - - Description : Read a Dword from the Frame Buffer Space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG *uDword | Dword to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadMemoryDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG *pulDword) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *pulDword = *((ULONG *)(pClientStruct->ulFrameBufferBase + ulOffset)); - - return 0; -} - - -/******************************************************************************\ - - Function : ClientWriteMemoryByte - - Description : Write a Byte from the Frame Buffer space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR ucByte | CHAR to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteMemoryByte(LPBOARDHANDLE pBoard, ULONG ulOffset, UCHAR ucByte) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *((UCHAR *)(pClientStruct->ulFrameBufferBase + ulOffset)) = ucByte; - - return 0; -} - - -/******************************************************************************\ - - Function : ClientWriteMemoryDword - - Description : Write a Dword from the Frame Buffer space. - - I/O desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG ulDword | Dword to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteMemoryDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG ulDword) -{ - LPCLIENTDATA pClientStruct = MGAGetClientPointer(pBoard); - - ASSERT_HANDLER(pBoard); - - *((ULONG *)(pClientStruct->ulFrameBufferBase + ulOffset)) = ulDword; - - return 0; -} - - -/******************************************************************************\ - - Function : ClientOpenSystemDevice - - Description : Map a System device aperture for future call to - ClientReadSystemDeviceX and ClientWriteSystemDeviceX. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulAddress | Physical address of the Register aperture - ULONG ulSize | Size in Byte of the Register Aperture - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientOpenSystemDevice(LPBOARDHANDLE pBoard, ULONG ulAddress, - ULONG ulSize) -{ - return 1; -} - - -/******************************************************************************\ - - Function : ClientCloseSystemDevice - - Description : Unmap the System Device aperture address and free - resources needed to address it. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientCloseSystemDevice (LPBOARDHANDLE pBoard) -{ - return 1; -} - - -/******************************************************************************\ - - Function : ClientReadSystemDeviceByte - - Description : Read a Byte from the device Space. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG pucByte | Byte to read the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadSystemDeviceByte(LPBOARDHANDLE pBoard, ULONG ulOffset, - UCHAR *pucByte) -{ - return 1; -} - - -/******************************************************************************\ - - Function : ClientReadSystemDeviceDword - - Description : Read a Dword from the Frame Buffer Space - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG ulDword | Dword to Read the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadSystemDeviceDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG *pulDword) -{ - return 1; -} - - -/******************************************************************************\ - - Function : ClientWriteSystemByte - - Description : Write a Byte from the System Device Aperture - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - UCHAR ucByte | Byte to receive the data - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteSystemDeviceByte(LPBOARDHANDLE pBoard, ULONG ulOffset, - UCHAR ucByte) -{ - return 1; -} - - -/******************************************************************************\ - - Function : ClientWriteSystemDword - - Description : Write a Dword from the System Device Aperture. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulOffset | Offset of the Byte to be read. - ULONG uDword | Dword to receive the data - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWriteSystemDeviceDword(LPBOARDHANDLE pBoard, ULONG ulOffset, - ULONG ulDword) -{ - return 1; -} - - -/******************************************************************************\ - - Function : ClientWait - - Description : Wait for ulDelayus micro-seconds. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - ULONG ulDelayus | Delay in uSec - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientWait (LPBOARDHANDLE pBoard, ULONG ulDelayus) -{ - int i; - ULONG ulTmp; - - ASSERT_HANDLER(pBoard); - - for(i = 0; i < ulDelayus * 3; i++) - { - ClientReadRegisterDword(pBoard,0x1e14,&ulTmp); - } - - return 0; -} - - -/******************************************************************************\ - - Function : ClientGetBiosInfo - - Description : This function will be call if no PINS can be found - in physical EEPROM. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - LPUCHAR | Buffer where we copy bios pins. - ULONG | Bios version - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientGetBiosInfo(LPBOARDHANDLE pBoard, LPUCHAR pucPins,LPULONG pulBIOSVersion) -{ - Bool bNotFound = TRUE; - UCHAR ucBIOS[32768]; - UCHAR ucTmpByte; - UCHAR ucCheckSum; - UCHAR ucPinsIndex; - UCHAR ucPinsSize; - ULONG ulTmpDword; - ULONG ulPinsOffset = 0; - ULONG ulPCIINFOffset; - - ASSERT_HANDLER(pBoard); - - xf86ReadBIOS(0xc0000,0,ucBIOS,32768); - - if(ucBIOS[0] == 0x55) - { - if(ucBIOS[1] == 0xaa) - { - while((ulPinsOffset < 0x10000) && bNotFound) - { - ulTmpDword = *(ULONG *)(ucBIOS + ulPinsOffset); - ucPinsSize = (UCHAR) (ulTmpDword >> 16); - if(((ulTmpDword & 0x0000ffff) == 0x0000412e) - && ucPinsSize <= 128) - { - ucCheckSum = 0; - for(ucPinsIndex = 0;ucPinsIndex < ucPinsSize; ucPinsIndex++) - { - pucPins[ucPinsIndex] = ucBIOS[ulPinsOffset + - ucPinsIndex]; - ucCheckSum += pucPins[ucPinsIndex]; - } - if(ucCheckSum == 0) - { - bNotFound = FALSE; - } - } - ulPinsOffset++; - } - - if(bNotFound) - { - return 1; - } - - ulPCIINFOffset = *(ULONG *)(ucBIOS + 0x18); - ulPCIINFOffset &= 0x0000ffff; - ulTmpDword = *(ULONG *)(ucBIOS + ulPCIINFOffset); - - if(ulTmpDword == 0x52494350) /* "PCIR" */ - { - ulPCIINFOffset += 0x12; - ulTmpDword = *(ULONG *)(ucBIOS + ulPCIINFOffset); - *pulBIOSVersion = ((ULONG) ((ulTmpDword & 0xf0) >> 4) << 16) | - ((ulTmpDword &0xf) << 12) | ((ulTmpDword >> 8) - & 0xff); - } - else - { - return 1; - } - } - else - { - return 1; - } - } - else - { - return 1; - } - - if(!*pulBIOSVersion) - { - ucTmpByte = ucBIOS[5]; - *pulBIOSVersion = ((ULONG) (ucTmpByte >> 4) << 16) | ((ULONG) - (ucTmpByte & 0x0f) << 12); - } - - return 0; -} - -/******************************************************************************\ - - Function : ClientCallBiosInt10 - - Description : Call the BIOS Int10h with specified parameters. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - LPBIOSREGS pBiosRegs | Pointor to the Bios register - structure. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientCallBiosInt10(LPBOARDHANDLE pBoard, LPBIOSREGS pBiosRegs) -{ - ASSERT_HANDLER(pBoard); - - return 1; -} - - -/******************************************************************************\ - - Function : ClientReadDDCEdid - - Description : Not implemented. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - LPBIOSREGS pBiosRegs | Pointor to the Bios register - structure. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientReadDDCEdid(LPBOARDHANDLE pBoard, LPUCHAR pEdid, - ULONG ulMonitorIndex) -{ - ASSERT_HANDLER(pBoard); - - return 1; -} - - -/******************************************************************************\ - - Function : ClientCustomCall - - Description : Not implemented. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - LPBIOSREGS pBiosRegs | Pointor to the Bios register - structure. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientCustomCall(LPBOARDHANDLE pBoard, ULONG ulServiceNumber, - LPVOID pInData, LPVOID pOutData) -{ - ASSERT_HANDLER(pBoard); - - return 1; -} - - -/******************************************************************************\ - - Function : ClientApplyEpromPatch - - Description : Not implemented. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - LPBIOSREGS pBiosRegs | Pointor to the Bios register - structure. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientApplyEpromPatch(LPBOARDHANDLE pBoard) -{ - ASSERT_HANDLER(pBoard); - - return 1; -} - - -/******************************************************************************\ - - Function : ClientDetectHostInterface - - Description : Not implemented. - - I/O Desc. : LPBOARDHANDLE pBoard | Handle to the board structure - containing all the information about a specific board. - LPBIOSREGS pBiosRegs | Pointor to the Bios register - structure. - - Return Val : ULONG - -\******************************************************************************/ -ULONG ClientDetectHostInterface(LPBOARDHANDLE pBoard, LPULONG pulData) -{ - ASSERT_HANDLER(pBoard); - - return 1; -} - @@ -26,6 +26,9 @@ #include "xf86DDC.h" #include "xf86xv.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" + #ifdef XF86DRI #include "xf86drm.h" @@ -40,17 +43,11 @@ #include "mga_dri.h" #endif -#ifdef USEMGAHAL -#include "client.h" -#endif - typedef enum { - OPTION_SW_CURSOR, OPTION_HW_CURSOR, OPTION_PCI_RETRY, OPTION_SYNC_ON_GREEN, OPTION_NOACCEL, - OPTION_SHOWCACHE, OPTION_OVERLAY, OPTION_MGA_SDRAM, OPTION_SHADOW_FB, @@ -59,27 +56,11 @@ typedef enum { OPTION_SET_MCLK, OPTION_OVERCLOCK_MEM, OPTION_VIDEO_KEY, - OPTION_ROTATE, OPTION_TEXTURED_VIDEO, - OPTION_CRTC2HALF, - OPTION_CRTC2RAM, OPTION_INT10, OPTION_AGP_MODE, OPTION_AGP_SIZE, - OPTION_DIGITAL1, - OPTION_DIGITAL2, - OPTION_TV, - OPTION_TVSTANDARD, - OPTION_CABLETYPE, - OPTION_USEIRQZERO, - OPTION_NOHAL, - OPTION_SWAPPED_HEAD, OPTION_DRI, - OPTION_MERGEDFB, - OPTION_HSYNC2, - OPTION_VREFRESH2, - OPTION_MONITOR2POS, - OPTION_METAMODES, OPTION_OLDDMA, OPTION_PCIDMA, OPTION_ACCELMETHOD @@ -147,6 +128,20 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*); outMGAdreg(MGA1064_DATA, tmp | (val)); \ } while (0) +#define inTi3026dreg(reg) INREG8(RAMDAC_OFFSET + (reg)) + +#define outTi3026dreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val) + +#define inTi3026(reg) \ + (outTi3026dreg(TVP3026_INDEX, reg), inTi3026dreg(TVP3026_DATA)) + +#define outTi3026(reg, mask, val) \ + do { /* note: mask and reg may get evaluated twice */ \ + unsigned char tmp = (mask) ? (inTi3026(reg) & (mask)) : 0; \ + outTi3026dreg(TVP3026_INDEX, reg); \ + outTi3026dreg(TVP3026_DATA, tmp | (val)); \ + } while (0) + #define MGAWAITVSYNC() \ do { \ unsigned int count = 0; \ @@ -182,36 +177,6 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*); #define MGA_DRIVER_NAME "mga" typedef struct { - unsigned char ExtVga[6]; - unsigned char DacClk[6]; - unsigned char * DacRegs; - unsigned long crtc2[0x58]; - unsigned char dac2[0x21]; - CARD32 Option; - CARD32 Option2; - CARD32 Option3; - long Clock; - Bool PIXPLLCSaved; -} MGARegRec, *MGARegPtr; - -/* For programming the second CRTC */ -typedef struct { - CARD32 ulDispWidth; /* Display Width in pixels*/ - CARD32 ulDispHeight; /* Display Height in pixels*/ - CARD32 ulBpp; /* Bits Per Pixels / input format*/ - CARD32 ulPixClock; /* Pixel Clock in kHz*/ - CARD32 ulHFPorch; /* Horizontal front porch in pixels*/ - CARD32 ulHSync; /* Horizontal Sync in pixels*/ - CARD32 ulHBPorch; /* Horizontal back porch in pixels*/ - CARD32 ulVFPorch; /* Vertical front porch in lines*/ - CARD32 ulVSync; /* Vertical Sync in lines*/ - CARD32 ulVBPorch; /* Vertical back Porch in lines*/ - CARD32 ulFBPitch; /* Pitch*/ - CARD32 flSignalMode; /* Signal Mode*/ -} xMODEINFO; - - -typedef struct { int brightness; int contrast; Bool doubleBuffer; @@ -252,9 +217,6 @@ typedef struct { void (*LoadPalette)(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); void (*RestorePalette)(ScrnInfoPtr, unsigned char *); void (*PreInit)(ScrnInfoPtr); - void (*Save)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); - void (*Restore)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); - Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr); } MGARamdacRec, *MGARamdacPtr; @@ -277,12 +239,7 @@ typedef struct { } MGAPaletteInfo; #define MGAPTR(p) ((MGAPtr)((p)->driverPrivate)) - -/*avoids segfault by returning false if pMgaHwInfo not defined*/ -#define ISDIGITAL1(p) (p->pMgaHwInfo && ((p->pMgaHwInfo->ulCapsFirstOutput) & MGAHWINFOCAPS_OUTPUT_DIGITAL)) -#define ISDIGITAL2(p) (p->pMgaHwInfo && ((p->pMgaHwInfo->ulCapsSecondOutput) & MGAHWINFOCAPS_OUTPUT_DIGITAL)) -#define ISTV1(p) (p->pMgaHwInfo && ((p->pMgaHwInfo->ulCapsFirstOutput) & MGAHWINFOCAPS_OUTPUT_TV)) -#define ISTV2(p) (p->pMgaHwInfo && ((p->pMgaHwInfo->ulCapsSecondOutput) & MGAHWINFOCAPS_OUTPUT_TV)) +#define MGACRTCDATAPTR(p) ((MgaCrtcDataPtr) ((p)->driver_private)) #ifdef DISABLE_VGA_IO typedef struct mgaSave { @@ -291,34 +248,6 @@ typedef struct mgaSave { } MgaSave, *MgaSavePtr; #endif - -typedef enum { - mgaLeftOf, - mgaRightOf, - mgaAbove, - mgaBelow, - mgaClone -} MgaScrn2Rel; - -typedef struct { - int lastInstance; -#ifdef USEMGAHAL - LPCLIENTDATA pClientStruct; - LPBOARDHANDLE pBoard; - LPMGAHWINFO pMgaHwInfo; -#endif - int refCount; - CARD32 masterFbAddress; - long masterFbMapSize; - CARD32 slaveFbAddress; - long slaveFbMapSize; - int mastervideoRam; - int slavevideoRam; - Bool directRenderingEnabled; - ScrnInfoPtr pScrn_1; - ScrnInfoPtr pScrn_2; -} MGAEntRec, *MGAEntPtr; - /** * Track the range of a voltage controlled osciliator (VCO). */ @@ -356,6 +285,14 @@ typedef enum { MGA_HOST_AGP_4x = 7 /**< AGP 4x capable. */ } mga_host_t; +typedef enum { + MGA_CONNECTOR_NONE = 0, + MGA_CONNECTOR_HD15, + MGA_CONNECTOR_DVI, + MGA_CONNECTOR_TV, + MGA_CONNECTOR_LAST = MGA_CONNECTOR_TV +} mga_connector_t; + /** * Card information derrived from BIOS PInS data. */ @@ -396,16 +333,15 @@ struct mga_bios_values { * Type of physical interface used for the card. */ mga_host_t host_interface; + + /** + * On G450 and G550 PInS lists the available connectors. + */ + mga_connector_t connector[2]; }; typedef struct { -#ifdef USEMGAHAL - LPCLIENTDATA pClientStruct; - LPBOARDHANDLE pBoard; - LPMGAMODEINFO pMgaModeInfo; - LPMGAHWINFO pMgaHwInfo; -#endif EntityInfoPtr pEnt; struct mga_bios_values bios; CARD8 BiosOutputMode; @@ -417,7 +353,6 @@ typedef struct { int is_Gx50:1; int is_G200SE:1; - int is_HAL_chipset:1; Bool Primary; Bool Interleave; @@ -451,7 +386,6 @@ typedef struct { Bool Dac6Bit; Bool HWCursor; Bool UsePCIRetry; - Bool ShowCache; Bool Overlay8Plus24; Bool ShadowFB; unsigned char * ShadowPtr; @@ -459,8 +393,6 @@ typedef struct { int MemClk; int MinClock; int MaxClock; - MGARegRec SavedReg; - MGARegRec ModeReg; int MaxFastBlitY; CARD32 BltScanDirection; CARD32 FilledRectCMD; @@ -484,9 +416,6 @@ typedef struct { CARD32 *Atype; CARD32 *AtypeNoBLK; void (*PreInit)(ScrnInfoPtr pScrn); - void (*Save)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); - void (*Restore)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); - Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr); void (*PointerMoved)(int index, int x, int y); CloseScreenProcPtr CloseScreen; ScreenBlockHandlerProcPtr BlockHandler; @@ -525,8 +454,7 @@ typedef struct { __GLXvisualConfig* pVisualConfigs; MGAConfigPrivPtr pVisualConfigsPriv; MGADRIServerPrivatePtr DRIServerInfo; - - MGARegRec DRContextRegs; + Bool dri_lock_held; Bool haveQuiescense; void (*GetQuiescence)(ScrnInfoPtr pScrn); @@ -541,15 +469,12 @@ typedef struct { Bool forcePciDma; #endif XF86VideoAdaptorPtr adaptor; - Bool DualHeadEnabled; - Bool Crtc2IsTV; Bool SecondCrtc; Bool SecondOutput; GDevPtr device; /* The hardware's real SrcOrg */ int realSrcOrg; - MGAEntPtr entityPrivate; void (*SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); void (*SubsequentSolidFillRect)(ScrnInfoPtr pScrn, @@ -563,9 +488,6 @@ typedef struct { MGAPaletteInfo palinfo[256]; /* G400 hardware bug workaround */ FBLinearPtr LinearScratch; Bool softbooted; -#ifdef USEMGAHAL - Bool HALLoaded; -#endif OptionInfoPtr Options; /* Exa */ @@ -578,24 +500,13 @@ typedef struct { int mask_w2; int mask_h2; CARD32 src_pitch; /* FIXME kill me */ - -/* Merged Framebuffer data */ - Bool MergedFB; - - /* Real values specific to monitor1, since the original ones are replaced */ - DisplayModePtr M1modes; /* list of actual modes */ - DisplayModePtr M1currentMode; /* current mode */ - int M1frameX0; /* viewport position */ - int M1frameY0; - int M1frameX1; - int M1frameY1; - - ScrnInfoPtr pScrn2; /*pointer to second CRTC screeninforec, - if in merged mode */ -/* End of Merged Framebuffer Data */ - int HALGranularityOffX, HALGranularityOffY; } MGARec, *MGAPtr; +typedef enum { + MGA_PIXEL_PLL, + MGA_VIDEO_PLL +} mga_pll_t; + extern CARD32 MGAAtype[16]; extern CARD32 MGAAtypeNoBLK[16]; @@ -620,21 +531,12 @@ extern CARD32 MGAAtypeNoBLK[16]; /* Prototypes */ void MGAAdjustFrame(int scrnIndex, int x, int y, int flags); -Bool MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags); void MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode); Bool MGAGetRec(ScrnInfoPtr pScrn); void MGAProbeDDC(ScrnInfoPtr pScrn, int index); void MGASoftReset(ScrnInfoPtr pScrn); void MGAFreeRec(ScrnInfoPtr pScrn); Bool mga_read_and_process_bios(ScrnInfoPtr pScrn); -void MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, - int flags); -void MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags); -void MGADisplayPowerManagementSetCrtc2(ScrnInfoPtr pScrn, - int PowerManagementMode, - int flags); -void MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y); - void MGA2064SetupFuncs(ScrnInfoPtr pScrn); void MGAGSetupFuncs(ScrnInfoPtr pScrn); @@ -684,6 +586,9 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ); void MGADRICloseScreen( ScreenPtr pScreen ); Bool MGADRIFinishScreenInit( ScreenPtr pScreen ); +Bool MGADRILock(ScrnInfoPtr scrn); +void MGADRIUnlock(ScrnInfoPtr scrn); + Bool MGALockUpdate( ScrnInfoPtr pScrn, drmLockFlags flags ); void MGAGetQuiescence( ScrnInfoPtr pScrn ); @@ -702,20 +607,11 @@ Bool MgaInitDma(ScrnInfoPtr pScrn, int prim_size); Bool MGAMavenRead(ScrnInfoPtr pScrn, I2CByte reg, I2CByte *val); -void MGACRTC2Set(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo); -void MGAEnableSecondOutPut(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo); -void MGACRTC2SetPitch(ScrnInfoPtr pSrcn, xMODEINFO *pModeInfo); -void MGACRTC2SetDisplayStart(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo, CARD32 base, CARD32 ulX, CARD32 ulY); - -void MGACRTC2Get(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo); -void MGACRTC2GetPitch(ScrnInfoPtr pSrcn, xMODEINFO *pModeInfo); -void MGACRTC2GetDisplayStart(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo, CARD32 base, CARD32 ulX, CARD32 ulY); - -double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out); +double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, mga_pll_t pll, long f_out); #ifdef DEBUG -void MGAG450PrintPLL(ScrnInfoPtr pScrn); +void MGAG450PrintPLL(ScrnInfoPtr pScrn, mga_pll_t pll); #endif -long MGAG450SavePLLFreq(ScrnInfoPtr pScrn); +long MGAG450SavePLLFreq(ScrnInfoPtr pScrn, mga_pll_t pll); void MGAprintDac(ScrnInfoPtr pScrn); void MGAG200SESaveFonts(ScrnInfoPtr, vgaRegPtr); void MGAG200SERestoreFonts(ScrnInfoPtr, vgaRegPtr); @@ -723,25 +619,16 @@ void MGAG200SESaveMode(ScrnInfoPtr, vgaRegPtr); void MGAG200SERestoreMode(ScrnInfoPtr, vgaRegPtr); void MGAG200SEHWProtect(ScrnInfoPtr, Bool); -#ifdef USEMGAHAL -/************ ESC Call Definition ***************/ -typedef struct { - char *function; - void (*funcptr)(ScrnInfoPtr pScrn, unsigned long *param, char *out, DisplayModePtr pMode); -} MGAEscFuncRec, *MGAEscFuncPtr; +Bool Mga2064CrtcInit(ScrnInfoPtr pScrn); +xf86OutputPtr Mga2064OutputInit(ScrnInfoPtr pScrn); -typedef struct { - char function[32]; - unsigned long parameters[32]; -} EscCmdStruct; +Bool MgaGCrtc1Init(ScrnInfoPtr pScrn); +Bool MgaGCrtc2Init(ScrnInfoPtr pScrn); -extern LPMGAMODEINFO pMgaModeInfo[2]; -extern MGAMODEINFO TmpMgaModeInfo[2]; - -extern void MGAExecuteEscCmd(ScrnInfoPtr pScrn, char *cmdline , char *sResult, DisplayModePtr pMode); -void MGAFillDisplayModeStruct(DisplayModePtr pMode, LPMGAMODEINFO pModeInfo); -/************************************************/ -#endif +xf86OutputPtr MgaGOutputDac1Init(ScrnInfoPtr pScrn, Bool number); +xf86OutputPtr MgaGOutputDac2Init(ScrnInfoPtr pScrn, Bool number); +xf86OutputPtr MgaGOutputPanel1Init(ScrnInfoPtr pScrn, Bool number); +xf86OutputPtr MgaGOutputPanel2Init(ScrnInfoPtr pScrn, Bool number); static __inline__ void MGA_MARK_SYNC(MGAPtr pMga, ScrnInfoPtr pScrn) diff --git a/src/mga_2064_crtc.c b/src/mga_2064_crtc.c new file mode 100644 index 0000000..1230420 --- /dev/null +++ b/src/mga_2064_crtc.c @@ -0,0 +1,942 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.58tsi Exp $ */ +/* + * Copyright 1994 by Robin Cutshaw <robin@XFree86.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ROBIN CUTSHAW BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * + * Modified for TVP3026 by Harald Koenig <koenig@tat.physik.uni-tuebingen.de> + * + * Modified for MGA Millennium by Xavier Ducoin <xavier@rd.lectra.fr> + * + * Doug Merritt <doug@netcom.com> + * 24bpp: fixed high res stripe glitches, clock glitches on all res + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" + +/* Drivers for PCI hardware need this */ +#include "xf86PciInfo.h" + +/* Drivers that need to access the PCI config space directly need this */ +#include "xf86Pci.h" + +#include "mga_reg.h" +#include "mga.h" +#include "mga_macros.h" +#include "mga_dac3026.h" + +/* + * Only change these bits in the Option register. Make sure that the + * vgaioen bit is never in this mask because it is controlled elsewhere + */ +#define OPTION_MASK 0xFFEFFEFF /* ~(eepromwt | vgaioen) */ + + +#define DACREGSIZE 21 +#define PALETTE_SIZE (256 * 3) + +typedef struct { + unsigned char ExtVga[6]; + unsigned char DacClk[6]; + unsigned char DacRegs[DACREGSIZE]; + CARD32 Option; +} MgaCrtcStateRec, *MgaCrtcStatePtr; + +typedef struct { + MgaCrtcStateRec saved_state; +} MgaCrtcDataRec, *MgaCrtcDataPtr; + +static void crtc_dpms(xf86CrtcPtr crtc, int mode); +static void crtc_save(xf86CrtcPtr crtc); +static void crtc_restore(xf86CrtcPtr crtc); +static void crtc_prepare(xf86CrtcPtr crtc); +static void crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y); +static void crtc_commit(xf86CrtcPtr crtc); +static void crtc_destroy(xf86CrtcPtr crtc); + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = crtc_save, + .restore = crtc_restore, + .prepare = crtc_prepare, + .mode_set = crtc_mode_set, + .commit = crtc_commit, + .destroy = crtc_destroy +}; + +/* + * indexes to ti3026 registers (the order is important) + */ +const static unsigned char MGADACregs[DACREGSIZE] = { + 0x0F, 0x18, 0x19, 0x1A, 0x1C, 0x1D, 0x1E, 0x2A, 0x2B, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x06 +}; + +/* note: to fix a cursor hw glitch, register 0x37 (blue color key) needs + to be set to magic numbers, even though they are "never" used because + blue keying disabled in 0x38. + + Matrox sez: + + ...The more precise statement of the software workaround is to insure + that bits 7-5 of register 0x37 (Blue Color Key High) and bits 7-5 of + register 0x38 (HZOOM)are the same... +*/ + +/* also note: the values of the MUX control register 0x19 (index [2]) can be + found in table 2-17 of the 3026 manual. If interlace is set, the values + listed here are incremented by one. +*/ + +/* + * initial values of ti3026 registers + */ +const static unsigned char MGADACbpp8[DACREGSIZE] = { + 0x06, 0x80, 0x4b, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0, 0x00, + 0x00 +}; +const static unsigned char MGADACbpp16[DACREGSIZE] = { + 0x07, 0x45, 0x53, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, + 0x00 +}; +/* + * [0] value was 0x07, but changed to 0x06 by Doug Merrit to fix high res + * stripe glitches and clock glitches at 24bpp. + */ +/* [0] value is now set inside of MGA3026Init, based on the silicon revision + It is still set to 7 or 6 based on the revision, though, since setting to + 8 as in the documentation makes (some?) revB chips get the colors wrong... + maybe BGR instead of RGB? This only applies to 24bpp, since it is the only + one documented as depending on revision. + */ + +const static unsigned char MGADACbpp24[DACREGSIZE] = { + 0x06, 0x56, 0x5b, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, + 0x00 +}; +const static unsigned char MGADACbpp32[DACREGSIZE] = { + 0x07, 0x46, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, + 0x00 +}; + +/* on at least some 2064Ws, the PSEL line flips at 4MB or so, so PSEL keying + has to be off in register 0x1e -> bit4 clear */ + +const static unsigned char MGADACbpp8plus24[DACREGSIZE] = { + 0x07, 0x06, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00, + 0x00 +}; + +/* + * MGATi3026CalcClock - Calculate the PLL settings (m, n, p). + * + * DESCRIPTION + * For more information, refer to the Texas Instruments + * "TVP3026 Data Manual" (document SLAS098B). + * Section 2.4 "PLL Clock Generators" + * Appendix A "Frequency Synthesis PLL Register Settings" + * Appendix B "PLL Programming Examples" + * + * PARAMETERS + * f_out IN Desired clock frequency. + * f_max IN Maximum allowed clock frequency. + * m OUT Value of PLL 'm' register. + * n OUT Value of PLL 'n' register. + * p OUT Value of PLL 'p' register. + * + * HISTORY + * January 11, 1997 - [aem] Andrew E. Mileski + * Split off from MGATi3026SetClock. + */ + +/* The following values are in kHz */ +#define TI_MIN_VCO_FREQ 110000 +#define TI_MAX_VCO_FREQ 220000 +#define TI_MAX_MCLK_FREQ 100000 +#define TI_REF_FREQ 14318.18 + +static double +MGATi3026CalcClock (long f_out, long f_max, int *m, int *n, int *p) +{ + int best_m = 0, best_n = 0; + double f_pll, f_vco; + double m_err, inc_m, calc_m; + + /* Make sure that f_min <= f_out <= f_max */ + if ( f_out < ( TI_MIN_VCO_FREQ / 8 )) + f_out = TI_MIN_VCO_FREQ / 8; + if ( f_out > f_max ) + f_out = f_max; + + /* + * f_pll = f_vco / 2 ^ p + * Choose p so that TI_MIN_VCO_FREQ <= f_vco <= TI_MAX_VCO_FREQ + * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ + * we don't have to bother checking for this maximum limit. + */ + f_vco = ( double ) f_out; + for ( *p = 0; *p < 3 && f_vco < TI_MIN_VCO_FREQ; ( *p )++ ) + f_vco *= 2.0; + + /* + * We avoid doing multiplications by ( 65 - n ), + * and add an increment instead - this keeps any error small. + */ + inc_m = f_vco / ( TI_REF_FREQ * 8.0 ); + + /* Initial value of calc_m for the loop */ + calc_m = inc_m + inc_m + inc_m; + + /* Initial amount of error for an integer - impossibly large */ + m_err = 2.0; + + /* Search for the closest INTEGER value of ( 65 - m ) */ + for ( *n = 3; *n <= 25; ( *n )++, calc_m += inc_m ) { + + /* Ignore values of ( 65 - m ) which we can't use */ + if ( calc_m < 3.0 || calc_m > 64.0 ) + continue; + + /* + * Pick the closest INTEGER (has smallest fractional part). + * The optimizer should clean this up for us. + */ + if (( calc_m - ( int ) calc_m ) < m_err ) { + m_err = calc_m - ( int ) calc_m; + best_m = ( int ) calc_m; + best_n = *n; + } + } + + /* 65 - ( 65 - x ) = x */ + *m = 65 - best_m; + *n = 65 - best_n; + + /* Now all the calculations can be completed */ + f_vco = 8.0 * TI_REF_FREQ * best_m / best_n; + f_pll = f_vco / ( 1 << *p ); + +#ifdef DEBUG + ErrorF( "f_out=%ld f_pll=%.1f f_vco=%.1f n=%d m=%d p=%d\n", + f_out, f_pll, f_vco, *n, *m, *p ); +#endif + + return f_pll; +} + +/* + * MGATi3026SetMCLK - Set the memory clock (MCLK) PLL. + * + * HISTORY + * January 11, 1997 - [aem] Andrew E. Mileski + * Written and tested. + */ +static void +MGATi3026SetMCLK( ScrnInfoPtr scrn, long f_out ) +{ + int mclk_m, mclk_n, mclk_p; + int pclk_m, pclk_n, pclk_p; + int mclk_ctl; + MGAPtr pMga = MGAPTR(scrn); + + MGATi3026CalcClock(f_out, TI_MAX_MCLK_FREQ, &mclk_m, &mclk_n, &mclk_p); + + /* Save PCLK settings */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xfc ); + pclk_n = inTi3026( TVP3026_PIX_CLK_DATA ); + outTi3026( TVP3026_PLL_ADDR, 0, 0xfd ); + pclk_m = inTi3026( TVP3026_PIX_CLK_DATA ); + outTi3026( TVP3026_PLL_ADDR, 0, 0xfe ); + pclk_p = inTi3026( TVP3026_PIX_CLK_DATA ); + + /* Stop PCLK (PLLEN = 0, PCLKEN = 0) */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xfe ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, 0x00 ); + + /* Set PCLK to the new MCLK frequency (PLLEN = 1, PCLKEN = 0 ) */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xfc ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, ( mclk_n & 0x3f ) | 0xc0 ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, mclk_m & 0x3f ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, ( mclk_p & 0x03 ) | 0xb0 ); + + /* Wait for PCLK PLL to lock on frequency */ + while (( inTi3026( TVP3026_PIX_CLK_DATA ) & 0x40 ) == 0 ) { + ; + } + + /* Output PCLK on MCLK pin */ + mclk_ctl = inTi3026( TVP3026_MCLK_CTL ); + outTi3026( TVP3026_MCLK_CTL, 0, mclk_ctl & 0xe7 ); + outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x08 ); + + /* Stop MCLK (PLLEN = 0 ) */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xfb ); + outTi3026( TVP3026_MEM_CLK_DATA, 0, 0x00 ); + + /* Set MCLK to the new frequency (PLLEN = 1) */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xf3 ); + outTi3026( TVP3026_MEM_CLK_DATA, 0, ( mclk_n & 0x3f ) | 0xc0 ); + outTi3026( TVP3026_MEM_CLK_DATA, 0, mclk_m & 0x3f ); + outTi3026( TVP3026_MEM_CLK_DATA, 0, ( mclk_p & 0x03 ) | 0xb0 ); + + /* Wait for MCLK PLL to lock on frequency */ + while (( inTi3026( TVP3026_MEM_CLK_DATA ) & 0x40 ) == 0 ) { + ; + } + + /* Output MCLK PLL on MCLK pin */ + outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x10 ); + outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x18 ); + + /* Stop PCLK (PLLEN = 0, PCLKEN = 0 ) */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xfe ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, 0x00 ); + + /* Restore PCLK (PLLEN = ?, PCLKEN = ?) */ + outTi3026( TVP3026_PLL_ADDR, 0, 0xfc ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_n ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_m ); + outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_p ); + + /* Wait for PCLK PLL to lock on frequency */ + while (( inTi3026( TVP3026_PIX_CLK_DATA ) & 0x40 ) == 0 ) { + ; + } +} + +/* + * state_set_pclk - Set the pixel (PCLK) and loop (LCLK) clocks. + * + * PARAMETERS + * f_pll IN Pixel clock PLL frequencly in kHz. + * bpp IN Bytes per pixel. + * + * HISTORY + * January 11, 1997 - [aem] Andrew E. Mileski + * Split to simplify code for MCLK (=GCLK) setting. + * + * December 14, 1996 - [aem] Andrew E. Mileski + * Fixed loop clock to be based on the calculated, not requested, + * pixel clock. Added f_max = maximum f_vco frequency. + * + * October 19, 1996 - [aem] Andrew E. Mileski + * Commented the loop clock code (wow, I understand everything now), + * and simplified it a bit. This should really be two separate functions. + * + * October 1, 1996 - [aem] Andrew E. Mileski + * Optimized the m & n picking algorithm. Added maxClock detection. + * Low speed pixel clock fix (per the docs). Documented what I understand. + * + * ?????, ??, ???? - [???] ???????????? + * Based on the TVP3026 code in the S3 driver. + */ + +static void +state_set_pclk(ScrnInfoPtr scrn, MgaCrtcStatePtr state, long f_out, int bpp) +{ + /* Pixel clock values */ + int m, n, p; + + /* Loop clock values */ + int lm, ln, lp, lq; + double z; + + /* The actual frequency output by the clock */ + double f_pll; + + long f_max = TI_MAX_VCO_FREQ; + + MGAPtr pMga = MGAPTR(scrn); + + /* Get the maximum pixel clock frequency */ + if (pMga->MaxClock > TI_MAX_VCO_FREQ) + f_max = pMga->MaxClock; + + /* Do the calculations for m, n, and p */ + f_pll = MGATi3026CalcClock( f_out, f_max, & m, & n, & p ); + + /* Values for the pixel clock PLL registers */ + state->DacClk[ 0 ] = ( n & 0x3f ) | 0xc0; + state->DacClk[ 1 ] = ( m & 0x3f ); + state->DacClk[ 2 ] = ( p & 0x03 ) | 0xb0; + + /* + * Now that the pixel clock PLL is setup, + * the loop clock PLL must be setup. + */ + + /* + * First we figure out lm, ln, and z. + * Things are different in packed pixel mode (24bpp) though. + */ + if ( pMga->CurrentLayout.bitsPerPixel == 24 ) { + + /* ln:lm = ln:3 */ + lm = 65 - 3; + + /* Check for interleaved mode */ + if ( bpp == 2 ) + /* ln:lm = 4:3 */ + ln = 65 - 4; + else + /* ln:lm = 8:3 */ + ln = 65 - 8; + + /* Note: this is actually 100 * z for more precision */ + z = ( 11000 * ( 65 - ln )) / (( f_pll / 1000 ) * ( 65 - lm )); + } + else { + /* ln:lm = ln:4 */ + lm = 65 - 4; + + /* Note: bpp = bytes per pixel */ + ln = 65 - 4 * ( 64 / 8 ) / bpp; + + /* Note: this is actually 100 * z for more precision */ + z = (( 11000 / 4 ) * ( 65 - ln )) / ( f_pll / 1000 ); + } + + /* + * Now we choose dividers lp and lq so that the VCO frequency + * is within the operating range of 110 MHz to 220 MHz. + */ + + /* Assume no lq divider */ + lq = 0; + + /* Note: z is actually 100 * z for more precision */ + if ( z <= 200.0 ) + lp = 0; + else if ( z <= 400.0 ) + lp = 1; + else if ( z <= 800.0 ) + lp = 2; + else if ( z <= 1600.0 ) + lp = 3; + else { + lp = 3; + lq = ( int )( z / 1600.0 ); + } + + /* Values for the loop clock PLL registers */ + if ( pMga->CurrentLayout.bitsPerPixel == 24 ) { + /* Packed pixel mode values */ + state->DacClk[ 3 ] = ( ln & 0x3f ) | 0x80; + state->DacClk[ 4 ] = ( lm & 0x3f ) | 0x80; + state->DacClk[ 5 ] = ( lp & 0x03 ) | 0xf8; + } else { + /* Non-packed pixel mode values */ + state->DacClk[ 3 ] = ( ln & 0x3f ) | 0xc0; + state->DacClk[ 4 ] = ( lm & 0x3f ); + state->DacClk[ 5 ] = ( lp & 0x03 ) | 0xf0; + } + state->DacRegs[ 18 ] = lq | 0x38; + +#ifdef DEBUG + ErrorF( "bpp=%d z=%.1f ln=%d lm=%d lp=%d lq=%d\n", + bpp, z, ln, lm, lp, lq ); +#endif +} + +static void +state_set(xf86CrtcPtr crtc, MgaCrtcStatePtr state, DisplayModePtr mode) +{ + ScrnInfoPtr scrn = crtc->scrn; + int hd, hs, he, ht, vd, vs, ve, vt, wd; + int i, BppShift, index_1d = 0; + const unsigned char* initDAC; + MGAPtr pMga = MGAPTR(scrn); + MGARamdacPtr MGAdac = &pMga->Dac; + MGAFBLayout *layout = &pMga->CurrentLayout; + vgaRegPtr pVga = &VGAHWPTR(scrn)->ModeReg; + + BppShift = pMga->BppShifts[(layout->bitsPerPixel >> 3) - 1]; + + switch (layout->bitsPerPixel) { + case 8: + initDAC = MGADACbpp8; + break; + case 16: + initDAC = MGADACbpp16; + break; + case 24: + initDAC = MGADACbpp24; + break; + case 32: + if(layout->Overlay8Plus24) + initDAC = MGADACbpp8plus24; + else + initDAC = MGADACbpp32; + + break; + default: + FatalError("MGA: unsupported bits per pixel\n"); + } + + for (i = 0; i < DACREGSIZE; i++) { + state->DacRegs[i] = initDAC[i]; + + if (MGADACregs[i] == 0x1D) + index_1d = i; + } + + if ((layout->bitsPerPixel == 32) && layout->Overlay8Plus24) { + state->DacRegs[9] = pMga->colorKey; + state->DacRegs[10] = pMga->colorKey; + } + + if ((layout->bitsPerPixel == 16) && (layout->weight.red == 5) && + (layout->weight.green == 5) && (layout->weight.blue == 5)) + state->DacRegs[1] &= ~0x01; + + if (pMga->Interleave) + state->DacRegs[2] += 1; + + if (layout->bitsPerPixel == 24) { + int silicon_rev; + + /* we need to set DacRegs[0] differently based on the silicon + * revision of the 3026 RAMDAC, as per page 2-14 of tvp3026.pdf. + * If we have rev A silicon, we want 0x07; rev B silicon wants + * 0x06. + */ + silicon_rev = inTi3026(TVP3026_SILICON_REV); + +#ifdef DEBUG + ErrorF("TVP3026 revision 0x%x (rev %s)\n", + silicon_rev, (silicon_rev <= 0x20) ? "A" : "B"); +#endif + + if (silicon_rev <= 0x20) + state->DacRegs[0] = 0x07; /* rev A */ + else + state->DacRegs[0] = 0x06; /* rev B */ + } + + /* + * This will initialize all of the generic VGA registers. + */ + if (!vgaHWInit(scrn, mode)) + return; + + /* + * Here all of the MGA registers get filled in. + */ + hd = (mode->HDisplay >> 3) - 1; + hs = (mode->HSyncStart >> 3) - 1; + he = (mode->HSyncEnd >> 3) - 1; + ht = (mode->HTotal >> 3) - 1; + vd = mode->VDisplay - 1; + vs = mode->VSyncStart - 1; + ve = mode->VSyncEnd - 1; + vt = mode->VTotal - 2; + + /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange + * vertical stripes + */ + if ((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04) + ht++; + + if (layout->bitsPerPixel == 24) + wd = (layout->displayWidth * 3) >> (4 - BppShift); + else + wd = layout->displayWidth >> (4 - BppShift); + + state->ExtVga[0] = 0; + state->ExtVga[5] = 0; + + if (mode->Flags & V_INTERLACE) { + state->ExtVga[0] = 0x80; + state->ExtVga[5] = (hs + he - ht) >> 1; + + wd <<= 1; + vt &= 0xFFFE; + + /* enable interlaced cursor */ + state->DacRegs[20] |= 0x20; + } + + state->ExtVga[0] |= (wd & 0x300) >> 4; + state->ExtVga[1] = (((ht - 4) & 0x100) >> 8) | + ((hd & 0x100) >> 7) | + ((hs & 0x100) >> 6) | + (ht & 0x40); + state->ExtVga[2] = ((vt & 0xc00) >> 10) | + ((vd & 0x400) >> 8) | + ((vd & 0xc00) >> 7) | + ((vs & 0xc00) >> 5); + + if (layout->bitsPerPixel == 24) + state->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80; + else + state->ExtVga[3] = ((1 << BppShift) - 1) | 0x80; + + /* Set viddelay (CRTCEXT3 Bits 3-4). */ + state->ExtVga[3] |= (scrn->videoRam == 8192 ? 0x10 + : scrn->videoRam == 2048 ? 0x08 : 0x00); + + state->ExtVga[4] = 0; + + pVga->CRTC[0] = ht - 4; + pVga->CRTC[1] = hd; + pVga->CRTC[2] = hd; + pVga->CRTC[3] = (ht & 0x1F) | 0x80; + pVga->CRTC[4] = hs; + pVga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F); + pVga->CRTC[6] = vt & 0xFF; + pVga->CRTC[7] = ((vt & 0x100) >> 8 ) | + ((vd & 0x100) >> 7 ) | + ((vs & 0x100) >> 6 ) | + ((vd & 0x100) >> 5 ) | + 0x10 | + ((vt & 0x200) >> 4 ) | + ((vd & 0x200) >> 3 ) | + ((vs & 0x200) >> 2 ); + pVga->CRTC[9] = ((vd & 0x200) >> 4) | 0x40; + pVga->CRTC[16] = vs & 0xFF; + pVga->CRTC[17] = (ve & 0x0F) | 0x20; + pVga->CRTC[18] = vd & 0xFF; + pVga->CRTC[19] = wd & 0xFF; + pVga->CRTC[21] = vd & 0xFF; + pVga->CRTC[22] = (vt + 1) & 0xFF; + + if (mode->Flags & V_DBLSCAN) + pVga->CRTC[9] |= 0x80; + + /* Per DDK vid.c line 75, sync polarity should be controlled + * via the TVP3026 RAMDAC register 1D and so MISC Output Register + * should always have bits 6 and 7 set. + */ + + pVga->MiscOutReg |= 0xC0; + + if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) && + (mode->Flags & (V_PVSYNC | V_NVSYNC))) { + if (mode->Flags & V_PHSYNC) + state->DacRegs[index_1d] |= 0x01; + if (mode->Flags & V_PVSYNC) + state->DacRegs[index_1d] |= 0x02; + } else { + int VDisplay = mode->VDisplay; + + if (mode->Flags & V_DBLSCAN) + VDisplay *= 2; + if (VDisplay < 400) + state->DacRegs[index_1d] |= 0x01; /* +hsync -vsync */ + else if (VDisplay < 480) + state->DacRegs[index_1d] |= 0x02; /* -hsync +vsync */ + else if (VDisplay < 768) + state->DacRegs[index_1d] |= 0x00; /* -hsync -vsync */ + else + state->DacRegs[index_1d] |= 0x03; /* +hsync +vsync */ + } + + if (pMga->SyncOnGreen) + state->DacRegs[index_1d] |= 0x20; + + state->Option = 0x402C0100; /* fine for 2064 and 2164 */ + + if (pMga->Interleave) + state->Option |= 0x1000; + else + state->Option &= ~0x1000; + + /* must always have the pci retries on but rely on + * polling to keep them from occuring + */ + state->Option &= ~0x20000000; + + pVga->MiscOutReg |= 0x0C; + + /* XXX Need to check the first argument */ + state_set_pclk(scrn, state, mode->Clock, 1 << BppShift); + + /* FIXME + * this one writes registers rather than writing to the + * mgaReg->ModeReg and letting Restore write to the hardware + * but that's no big deal since we will Restore right after + * this function. + */ + + MGATi3026SetMCLK(scrn, MGAdac->MemoryClock); + +#ifdef DEBUG + ErrorF("%6ld: %02X %02X %02X %02X %02X %02X %08lX\n", + mode->Clock, state->DacClk[0], state->DacClk[1], + state->DacClk[2], state->DacClk[3], state->DacClk[4], + state->DacClk[5], state->Option); + + for (i = 0; i < sizeof(MGADACregs); i++) + ErrorF("%02X ", state->DacRegs[i]); + + for (i = 0; i < 6; i++) + ErrorF(" %02X", state->ExtVga[i]); + + ErrorF("\n"); +#endif + + /* This disables the VGA memory aperture */ + pVga->MiscOutReg &= ~0x02; +} + +/* + * This function restores a video mode. It basically writes out all of + * the registers that have previously been saved in the vgaMGARec data + * structure. + */ +static void +state_restore(xf86CrtcPtr crtc, MgaCrtcStatePtr state, + vgaRegPtr vga, int vga_flags) +{ + ScrnInfoPtr scrn = crtc->scrn; + MGAPtr pMga = MGAPTR(scrn); + int i; + + /* + * Code is needed to get things back to bank zero. + */ + for (i = 0; i < 6; i++) + OUTREG16(0x1FDE, (state->ExtVga[i] << 8) | i); + + pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, OPTION_MASK, + state->Option); + + /* select pixel clock PLL as clock source */ + outTi3026(TVP3026_CLK_SEL, 0, state->DacRegs[3]); + + /* set loop and pixel clock PLL PLLEN bits to 0 */ + outTi3026(TVP3026_PLL_ADDR, 0, 0x2A); + outTi3026(TVP3026_LOAD_CLK_DATA, 0, 0); + outTi3026(TVP3026_PIX_CLK_DATA, 0, 0); + + /* + * This function handles restoring the generic VGA registers. + */ + vgaHWRestore(scrn, vga, vga_flags); + + MGA3026RestorePalette(scrn, vga->DAC); + + /* + * Code to restore SVGA registers that have been saved/modified + * goes here. + */ + + /* program pixel clock PLL */ + outTi3026(TVP3026_PLL_ADDR, 0, 0x00); + + for (i = 0; i < 3; i++) + outTi3026(TVP3026_PIX_CLK_DATA, 0, state->DacClk[i]); + + if (vga->MiscOutReg & 0x08) { + /* poll until pixel clock PLL LOCK bit is set */ + outTi3026(TVP3026_PLL_ADDR, 0, 0x3F); + while (!(inTi3026(TVP3026_PIX_CLK_DATA) & 0x40)); + } + + /* set Q divider for loop clock PLL */ + outTi3026(TVP3026_MCLK_CTL, 0, state->DacRegs[18]); + + /* program loop PLL */ + outTi3026(TVP3026_PLL_ADDR, 0, 0x00); + + for (i = 3; i < 6; i++) + outTi3026(TVP3026_LOAD_CLK_DATA, 0, state->DacClk[i]); + + if ((vga->MiscOutReg & 0x08) && ((state->DacClk[3] & 0xC0) == 0xC0)) { + /* poll until loop PLL LOCK bit is set */ + outTi3026(TVP3026_PLL_ADDR, 0, 0x3F); + while (!(inTi3026(TVP3026_LOAD_CLK_DATA) & 0x40)); + } + + /* + * restore other DAC registers + */ + for (i = 0; i < DACREGSIZE; i++) + outTi3026(MGADACregs[i], 0, state->DacRegs[i]); + +#ifdef DEBUG + ErrorF("PCI retry (0-enabled / 1-disabled): %d\n", + !!(state->Option & 0x20000000)); +#endif +} + +static void +state_save(xf86CrtcPtr crtc, MgaCrtcStatePtr state, int vga_flags) +{ + ScrnInfoPtr scrn = crtc->scrn; + MGAPtr pMga = MGAPTR(scrn); + vgaRegPtr vga = &VGAHWPTR(scrn)->SavedReg; + int i; + + /* + * Code is needed to get back to bank zero. + */ + OUTREG16(MGAREG_CRTCEXT_INDEX, 0x0004); + + /* + * This function will handle creating the data structure and filling + * in the generic VGA portion. + */ + vgaHWSave(scrn, vga, vga_flags); + MGA3026SavePalette(scrn, vga->DAC); + + /* + * The port I/O code necessary to read in the extended registers + * into the fields of the vgaMGARec structure. + */ + for (i = 0; i < 6; i++) { + OUTREG8(0x1FDE, i); + state->ExtVga[i] = INREG8(0x1FDF); + } + + outTi3026(TVP3026_PLL_ADDR, 0, 0x00); + + for (i = 0; i < 3; i++) { + state->DacClk[i] = inTi3026(TVP3026_PIX_CLK_DATA); + outTi3026(TVP3026_PIX_CLK_DATA, 0, state->DacClk[i]); + } + + outTi3026(TVP3026_PLL_ADDR, 0, 0x00); + + for (i = 3; i < 6; i++) { + state->DacClk[i] = inTi3026(TVP3026_LOAD_CLK_DATA); + outTi3026(TVP3026_LOAD_CLK_DATA, 0, state->DacClk[i]); + } + + for (i = 0; i < DACREGSIZE; i++) + state->DacRegs[i] = inTi3026(MGADACregs[i]); + + state->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG); + +#ifdef DEBUG + ErrorF("read: %02X %02X %02X %02X %02X %02X %08lX\n", + state->DacClk[0], state->DacClk[1], + state->DacClk[2], state->DacClk[3], + state->DacClk[4], state->DacClk[5], + state->Option); + + for (i = 0; i < DACREGSIZE; i++) + ErrorF("%02X ", state->DacRegs[i]); + + for (i = 0; i < 6; i++) + ErrorF(" %02X", state->ExtVga[i]); + + ErrorF("\n"); +#endif +} + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ +} + +static void +crtc_save(xf86CrtcPtr crtc) +{ + MgaCrtcDataPtr data = MGACRTCDATAPTR(crtc); + MGAPtr pMga = MGAPTR(crtc->scrn); + int vga_flags = VGA_SR_MODE; + + if (pMga->Primary) + vga_flags |= VGA_SR_FONTS; + + state_save(crtc, &data->saved_state, vga_flags); +} + +static void +crtc_restore(xf86CrtcPtr crtc) +{ + MgaCrtcDataPtr data = MGACRTCDATAPTR(crtc); + MGAPtr pMga = MGAPTR(crtc->scrn); + vgaHWPtr vga = VGAHWPTR(crtc->scrn); + int vga_flags = VGA_SR_MODE; + + if (pMga->Primary) + vga_flags |= VGA_SR_FONTS; + + state_restore(crtc, &data->saved_state, &vga->SavedReg, vga_flags); +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ + crtc->funcs->dpms(crtc, DPMSModeOff); +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjust_mode, int x, int y) +{ + MgaCrtcStateRec state; + vgaHWPtr vga = VGAHWPTR(crtc->scrn); + + memset(&state, 0, sizeof (state)); + + state_set(crtc, &state, mode); + state_restore(crtc, &state, &vga->ModeReg, VGA_SR_MODE); +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ + crtc->funcs->dpms(crtc, DPMSModeOn); +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + if (crtc->driver_private) + xfree (crtc->driver_private); +} + +Bool +Mga2064CrtcInit(ScrnInfoPtr scrn) +{ + xf86CrtcPtr crtc; + MgaCrtcDataPtr data; + + data = xnfcalloc (sizeof (MgaCrtcDataRec), 1); + if (!data) + return FALSE; + + crtc = xf86CrtcCreate (scrn, &crtc_funcs); + if (!crtc) { + xfree(data); + return FALSE; + } + + crtc->driver_private = data; + + return TRUE; +} diff --git a/src/mga_2064_output.c b/src/mga_2064_output.c new file mode 100644 index 0000000..e344b6a --- /dev/null +++ b/src/mga_2064_output.c @@ -0,0 +1,196 @@ +/* + * Copyright 2007 Tilman Sauerbeck + * + * 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, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them 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 MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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: + * Tilman Sauerbeck <tilman@code-monkey.de> + * + * Sources: + * xf86-video-intel + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "xf86.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" + +#include "mga_reg.h" +#include "mga.h" + +#define MGAOUTPUTDATAPTR(p) ((MgaOutputDataPtr) ((p)->driver_private)) + +typedef struct { + I2CBusPtr ddc_bus; +} MgaOutputDataRec, *MgaOutputDataPtr; + +static void output_dpms(xf86OutputPtr output, int mode); +static int output_mode_valid(xf86OutputPtr output, DisplayModePtr mode); +static int output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_prepare(xf86OutputPtr output); +static void output_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_commit(xf86OutputPtr output); +static xf86OutputStatus output_detect(xf86OutputPtr output); +static DisplayModePtr output_get_modes(xf86OutputPtr output); +static void output_destroy(xf86OutputPtr output); + +static const xf86OutputFuncsRec output_funcs = { + .dpms = output_dpms, + .mode_valid = output_mode_valid, + .mode_fixup = output_mode_fixup, + .prepare = output_prepare, + .mode_set = output_mode_set, + .commit = output_commit, + .detect = output_detect, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +static void +output_dpms(xf86OutputPtr output, int mode) +{ + /* FIXME + * + * Prefer an implementation that doesn't depend on VGA specifics. + */ + + MGAPtr pMga = MGAPTR(output->scrn); + CARD8 seq1, crtcext1; + + OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */ + OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */ + + seq1 = INREG8(MGAREG_SEQ_DATA); + seq1 &= ~MGAREG_SEQ1_SCREEN_OFF; + + crtcext1 = INREG8(MGAREG_CRTCEXT_DATA); + crtcext1 &= ~MGAREG_CRTCEXT1_HSYNC_OFF; + crtcext1 &= ~MGAREG_CRTCEXT1_VSYNC_OFF; + + switch (mode) { + case DPMSModeOn: + /* nothing to do */ + break; + case DPMSModeStandby: + seq1 |= MGAREG_SEQ1_SCREEN_OFF; + crtcext1 = MGAREG_CRTCEXT1_HSYNC_OFF; + break; + case DPMSModeSuspend: + seq1 |= MGAREG_SEQ1_SCREEN_OFF; + crtcext1 |= MGAREG_CRTCEXT1_VSYNC_OFF; + break; + case DPMSModeOff: + seq1 |= MGAREG_SEQ1_SCREEN_OFF; + crtcext1 |= MGAREG_CRTCEXT1_HSYNC_OFF; + crtcext1 |= MGAREG_CRTCEXT1_VSYNC_OFF; + break; + } + + OUTREG8(MGAREG_SEQ_DATA, seq1); + OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1); +} + +static int +output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) +{ + return MODE_OK; +} + +static int +output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr pAdjustedMode) +{ + return TRUE; +} + +static void +output_prepare(xf86OutputPtr output) +{ +} + +static void +output_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ +} + +static void +output_commit(xf86OutputPtr output) +{ +} + +static xf86OutputStatus +output_detect(xf86OutputPtr output) +{ + MgaOutputDataPtr data = MGAOUTPUTDATAPTR(output); + + /* 0xa0 is DDC EEPROM address */ + if (xf86I2CProbeAddress(data->ddc_bus, 0xa0)) + return XF86OutputStatusConnected; + else + return XF86OutputStatusUnknown; +} + +static DisplayModePtr +output_get_modes(xf86OutputPtr output) +{ + MgaOutputDataPtr data = MGAOUTPUTDATAPTR(output); + xf86MonPtr mon; + + mon = xf86OutputGetEDID(output, data->ddc_bus); + xf86OutputSetEDID(output, mon); + + return xf86OutputGetEDIDModes(output); +} + +static void +output_destroy(xf86OutputPtr output) +{ + if (output->driver_private) + xfree(output->driver_private); +} + +xf86OutputPtr +Mga2064OutputInit(ScrnInfoPtr scrn) +{ + MGAPtr pMga = MGAPTR(scrn); + xf86OutputPtr output; + MgaOutputDataPtr data; + + data = xnfcalloc(sizeof(MgaOutputDataRec), 1); + if (!data) + return NULL; + + output = xf86OutputCreate(scrn, &output_funcs, "VGA"); + if (!output) { + xfree(data); + return NULL; + } + + output->driver_private = data; + + data->ddc_bus = pMga->DDC_Bus1; + + return output; +} diff --git a/src/mga_bios.c b/src/mga_bios.c index dd75f3f..bf70b84 100644 --- a/src/mga_bios.c +++ b/src/mga_bios.c @@ -118,6 +118,7 @@ static void mga_initialize_bios_values( MGAPtr pMga, (void) memset( bios, 0, sizeof( *bios ) ); bios->pixel.min_freq = 50000; + bios->connector[0] = bios->connector[1] = MGA_CONNECTOR_NONE; switch( pMga->Chipset ) { case PCI_CHIP_MGA2064: @@ -341,6 +342,7 @@ static void mga_parse_bios_ver_5( struct mga_bios_values * bios, const CARD8 * bios_data ) { const unsigned scale = (bios_data[4] != 0) ? 8000 : 6000; + mga_connector_t connector; if ( bios_data[38] != 0xff ) { @@ -397,6 +399,14 @@ static void mga_parse_bios_ver_5( struct mga_bios_values * bios, } bios->host_interface = (bios_data[113] >> 3) & 0x07; + + connector = bios_data[116] & 0x0f; + if (connector <= MGA_CONNECTOR_LAST) + bios->connector[0] = connector; + + connector = (bios_data[116] >> 4) & 0x0f; + if (connector <= MGA_CONNECTOR_LAST) + bios->connector[1] = connector; } diff --git a/src/mga_dac3026.c b/src/mga_dac3026.c index 1eddefd..a108e22 100644 --- a/src/mga_dac3026.c +++ b/src/mga_dac3026.c @@ -55,828 +55,14 @@ #include "xf86DDC.h" -/* - * Only change these bits in the Option register. Make sure that the - * vgaioen bit is never in this mask because it is controlled elsewhere - */ -#define OPTION_MASK 0xFFEFFEFF /* ~(eepromwt | vgaioen) */ +#include "mga_dac3026.h" -static void MGA3026LoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); -static void MGA3026SavePalette(ScrnInfoPtr, unsigned char*); -static void MGA3026RestorePalette(ScrnInfoPtr, unsigned char*); static void MGA3026RamdacInit(ScrnInfoPtr); -static void MGA3026Save(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); -static void MGA3026Restore(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); -static Bool MGA3026Init(ScrnInfoPtr, DisplayModePtr); static Bool MGA3026_i2cInit(ScrnInfoPtr pScrn); - /* * implementation */ - -/* - * indexes to ti3026 registers (the order is important) - */ -const static unsigned char MGADACregs[] = { - 0x0F, 0x18, 0x19, 0x1A, 0x1C, 0x1D, 0x1E, 0x2A, 0x2B, 0x30, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, - 0x06 -}; - -/* note: to fix a cursor hw glitch, register 0x37 (blue color key) needs - to be set to magic numbers, even though they are "never" used because - blue keying disabled in 0x38. - - Matrox sez: - - ...The more precise statement of the software workaround is to insure - that bits 7-5 of register 0x37 (Blue Color Key High) and bits 7-5 of - register 0x38 (HZOOM)are the same... -*/ - -/* also note: the values of the MUX control register 0x19 (index [2]) can be - found in table 2-17 of the 3026 manual. If interlace is set, the values - listed here are incremented by one. -*/ - -#define DACREGSIZE sizeof(MGADACregs) -/* - * initial values of ti3026 registers - */ -const static unsigned char MGADACbpp8[DACREGSIZE] = { - 0x06, 0x80, 0x4b, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0, 0x00, - 0x00 -}; -const static unsigned char MGADACbpp16[DACREGSIZE] = { - 0x07, 0x45, 0x53, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, - 0x00 -}; -/* - * [0] value was 0x07, but changed to 0x06 by Doug Merrit to fix high res - * stripe glitches and clock glitches at 24bpp. - */ -/* [0] value is now set inside of MGA3026Init, based on the silicon revision - It is still set to 7 or 6 based on the revision, though, since setting to - 8 as in the documentation makes (some?) revB chips get the colors wrong... - maybe BGR instead of RGB? This only applies to 24bpp, since it is the only - one documented as depending on revision. - */ - -const static unsigned char MGADACbpp24[DACREGSIZE] = { - 0x06, 0x56, 0x5b, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, - 0x00 -}; -const static unsigned char MGADACbpp32[DACREGSIZE] = { - 0x07, 0x46, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00, - 0x00 -}; - -/* on at least some 2064Ws, the PSEL line flips at 4MB or so, so PSEL keying - has to be off in register 0x1e -> bit4 clear */ - -const static unsigned char MGADACbpp8plus24[DACREGSIZE] = { - 0x07, 0x06, 0x5b, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00, - 0x00 -}; - -/* - * Read/write to the DAC via MMIO - */ - -/* - * These were functions. Use macros instead to avoid the need to - * pass pMga to them. - */ - -#define inTi3026dreg(reg) INREG8(RAMDAC_OFFSET + (reg)) - -#define outTi3026dreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val) - -#define inTi3026(reg) \ - (outTi3026dreg(TVP3026_INDEX, reg), inTi3026dreg(TVP3026_DATA)) - -#define outTi3026(reg, mask, val) \ - do { /* note: mask and reg may get evaluated twice */ \ - unsigned char tmp = (mask) ? (inTi3026(reg) & (mask)) : 0; \ - outTi3026dreg(TVP3026_INDEX, reg); \ - outTi3026dreg(TVP3026_DATA, tmp | (val)); \ - } while (0) - - -/* - * MGATi3026CalcClock - Calculate the PLL settings (m, n, p). - * - * DESCRIPTION - * For more information, refer to the Texas Instruments - * "TVP3026 Data Manual" (document SLAS098B). - * Section 2.4 "PLL Clock Generators" - * Appendix A "Frequency Synthesis PLL Register Settings" - * Appendix B "PLL Programming Examples" - * - * PARAMETERS - * f_out IN Desired clock frequency. - * f_max IN Maximum allowed clock frequency. - * m OUT Value of PLL 'm' register. - * n OUT Value of PLL 'n' register. - * p OUT Value of PLL 'p' register. - * - * HISTORY - * January 11, 1997 - [aem] Andrew E. Mileski - * Split off from MGATi3026SetClock. - */ - -/* The following values are in kHz */ -#define TI_MIN_VCO_FREQ 110000 -#define TI_MAX_VCO_FREQ 220000 -#define TI_MAX_MCLK_FREQ 100000 -#define TI_REF_FREQ 14318.18 - -static double -MGATi3026CalcClock ( - long f_out, long f_max, - int *m, int *n, int *p -){ - int best_m = 0, best_n = 0; - double f_pll, f_vco; - double m_err, inc_m, calc_m; - - /* Make sure that f_min <= f_out <= f_max */ - if ( f_out < ( TI_MIN_VCO_FREQ / 8 )) - f_out = TI_MIN_VCO_FREQ / 8; - if ( f_out > f_max ) - f_out = f_max; - - /* - * f_pll = f_vco / 2 ^ p - * Choose p so that TI_MIN_VCO_FREQ <= f_vco <= TI_MAX_VCO_FREQ - * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ - * we don't have to bother checking for this maximum limit. - */ - f_vco = ( double ) f_out; - for ( *p = 0; *p < 3 && f_vco < TI_MIN_VCO_FREQ; ( *p )++ ) - f_vco *= 2.0; - - /* - * We avoid doing multiplications by ( 65 - n ), - * and add an increment instead - this keeps any error small. - */ - inc_m = f_vco / ( TI_REF_FREQ * 8.0 ); - - /* Initial value of calc_m for the loop */ - calc_m = inc_m + inc_m + inc_m; - - /* Initial amount of error for an integer - impossibly large */ - m_err = 2.0; - - /* Search for the closest INTEGER value of ( 65 - m ) */ - for ( *n = 3; *n <= 25; ( *n )++, calc_m += inc_m ) { - - /* Ignore values of ( 65 - m ) which we can't use */ - if ( calc_m < 3.0 || calc_m > 64.0 ) - continue; - - /* - * Pick the closest INTEGER (has smallest fractional part). - * The optimizer should clean this up for us. - */ - if (( calc_m - ( int ) calc_m ) < m_err ) { - m_err = calc_m - ( int ) calc_m; - best_m = ( int ) calc_m; - best_n = *n; - } - } - - /* 65 - ( 65 - x ) = x */ - *m = 65 - best_m; - *n = 65 - best_n; - - /* Now all the calculations can be completed */ - f_vco = 8.0 * TI_REF_FREQ * best_m / best_n; - f_pll = f_vco / ( 1 << *p ); - -#ifdef DEBUG - ErrorF( "f_out=%ld f_pll=%.1f f_vco=%.1f n=%d m=%d p=%d\n", - f_out, f_pll, f_vco, *n, *m, *p ); -#endif - - return f_pll; -} - -/* - * MGATi3026SetMCLK - Set the memory clock (MCLK) PLL. - * - * HISTORY - * January 11, 1997 - [aem] Andrew E. Mileski - * Written and tested. - */ -static void -MGATi3026SetMCLK( ScrnInfoPtr pScrn, long f_out ) -{ - int mclk_m, mclk_n, mclk_p; - int pclk_m, pclk_n, pclk_p; - int mclk_ctl; - MGAPtr pMga = MGAPTR(pScrn); - - MGATi3026CalcClock(f_out, TI_MAX_MCLK_FREQ, &mclk_m, &mclk_n, &mclk_p); - - /* Save PCLK settings */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xfc ); - pclk_n = inTi3026( TVP3026_PIX_CLK_DATA ); - outTi3026( TVP3026_PLL_ADDR, 0, 0xfd ); - pclk_m = inTi3026( TVP3026_PIX_CLK_DATA ); - outTi3026( TVP3026_PLL_ADDR, 0, 0xfe ); - pclk_p = inTi3026( TVP3026_PIX_CLK_DATA ); - - /* Stop PCLK (PLLEN = 0, PCLKEN = 0) */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xfe ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, 0x00 ); - - /* Set PCLK to the new MCLK frequency (PLLEN = 1, PCLKEN = 0 ) */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xfc ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, ( mclk_n & 0x3f ) | 0xc0 ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, mclk_m & 0x3f ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, ( mclk_p & 0x03 ) | 0xb0 ); - - /* Wait for PCLK PLL to lock on frequency */ - while (( inTi3026( TVP3026_PIX_CLK_DATA ) & 0x40 ) == 0 ) { - ; - } - - /* Output PCLK on MCLK pin */ - mclk_ctl = inTi3026( TVP3026_MCLK_CTL ); - outTi3026( TVP3026_MCLK_CTL, 0, mclk_ctl & 0xe7 ); - outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x08 ); - - /* Stop MCLK (PLLEN = 0 ) */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xfb ); - outTi3026( TVP3026_MEM_CLK_DATA, 0, 0x00 ); - - /* Set MCLK to the new frequency (PLLEN = 1) */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xf3 ); - outTi3026( TVP3026_MEM_CLK_DATA, 0, ( mclk_n & 0x3f ) | 0xc0 ); - outTi3026( TVP3026_MEM_CLK_DATA, 0, mclk_m & 0x3f ); - outTi3026( TVP3026_MEM_CLK_DATA, 0, ( mclk_p & 0x03 ) | 0xb0 ); - - /* Wait for MCLK PLL to lock on frequency */ - while (( inTi3026( TVP3026_MEM_CLK_DATA ) & 0x40 ) == 0 ) { - ; - } - - /* Output MCLK PLL on MCLK pin */ - outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x10 ); - outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x18 ); - - /* Stop PCLK (PLLEN = 0, PCLKEN = 0 ) */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xfe ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, 0x00 ); - - /* Restore PCLK (PLLEN = ?, PCLKEN = ?) */ - outTi3026( TVP3026_PLL_ADDR, 0, 0xfc ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_n ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_m ); - outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_p ); - - /* Wait for PCLK PLL to lock on frequency */ - while (( inTi3026( TVP3026_PIX_CLK_DATA ) & 0x40 ) == 0 ) { - ; - } -} - -/* - * MGATi3026SetPCLK - Set the pixel (PCLK) and loop (LCLK) clocks. - * - * PARAMETERS - * f_pll IN Pixel clock PLL frequencly in kHz. - * bpp IN Bytes per pixel. - * - * HISTORY - * January 11, 1997 - [aem] Andrew E. Mileski - * Split to simplify code for MCLK (=GCLK) setting. - * - * December 14, 1996 - [aem] Andrew E. Mileski - * Fixed loop clock to be based on the calculated, not requested, - * pixel clock. Added f_max = maximum f_vco frequency. - * - * October 19, 1996 - [aem] Andrew E. Mileski - * Commented the loop clock code (wow, I understand everything now), - * and simplified it a bit. This should really be two separate functions. - * - * October 1, 1996 - [aem] Andrew E. Mileski - * Optimized the m & n picking algorithm. Added maxClock detection. - * Low speed pixel clock fix (per the docs). Documented what I understand. - * - * ?????, ??, ???? - [???] ???????????? - * Based on the TVP3026 code in the S3 driver. - */ - -static void -MGATi3026SetPCLK( ScrnInfoPtr pScrn, long f_out, int bpp ) -{ - /* Pixel clock values */ - int m, n, p; - - /* Loop clock values */ - int lm, ln, lp, lq; - double z; - - /* The actual frequency output by the clock */ - double f_pll; - - long f_max = TI_MAX_VCO_FREQ; - - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg = &pMga->ModeReg; - - /* Get the maximum pixel clock frequency */ - if ( pMga->MaxClock > TI_MAX_VCO_FREQ ) - f_max = pMga->MaxClock; - - /* Do the calculations for m, n, and p */ - f_pll = MGATi3026CalcClock( f_out, f_max, & m, & n, & p ); - - /* Values for the pixel clock PLL registers */ - pReg->DacClk[ 0 ] = ( n & 0x3f ) | 0xc0; - pReg->DacClk[ 1 ] = ( m & 0x3f ); - pReg->DacClk[ 2 ] = ( p & 0x03 ) | 0xb0; - - /* - * Now that the pixel clock PLL is setup, - * the loop clock PLL must be setup. - */ - - /* - * First we figure out lm, ln, and z. - * Things are different in packed pixel mode (24bpp) though. - */ - if ( pMga->CurrentLayout.bitsPerPixel == 24 ) { - - /* ln:lm = ln:3 */ - lm = 65 - 3; - - /* Check for interleaved mode */ - if ( bpp == 2 ) - /* ln:lm = 4:3 */ - ln = 65 - 4; - else - /* ln:lm = 8:3 */ - ln = 65 - 8; - - /* Note: this is actually 100 * z for more precision */ - z = ( 11000 * ( 65 - ln )) / (( f_pll / 1000 ) * ( 65 - lm )); - } - else { - /* ln:lm = ln:4 */ - lm = 65 - 4; - - /* Note: bpp = bytes per pixel */ - ln = 65 - 4 * ( 64 / 8 ) / bpp; - - /* Note: this is actually 100 * z for more precision */ - z = (( 11000 / 4 ) * ( 65 - ln )) / ( f_pll / 1000 ); - } - - /* - * Now we choose dividers lp and lq so that the VCO frequency - * is within the operating range of 110 MHz to 220 MHz. - */ - - /* Assume no lq divider */ - lq = 0; - - /* Note: z is actually 100 * z for more precision */ - if ( z <= 200.0 ) - lp = 0; - else if ( z <= 400.0 ) - lp = 1; - else if ( z <= 800.0 ) - lp = 2; - else if ( z <= 1600.0 ) - lp = 3; - else { - lp = 3; - lq = ( int )( z / 1600.0 ); - } - - /* Values for the loop clock PLL registers */ - if ( pMga->CurrentLayout.bitsPerPixel == 24 ) { - /* Packed pixel mode values */ - pReg->DacClk[ 3 ] = ( ln & 0x3f ) | 0x80; - pReg->DacClk[ 4 ] = ( lm & 0x3f ) | 0x80; - pReg->DacClk[ 5 ] = ( lp & 0x03 ) | 0xf8; - } else { - /* Non-packed pixel mode values */ - pReg->DacClk[ 3 ] = ( ln & 0x3f ) | 0xc0; - pReg->DacClk[ 4 ] = ( lm & 0x3f ); - pReg->DacClk[ 5 ] = ( lp & 0x03 ) | 0xf0; - } - pReg->DacRegs[ 18 ] = lq | 0x38; - -#ifdef DEBUG - ErrorF( "bpp=%d z=%.1f ln=%d lm=%d lp=%d lq=%d\n", - bpp, z, ln, lm, lp, lq ); -#endif -} - -/* - * MGA3026Init -- for mga2064 with ti3026 - * - * The 'mode' parameter describes the video mode. The 'mode' structure - * as well as the 'vga256InfoRec' structure can be dereferenced for - * information that is needed to initialize the mode. The 'new' macro - * (see definition above) is used to simply fill in the structure. - */ -static Bool -MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - int hd, hs, he, ht, vd, vs, ve, vt, wd; - int i, BppShift, index_1d = 0; - const unsigned char* initDAC; - MGAPtr pMga = MGAPTR(pScrn); - MGARamdacPtr MGAdac = &pMga->Dac; - MGAFBLayout *pLayout = &pMga->CurrentLayout; - MGARegPtr pReg = &pMga->ModeReg; - vgaRegPtr pVga = &VGAHWPTR(pScrn)->ModeReg; - - BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]; - - switch(pLayout->bitsPerPixel) - { - case 8: - initDAC = MGADACbpp8; - break; - case 16: - initDAC = MGADACbpp16; - break; - case 24: - initDAC = MGADACbpp24; - break; - case 32: - if(pLayout->Overlay8Plus24) - initDAC = MGADACbpp8plus24; - else - initDAC = MGADACbpp32; - break; - default: - FatalError("MGA: unsupported bits per pixel\n"); - } - - /* Allocate the DacRegs space if not done already */ - if (pReg->DacRegs == NULL) { - pReg->DacRegs = xnfcalloc(DACREGSIZE, 1); - } - for (i = 0; i < DACREGSIZE; i++) { - pReg->DacRegs[i] = initDAC[i]; - if (MGADACregs[i] == 0x1D) - index_1d = i; - } - - if((pLayout->bitsPerPixel == 32) && pLayout->Overlay8Plus24) { - pReg->DacRegs[9] = pMga->colorKey; - pReg->DacRegs[10] = pMga->colorKey; - } - - if ( (pLayout->bitsPerPixel == 16) && (pLayout->weight.red == 5) - && (pLayout->weight.green == 5) && (pLayout->weight.blue == 5) ) { - pReg->DacRegs[1] &= ~0x01; - } - if (pMga->Interleave ) pReg->DacRegs[2] += 1; - - - if ( pLayout->bitsPerPixel == 24 ) { - int silicon_rev; - /* we need to set DacRegs[0] differently based on the silicon - * revision of the 3026 RAMDAC, as per page 2-14 of tvp3026.pdf. - * If we have rev A silicon, we want 0x07; rev B silicon wants - * 0x06. - */ - silicon_rev = inTi3026(TVP3026_SILICON_REV); - -#ifdef DEBUG - ErrorF("TVP3026 revision 0x%x (rev %s)\n", - silicon_rev, (silicon_rev <= 0x20) ? "A" : "B"); -#endif - - if(silicon_rev <= 0x20) { - /* rev A */ - pReg->DacRegs[0] = 0x07; - } else { - /* rev B */ - pReg->DacRegs[0] = 0x06; - } - } - - /* - * This will initialize all of the generic VGA registers. - */ - if (!vgaHWInit(pScrn, mode)) - return(FALSE); - - /* - * Here all of the MGA registers get filled in. - */ - hd = (mode->CrtcHDisplay >> 3) - 1; - hs = (mode->CrtcHSyncStart >> 3) - 1; - he = (mode->CrtcHSyncEnd >> 3) - 1; - ht = (mode->CrtcHTotal >> 3) - 1; - vd = mode->CrtcVDisplay - 1; - vs = mode->CrtcVSyncStart - 1; - ve = mode->CrtcVSyncEnd - 1; - vt = mode->CrtcVTotal - 2; - - /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange - * vertical stripes - */ - if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04) - ht++; - - if (pLayout->bitsPerPixel == 24) - wd = (pLayout->displayWidth * 3) >> (4 - BppShift); - else - wd = pLayout->displayWidth >> (4 - BppShift); - - pReg->ExtVga[0] = 0; - pReg->ExtVga[5] = 0; - - if (mode->Flags & V_INTERLACE) - { - pReg->ExtVga[0] = 0x80; - pReg->ExtVga[5] = (hs + he - ht) >> 1; - wd <<= 1; - vt &= 0xFFFE; - - /* enable interlaced cursor */ - pReg->DacRegs[20] |= 0x20; - } - - pReg->ExtVga[0] |= (wd & 0x300) >> 4; - pReg->ExtVga[1] = (((ht - 4) & 0x100) >> 8) | - ((hd & 0x100) >> 7) | - ((hs & 0x100) >> 6) | - (ht & 0x40); - pReg->ExtVga[2] = ((vt & 0xc00) >> 10) | - ((vd & 0x400) >> 8) | - ((vd & 0xc00) >> 7) | - ((vs & 0xc00) >> 5); - if (pLayout->bitsPerPixel == 24) - pReg->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80; - else - pReg->ExtVga[3] = ((1 << BppShift) - 1) | 0x80; - - /* Set viddelay (CRTCEXT3 Bits 3-4). */ - pReg->ExtVga[3] |= (pScrn->videoRam == 8192 ? 0x10 - : pScrn->videoRam == 2048 ? 0x08 : 0x00); - - pReg->ExtVga[4] = 0; - - pVga->CRTC[0] = ht - 4; - pVga->CRTC[1] = hd; - pVga->CRTC[2] = hd; - pVga->CRTC[3] = (ht & 0x1F) | 0x80; - pVga->CRTC[4] = hs; - pVga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F); - pVga->CRTC[6] = vt & 0xFF; - pVga->CRTC[7] = ((vt & 0x100) >> 8 ) | - ((vd & 0x100) >> 7 ) | - ((vs & 0x100) >> 6 ) | - ((vd & 0x100) >> 5 ) | - 0x10 | - ((vt & 0x200) >> 4 ) | - ((vd & 0x200) >> 3 ) | - ((vs & 0x200) >> 2 ); - pVga->CRTC[9] = ((vd & 0x200) >> 4) | 0x40; - pVga->CRTC[16] = vs & 0xFF; - pVga->CRTC[17] = (ve & 0x0F) | 0x20; - pVga->CRTC[18] = vd & 0xFF; - pVga->CRTC[19] = wd & 0xFF; - pVga->CRTC[21] = vd & 0xFF; - pVga->CRTC[22] = (vt + 1) & 0xFF; - - if (mode->Flags & V_DBLSCAN) - pVga->CRTC[9] |= 0x80; - - /* Per DDK vid.c line 75, sync polarity should be controlled - * via the TVP3026 RAMDAC register 1D and so MISC Output Register - * should always have bits 6 and 7 set. */ - - pVga->MiscOutReg |= 0xC0; - if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) && - (mode->Flags & (V_PVSYNC | V_NVSYNC))) - { - if (mode->Flags & V_PHSYNC) - pReg->DacRegs[index_1d] |= 0x01; - if (mode->Flags & V_PVSYNC) - pReg->DacRegs[index_1d] |= 0x02; - } - else - { - int VDisplay = mode->VDisplay; - if (mode->Flags & V_DBLSCAN) - VDisplay *= 2; - if (VDisplay < 400) - pReg->DacRegs[index_1d] |= 0x01; /* +hsync -vsync */ - else if (VDisplay < 480) - pReg->DacRegs[index_1d] |= 0x02; /* -hsync +vsync */ - else if (VDisplay < 768) - pReg->DacRegs[index_1d] |= 0x00; /* -hsync -vsync */ - else - pReg->DacRegs[index_1d] |= 0x03; /* +hsync +vsync */ - } - - if (pMga->SyncOnGreen) - pReg->DacRegs[index_1d] |= 0x20; - - pReg->Option = 0x402C0100; /* fine for 2064 and 2164 */ - - if (pMga->Interleave) - pReg->Option |= 0x1000; - else - pReg->Option &= ~0x1000; - - /* must always have the pci retries on but rely on - polling to keep them from occuring */ - pReg->Option &= ~0x20000000; - - pVga->MiscOutReg |= 0x0C; - /* XXX Need to check the first argument */ - MGATi3026SetPCLK( pScrn, mode->Clock, 1 << BppShift ); - - /* this one writes registers rather than writing to the - mgaReg->ModeReg and letting Restore write to the hardware - but that's no big deal since we will Restore right after - this function */ - - MGA_NOT_HAL(MGATi3026SetMCLK(pScrn, MGAdac->MemoryClock)); - -#ifdef DEBUG - ErrorF("%6ld: %02X %02X %02X %02X %02X %02X %08lX\n", mode->Clock, - pReg->DacClk[0], pReg->DacClk[1], pReg->DacClk[2], pReg->DacClk[3], pReg->DacClk[4], pReg->DacClk[5], pReg->Option); - for (i=0; i<sizeof(MGADACregs); i++) ErrorF("%02X ", pReg->DacRegs[i]); - for (i=0; i<6; i++) ErrorF(" %02X", pReg->ExtVga[i]); - ErrorF("\n"); -#endif - - /* This disables the VGA memory aperture */ - pVga->MiscOutReg &= ~0x02; - return(TRUE); -} - -/* - * MGA3026Restore -- for mga2064 with ti3026 - * - * This function restores a video mode. It basically writes out all of - * the registers that have previously been saved in the vgaMGARec data - * structure. - */ -static void -MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, - Bool restoreFonts) -{ - int i; - MGAPtr pMga = MGAPTR(pScrn); - - /* - * Code is needed to get things back to bank zero. - */ - for (i = 0; i < 6; i++) - OUTREG16(0x1FDE, (mgaReg->ExtVga[i] << 8) | i); - - pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, OPTION_MASK, - mgaReg->Option); - - MGA_NOT_HAL( - /* select pixel clock PLL as clock source */ - outTi3026(TVP3026_CLK_SEL, 0, mgaReg->DacRegs[3]); - - /* set loop and pixel clock PLL PLLEN bits to 0 */ - outTi3026(TVP3026_PLL_ADDR, 0, 0x2A); - outTi3026(TVP3026_LOAD_CLK_DATA, 0, 0); - outTi3026(TVP3026_PIX_CLK_DATA, 0, 0); - ); /* MGA_NOT_HAL */ - - /* - * This function handles restoring the generic VGA registers. - */ - vgaHWRestore(pScrn, vgaReg, - VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0)); - MGA3026RestorePalette(pScrn, vgaReg->DAC); - - /* - * Code to restore SVGA registers that have been saved/modified - * goes here. - */ - - MGA_NOT_HAL( - /* program pixel clock PLL */ - outTi3026(TVP3026_PLL_ADDR, 0, 0x00); - for (i = 0; i < 3; i++) - outTi3026(TVP3026_PIX_CLK_DATA, 0, mgaReg->DacClk[i]); - - if (vgaReg->MiscOutReg & 0x08) { - /* poll until pixel clock PLL LOCK bit is set */ - outTi3026(TVP3026_PLL_ADDR, 0, 0x3F); - while ( ! (inTi3026(TVP3026_PIX_CLK_DATA) & 0x40) ); - } - - /* set Q divider for loop clock PLL */ - outTi3026(TVP3026_MCLK_CTL, 0, mgaReg->DacRegs[18]); - ); /* MGA_NOT_HAL */ - - /* program loop PLL */ - outTi3026(TVP3026_PLL_ADDR, 0, 0x00); - for (i = 3; i < 6; i++) - outTi3026(TVP3026_LOAD_CLK_DATA, 0, mgaReg->DacClk[i]); - - MGA_NOT_HAL( - if ((vgaReg->MiscOutReg & 0x08) && ((mgaReg->DacClk[3] & 0xC0) == 0xC0) ) { - /* poll until loop PLL LOCK bit is set */ - outTi3026(TVP3026_PLL_ADDR, 0, 0x3F); - while ( ! (inTi3026(TVP3026_LOAD_CLK_DATA) & 0x40) ); - } - ); /* MGA_NOT_HAL */ - - /* - * restore other DAC registers - */ - for (i = 0; i < DACREGSIZE; i++) - outTi3026(MGADACregs[i], 0, mgaReg->DacRegs[i]); - -#ifdef DEBUG - ErrorF("PCI retry (0-enabled / 1-disabled): %d\n", - !!(mgaReg->Option & 0x20000000)); -#endif -} - -/* - * MGA3026Save -- for mga2064 with ti3026 - * - * This function saves the video state. - */ -static void -MGA3026Save(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, - Bool saveFonts) -{ - int i; - MGAPtr pMga = MGAPTR(pScrn); - - /* Allocate the DacRegs space if not done already */ - if (mgaReg->DacRegs == NULL) { - mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1); - } - - /* - * Code is needed to get back to bank zero. - */ - OUTREG16(0x1FDE, 0x0004); - - /* - * This function will handle creating the data structure and filling - * in the generic VGA portion. - */ - vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts ? VGA_SR_FONTS : 0)); - MGA3026SavePalette(pScrn, vgaReg->DAC); - - /* - * The port I/O code necessary to read in the extended registers - * into the fields of the vgaMGARec structure. - */ - for (i = 0; i < 6; i++) - { - OUTREG8(0x1FDE, i); - mgaReg->ExtVga[i] = INREG8(0x1FDF); - } - - MGA_NOT_HAL( - outTi3026(TVP3026_PLL_ADDR, 0, 0x00); - for (i = 0; i < 3; i++) - outTi3026(TVP3026_PIX_CLK_DATA, 0, mgaReg->DacClk[i] = - inTi3026(TVP3026_PIX_CLK_DATA)); - - outTi3026(TVP3026_PLL_ADDR, 0, 0x00); - for (i = 3; i < 6; i++) - outTi3026(TVP3026_LOAD_CLK_DATA, 0, mgaReg->DacClk[i] = - inTi3026(TVP3026_LOAD_CLK_DATA)); - ); /* MGA_NOT_HAL */ - - for (i = 0; i < DACREGSIZE; i++) - mgaReg->DacRegs[i] = inTi3026(MGADACregs[i]); - - mgaReg->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG); - -#ifdef DEBUG - ErrorF("read: %02X %02X %02X %02X %02X %02X %08lX\n", - mgaReg->DacClk[0], mgaReg->DacClk[1], mgaReg->DacClk[2], mgaReg->DacClk[3], mgaReg->DacClk[4], mgaReg->DacClk[5], mgaReg->Option); - for (i=0; i<sizeof(MGADACregs); i++) ErrorF("%02X ", mgaReg->DacRegs[i]); - for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]); - ErrorF("\n"); -#endif -} - static void MGA3026LoadCursorImage( @@ -1025,7 +211,7 @@ MGA3026_I2CPutBits(I2CBusPtr b, int clock, int data) } -Bool +static Bool MGA3026_i2cInit(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); @@ -1034,8 +220,6 @@ MGA3026_i2cInit(ScrnInfoPtr pScrn) I2CPtr = xf86CreateI2CBusRec(); if(!I2CPtr) return FALSE; - pMga->DDC_Bus1 = I2CPtr; - I2CPtr->BusName = "DDC"; I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = MGA3026_I2CPutBits; @@ -1047,9 +231,12 @@ MGA3026_i2cInit(ScrnInfoPtr pScrn) /* I2CPtr->AcknTimeout = 10; */ if (!xf86I2CBusInit(I2CPtr)) { + xf86DestroyI2CBusRec(I2CPtr, TRUE, TRUE); return FALSE; + } else { + pMga->DDC_Bus1 = I2CPtr; + return TRUE; } - return TRUE; } static void @@ -1162,8 +349,7 @@ void MGA3026LoadPalette( } } - -static void +void MGA3026SavePalette(ScrnInfoPtr pScrn, unsigned char* pntr) { MGAPtr pMga = MGAPTR(pScrn); @@ -1174,7 +360,7 @@ MGA3026SavePalette(ScrnInfoPtr pScrn, unsigned char* pntr) *(pntr++) = inTi3026dreg(TVP3026_COL_PAL); } -static void +void MGA3026RestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr) { MGAPtr pMga = MGAPTR(pScrn); @@ -1191,9 +377,6 @@ void MGA2064SetupFuncs(ScrnInfoPtr pScrn) MGAPtr pMga = MGAPTR(pScrn); pMga->PreInit = MGA3026RamdacInit; - pMga->Save = MGA3026Save; - pMga->Restore = MGA3026Restore; - pMga->ModeInit = MGA3026Init; pMga->ddc1Read = MGA3026_ddc1Read; /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */ pMga->DDC1SetSpeed = vgaHWddc1SetSpeedWeak(); diff --git a/src/mga_dac3026.h b/src/mga_dac3026.h new file mode 100644 index 0000000..e8849b0 --- /dev/null +++ b/src/mga_dac3026.h @@ -0,0 +1,30 @@ +/* + * Copyright 1994 by Robin Cutshaw <robin@XFree86.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Robin Cutshaw not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Robin Cutshaw makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ROBIN CUTSHAW BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _MGA_DAC3026_H_ +#define _MGA_DAC3026_H_ + +void MGA3026RestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr); +void MGA3026LoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); +void MGA3026SavePalette(ScrnInfoPtr pScrn, unsigned char* pntr); + +#endif diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 99eff18..100bf43 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -28,7 +28,6 @@ #include "mga_reg.h" #include "mga.h" #include "mga_macros.h" -#include "mga_maven.h" #include "xf86DDC.h" @@ -38,588 +37,10 @@ /* * implementation */ - -#define DACREGSIZE 0x50 - -/* - * Only change bits shown in this mask. Ideally reserved bits should be - * zeroed here. Also, don't change the vgaioen bit here since it is - * controlled elsewhere. - * - * XXX These settings need to be checked. - */ -#define OPTION1_MASK 0xFFFFFEFF -#define OPTION2_MASK 0xFFFFFFFF -#define OPTION3_MASK 0xFFFFFFFF - -#define OPTION1_MASK_PRIMARY 0xFFFC0FF static void MGAGRamdacInit(ScrnInfoPtr); -static void MGAGSave(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); -static void MGAGRestore(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool); -static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr); -static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); static Bool MGAG_i2cInit(ScrnInfoPtr pScrn); -static void -MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P) -{ - unsigned int ulComputedFo; - unsigned int ulFDelta; - unsigned int ulFPermitedDelta; - unsigned int ulFTmpDelta; - unsigned int ulVCOMax, ulVCOMin; - unsigned int ulTestP; - unsigned int ulTestM; - unsigned int ulTestN; - unsigned int ulPLLFreqRef; - - ulVCOMax = 320000; - ulVCOMin = 160000; - ulPLLFreqRef = 25000; - - ulFDelta = 0xFFFFFFFF; - /* Permited delta is 0.5% as VESA Specification */ - ulFPermitedDelta = lFo * 5 / 1000; - - /* Then we need to minimize the M while staying within 0.5% */ - for (ulTestP = 8; ulTestP > 0; ulTestP >>= 1) { - if ((lFo * ulTestP) > ulVCOMax) continue; - if ((lFo * ulTestP) < ulVCOMin) continue; - - for (ulTestN = 17; ulTestN <= 256; ulTestN++) { - for (ulTestM = 1; ulTestM <= 32; ulTestM++) { - ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP); - if (ulComputedFo > lFo) - ulFTmpDelta = ulComputedFo - lFo; - else - ulFTmpDelta = lFo - ulComputedFo; - - if (ulFTmpDelta < ulFDelta) { - ulFDelta = ulFTmpDelta; - *M = ulTestM - 1; - *N = ulTestN - 1; - *P = ulTestP - 1; - } - } - } - } -} - - -/** - * Calculate the PLL settings (m, n, p, s). - * - * For more information, refer to the Matrox "MGA1064SG Developer - * Specification" (document 10524-MS-0100). chapter 5.7.8. "PLLs Clocks - * Generators" - * - * \param f_out Desired clock frequency, measured in kHz. - * \param best_m Value of PLL 'm' register. - * \param best_n Value of PLL 'n' register. - * \param p Value of PLL 'p' register. - * \param s Value of PLL 's' filter register (pix pll clock only). - */ - -static void -MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, - int *best_m, int *best_n, int *p, int *s ) -{ - MGAPtr pMga = MGAPTR(pScrn); - int m, n; - double f_vco; - double m_err, calc_f; - const double ref_freq = (double) pMga->bios.pll_ref_freq; - int feed_div_min, feed_div_max; - int in_div_min, in_div_max; - int post_div_max; - - switch( pMga->Chipset ) - { - case PCI_CHIP_MGA1064: - feed_div_min = 100; - feed_div_max = 127; - in_div_min = 1; - in_div_max = 31; - post_div_max = 7; - break; - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: - feed_div_min = 7; - feed_div_max = 127; - in_div_min = 1; - in_div_max = 31; - post_div_max = 7; - break; - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: - case PCI_CHIP_MGAG100: - case PCI_CHIP_MGAG100_PCI: - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - default: - feed_div_min = 7; - feed_div_max = 127; - in_div_min = 1; - in_div_max = 6; - post_div_max = 7; - break; - } - - /* Make sure that f_min <= f_out */ - if ( f_out < ( pMga->bios.pixel.min_freq / 8)) - f_out = pMga->bios.pixel.min_freq / 8; - - /* - * f_pll = f_vco / (p+1) - * Choose p so that - * pMga->bios.pixel.min_freq <= f_vco <= pMga->bios.pixel.max_freq - * we don't have to bother checking for this maximum limit. - */ - f_vco = ( double ) f_out; - for ( *p = 0; *p <= post_div_max && f_vco < pMga->bios.pixel.min_freq; - *p = *p * 2 + 1, f_vco *= 2.0); - - /* Initial amount of error for frequency maximum */ - m_err = f_out; - - /* Search for the different values of ( m ) */ - for ( m = in_div_min ; m <= in_div_max ; m++ ) - { - /* see values of ( n ) which we can't use */ - for ( n = feed_div_min; n <= feed_div_max; n++ ) - { - calc_f = ref_freq * (n + 1) / (m + 1) ; - - /* - * Pick the closest frequency. - */ - if ( abs(calc_f - f_vco) < m_err ) { - m_err = abs(calc_f - f_vco); - *best_m = m; - *best_n = n; - } - } - } - - /* Now all the calculations can be completed */ - f_vco = ref_freq * (*best_n + 1) / (*best_m + 1); - - /* Adjustments for filtering pll feed back */ - if ( (50000.0 <= f_vco) - && (f_vco < 100000.0) ) - *s = 0; - if ( (100000.0 <= f_vco) - && (f_vco < 140000.0) ) - *s = 1; - if ( (140000.0 <= f_vco) - && (f_vco < 180000.0) ) - *s = 2; - if ( (180000.0 <= f_vco) ) - *s = 3; - -#ifdef DEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "f_out_requ =%ld f_pll_real=%.1f f_vco=%.1f n=0x%x m=0x%x p=0x%x s=0x%x\n", - f_out, (f_vco / (*p + 1)), f_vco, *best_n, *best_m, *p, *s ); -#endif -} - -/* - * MGAGSetPCLK - Set the pixel (PCLK) clock. - */ -static void -MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) -{ - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg = &pMga->ModeReg; - - /* Pixel clock values */ - int m, n, p, s; - - if(MGAISGx50(pMga)) { - pReg->Clock = f_out; - return; - } - - if (pMga->is_G200SE) { - MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p); - - pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m; - pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n; - pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p; - } else { - /* Do the calculations for m, n, p and s */ - MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); - - /* Values for the pixel clock PLL registers */ - pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; - pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; - pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | - ((s & 0x03) << 3); - } -} - -/* - * MGAGInit - */ -static Bool -MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - /* - * initial values of the DAC registers - */ - const static unsigned char initDAC[] = { - /* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0, - /* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x18: */ 0x00, 0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20, - /* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* 0x28: */ 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x40, - /* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83, - /* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A, - /* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 - }; - - int i; - int hd, hs, he, ht, vd, vs, ve, vt, wd; - int BppShift; - MGAPtr pMga; - MGARegPtr pReg; - vgaRegPtr pVga; - MGAFBLayout *pLayout; - xMODEINFO ModeInfo; - - ModeInfo.ulDispWidth = mode->HDisplay; - ModeInfo.ulDispHeight = mode->VDisplay; - ModeInfo.ulFBPitch = mode->HDisplay; - ModeInfo.ulBpp = pScrn->bitsPerPixel; - ModeInfo.flSignalMode = 0; - ModeInfo.ulPixClock = mode->Clock; - ModeInfo.ulHFPorch = mode->HSyncStart - mode->HDisplay; - ModeInfo.ulHSync = mode->HSyncEnd - mode->HSyncStart; - ModeInfo.ulHBPorch = mode->HTotal - mode->HSyncEnd; - ModeInfo.ulVFPorch = mode->VSyncStart - mode->VDisplay; - ModeInfo.ulVSync = mode->VSyncEnd - mode->VSyncStart; - ModeInfo.ulVBPorch = mode->VTotal - mode->VSyncEnd; - - pMga = MGAPTR(pScrn); - pReg = &pMga->ModeReg; - pVga = &VGAHWPTR(pScrn)->ModeReg; - pLayout = &pMga->CurrentLayout; - - BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]; - - MGA_NOT_HAL( - /* Allocate the DacRegs space if not done already */ - if (pReg->DacRegs == NULL) { - pReg->DacRegs = xnfcalloc(DACREGSIZE, 1); - } - for (i = 0; i < DACREGSIZE; i++) { - pReg->DacRegs[i] = initDAC[i]; - } - ); /* MGA_NOT_HAL */ - - switch(pMga->Chipset) - { - case PCI_CHIP_MGA1064: - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x44; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; - pReg->Option = 0x5F094F21; - pReg->Option2 = 0x00000000; - break; - case PCI_CHIP_MGAG100: - case PCI_CHIP_MGAG100_PCI: - pReg->DacRegs[MGA1064_VREF_CTL] = 0x03; - - if(pMga->HasSDRAM) { - if(pMga->OverclockMem) { - /* 220 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x38; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; - } else { - /* 203 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x01; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x0E; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; - } - pReg->Option = 0x404991a9; - } else { - if(pMga->OverclockMem) { - /* 143 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10; - } else { - /* 124 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x16; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08; - } - pReg->Option = 0x4049d121; - } - pReg->Option2 = 0x0000007; - break; - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: -#ifdef USEMGAHAL - MGA_HAL(break;); -#endif - if (MGAISGx50(pMga)) - break; - - if(pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */ - if(pMga->OverclockMem) { - /* 150/200 */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x05; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x42; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; - pReg->Option3 = 0x019B8419; - pReg->Option = 0x50574120; - } else { - /* 125/166 */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; - pReg->Option3 = 0x019B8419; - pReg->Option = 0x5053C120; - } - } else { - if(pMga->OverclockMem) { - /* 125/166 */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; - pReg->Option3 = 0x019B8419; - pReg->Option = 0x5053C120; - } else { - /* 110/166 */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08; - pReg->Option3 = 0x0190a421; - pReg->Option = 0x50044120; - } - } - if(pMga->HasSDRAM) - pReg->Option &= ~(1 << 14); - pReg->Option2 = 0x01003000; - break; - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: -#ifdef USEMGAHAL - MGA_HAL(break;); -#endif - pReg->DacRegs[ MGA1064_VREF_CTL ] = 0x03; - pReg->DacRegs[MGA1064_PIX_CLK_CTL] = - MGA1064_PIX_CLK_CTL_SEL_PLL; - - pReg->DacRegs[MGA1064_MISC_CTL] = - MGA1064_MISC_CTL_DAC_EN | - MGA1064_MISC_CTL_VGA8 | - MGA1064_MISC_CTL_DAC_RAM_CS; - - if (pMga->HasSDRAM) - pReg->Option = 0x40049120; - pReg->Option2 = 0x00008000; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - default: -#ifdef USEMGAHAL - MGA_HAL(break;); -#endif - if(pMga->OverclockMem) { - /* 143 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10; - } else { - /* 124 Mhz */ - pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04; - pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x2D; - pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x19; - } - pReg->Option2 = 0x00008000; - if(pMga->HasSDRAM) - pReg->Option = 0x40499121; - else - pReg->Option = 0x4049cd21; - break; - } - - MGA_NOT_HAL( - /* must always have the pci retries on but rely on - polling to keep them from occuring */ - pReg->Option &= ~0x20000000; - - switch(pLayout->bitsPerPixel) - { - case 8: - pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_8bits; - break; - case 16: - pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_16bits; - if ( (pLayout->weight.red == 5) && (pLayout->weight.green == 5) - && (pLayout->weight.blue == 5) ) { - pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_15bits; - } - break; - case 24: - pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_24bits; - break; - case 32: - if(pLayout->Overlay8Plus24) { - pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32bits; - pReg->DacRegs[ MGA1064_COL_KEY_MSK_LSB ] = 0xFF; - pReg->DacRegs[ MGA1064_COL_KEY_LSB ] = pMga->colorKey; - } else - pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32_24bits; - break; - default: - FatalError("MGA: unsupported depth\n"); - } - ); /* MGA_NOT_HAL */ - - /* - * This will initialize all of the generic VGA registers. - */ - if (!vgaHWInit(pScrn, mode)) - return(FALSE); - - /* - * Here all of the MGA registers get filled in. - */ - hd = (mode->CrtcHDisplay >> 3) - 1; - hs = (mode->CrtcHSyncStart >> 3) - 1; - he = (mode->CrtcHSyncEnd >> 3) - 1; - ht = (mode->CrtcHTotal >> 3) - 1; - vd = mode->CrtcVDisplay - 1; - vs = mode->CrtcVSyncStart - 1; - ve = mode->CrtcVSyncEnd - 1; - vt = mode->CrtcVTotal - 2; - - /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange - * vertical stripes - */ - if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04) - ht++; - - if (pLayout->bitsPerPixel == 24) - wd = (pLayout->displayWidth * 3) >> (4 - BppShift); - else - wd = pLayout->displayWidth >> (4 - BppShift); - - pReg->ExtVga[0] = 0; - pReg->ExtVga[5] = 0; - - if (mode->Flags & V_INTERLACE) - { - pReg->ExtVga[0] = 0x80; - pReg->ExtVga[5] = (hs + he - ht) >> 1; - wd <<= 1; - vt &= 0xFFFE; - } - - pReg->ExtVga[0] |= (wd & 0x300) >> 4; - pReg->ExtVga[1] = (((ht - 4) & 0x100) >> 8) | - ((hd & 0x100) >> 7) | - ((hs & 0x100) >> 6) | - (ht & 0x40); - pReg->ExtVga[2] = ((vt & 0xc00) >> 10) | - ((vd & 0x400) >> 8) | - ((vd & 0xc00) >> 7) | - ((vs & 0xc00) >> 5) | - ((vd & 0x400) >> 3); /* linecomp */ - if (pLayout->bitsPerPixel == 24) - pReg->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80; - else - pReg->ExtVga[3] = ((1 << BppShift) - 1) | 0x80; - - pReg->ExtVga[4] = 0; - - pVga->CRTC[0] = ht - 4; - pVga->CRTC[1] = hd; - pVga->CRTC[2] = hd; - pVga->CRTC[3] = (ht & 0x1F) | 0x80; - pVga->CRTC[4] = hs; - pVga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F); - pVga->CRTC[6] = vt & 0xFF; - pVga->CRTC[7] = ((vt & 0x100) >> 8 ) | - ((vd & 0x100) >> 7 ) | - ((vs & 0x100) >> 6 ) | - ((vd & 0x100) >> 5 ) | - ((vd & 0x100) >> 4 ) | /* linecomp */ - ((vt & 0x200) >> 4 ) | - ((vd & 0x200) >> 3 ) | - ((vs & 0x200) >> 2 ); - pVga->CRTC[9] = ((vd & 0x200) >> 4) | - ((vd & 0x200) >> 3); /* linecomp */ - pVga->CRTC[16] = vs & 0xFF; - pVga->CRTC[17] = (ve & 0x0F) | 0x20; - pVga->CRTC[18] = vd & 0xFF; - pVga->CRTC[19] = wd & 0xFF; - pVga->CRTC[21] = vd & 0xFF; - pVga->CRTC[22] = (vt + 1) & 0xFF; - pVga->CRTC[24] = vd & 0xFF; /* linecomp */ - - MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_LOW] = pMga->FbCursorOffset >> 10); - MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_HI] = pMga->FbCursorOffset >> 18); - - if (pMga->SyncOnGreen) { - MGA_NOT_HAL( - pReg->DacRegs[MGA1064_GEN_CTL] &= - ~MGA1064_GEN_CTL_SYNC_ON_GREEN_DIS; - ); - - pReg->ExtVga[3] |= 0x40; - } - - /* select external clock */ - pVga->MiscOutReg |= 0x0C; - - MGA_NOT_HAL( - if (mode->Flags & V_DBLSCAN) - pVga->CRTC[9] |= 0x80; - - if(MGAISGx50(pMga)) { - OUTREG(MGAREG_ZORG, 0); - } - - MGAGSetPCLK(pScrn, mode->Clock); - ); /* MGA_NOT_HAL */ - - /* This disables the VGA memory aperture */ - pVga->MiscOutReg &= ~0x02; - - /* Urgh. Why do we define our own xMODEINFO structure instead - * of just passing the blinkin' DisplayModePtr? If we're going to - * just cut'n'paste routines from the HALlib, it would be better - * just to strip the MacroVision stuff out of the HALlib and release - * that, surely? - */ - /********************* Second Crtc programming **************/ - /* Writing values to crtc2[] array */ - if (pMga->SecondCrtc) - { - MGACRTC2Get(pScrn, &ModeInfo); - MGACRTC2GetPitch(pScrn, &ModeInfo); - MGACRTC2GetDisplayStart(pScrn, &ModeInfo,0,0,0); - } - -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* Disable byte-swapping for big-endian architectures - the XFree - driver seems to like a little-endian framebuffer -ReneR */ - /* pReg->Option |= 0x80000000; */ - pReg->Option &= ~0x80000000; -#endif - - return(TRUE); -} - /* * MGAGLoadPalette */ @@ -685,7 +106,7 @@ void MGAGLoadPalette( * MGAGRestorePalette */ -static void +void MGAGRestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr) { MGAPtr pMga = MGAPTR(pScrn); @@ -699,7 +120,7 @@ MGAGRestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr) /* * MGAGSavePalette */ -static void +void MGAGSavePalette(ScrnInfoPtr pScrn, unsigned char* pntr) { MGAPtr pMga = MGAPTR(pScrn); @@ -710,275 +131,6 @@ MGAGSavePalette(ScrnInfoPtr pScrn, unsigned char* pntr) *(pntr++) = inMGAdreg(MGA1064_COL_PAL); } -/* - * MGAGRestore - * - * This function restores a video mode. It basically writes out all of - * the registers that have previously been saved. - */ -static void -MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, - Bool restoreFonts) -{ - int i; - MGAPtr pMga = MGAPTR(pScrn); - CARD32 optionMask; - - /* - * Pixel Clock needs to be restored regardless if we use - * HALLib or not. HALlib doesn't do a good job restoring - * VESA modes. MATROX: hint, hint. - */ - if (MGAISGx50(pMga) && mgaReg->Clock) { - /* - * With HALlib program only when restoring to console! - * To test this we check for Clock == 0. - */ - MGAG450SetPLLFreq(pScrn, mgaReg->Clock); - mgaReg->PIXPLLCSaved = FALSE; - } - - if(!pMga->SecondCrtc) { - /* Do not set the memory config for primary cards as it - should be correct already. Only on little endian architectures - since we need to modify the byteswap bit. -ReneR */ -#if X_BYTE_ORDER == X_BIG_ENDIAN - optionMask = OPTION1_MASK; -#else - optionMask = (pMga->Primary) ? OPTION1_MASK_PRIMARY : OPTION1_MASK; -#endif - -MGA_NOT_HAL( - /* - * Code is needed to get things back to bank zero. - */ - - /* restore DAC registers - * according to the docs we shouldn't write to reserved regs*/ - for (i = 0; i < DACREGSIZE; i++) { - if( (i <= 0x03) || - (i == 0x07) || - (i == 0x0b) || - (i == 0x0f) || - ((i >= 0x13) && (i <= 0x17)) || - (i == 0x1b) || - (i == 0x1c) || - ((i >= 0x1f) && (i <= 0x29)) || - ((i >= 0x30) && (i <= 0x37)) || - (MGAISGx50(pMga) && !mgaReg->PIXPLLCSaved && - ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) || - (i == 0x4c) || (i == 0x4d) || (i == 0x4e)))) - continue; - if (pMga->is_G200SE - && ((i == 0x2C) || (i == 0x2D) || (i == 0x2E))) - continue; - outMGAdac(i, mgaReg->DacRegs[i]); - } - - if (!MGAISGx50(pMga)) { - /* restore pci_option register */ - pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, optionMask, - mgaReg->Option); - if (pMga->Chipset != PCI_CHIP_MGA1064) - pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK, - mgaReg->Option2); - if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) - pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK, - mgaReg->Option3); - } -); /* MGA_NOT_HAL */ -#ifdef USEMGAHAL - /* - * Work around another bug in HALlib: it doesn't restore the - * DAC width register correctly. MATROX: hint, hint. - */ - MGA_HAL( - outMGAdac(MGA1064_MUL_CTL,mgaReg->DacRegs[0]); - outMGAdac(MGA1064_MISC_CTL,mgaReg->DacRegs[1]); - if (!MGAISGx50(pMga)) { - outMGAdac(MGA1064_PIX_PLLC_M,mgaReg->DacRegs[2]); - outMGAdac(MGA1064_PIX_PLLC_N,mgaReg->DacRegs[3]); - outMGAdac(MGA1064_PIX_PLLC_P,mgaReg->DacRegs[4]); - } - ); -#endif - /* restore CRTCEXT regs */ - for (i = 0; i < 6; i++) - OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[i] << 8) | i); - - /* This handles restoring the generic VGA registers. */ - if (pMga->is_G200SE) { - MGAG200SERestoreMode(pScrn, vgaReg); - if (restoreFonts) - MGAG200SERestoreFonts(pScrn, vgaReg); - } else { - vgaHWRestore(pScrn, vgaReg, - VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0)); - } - MGAGRestorePalette(pScrn, vgaReg->DAC); - - /* - * this is needed to properly restore start address - */ - OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[0] << 8) | 0); - } else { - /* Second Crtc */ - xMODEINFO ModeInfo; - -MGA_NOT_HAL( - /* Enable Dual Head */ - MGACRTC2Set(pScrn, &ModeInfo); - MGAEnableSecondOutPut(pScrn, &ModeInfo); - MGACRTC2SetPitch(pScrn, &ModeInfo); - MGACRTC2SetDisplayStart(pScrn, &ModeInfo,0,0,0); - - for (i = 0x80; i <= 0xa0; i ++) { - if (i== 0x8d) { - i = 0x8f; - continue; - } - outMGAdac(i, mgaReg->dac2[ i - 0x80]); - } -); /* MGA_NOT_HAL */ - - } - -#ifdef DEBUG - ErrorF("Setting DAC:"); - for (i=0; i<DACREGSIZE; i++) { -#if 1 - if(!(i%16)) ErrorF("\n%02X: ",i); - ErrorF("%02X ", mgaReg->DacRegs[i]); -#else - if(!(i%8)) ErrorF("\n%02X: ",i); - ErrorF("0x%02X, ", mgaReg->DacRegs[i]); -#endif - } - ErrorF("\nOPTION = %08lX\n", mgaReg->Option); - ErrorF("OPTION2 = %08lX\n", mgaReg->Option2); - ErrorF("CRTCEXT:"); - for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]); - ErrorF("\n"); -#endif - -} - -/* - * MGAGSave - * - * This function saves the video state. - */ -static void -MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, - Bool saveFonts) -{ - int i; - MGAPtr pMga = MGAPTR(pScrn); - - /* - * Pixel Clock needs to be restored regardless if we use - * HALLib or not. HALlib doesn't do a good job restoring - * VESA modes (s.o.). MATROX: hint, hint. - */ - if (MGAISGx50(pMga)) { - mgaReg->Clock = MGAG450SavePLLFreq(pScrn); - } - - if(pMga->SecondCrtc == TRUE) { - for(i = 0x80; i < 0xa0; i++) - mgaReg->dac2[i-0x80] = inMGAdac(i); - - return; - } - - MGA_NOT_HAL( - /* Allocate the DacRegs space if not done already */ - if (mgaReg->DacRegs == NULL) { - mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1); - } - ); /* MGA_NOT_HAL */ - - /* - * Code is needed to get back to bank zero. - */ - OUTREG16(MGAREG_CRTCEXT_INDEX, 0x0004); - - /* - * This function will handle creating the data structure and filling - * in the generic VGA portion. - */ - if (pMga->is_G200SE) { - MGAG200SESaveMode(pScrn, vgaReg); - if (saveFonts) - MGAG200SESaveFonts(pScrn, vgaReg); - } else { - vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | - (saveFonts ? VGA_SR_FONTS : 0)); - } - MGAGSavePalette(pScrn, vgaReg->DAC); - /* - * Work around another bug in HALlib: it doesn't restore the - * DAC width register correctly. - */ - -#ifdef USEMGAHAL - /* - * Work around another bug in HALlib: it doesn't restore the - * DAC width register correctly (s.o.). MATROX: hint, hint. - */ - MGA_HAL( - if (mgaReg->DacRegs == NULL) { - mgaReg->DacRegs = xnfcalloc(MGAISGx50(pMga) ? 2 : 5, 1); - } - mgaReg->DacRegs[0] = inMGAdac(MGA1064_MUL_CTL); - mgaReg->DacRegs[1] = inMGAdac(MGA1064_MISC_CTL); - if (!MGAISGx50(pMga)) { - mgaReg->DacRegs[2] = inMGAdac(MGA1064_PIX_PLLC_M); - mgaReg->DacRegs[3] = inMGAdac(MGA1064_PIX_PLLC_N); - mgaReg->DacRegs[4] = inMGAdac(MGA1064_PIX_PLLC_P); - } - ); -#endif - MGA_NOT_HAL( - /* - * The port I/O code necessary to read in the extended registers. - */ - for (i = 0; i < DACREGSIZE; i++) - mgaReg->DacRegs[i] = inMGAdac(i); - - mgaReg->PIXPLLCSaved = TRUE; - - mgaReg->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG); - - mgaReg->Option2 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION2); - if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) - mgaReg->Option3 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION3); - ); /* MGA_NOT_HAL */ - - for (i = 0; i < 6; i++) - { - OUTREG8(MGAREG_CRTCEXT_INDEX, i); - mgaReg->ExtVga[i] = INREG8(MGAREG_CRTCEXT_DATA); - } - -#ifdef DEBUG - ErrorF("Saved values:\nDAC:"); - for (i=0; i<DACREGSIZE; i++) { -#if 1 - if(!(i%16)) ErrorF("\n%02X: ",i); - ErrorF("%02X ", mgaReg->DacRegs[i]); -#else - if(!(i%8)) ErrorF("\n%02X: ",i); - ErrorF("0x%02X, ", mgaReg->DacRegs[i]); -#endif - } - ErrorF("\nOPTION = %08lX\n:", mgaReg->Option); - ErrorF("OPTION2 = %08lX\nCRTCEXT:", mgaReg->Option2); - for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]); - ErrorF("\n"); -#endif -} - /**** *** HW Cursor */ @@ -1028,12 +180,6 @@ MGAGSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) x += 64; y += 64; -#ifdef USEMGAHAL - MGA_HAL( - x += pMga->HALGranularityOffX; - y += pMga->HALGranularityOffY; - ); -#endif /* cursor update must never occurs during a retrace period (pp 4-160) */ while( INREG( MGAREG_Status ) & 0x08 ); @@ -1107,8 +253,6 @@ static const int DDC_P1_SDA_MASK = (1 << 1); static const int DDC_P1_SCL_MASK = (1 << 3); static const int DDC_P2_SDA_MASK = (1 << 0); static const int DDC_P2_SCL_MASK = (1 << 2); -static const int MAVEN_SDA_MASK = (1 << 4); -static const int MAVEN_SCL_MASK = (1 << 5); static unsigned int MGAG_ddc1Read(ScrnInfoPtr pScrn) @@ -1184,11 +328,6 @@ MGAG_DDC_P2_I2CPutBits(I2CBusPtr b, int clock, int data) { MGAG_I2CPutBits(b, clock, data, DDC_P2_SCL_MASK, DDC_P2_SDA_MASK); } -static void -MGAG_MAVEN_I2CPutBits(I2CBusPtr b, int clock, int data) -{ - MGAG_I2CPutBits(b, clock, data, MAVEN_SCL_MASK, MAVEN_SDA_MASK); -} static void MGAG_DDC_P1_I2CGetBits(I2CBusPtr b, int *clock, int *data) @@ -1200,11 +339,6 @@ MGAG_DDC_P2_I2CGetBits(I2CBusPtr b, int *clock, int *data) { MGAG_I2CGetBits(b, clock, data, DDC_P2_SCL_MASK, DDC_P2_SDA_MASK); } -static void -MGAG_MAVEN_I2CGetBits(I2CBusPtr b, int *clock, int *data) -{ - MGAG_I2CGetBits(b, clock, data, MAVEN_SCL_MASK, MAVEN_SDA_MASK); -} Bool MGAG_i2cInit(ScrnInfoPtr pScrn) @@ -1212,110 +346,38 @@ MGAG_i2cInit(ScrnInfoPtr pScrn) MGAPtr pMga = MGAPTR(pScrn); I2CBusPtr I2CPtr; - if (pMga->SecondCrtc == FALSE) { - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; + I2CPtr = xf86CreateI2CBusRec(); + if(!I2CPtr) return FALSE; - pMga->DDC_Bus1 = I2CPtr; + pMga->DDC_Bus1 = I2CPtr; - I2CPtr->BusName = "DDC P1"; - I2CPtr->scrnIndex = pScrn->scrnIndex; - I2CPtr->I2CPutBits = MGAG_DDC_P1_I2CPutBits; - I2CPtr->I2CGetBits = MGAG_DDC_P1_I2CGetBits; - I2CPtr->AcknTimeout = 5; + I2CPtr->BusName = "DDC P1"; + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->I2CPutBits = MGAG_DDC_P1_I2CPutBits; + I2CPtr->I2CGetBits = MGAG_DDC_P1_I2CGetBits; + I2CPtr->AcknTimeout = 5; - if (!xf86I2CBusInit(I2CPtr)) { - xf86DestroyI2CBusRec(pMga->DDC_Bus1, TRUE, TRUE); - pMga->DDC_Bus1 = NULL; - return FALSE; - } + if (!xf86I2CBusInit(I2CPtr)) { + xf86DestroyI2CBusRec(pMga->DDC_Bus1, TRUE, TRUE); + pMga->DDC_Bus1 = NULL; + return FALSE; } - else { + /* We have a dual head setup on G-series, set up DDC #2. */ - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; - - pMga->DDC_Bus2 = I2CPtr; - - I2CPtr->BusName = "DDC P2"; - I2CPtr->scrnIndex = pScrn->scrnIndex; - I2CPtr->I2CPutBits = MGAG_DDC_P2_I2CPutBits; - I2CPtr->I2CGetBits = MGAG_DDC_P2_I2CGetBits; - I2CPtr->AcknTimeout = 5; - - if (!xf86I2CBusInit(I2CPtr)) { - xf86DestroyI2CBusRec(pMga->DDC_Bus2, TRUE, TRUE); - pMga->DDC_Bus2 = NULL; - } - else { - if (!xf86I2CProbeAddress(pMga->DDC_Bus2, 0xA0)) { /* 0xA0 is DDC EEPROM address */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC #2 unavailable -> TV cable connected or no monitor connected!\n"); - pMga->Crtc2IsTV = TRUE; /* assume for now. We need to fix HAL interactions. */ - } - } - - /* Then try to set up MAVEN bus. */ - - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; - pMga->Maven_Bus = I2CPtr; - - I2CPtr->BusName = "MAVEN"; - I2CPtr->scrnIndex = pScrn->scrnIndex; - I2CPtr->I2CPutBits = MGAG_MAVEN_I2CPutBits; - I2CPtr->I2CGetBits = MGAG_MAVEN_I2CGetBits; - I2CPtr->StartTimeout = 5; - - if (!xf86I2CBusInit(I2CPtr)) { - xf86DestroyI2CBusRec(pMga->Maven_Bus, TRUE, TRUE); - pMga->Maven_Bus = NULL; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to register MAVEN I2C bus!\n"); - } - else { - Bool failed = FALSE; - /* Try to detect the MAVEN. */ - if (xf86I2CProbeAddress(pMga->Maven_Bus, MAVEN_READ) == TRUE) { - I2CDevPtr dp = xf86CreateI2CDevRec(); - if (dp) { - I2CByte maven_ver; - - pMga->Maven = dp; - dp->DevName = "MGA-TVO"; - dp->SlaveAddr = MAVEN_WRITE; - dp->pI2CBus = pMga->Maven_Bus; - if (!xf86I2CDevInit(dp)) { - xf86DestroyI2CDevRec(dp, TRUE); - pMga->Maven = NULL; - failed = TRUE; - } - if (MGAMavenRead(pScrn, 0xB2, &maven_ver)) { - if (maven_ver < 0x14) { /* heuristic stolen from matroxfb */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MAVEN revision MGA-TVO-B detected (0x%x)\n", maven_ver); - pMga->Maven_Version = 'B'; - } - else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MAVEN revision MGA-TVO-C detected (0x%x)\n", maven_ver); - pMga->Maven_Version = 'C'; - } - } - else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to determine MAVEN hardware version!\n"); - } - } - else { - failed = TRUE; - } - } - else { - failed = TRUE; - } - - if (failed) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to register MGA-TVO I2C device!\n"); - pMga->Maven = NULL; - pMga->Maven_Version = 0; - } - } + I2CPtr = xf86CreateI2CBusRec(); + if(!I2CPtr) return FALSE; + + pMga->DDC_Bus2 = I2CPtr; + + I2CPtr->BusName = "DDC P2"; + I2CPtr->scrnIndex = pScrn->scrnIndex; + I2CPtr->I2CPutBits = MGAG_DDC_P2_I2CPutBits; + I2CPtr->I2CGetBits = MGAG_DDC_P2_I2CGetBits; + I2CPtr->AcknTimeout = 5; + + if (!xf86I2CBusInit(I2CPtr)) { + xf86DestroyI2CBusRec(pMga->DDC_Bus2, TRUE, TRUE); + pMga->DDC_Bus2 = NULL; } return TRUE; @@ -1379,9 +441,6 @@ void MGAGSetupFuncs(ScrnInfoPtr pScrn) MGAPtr pMga = MGAPTR(pScrn); pMga->PreInit = MGAGRamdacInit; - pMga->Save = MGAGSave; - pMga->Restore = MGAGRestore; - pMga->ModeInit = MGAGInit; pMga->ddc1Read = MGAG_ddc1Read; /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */ pMga->DDC1SetSpeed = vgaHWddc1SetSpeedWeak(); diff --git a/src/mga_dacG.h b/src/mga_dacG.h new file mode 100644 index 0000000..0223829 --- /dev/null +++ b/src/mga_dacG.h @@ -0,0 +1,12 @@ +/* + * MGA-1064, MGA-G100, MGA-G200, MGA-G400, MGA-G550 RAMDAC driver + */ + +#ifndef _MGA_DACG_H_ +#define _MGA_DACG_H_ + +void MGAGRestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr); +void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); +void MGAGSavePalette(ScrnInfoPtr pScrn, unsigned char* pntr); + +#endif diff --git a/src/mga_dh.c b/src/mga_dh.c deleted file mode 100644 index 8cfd54c..0000000 --- a/src/mga_dh.c +++ /dev/null @@ -1,451 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dh.c,v 1.4tsi Exp $ */ -/********************************************************************* -* G450: This is for Dual Head. -* Matrox Graphics -* Author : Luugi Marsan -**********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* All drivers should typically include these */ -#include "xf86.h" -#include "xf86_OSproc.h" - -/* Drivers for PCI hardware need this */ -#include "xf86PciInfo.h" - -/* Drivers that need to access the PCI config space directly need this */ -#include "xf86Pci.h" - -#include "mga_reg.h" -#include "mga.h" - -#define MNP_TABLE_SIZE 64 -#define CLKSEL_MGA 0x0c -#define PLLLOCK 0x40 - -/* Misc field*/ -#define IOADDSEL 0x01 -#define RAMMAPEN 0x02 -#define CLKSEL_25175 0x00 -#define CLKSEL_28322 0x04 -#define CLKSEL_MGA 0x0c -#define VIDEODIS 0x10 -#define HPGODDEV 0x20 -#define HSYNCPOL 0x40 -#define VSYNCPOL 0x80 - -/* XSYNCCTRL field */ -#define XSYNCCTRL_DAC1HSPOL_SHIFT 2 -#define XSYNCCTRL_DAC1HSPOL_MASK (1 << XSYNCCTRL_DAC1HSPOL_SHIFT) -#define XSYNCCTRL_DAC1HSPOL_NEG (1 << XSYNCCTRL_DAC1HSPOL_SHIFT) -#define XSYNCCTRL_DAC1HSPOL_POS 0 -#define XSYNCCTRL_DAC1VSPOL_SHIFT 3 -#define XSYNCCTRL_DAC1VSPOL_MASK (1 << XSYNCCTRL_DAC1VSPOL_SHIFT) -#define XSYNCCTRL_DAC1VSPOL_NEG (1 << XSYNCCTRL_DAC1VSPOL_SHIFT) -#define XSYNCCTRL_DAC1VSPOL_POS 0 -#define XSYNCCTRL_DAC2HSPOL_SHIFT 6 -#define XSYNCCTRL_DAC2HSPOL_MASK (1 << XSYNCCTRL_DAC2HSPOL_SHIFT) -#define XSYNCCTRL_DAC2HSPOL_NEG (1 << XSYNCCTRL_DAC2HSPOL_SHIFT) -#define XSYNCCTRL_DAC2HSPOL_POS 0 -#define XSYNCCTRL_DAC2VSPOL_SHIFT 7 -#define XSYNCCTRL_DAC2VSPOL_MASK (1 << XSYNCCTRL_DAC2VSPOL_SHIFT) -#define XSYNCCTRL_DAC2VSPOL_NEG (1 << XSYNCCTRL_DAC2VSPOL_SHIFT) -#define XSYNCCTRL_DAC2VSPOL_POS 0 -#define XSYNCCTRL_DAC1HSOFF_SHIFT 0 -#define XSYNCCTRL_DAC1HSOFF_MASK (1 << XSYNCCTRL_DAC1HSOFF_SHIFT) -#define XSYNCCTRL_DAC1HSOFF_OFF (1 << XSYNCCTRL_DAC1HSOFF_SHIFT) -#define XSYNCCTRL_DAC1HSOFF_ON 1 -#define XSYNCCTRL_DAC1VSOFF_SHIFT 1 -#define XSYNCCTRL_DAC1VSOFF_MASK (1 << XSYNCCTRL_DAC1VSOFF_SHIFT) -#define XSYNCCTRL_DAC1VSOFF_OFF (1 << XSYNCCTRL_DAC1VSOFF_SHIFT) -#define XSYNCCTRL_DAC1VSOFF_ON 0 -#define XSYNCCTRL_DAC2HSOFF_SHIFT 4 -#define XSYNCCTRL_DAC2HSOFF_MASK (1 << XSYNCCTRL_DAC2HSOFF_SHIFT) -#define XSYNCCTRL_DAC2HSOFF_OFF (1 << XSYNCCTRL_DAC2HSOFF_SHIFT) -#define XSYNCCTRL_DAC2HSOFF_ON 0 -#define XSYNCCTRL_DAC2VSOFF_SHIFT 5 -#define XSYNCCTRL_DAC2VSOFF_MASK (1 << XSYNCCTRL_DAC2VSOFF_SHIFT) -#define XSYNCCTRL_DAC2VSOFF_OFF (1 << XSYNCCTRL_DAC2VSOFF_SHIFT) -#define XSYNCCTRL_DAC2VSOFF_ON 0 - -#define POS_HSYNC 0x00000004 -#define POS_VSYNC 0x00000008 - - -/* Set CRTC 2*/ -/* Uses the mode given by xfree86 to setup the registry */ -/* Does not write to the hard yet */ -void MGACRTC2Get(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) -{ - - - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg = &pMga->ModeReg; - - xMODEINFO tmpModeInfo; - CARD32 ulHTotal; - CARD32 ulHDispEnd; - CARD32 ulHBlkStr; - CARD32 ulHSyncStr; - CARD32 ulHSyncEnd; - CARD32 ulVTotal; - CARD32 ulVDispEnd; - CARD32 ulVBlkStr; - CARD32 ulVSyncStr; - CARD32 ulVSyncEnd; - CARD32 ulOffset; - CARD32 ulCtl2; - CARD32 ulDataCtl2; - CARD32 ulDispHeight = pModeInfo->ulDispHeight; - -#ifdef DEBUG - ErrorF("ENTER MGACRTC2Get\n"); -#endif - - tmpModeInfo = *pModeInfo; - - - /* First compute the Values */ - - ulHTotal = tmpModeInfo.ulDispWidth + - tmpModeInfo.ulHFPorch + - tmpModeInfo.ulHBPorch + - tmpModeInfo.ulHSync; - - ulHDispEnd = tmpModeInfo.ulDispWidth; - ulHBlkStr = ulHDispEnd; - ulHSyncStr = ulHBlkStr + tmpModeInfo.ulHFPorch; - ulHSyncEnd = ulHSyncStr + tmpModeInfo.ulHSync; - - ulVTotal = ulDispHeight + - tmpModeInfo.ulVFPorch + - tmpModeInfo.ulVBPorch + - tmpModeInfo.ulVSync; - - - ulVDispEnd = ulDispHeight; - ulVBlkStr = ulVDispEnd; - ulVSyncStr = ulVBlkStr + tmpModeInfo.ulVFPorch; - ulVSyncEnd = ulVSyncStr + tmpModeInfo.ulVSync; - - ulOffset = tmpModeInfo.ulFBPitch; - - - - ulCtl2 = INREG(MGAREG_C2CTL); - ulDataCtl2 = INREG(MGAREG_C2DATACTL); - - ulCtl2 &= 0xFF1FFFFF; - ulDataCtl2 &= 0xFFFFFF00; - - switch (tmpModeInfo.ulBpp) - { - case 15: ulCtl2 |= 0x00200000; - ulOffset <<= 1; - break; - case 16: ulCtl2 |= 0x00400000; - ulOffset <<= 1; - break; - case 32: ulCtl2 |= 0x00800000; - ulOffset <<= 2; - break; - } - - - pReg->crtc2[ MGAREG2_C2CTL ] = ulCtl2; - pReg->crtc2[ MGAREG2_C2DATACTL ] = ulDataCtl2; - - /* Horizontal Value*/ - pReg->crtc2[MGAREG2_C2HPARAM] = (((ulHDispEnd-8) << 16) | (ulHTotal-8)) ; - pReg->crtc2[MGAREG2_C2HSYNC] = (((ulHSyncEnd-8) << 16) | (ulHSyncStr-8)) ; - - - /*Vertical Value*/ - pReg->crtc2[MGAREG2_C2VPARAM] = (((ulVDispEnd-1) << 16) | (ulVTotal-1)) ; - pReg->crtc2[MGAREG2_C2VSYNC] = (((ulVSyncEnd-1) << 16) | (ulVSyncStr-1)) ; - - /** Offset value*/ - - pReg->crtc2[MGAREG2_C2OFFSET] = ulOffset; - -#ifdef DEBUG - ErrorF("EXIT MGACRTC2Get\n"); -#endif - -} - -/* Set CRTC 2*/ -/* Writes to the hardware */ -void MGACRTC2Set(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) -{ - - - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg = &pMga->ModeReg; - -#ifdef DEBUG - ErrorF("ENTER MGACRTC2Set\n"); -#endif - - - /* This writes to the registers manually */ - OUTREG(MGAREG_C2CTL, pReg->crtc2[MGAREG2_C2CTL]); - OUTREG(MGAREG_C2DATACTL,pReg->crtc2[MGAREG2_C2DATACTL]); - - - /* Horizontal Value*/ - OUTREG(MGAREG_C2HPARAM, pReg->crtc2[MGAREG2_C2HPARAM]); - OUTREG(MGAREG_C2HSYNC, pReg->crtc2[MGAREG2_C2HSYNC]); - - - /*Vertical Value*/ - OUTREG(MGAREG_C2VPARAM, pReg->crtc2[MGAREG2_C2VPARAM]); - OUTREG(MGAREG_C2VSYNC, pReg->crtc2[MGAREG2_C2VSYNC]); - - /** Offset value*/ - - OUTREG(MGAREG_C2OFFSET, pReg->crtc2[MGAREG2_C2OFFSET]); -#ifdef DEBUG - ErrorF("EXIT MGACRTC2Set\n"); -#endif - -} - - -/* Set CRTC2 on the right output */ -void MGAEnableSecondOutPut(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) -{ - CARD8 ucByte, ucXDispCtrl; - CARD32 ulC2CTL; - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; - pReg = &pMga->ModeReg; -#ifdef DEBUG - ErrorF("ENTER MGAEnableSecondOutPut\n"); -#endif - - - /* Route Video PLL on second CRTC */ - ulC2CTL = INREG( MGAREG_C2CTL); - - /*--- Disable Pixel clock oscillations On Crtc1 */ - OUTREG( MGAREG_C2CTL, ulC2CTL | MGAREG_C2CTL_PIXCLKDIS_MASK); - /*--- Have to wait minimum time (2 acces will be ok) */ - (void) INREG( MGAREG_Status); - (void) INREG( MGAREG_Status); - - - ulC2CTL &= ~MGAREG_C2CTL_PIXCLKSEL_MASK; - ulC2CTL &= ~MGAREG_C2CTL_PIXCLKSELH_MASK; - - ulC2CTL |= MGAREG_C2CTL_PIXCLKSEL_VIDEOPLL; - - - OUTREG( MGAREG_C2CTL, ulC2CTL); - - /*--- Enable Pixel clock oscillations on CRTC2*/ - ulC2CTL &= ~MGAREG_C2CTL_PIXCLKDIS_MASK; - OUTREG( MGAREG_C2CTL, ulC2CTL); - - - /* We don't use MISC synch pol, must be 0*/ - ucByte = inMGAdreg( MGAREG_MISC_READ); - - OUTREG8(MGAREG_MISC_WRITE, (CARD8)(ucByte & ~(HSYNCPOL| VSYNCPOL) )); - - - - - /* Set Rset to 0.7 V*/ - ucByte = inMGAdac(MGA1064_GEN_IO_CTL); - ucByte &= ~0x40; - pReg->DacRegs[MGA1064_GEN_IO_CTL] = ucByte; - outMGAdac (MGA1064_GEN_IO_CTL, ucByte); - - ucByte = inMGAdac( MGA1064_GEN_IO_DATA); - ucByte &= ~0x40; - pReg->DacRegs[MGA1064_GEN_IO_DATA]= ucByte; - outMGAdac (MGA1064_GEN_IO_DATA, ucByte); - - /* Since G550 can swap outputs at BIOS initialisation, we must check which - * DAC is 'logically' used as the secondary (don't assume its DAC2 anymore) */ - - ulC2CTL = INREG(MGAREG_C2CTL); - ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); - - ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; - - if (!pMga->SecondOutput) { - /* Route Crtc2 on Output1 */ - ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; - ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC2; - } - else { - /* Route Crtc2 on Output2*/ - ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC2; - ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_MASK; - } - - /* Enable CRTC2*/ - ulC2CTL |= MGAREG_C2CTL_C2_EN; - - pReg->dac2[ MGA1064_DISP_CTL - 0x80] = ucXDispCtrl; - - - - OUTREG( MGAREG_C2CTL, ulC2CTL); - - /* Set DAC2 Synch polarity*/ - ucByte = inMGAdac( MGA1064_SYNC_CTL); - ucByte &= ~(XSYNCCTRL_DAC2HSPOL_MASK | XSYNCCTRL_DAC2VSPOL_MASK); - if ( !(pModeInfo->flSignalMode & POS_HSYNC) ) - { - ucByte |= XSYNCCTRL_DAC2HSPOL_NEG; - } - if ( !(pModeInfo->flSignalMode & POS_VSYNC) ) - { - ucByte |= XSYNCCTRL_DAC2VSPOL_NEG; - } - - /* Enable synch output*/ - ucByte &= ~(XSYNCCTRL_DAC2HSOFF_MASK | XSYNCCTRL_DAC2VSOFF_MASK); - pReg->dac2[ MGA1064_SYNC_CTL - 0x80] = ucByte; - - /* Power up DAC2, Fifo. - * The TMDS is powered down here, which is likely wrong. - */ - pReg->dac2[MGA1064_PWR_CTL - 0x80] = - MGA1064_PWR_CTL_DAC2_EN | - MGA1064_PWR_CTL_VID_PLL_EN | - MGA1064_PWR_CTL_RFIFO_EN | - MGA1064_PWR_CTL_CFIFO_EN; - - -#ifdef DEBUG - ErrorF("EXIT MGAEnableSecondOutPut\n"); -#endif -} - - - - - -void MGACRTC2GetPitch (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) -{ - CARD32 ulOffset; - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; - - pReg = &pMga->ModeReg; -#ifdef DEBUG - ErrorF("ENTER MGACRTC2GetPitch\n"); -#endif - - - switch(pModeInfo->ulBpp) - { - case 15: - case 16: - ulOffset = pModeInfo->ulFBPitch * 2; - break; - case 32: - ulOffset = pModeInfo->ulFBPitch * 4; - break; - default: /* Muffle compiler */ - ulOffset = pModeInfo->ulFBPitch; - break; - } - - pReg->crtc2[MGAREG2_C2OFFSET] = ulOffset; - -#ifdef DEBUG - ErrorF("EXIT MGACRTC2GetPitch\n"); -#endif - -} - -void MGACRTC2SetPitch (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) -{ - - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; - pReg = &pMga->ModeReg; - -#ifdef DEBUG - ErrorF("ENTER CRCT2SetPitch\n"); -#endif - - - OUTREG(MGAREG_C2OFFSET, pReg->crtc2[MGAREG2_C2OFFSET]); -#ifdef DEBUG - ErrorF("EXIT CRCT2SetPitch\n"); -#endif - -} - - - /* Set Display Start*/ - /* base in bytes*/ -void MGACRTC2GetDisplayStart (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo, CARD32 base, CARD32 ulX, CARD32 ulY) -{ - - CARD32 ulAddress; - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; - pReg = &pMga->ModeReg; - -#ifdef DEBUG - ErrorF("ENTER MGACRTC2GetDisplayStart\n"); -#endif - - - pReg = &pMga->ModeReg; - - ulAddress = (pModeInfo->ulFBPitch * ulY + ulX); - switch(pModeInfo->ulBpp) - { - case 15: - case 16: - ulAddress <<= 1; - break; - case 32: - ulAddress <<= 2; - break; - } - - pReg->crtc2[MGAREG2_C2STARTADD0] = ulAddress + base; -#ifdef DEBUG - ErrorF("EXIT MGACRTC2GetDisplayStart\n"); -#endif - -} - -void MGACRTC2SetDisplayStart (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo, CARD32 base, CARD32 ulX, CARD32 ulY) -{ - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; - pReg = &pMga->ModeReg; -#ifdef DEBUG - ErrorF("ENTER MGACRTC2SetDisplayStart\n"); -#endif - - OUTREG(MGAREG_C2STARTADD0, pReg->crtc2[MGAREG2_C2STARTADD0]); -#ifdef DEBUG - ErrorF("EXIT MGACRTC2SetDisplayStart\n"); -#endif - -} - - - - - - - - - - - diff --git a/src/mga_dri.c b/src/mga_dri.c index 731c354..ce81982 100644 --- a/src/mga_dri.c +++ b/src/mga_dri.c @@ -392,28 +392,6 @@ void MGAGetQuiescence( ScrnInfoPtr pScrn ) } } -void MGAGetQuiescenceShared( ScrnInfoPtr pScrn ) -{ - MGAPtr pMga = MGAPTR(pScrn); - MGAEntPtr pMGAEnt = pMga->entityPrivate; - MGAPtr pMGA2 = MGAPTR(pMGAEnt->pScrn_2); - - pMga = MGAPTR(pMGAEnt->pScrn_1); - pMga->haveQuiescense = 1; - pMGA2->haveQuiescense = 1; - - if ( pMGAEnt->directRenderingEnabled ) { - MGAWaitForIdleDMA( pMGAEnt->pScrn_1 ); - - /* FIXME what about EXA? */ -#ifdef USE_XAA - if (!pMga->Exa && pMga->AccelInfoRec) - pMga->RestoreAccelState( pScrn ); -#endif - xf86SetLastScrnFlag( pScrn->entityList[0], pScrn->scrnIndex ); - } -} - static void MGASwapContext( ScreenPtr pScreen ) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -427,21 +405,6 @@ static void MGASwapContext( ScreenPtr pScreen ) MGA_MARK_SYNC(pMga, pScrn); } -static void MGASwapContextShared( ScreenPtr pScreen ) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - MGAPtr pMga = MGAPTR(pScrn); - MGAEntPtr pMGAEnt = pMga->entityPrivate; - MGAPtr pMGA2 = MGAPTR(pMGAEnt->pScrn_2); - - pMga = MGAPTR(pMGAEnt->pScrn_1); - - pMga->haveQuiescense = pMGA2->haveQuiescense = 0; - - MGA_MARK_SYNC(pMga, pScrn); - MGA_MARK_SYNC(pMGA2, pMGAEnt->pScrn_2); -} - /* FIXME: This comment is out of date, since we aren't overriding * Block/Wakeuphandler anymore. * @@ -476,19 +439,6 @@ MGADRISwapContext( ScreenPtr pScreen, DRISyncType syncType, } } -static void -MGADRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType, - DRIContextType oldContextType, void *oldContext, - DRIContextType newContextType, void *newContext ) -{ - if ( syncType == DRI_3D_SYNC && - oldContextType == DRI_2D_CONTEXT && - newContextType == DRI_2D_CONTEXT ) - { - MGASwapContextShared( pScreen ); - } -} - void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) { MGAPtr pMga = MGAPTR(pScrn); @@ -1159,6 +1109,7 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) return FALSE; } pMga->pDRIInfo = pDRIInfo; + pMga->dri_lock_held = FALSE; pDRIInfo->drmDriverName = MGAKernelDriverName; pDRIInfo->clientDriverName = MGAClientDriverName; @@ -1234,12 +1185,7 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) pDRIInfo->CreateContext = MGACreateContext; pDRIInfo->DestroyContext = MGADestroyContext; - if ( xf86IsEntityShared( pScrn->entityList[0] ) - && pMga->DualHeadEnabled) { - pDRIInfo->SwapContext = MGADRISwapContextShared; - } else { - pDRIInfo->SwapContext = MGADRISwapContext; - } + pDRIInfo->SwapContext = MGADRISwapContext; #ifdef USE_EXA if (pMga->Exa) { @@ -1532,3 +1478,31 @@ void MGADRICloseScreen( ScreenPtr pScreen ) xfree( pMga->pVisualConfigsPriv ); } } + +Bool +MGADRILock(ScrnInfoPtr scrn) +{ + MGAPtr pMga = MGAPTR(scrn); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + Bool ret = FALSE; + + if (pMga->directRenderingEnabled && !pMga->dri_lock_held) { + DRILock(screen, 0); + pMga->dri_lock_held = TRUE; + ret = TRUE; + } + + return ret; +} + +void +MGADRIUnlock(ScrnInfoPtr scrn) +{ + MGAPtr pMga = MGAPTR(scrn); + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + + if (pMga->directRenderingEnabled && pMga->dri_lock_held) { + DRIUnlock(screen); + pMga->dri_lock_held = FALSE; + } +} diff --git a/src/mga_driver.c b/src/mga_driver.c index a9323fe..b3a9f07 100644 --- a/src/mga_driver.c +++ b/src/mga_driver.c @@ -100,6 +100,9 @@ #include "dri.h" #endif +#include "xf86Crtc.h" +#include "xf86RandR12.h" + #include <unistd.h> /* @@ -117,8 +120,7 @@ static Bool MGAEnterVT(int scrnIndex, int flags); static Bool MGAEnterVTFBDev(int scrnIndex, int flags); static void MGALeaveVT(int scrnIndex, int flags); static Bool MGACloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool MGASaveScreen(ScreenPtr pScreen, int mode); -static Bool MGASaveScreenCrtc2(ScreenPtr pScreen, int mode); +static Bool MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags); /* This shouldn't be needed since RAC will disable all I/O for MGA cards. */ #ifdef DISABLE_VGA_IO @@ -136,14 +138,11 @@ static Bool MGAMapMem(ScrnInfoPtr pScrn); static Bool MGAUnmapMem(ScrnInfoPtr pScrn); static void MGASave(ScrnInfoPtr pScrn); static void MGARestore(ScrnInfoPtr pScrn); -static Bool MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static Bool MGASetMode(ScrnInfoPtr pScrn, DisplayModePtr mode); static void MGABlockHandler(int, pointer, pointer, pointer); static void MGAG100BlackMagic(ScrnInfoPtr pScrn); -static int MGAEntityIndex = -1; - -#include "mga_merge.h" - +static Bool crtc_config_resize(ScrnInfoPtr scrn, int width, int height); /* * This contains the functions needed by the server after loading the @@ -199,12 +198,10 @@ static PciChipsets MGAPciChipsets[] = { }; static const OptionInfoRec MGAOptions[] = { - { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE }, { OPTION_MGA_SDRAM, "MGASDRAM", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, @@ -213,26 +210,11 @@ static const OptionInfoRec MGAOptions[] = { { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE }, { OPTION_OVERCLOCK_MEM, "OverclockMem", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, - { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { OPTION_TEXTURED_VIDEO, "TexturedVideo",OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CRTC2HALF, "Crtc2Half", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_CRTC2RAM, "Crtc2Ram", OPTV_INTEGER, {0}, FALSE }, { OPTION_INT10, "Int10", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_DIGITAL1, "DigitalScreen1",OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_DIGITAL2, "DigitalScreen2",OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_TV, "TV", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_TVSTANDARD, "TVStandard", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_CABLETYPE, "CableType", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_NOHAL, "NoHal", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_SWAPPED_HEAD, "SwappedHead", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_HSYNC2, "Monitor2HSync", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_VREFRESH2, "Monitor2VRefresh", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_MONITOR2POS, "Monitor2Position", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, { OPTION_OLDDMA, "OldDmaInit", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCIDMA, "ForcePciDma", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE }, @@ -260,7 +242,6 @@ static const char *vgahwSymbols[] = { "vgaHWProtect", "vgaHWRestore", "vgaHWSave", - "vgaHWSaveScreen", "vgaHWSetMmioFuncs", "vgaHWUnlock", "vgaHWUnmapMem", @@ -413,22 +394,6 @@ static const char *fbdevHWSymbols[] = { NULL }; -#ifdef USEMGAHAL -static const char *halSymbols[] = { - "MGACloseLibrary", - "MGAGetBOARDHANDLESize", - "MGAGetHardwareInfo", - "MGAOpenLibrary", - "MGARestoreVgaState", - "MGASaveVgaState", - "MGASetMode", - "MGASetVgaMode", - "MGAValidateMode", - "MGAValidateVideoParameters", - "HALSetDisplayStart", - NULL -}; -#endif #ifdef XFree86LOADER static MODULESETUPPROTO(mgaSetup); @@ -449,6 +414,10 @@ static XF86ModuleVersionInfo mgaVersRec = _X_EXPORT XF86ModuleData MGA_MODULE_DATA = { &mgaVersRec, mgaSetup, NULL }; +static const xf86CrtcConfigFuncsRec crtc_config_funcs = { + .resize = crtc_config_resize +}; + static pointer mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) { @@ -483,9 +452,6 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) #ifdef XF86DRI drmSymbols, driSymbols, #endif -#ifdef USEMGAHAL - halSymbols, -#endif NULL); /* @@ -622,7 +588,6 @@ MGAProbe(DriverPtr drv, int flags) foundScreen = TRUE; else for (i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn; - EntityInfoPtr pEnt; #ifdef DISABLE_VGA_IO MgaSavePtr smga; #endif @@ -659,37 +624,6 @@ MGAProbe(DriverPtr drv, int flags) foundScreen = TRUE; } - - /* - * For cards that can do dual head per entity, mark the entity - * as sharable. - */ - pEnt = xf86GetEntityInfo(usedChips[i]); - if ((pEnt->chipset == PCI_CHIP_MGAG400 || pEnt->chipset == PCI_CHIP_MGAG550)) { - MGAEntPtr pMgaEnt = NULL; - DevUnion *pPriv; - - xf86SetEntitySharable(usedChips[i]); - /* Allocate an entity private if necessary */ - if (MGAEntityIndex < 0) - MGAEntityIndex = xf86AllocateEntityPrivateIndex(); - pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); - if (!pPriv->ptr) { - pPriv->ptr = xnfcalloc(sizeof(MGAEntRec), 1); - pMgaEnt = pPriv->ptr; - pMgaEnt->lastInstance = -1; - } else { - pMgaEnt = pPriv->ptr; - } - /* - * Set the entity instance for this instance of the driver. For - * dual head per card, instance 0 is the "master" instance, driving - * the primary head, and instance 1 is the "slave". - */ - pMgaEnt->lastInstance++; - xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0], - pMgaEnt->lastInstance); - } } xfree(usedChips); @@ -931,33 +865,11 @@ MGAdoDDC(ScrnInfoPtr pScrn) hwp = VGAHWPTR(pScrn); pMga = MGAPTR(pScrn); - /* Load DDC if we have the code to use it */ - /* This gives us DDC1 */ - if (pMga->ddc1Read || pMga->i2cInit) { - if (xf86LoadSubModule(pScrn, "ddc")) { - xf86LoaderReqSymLists(ddcSymbols, NULL); - } else { - /* ddc module not found, we can do without it */ - pMga->ddc1Read = NULL; - pMga->DDC_Bus1 = NULL; - pMga->DDC_Bus2 = NULL; - return NULL; - } - } else - return NULL; - #if MGAuseI2C /* - DDC can use I2C bus */ /* Load I2C if we have the code to use it */ if (pMga->i2cInit) { - if ( xf86LoadSubModule(pScrn, "i2c") ) { - xf86LoaderReqSymLists(i2cSymbols,NULL); - } else { - /* i2c module not found, we can do without it */ - pMga->i2cInit = NULL; - pMga->DDC_Bus1 = NULL; - pMga->DDC_Bus2 = NULL; - } + xf86LoaderReqSymLists(i2cSymbols,NULL); } #endif /* MGAuseI2C */ @@ -1148,24 +1060,65 @@ MGAMavenRead(ScrnInfoPtr pScrn, I2CByte reg, I2CByte *val) return TRUE; } +static void +setup_g_outputs(ScrnInfoPtr scrn) +{ + MGAPtr pMga; + xf86OutputPtr output; + Bool number_vga = FALSE, number_dvi = FALSE; + + pMga = MGAPTR(scrn); + + /* first output */ + switch (pMga->bios.connector[0]) { + case MGA_CONNECTOR_DVI: + number_dvi = pMga->bios.connector[1] == MGA_CONNECTOR_DVI; + output = MgaGOutputPanel1Init (scrn, number_dvi); + break; + default: + /* in case PInS doesn't contain connector info + * or it claims there's no primary output + * we just assume it's VGA. + */ + number_vga = pMga->bios.connector[1] == MGA_CONNECTOR_HD15; + output = MgaGOutputDac1Init (scrn, number_vga); + break; + } + + /* the first output can be mapped to any crtc */ + output->possible_crtcs = 1 | 2; + + /* second output */ + switch (pMga->bios.connector[1]) { + case MGA_CONNECTOR_HD15: + output = MgaGOutputDac2Init (scrn, number_vga); + break; + case MGA_CONNECTOR_DVI: + output = MgaGOutputPanel2Init (scrn, number_dvi); + break; + default: + output = NULL; + break; + } + + /* the second output can only be mapped to crtc 2 */ + if (output) + output->possible_crtcs = 2; +} + /* Mandatory */ static Bool MGAPreInit(ScrnInfoPtr pScrn, int flags) { MGAPtr pMga; MessageType from; - int i; double real; int bytesPerPixel; ClockRangePtr clockRanges; const char *s; int flags24; - MGAEntPtr pMgaEnt = NULL; - Bool Default; -#ifdef USEMGAHAL - ULONG status; - CARD8 MiscCtlReg; -#endif + Bool Default, is_2064 = FALSE; + xf86OutputPtr output; /* * Note: This function is only called once at server startup, and @@ -1199,13 +1152,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (pMga->pEnt->location.type != BUS_PCI) return FALSE; - /* Allocate an entity private if necessary */ - if (xf86IsEntityShared(pScrn->entityList[0])) { - pMgaEnt = xf86GetEntityPrivate(pScrn->entityList[0], - MGAEntityIndex)->ptr; - pMga->entityPrivate = pMgaEnt; - } - /* Set pMga->device to the relevant Device section */ pMga->device = xf86GetDevFromEntity(pScrn->entityList[0], pScrn->entityInstanceList[0]); @@ -1306,103 +1252,13 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) || (pMga->Chipset == PCI_CHIP_MGAG550); pMga->is_G200SE = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI); - pMga->is_HAL_chipset = ((pMga->Chipset == PCI_CHIP_MGAG200_PCI) || - (pMga->Chipset == PCI_CHIP_MGAG200) || - (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || - (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI) || - (pMga->Chipset == PCI_CHIP_MGAG400) || - (pMga->Chipset == PCI_CHIP_MGAG550)); - -#ifdef USEMGAHAL - if (HAL_CHIPSETS) { - Bool loadHal = TRUE; - - from = X_DEFAULT; - if (xf86FindOption(pMga->device->options, "NoHal")) { - loadHal = !xf86SetBoolOption(pMga->device->options, - "NoHal", !loadHal); - from = X_CONFIG; - } else if (xf86FindOption(pMga->device->options, "Hal")) { - loadHal = xf86SetBoolOption(pMga->device->options, - "Hal", loadHal); - from = X_CONFIG; - } - if (loadHal && xf86LoadSubModule(pScrn, "mga_hal")) { - xf86LoaderReqSymLists(halSymbols, NULL); - xf86DrvMsg(pScrn->scrnIndex, from,"Matrox HAL module used\n"); - pMga->HALLoaded = TRUE; - } else { - xf86DrvMsg(pScrn->scrnIndex, from, "Matrox HAL module not loaded " - "- using builtin mode setup instead\n"); - pMga->HALLoaded = FALSE; - } - } -#endif - pMga->DualHeadEnabled = FALSE; - if (xf86IsEntityShared(pScrn->entityList[0])) {/* dual-head mode requested*/ - if ( -#ifdef USEMGAHAL - pMga->HALLoaded || -#endif - !MGA_DH_NEEDS_HAL(pMga)) { - pMga->DualHeadEnabled = TRUE; - } else if (xf86IsPrimInitDone(pScrn->entityList[0])) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "This card requires the \"mga_hal\" module for dual-head operation\n" - "\tIt can be found at the Matrox web site <http://www.matrox.com>\n"); - } - } - - /* - * In case of DualHead, we need to determine if we are the 'master' head - * or the 'slave' head. In order to do that, at the end of the first - * initialisation, PrimInit is set as DONE to the shared entity. So that - * the second initialisation knows that something has been done before it. - * This always assume that the first device initialised is the master - * head, and the second the slave. - * - */ - if (xf86IsEntityShared(pScrn->entityList[0])) { /* dual-head mode */ - if (!xf86IsPrimInitDone(pScrn->entityList[0])) { /* Is it the first initialisation? */ - /* First CRTC */ - pMga->SecondCrtc = FALSE; - pMga->HWCursor = TRUE; - pMgaEnt->pScrn_1 = pScrn; - } else if (pMga->DualHeadEnabled) { - /* Second CRTC */ - pMga->SecondCrtc = TRUE; - pMga->HWCursor = FALSE; - pMgaEnt->pScrn_2 = pScrn; - pScrn->AdjustFrame = MGAAdjustFrameCrtc2; - /* - * Fail initialization of second head if we are in MergeFB mode, - * since we do it ourselfs. - */ - if(pMgaEnt->pScrn_1 && MGAPTR(pMgaEnt->pScrn_1)->MergedFB) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Primary head in Merged framebuffer mode. \n" - "Don't let Xfree try to manage the second head.\n" - "Remove the second screen in the \"ServerLayout\"\n" - "Section of the config file."); - return FALSE; - } - } else { - return FALSE; - } - } + pMga->SecondCrtc = FALSE; + pMga->HWCursor = TRUE; - if (pMga->DualHeadEnabled) { #ifdef XF86DRI - pMga->GetQuiescence = MGAGetQuiescenceShared; + pMga->GetQuiescence = MGAGetQuiescence; #endif - } else { /* single-head mode */ - pMga->SecondCrtc = FALSE; - pMga->HWCursor = TRUE; -#ifdef XF86DRI - pMga->GetQuiescence = MGAGetQuiescence; -#endif - } @@ -1584,10 +1440,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMga->SyncOnGreen = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n"); } - if (xf86ReturnOptValBool(pMga->Options, OPTION_SHOWCACHE, FALSE)) { - pMga->ShowCache = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n"); - } if (xf86ReturnOptValBool(pMga->Options, OPTION_MGA_SDRAM, FALSE)) { pMga->HasSDRAM = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Has SDRAM\n"); @@ -1643,41 +1495,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (xf86ReturnOptValBool(pMga->Options, OPTION_TEXTURED_VIDEO, FALSE)) { pMga->TexturedVideo = TRUE; } - if (xf86ReturnOptValBool(pMga->Options, OPTION_MERGEDFB, FALSE)) { - if(!MGAISGx50(pMga)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "\"Merged Framebuffer\" mode only supported on G450 and G550 boards.\n"); - } else { -#ifdef USEMGAHAL - if(pMga->HALLoaded) - { - pMga->MergedFB = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using \"Merged Framebuffer\" mode.\n"); - /* - * a few options that won't work well together - */ - if(pMga->HWCursor) /*Should we give the choice? */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - " -- Hardware Cursor disabled.\n"); - pMga->HWCursor = FALSE; - if(pMga->ShadowFB) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - " -- Shadow Framebuffer disabled.\n"); - pMga->ShadowFB = FALSE; - if(pMga->FBDev) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - " -- Framebuffer device disabled.\n"); - pMga->FBDev = FALSE; - } /* MGA_HAL */ - else -#endif - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "HALLib not loaded! NOT using \"Merged Framebuffer\" mode.\n"); - } /* MGA_NOT_HAL */ - } /* ISMGAGx50() */ - } if (pMga->FBDev) { /* check for linux framebuffer device */ if (!xf86LoadSubModule(pScrn, "fbdevhw")) @@ -1692,39 +1509,11 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pScrn->ValidMode = fbdevHWValidModeWeak(); } pMga->Rotate = 0; - if ((s = xf86GetOptValString(pMga->Options, OPTION_ROTATE))) { - if(!pMga->MergedFB) { - if(!xf86NameCmp(s, "CW")) { - pMga->ShadowFB = TRUE; - pMga->NoAccel = TRUE; - pMga->HWCursor = FALSE; - pMga->Rotate = 1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Rotating screen clockwise - acceleration disabled\n"); - } else - if(!xf86NameCmp(s, "CCW")) { - pMga->ShadowFB = TRUE; - pMga->NoAccel = TRUE; - pMga->HWCursor = FALSE; - pMga->Rotate = -1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Rotating screen counter clockwise - acceleration disabled\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "\"%s\" is not a valid value for Option \"Rotate\"\n", s); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid options are \"CW\" or \"CCW\"\n"); - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - " -- Rotation disabled.\n"); - } - } - switch (pMga->Chipset) { case PCI_CHIP_MGA2064: case PCI_CHIP_MGA2164: case PCI_CHIP_MGA2164_AGP: + is_2064 = TRUE; MGA2064SetupFuncs(pScrn); break; case PCI_CHIP_MGA1064: @@ -1913,64 +1702,22 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pScrn->videoRam = MGACountRam(pScrn); } - if (pMga->DualHeadEnabled) { - /* This takes gives either half or 8 meg to the second head - * whichever is less. */ - if(pMga->SecondCrtc == FALSE) { - Bool UseHalf = FALSE; - int adjust; - - xf86GetOptValBool(pMga->Options, OPTION_CRTC2HALF, &UseHalf); - adjust = pScrn->videoRam / 2; - - if (UseHalf == TRUE || - xf86GetOptValInteger(pMga->Options, OPTION_CRTC2RAM, &adjust)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Crtc2 will use %dK of VideoRam\n", - adjust); - } else { - adjust = min(adjust, 8192); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Crtc2 will use %dK of VideoRam\n", - adjust); - } - pMgaEnt->mastervideoRam = pScrn->videoRam - adjust; - pScrn->videoRam = pMgaEnt->mastervideoRam; - pMgaEnt->slavevideoRam = adjust; - pMgaEnt->masterFbAddress = pMga->FbAddress; - pMga->FbMapSize = - pMgaEnt->masterFbMapSize = pScrn->videoRam * 1024; - pMgaEnt->slaveFbAddress = pMga->FbAddress + - pMgaEnt->masterFbMapSize; - pMgaEnt->slaveFbMapSize = pMgaEnt->slavevideoRam * 1024; - pMga->realSrcOrg = pMga->SrcOrg = 0; - pMga->DstOrg = 0; - } else { - pMga->FbAddress = pMgaEnt->slaveFbAddress; - pMga->FbMapSize = pMgaEnt->slaveFbMapSize; - pScrn->videoRam = pMgaEnt->slavevideoRam; - pMga->DstOrg = pMga->realSrcOrg = - pMgaEnt->slaveFbAddress - pMgaEnt->masterFbAddress; - pMga->SrcOrg = 0; /* This is not stored in hw format!! */ - } - pMgaEnt->refCount++; - } else { - /* Normal Handling of video ram etc */ - pMga->FbMapSize = pScrn->videoRam * 1024; - switch(pMga->Chipset) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: - pMga->SrcOrg = 0; - pMga->DstOrg = 0; - break; - default: - break; - } + /* Normal Handling of video ram etc */ + pMga->FbMapSize = pScrn->videoRam * 1024; + switch(pMga->Chipset) { + case PCI_CHIP_MGAG550: + case PCI_CHIP_MGAG400: + case PCI_CHIP_MGAG200: + case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + pMga->SrcOrg = 0; + pMga->DstOrg = 0; + break; + default: + break; } + xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam); @@ -1980,17 +1727,59 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMga->BppShifts[2] = 0; pMga->BppShifts[3] = 2; + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit(pScrn, &crtc_config_funcs); + + xf86CrtcSetSizeRange(pScrn, 320, 200, 2560, 1024); + + if (is_2064) + Mga2064CrtcInit (pScrn); + else { + switch(pMga->Chipset) { + case PCI_CHIP_MGAG400: + case PCI_CHIP_MGAG550: + MgaGCrtc1Init (pScrn); + MgaGCrtc2Init (pScrn); + break; + default: + MgaGCrtc1Init (pScrn); + } + } + + if (pMga->i2cInit) { + pMga->i2cInit(pScrn); + } + + if (is_2064) { + output = Mga2064OutputInit (pScrn); + output->possible_crtcs = 1; + } else + setup_g_outputs (pScrn); + /* * fill MGAdac struct * Warning: currently, it should be after RAM counting */ (*pMga->PreInit)(pScrn); +#if 0 #if !defined(__powerpc__) /* Read and print the Monitor DDC info */ pScrn->monitor->DDC = MGAdoDDC(pScrn); #endif /* !__powerpc__ */ +#endif + if (!MGAMapMem(pScrn)) { + ErrorF("cannot map memory for probing.\n"); + return FALSE; + } + + if (!xf86InitialConfiguration(pScrn, FALSE)) { + MGAUnmapMem(pScrn); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found.\n"); + return FALSE; + } + MGAUnmapMem(pScrn); if (!pScrn->monitor->DDC && pMga->is_G200SE) { /* Jam in ranges big enough for 1024x768 */ @@ -2077,15 +1866,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->minClock = pMga->MinClock; clockRanges->maxClock = pMga->MaxClock; clockRanges->clockIndex = -1; /* programmable */ - clockRanges->interlaceAllowed = TRUE; + clockRanges->interlaceAllowed = !pMga->SecondCrtc; clockRanges->doubleScanAllowed = TRUE; -#ifdef USEMGAHAL - MGA_HAL(clockRanges->interlaceAllowed = FALSE); - MGA_HAL(clockRanges->doubleScanAllowed = FALSE); -#endif - if (pMga->SecondCrtc == TRUE) - clockRanges->interlaceAllowed = FALSE; - clockRanges->ClockMulFactor = 1; clockRanges->ClockDivFactor = 1; @@ -2100,161 +1882,11 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMga->MemClk / 1000.0); } - /* - * xf86ValidateModes will check that the mode HTotal and VTotal values - * don't exceed the chipset's limit if pScrn->maxHValue and - * pScrn->maxVValue are set. Since our MGAValidMode() already takes - * care of this, we don't worry about setting them here. - */ - { - int Pitches1[] = - {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0}; - int Pitches2[] = - {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664, - 1920, 2048, 0}; - int *linePitches = NULL; - int minPitch = 256; - int maxPitch = 2048; - - switch(pMga->Chipset) { - case PCI_CHIP_MGA2064: - if (!pMga->NoAccel) { - linePitches = xalloc(sizeof(Pitches1)); - memcpy(linePitches, Pitches1, sizeof(Pitches1)); - minPitch = maxPitch = 0; - } - break; - case PCI_CHIP_MGA2164: - case PCI_CHIP_MGA2164_AGP: - case PCI_CHIP_MGA1064: - if (!pMga->NoAccel) { - linePitches = xalloc(sizeof(Pitches2)); - memcpy(linePitches, Pitches2, sizeof(Pitches2)); - minPitch = maxPitch = 0; - } - break; - case PCI_CHIP_MGAG100: - case PCI_CHIP_MGAG100_PCI: - maxPitch = 2048; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: - maxPitch = 4096; - break; - } - - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, - pScrn->display->modes, clockRanges, - linePitches, minPitch, maxPitch, - pMga->Roundings[(pScrn->bitsPerPixel >> 3) - 1] * - pScrn->bitsPerPixel, 128, 2048, - pScrn->display->virtualX, - pScrn->display->virtualY, - pMga->FbMapSize, - LOOKUP_BEST_REFRESH); - - if (linePitches) - xfree(linePitches); - } - - - if (i < 1 && pMga->FBDev) { - fbdevHWUseBuildinMode(pScrn); - pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ - i = 1; - } - if (i == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n"); - MGAFreeRec(pScrn); - return FALSE; - } - - /* Prune the modes marked as invalid */ - xf86PruneDriverModes(pScrn); - - if (i == 0 || pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - MGAFreeRec(pScrn); - return FALSE; - } -#ifdef USEMGAHAL - MGA_HAL( - - if(pMga->SecondCrtc == FALSE) { - - pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); - pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); - pMga->pClientStruct->pMga = (MGAPtr) pMga; - - MGAMapMem(pScrn); - /* - * For some reason the MGAOPM_DMA_BLIT bit needs to be set - * on G200 before opening the HALlib. I don't know why. - * MATROX: hint, hint. - */ - /*if (pMga->Chipset == PCI_CHIP_MGAG200 || - pMga->Chipset == PCI_CHIP_MGAG200_PCI) */{ - CARD32 opmode; - opmode = INREG(MGAREG_OPMODE); - OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | opmode); - } - /* wrapping OpenLibrary to fix broken registers. MATROX: hint, hint. */ - MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); - MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); - outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); - MGAUnmapMem(pScrn); - pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); - MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); - - /* copy the board handles */ - if (pMga->DualHeadEnabled) { - pMgaEnt->pClientStruct = pMga->pClientStruct; - pMgaEnt->pBoard = pMga->pBoard; - pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; - } - - } else { /* Second CRTC && entity is shared */ - pMga->pBoard = pMgaEnt->pBoard; - pMga->pClientStruct = pMgaEnt->pClientStruct; - pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; - - } - - MGAFillModeInfoStruct(pScrn,NULL); - /* Fields usually handled by MGAFillModeInfoStruct, but are unavailable - * because no mode is given - */ - pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX; - pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY; - - - if (ISDIGITAL1(pMga)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Digital screen detected on first head.\n"); - if (ISTV1(pMga)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "TV detected on first head.\n"); - if (ISDIGITAL2(pMga)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Digital screen detected on second head.\n"); - if (ISTV2(pMga)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "TV detected on second head.\n"); - - - if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MGAValidateMode from HALlib found the mode to be invalid.\n" - "\tError: 0x%lx\n", status); + if (!xf86RandR12PreInit(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "RandR initialization failure.\n"); return FALSE; } - pScrn->displayWidth = pMga->pMgaModeInfo->ulFBPitch; - ); /* MGA_HAL */ -#endif if (pMga->HasSDRAM) { /* don't bother checking */ } else if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) || @@ -2263,16 +1895,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) (pMga->PciInfo->subsysCard == PCI_CARD_PROD_G100_SD)) { pMga->HasSDRAM = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n"); - } - /* - * Can we trust HALlib to set the memory configuration - * registers correctly? - */ - else if ((pMga->softbooted || pMga->Primary -#ifdef USEMGAHAL - /*|| pMga->HALLoaded*/ -#endif - ) && + } else if ((pMga->softbooted || pMga->Primary) && (pMga->Chipset != PCI_CHIP_MGA2064) && (pMga->Chipset != PCI_CHIP_MGA2164) && (pMga->Chipset != PCI_CHIP_MGA2164_AGP)) { @@ -2291,10 +1914,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) * driver and if the driver doesn't provide code to set them. They * are not pre-initialised at all. */ -#ifdef USEMGAHAL - MGA_HAL(xf86SetCrtcForModes(pScrn, 0)); -#endif - MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V)); + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; @@ -2354,47 +1974,25 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n", pMga->YDstOrg); - if(pMga->DualHeadEnabled) { - if(pMga->SecondCrtc == FALSE) { - pMga->FbUsableSize = pMgaEnt->masterFbMapSize; - /* Allocate HW cursor buffer at the end of video ram */ - if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { - if( pScrn->virtualY * pScrn->displayWidth * - pScrn->bitsPerPixel / 8 <= - pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) { - pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; - pMga->FbCursorOffset = - pMgaEnt->masterFbMapSize - - pMga->Dac.CursorOffscreenMemSize; - } else { - pMga->HWCursor = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Too little offscreen memory for HW cursor; " - "using SW cursor\n"); - } - } - } else { /* Second CRTC */ - pMga->FbUsableSize = pMgaEnt->slaveFbMapSize; - pMga->HWCursor = FALSE; - } - } else { - pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel; - /* Allocate HW cursor buffer at the end of video ram */ - if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { - if( pScrn->virtualY * pScrn->displayWidth * - pScrn->bitsPerPixel / 8 <= - pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) { - pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; - pMga->FbCursorOffset = - pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize; - } else { - pMga->HWCursor = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Too little offscreen memory for HW cursor; " - "using SW cursor\n"); - } - } + + pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel; + + /* Allocate HW cursor buffer at the end of video ram */ + if (pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize) { + if (pScrn->virtualY * pScrn->displayWidth * + pScrn->bitsPerPixel / 8 <= + pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize) { + pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; + pMga->FbCursorOffset = + pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize; + } else { + pMga->HWCursor = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Too little offscreen memory for HW cursor; " + "using SW cursor\n"); + } } + /* * XXX This should be taken into account in some way in the mode valdation * section. @@ -2474,52 +2072,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMga->CurrentLayout.mode = pScrn->currentMode; - - if(pMga->MergedFB) { - MGAPreInitMergedFB(pScrn,flags); - }; - - -#ifdef USEMGAHAL - MGA_HAL( - /* Close the library after preinit */ - /* This needs to only happen after this board has completed preinit - * both times - */ - - if(pMga->DualHeadEnabled) { - /* Entity is shared make sure refcount == 2 */ - /* If ref count is 2 then reset it to 0 */ - if(pMgaEnt->refCount == 2) { - /* Both boards have done there initialization */ - MGACloseLibrary(pMga->pBoard); - - if (pMga->pBoard) - xfree(pMga->pBoard); - if (pMga->pClientStruct) - xfree(pMga->pClientStruct); - if (pMga->pMgaModeInfo) - xfree(pMga->pMgaModeInfo); - if (pMga->pMgaHwInfo) - xfree(pMga->pMgaHwInfo); - pMgaEnt->refCount = 0; - } - } else { - MGACloseLibrary(pMga->pBoard); - - if (pMga->pBoard) - xfree(pMga->pBoard); - if (pMga->pClientStruct) - xfree(pMga->pClientStruct); - if (pMga->pMgaModeInfo) - xfree(pMga->pMgaModeInfo); - if (pMga->pMgaHwInfo) - xfree(pMga->pMgaHwInfo); - } - - ); /* MGA_HAL */ -#endif - xf86SetPrimInitDone(pScrn->entityList[0]); return TRUE; @@ -2645,185 +2197,42 @@ MGAUnmapMemFBDev(ScrnInfoPtr pScrn) return TRUE; } - - - /* * This function saves the video state. */ static void -MGASave(ScrnInfoPtr pScrn) -{ - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg = &hwp->SavedReg; - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr mgaReg = &pMga->SavedReg; - - if(pMga->SecondCrtc == TRUE) return; -#ifdef USEMGAHAL - MGA_HAL(if (pMga->pBoard != NULL) MGASaveVgaState(pMga->pBoard)); -#endif - - /* I need to save the registers for the second head also */ - /* Save the register for 0x80 to 0xa0 */ - /* Could call it dac2Saved */ - - /* Only save text mode fonts/text for the primary card */ - (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary); -} - -#ifdef USEMGAHAL -/* Convert DisplayModeRec parameters in MGAMODEINFO parameters. -* mode parameter optionnal. */ -void -MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode) +MGASave(ScrnInfoPtr scrn) { - const char *s; - MGAPtr pMga = MGAPTR(pScrn); - - Bool digital1 = FALSE; - Bool digital2 = FALSE; - Bool tv1 = FALSE; - Bool tv2 = FALSE; - Bool swap_head - = xf86ReturnOptValBool(pMga->Options, OPTION_SWAPPED_HEAD, FALSE); - - if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) { - mode = pMga->SecondCrtc ? - ((MergedDisplayModePtr)mode->Private)->Monitor2 - : ((MergedDisplayModePtr)mode->Private)->Monitor1; - } - - - if (pMga->pMgaHwInfo) - { - digital1 = ISDIGITAL1(pMga); - digital2 = ISDIGITAL2(pMga); - tv1 = ISTV1(pMga); - tv2 = ISTV2(pMga); - } + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int i; - /*FIXME: causes segfault elsewhere if not commented*/ - /*if(!pMga->pMgaModeInfo)*/ pMga->pMgaModeInfo = xalloc(sizeof(MGAMODEINFO)); - pMga->pMgaModeInfo->flOutput = 0; - pMga->pMgaModeInfo->ulDeskWidth = pScrn->virtualX; - pMga->pMgaModeInfo->ulDeskHeight = pScrn->virtualY; - pMga->pMgaModeInfo->ulFBPitch = 0; - pMga->pMgaModeInfo->ulBpp = pScrn->bitsPerPixel; - pMga->pMgaModeInfo->ulZoom = 1; - pMga->pMgaModeInfo->flSignalMode = 0x10; - - /* Set TV standard */ - if ((s = xf86GetOptValString(pMga->Options, OPTION_TVSTANDARD))) { - if (!xf86NameCmp(s, "PAL")) { - pMga->pMgaModeInfo->flSignalMode = 0x00; - pMga->pMgaModeInfo->ulRefreshRate = 50; - pMga->pMgaModeInfo->ulTVStandard = TV_PAL; - } else { - pMga->pMgaModeInfo->ulRefreshRate = 60; - pMga->pMgaModeInfo->ulTVStandard = TV_NTSC; - } - } else { - pMga->pMgaModeInfo->ulRefreshRate = 0; - pMga->pMgaModeInfo->ulTVStandard = TV_NTSC; - } + /* Save CRTC states */ + for (i = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; - /* Set Cable Type */ - if ((s = xf86GetOptValString(pMga->Options, OPTION_CABLETYPE))) { - if (!xf86NameCmp(s, "SCART_RGB")) { - pMga->pMgaModeInfo->ulCableType = TV_SCART_RGB; - } else if (!xf86NameCmp(s, "SCART_COMPOSITE")) { - pMga->pMgaModeInfo->ulCableType = TV_SCART_COMPOSITE; - } else if (!xf86NameCmp(s, "SCART_TYPE2")) { - pMga->pMgaModeInfo->ulCableType = TV_SCART_TYPE2; - } else { - pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE; - } - } else { - pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE; + crtc->funcs->save(crtc); } - if(mode) { - pMga->pMgaModeInfo->ulHorizRate = 0; - pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay; - pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay; - pMga->pMgaModeInfo->ulPixClock = mode->Clock; - pMga->pMgaModeInfo->ulHFPorch = mode->HSyncStart - mode->HDisplay; - pMga->pMgaModeInfo->ulHSync = mode->HSyncEnd - mode->HSyncStart; - pMga->pMgaModeInfo->ulHBPorch = mode->HTotal - mode->HSyncEnd; - pMga->pMgaModeInfo->ulVFPorch = mode->VSyncStart - mode->VDisplay; - pMga->pMgaModeInfo->ulVSync = mode->VSyncEnd - mode->VSyncStart; - pMga->pMgaModeInfo->ulVBPorch = mode->VTotal - mode->VSyncEnd; - } - /* Use DstOrg directly */ - /* This is an offset in pixels not memory */ - pMga->pMgaModeInfo->ulDstOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8); - pMga->pMgaModeInfo->ulDisplayOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8); - pMga->pMgaModeInfo->ulPanXGran = 0; - pMga->pMgaModeInfo->ulPanYGran = 0; + /* Save output states */ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; - if(pMga->SecondCrtc == TRUE) { - pMga->pMgaModeInfo->flOutput = MGAMODEINFO_SECOND_CRTC | - MGAMODEINFO_FORCE_PITCH | - MGAMODEINFO_FORCE_DISPLAYORG; - if (digital2) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; - } else if (tv2) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; - } else { - if (!swap_head) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2; - } else { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1; - } - } - } else { - pMga->pMgaModeInfo->flOutput = MGAMODEINFO_FORCE_PITCH; - if (digital1) { - if ((pMga->Chipset == PCI_CHIP_MGAG200) || - (pMga->Chipset == PCI_CHIP_MGAG200_PCI)) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_FLATPANEL1; - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; - } else { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1; - } - } else if (tv1) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; - } else { - if (!swap_head) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1; - } else { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2; - } - } + output->funcs->save(output); } - pMga->pMgaModeInfo->ulFBPitch = pScrn->displayWidth; } -#endif - -/* - * Initialise a new mode. This is currently still using the old - * "initialise struct, restore/write struct to HW" model. That could - * be changed. - */ static Bool -MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +MGASetMode(ScrnInfoPtr scrn, DisplayModePtr mode) { + MGAPtr pMga = MGAPTR(scrn); + +#if 0 /* old */ vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg; - MGAPtr pMga = MGAPTR(pScrn); MGARegPtr mgaReg; -#ifdef USEMGAHAL - ULONG status; -#endif vgaHWUnlock(hwp); -/* if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) { - mode = (DisplayModePtr)mode->Private; - }*/ - /* Initialise the ModeReg values */ if (!vgaHWInit(pScrn, mode)) return FALSE; @@ -2834,129 +2243,23 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) /* Program the registers */ if (pMga->is_G200SE) { - MGAG200SEHWProtect(pScrn, TRUE); + MGAG200SEHWProtect(pScrn, TRUE); } else { - vgaHWProtect(pScrn, TRUE); + vgaHWProtect(pScrn, TRUE); } vgaReg = &hwp->ModeReg; mgaReg = &pMga->ModeReg; -#ifdef USEMGAHAL - MGA_HAL( - MGAFillModeInfoStruct(pScrn,mode); - - /* Validate the parameters */ - if ((status = MGAValidateMode(pMga->pBoard, pMga->pMgaModeInfo)) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MGAValidateMode from HALlib found the mode to be invalid.\n" - "\tError: %lx\n", status); - return FALSE; - } - - /* - * Find mode for second head. - */ - if(pMga->MergedFB) { - - MGAFillModeInfoStruct(pMga->pScrn2,mode); - /* Validates the Video parameters */ - if ((status = MGAValidateVideoParameters(pMga->pBoard, MGAPTR(pMga->pScrn2)->pMgaModeInfo)) - != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MGAValidateVideoParameters from HALlib found the mode to be invalid.\n\tError: %lx\n", status); - return FALSE; - } - } - ); /*MGA_HAL */ - -#endif - -#ifdef USEMGAHAL -MGA_HAL( - - /*************************** ESC *****************************/ - TmpMgaModeInfo[0] = *pMga->pMgaModeInfo; - - if(pMga->SecondCrtc == TRUE) - pMgaModeInfo[1] = pMga->pMgaModeInfo; - else - pMgaModeInfo[0] = pMga->pMgaModeInfo; - - TmpMgaModeInfo[0].ulDispWidth = 0; - - if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB - compatibility will exist */ - MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo); - /*************************************************************/ - -); /* MGA_HAL */ -#endif - -#ifdef XF86DRI - if (pMga->directRenderingEnabled) { - DRILock(screenInfo.screens[pScrn->scrnIndex], 0); - } #endif -#ifdef USEMGAHAL - MGA_HAL( - /* Initialize the board */ - if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MGASetMode returned an error." - " Make sure to validate the mode before.\n"); - return FALSE; - } - if(pMga->MergedFB - && MGASetMode(pMga->pBoard,MGAPTR(pMga->pScrn2)->pMgaModeInfo) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MGASetMode returned an error." - " Make sure to validate the mode before.\n"); - } + xf86SetSingleMode(scrn, mode, RR_Rotate_0); - ); /* MGA_HAL */ - - /* getting around bugs in the HAL lib. MATROX: hint, hint. */ - MGA_HAL( - switch (pMga->Chipset) { - case PCI_CHIP_MGA1064: - case PCI_CHIP_MGAG100: - case PCI_CHIP_MGAG100_PCI: - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: - if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) { - outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, - pMga->FbCursorOffset >> 10); - outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, - pMga->FbCursorOffset >> 18); - outMGAdac(MGA1064_CURSOR_CTL, 0x00); - } - if (pMga->Overlay8Plus24 == TRUE) { - outMGAdac(MGA1064_MUL_CTL, MGA1064_MUL_CTL_32bits); - outMGAdac(MGA1064_COL_KEY_MSK_LSB,0xFF); - outMGAdac(MGA1064_COL_KEY_LSB,pMga->colorKey); - outMGAdac(MGA1064_COL_KEY_MSK_MSB,0xFF); - outMGAdac(MGA1064_COL_KEY_MSB,0xFF); - } - break; - default: - break; - } - ); /* MGA_HAL */ -#endif - - MGA_NOT_HAL((*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE)); - - MGAStormSync(pScrn); - MGAStormEngineInit(pScrn); + MGAStormSync(scrn); + MGAStormEngineInit(scrn); if (pMga->is_G200SE) { - MGAG200SEHWProtect(pScrn,FALSE); + MGAG200SEHWProtect(scrn, FALSE); } else { - vgaHWProtect(pScrn, FALSE); + vgaHWProtect(scrn, FALSE); } if (xf86IsPc98()) { @@ -2966,132 +2269,38 @@ MGA_HAL( outb(0xfac, 0x02); } - MGA_NOT_HAL( - if (pMga->is_G200SE) { - OUTREG8(0x1FDE, 0x06); - OUTREG8(0x1FDF, 0x14); - } - ); - - pMga->CurrentLayout.mode = mode; - - if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) { - pMga->M1currentMode = (DisplayModePtr)mode->Private; + if (pMga->is_G200SE) { + OUTREG8(0x1FDE, 0x06); + OUTREG8(0x1FDF, 0x14); } -#ifdef XF86DRI - if (pMga->directRenderingEnabled) - DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); -#endif -#ifdef DEBUG - MGAG450PrintPLL(pScrn); -#endif return TRUE; } -static -void MGARestoreSecondCrtc(ScrnInfoPtr pScrn) -{ - MGAPtr pMga = MGAPTR(pScrn); - - if (MGAISGx50(pMga)) { - /* Force to return in clone mode */ - if (pMga->SecondOutput - && (xf86IsEntityShared(pScrn->entityList[0]) || pMga->SecondCrtc) - && !pMga->MergedFB) { - /* Do this branch if - * SecondOutput - * and not Unshared Primary - * and not Merged Mode (usualy means Unshared Primary) - */ - CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); - - ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; - ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; - - outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl); - - } else { - CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); - CARD32 ulC2CTL = INREG(MGAREG_C2CTL); - - ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; - ucXDispCtrl |= MGA1064_DISP_CTL_DAC1OUTSEL_EN; - ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; - - /* crtcdacsel -> crtc1 */ - ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_CRTC2; - ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC1; - - outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl); - OUTREG(MGAREG_C2CTL, ulC2CTL); - } - - } else { - /* Force to close second crtc */ - CARD32 ulC2CTL = INREG(MGAREG_C2CTL); - - ulC2CTL &= ~MGAREG_C2CTL_C2_EN; - - OUTREG(MGAREG_C2CTL, ulC2CTL); - } -} - /* * Restore the initial (text) mode. */ static void -MGARestore(ScrnInfoPtr pScrn) +MGARestore(ScrnInfoPtr scrn) { - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg = &hwp->SavedReg; - MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr mgaReg = &pMga->SavedReg; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int i; - if (pScrn->pScreen != NULL) - MGAStormSync(pScrn); + if (scrn->pScreen != NULL) + MGAStormSync(scrn); - /* - * Restore the second crtc if: - * first and only driver entity - * second entity - * Merged Framebuffer mode (first and only driver entity) - */ - if((!xf86IsEntityShared(pScrn->entityList[0]) && !pMga->SecondCrtc) - || pMga->SecondCrtc || pMga->MergedFB) { - /* if(pMga->MergedFB) { - if(pMga->pScrn2) - MGARestoreSecondCrtc(pMga->pScrn2); - } else*/ - MGARestoreSecondCrtc(pScrn); - /* if we are second instance of driver, we've done our job, exit */ - if(pMga->SecondCrtc) return; - } - - /* Only restore text mode fonts/text for the primary card */ - if (pMga->is_G200SE) { - MGAG200SEHWProtect(pScrn,TRUE); - } else { - vgaHWProtect(pScrn, TRUE); - } - if (pMga->Primary) { -#ifdef USEMGAHAL - MGA_HAL( - if(pMga->pBoard != NULL) { - MGASetVgaMode(pMga->pBoard); - MGARestoreVgaState(pMga->pBoard); - } - ); /* MGA_HAL */ -#endif - (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE); - } else { - vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + /* Restore CRTC states */ + for (i = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + + crtc->funcs->restore(crtc); } - if (pMga->is_G200SE) { - MGAG200SEHWProtect(pScrn,FALSE); - } else { - vgaHWProtect(pScrn,FALSE); + /* Restore output states */ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + + output->funcs->restore(output); } } @@ -3133,7 +2342,6 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) VisualPtr visual; unsigned char *FBStart; int width, height, displayWidth; - MGAEntPtr pMgaEnt = NULL; int f; CARD32 VRTemp, FBTemp; #ifdef XF86DRI @@ -3169,86 +2377,10 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) || (pMga->Chipset == PCI_CHIP_MGAG100_PCI)) MGAG100BlackMagic(pScrn); - if (pMga->DualHeadEnabled) { - DevUnion *pPriv; - pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); - pMgaEnt = pPriv->ptr; - pMgaEnt->refCount++; -#ifdef USEMGAHAL - MGA_HAL( - if(pMgaEnt->refCount == 1) { - CARD8 MiscCtlReg; - pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); - pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); - pMga->pClientStruct->pMga = (MGAPtr) pMga; - - /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/ - MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); - MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); - outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); - pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); - MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); - - /* Detecting for type of display */ - if (pMga->pMgaHwInfo->ulCapsSecondOutput & MGAHWINFOCAPS_OUTPUT_TV) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TV detected\n"); - } - if (pMga->pMgaHwInfo->ulCapsFirstOutput & - MGAHWINFOCAPS_OUTPUT_DIGITAL) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Digital Screen detected\n"); - } - if (pMga->pMgaHwInfo->ulCapsSecondOutput & - MGAHWINFOCAPS_OUTPUT_DIGITAL) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Digital Screen detected\n"); - } - - /* Now copy these to the entitystructure */ - pMgaEnt->pClientStruct = pMga->pClientStruct; - pMgaEnt->pBoard = pMga->pBoard; - pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; - } else { /* Ref count is 2 */ - pMga->pClientStruct = pMgaEnt->pClientStruct; - pMga->pBoard = pMgaEnt->pBoard; - pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; - } - ); /* MGA_HAL */ -#endif - } else { -#ifdef USEMGAHAL - CARD8 MiscCtlReg; - - MGA_HAL( - pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); - pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); - pMga->pClientStruct->pMga = (MGAPtr) pMga; - - MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); - /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/ - MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); - outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); - pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); - MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); - ); /* MGA_HAL */ -#endif - } if (pMga->is_G200SE) { pScrn->videoRam = VRTemp; pMga->FbMapSize = FBTemp; } -#ifdef USEMGAHAL - MGA_HAL( - /* There is a problem in the HALlib: set soft reset bit */ - /* MATROX: hint, hint. */ - if (!pMga->Primary && !pMga->FBDev && - (pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SG) ) { - OUTREG(MGAREG_Reset, 1); - usleep(200); - OUTREG(MGAREG_Reset, 0); - } - ); /* MGA_HAL */ -#endif /* Initialise the MMIO vgahw functions */ vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET); @@ -3288,23 +2420,16 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) MGAStormEngineInit(pScrn); } else { + pScrn->vtSema = TRUE; + /* Save the current state */ MGASave(pScrn); - /* Initialise the first mode */ - if (!MGAModeInit(pScrn, pScrn->currentMode)) - return FALSE; - } - /* Darken the screen for aesthetic reasons and set the viewport */ - if (pMga->SecondCrtc == TRUE && !pMga->MergedFB) { - MGASaveScreenCrtc2(pScreen, SCREEN_SAVER_ON); - } - if (pMga->SecondCrtc == FALSE && !pMga->MergedFB) { - MGASaveScreen(pScreen, SCREEN_SAVER_ON); - } - if( pMga->MergedFB ) { - MGASaveScreenMerged( pScreen, SCREEN_SAVER_ON ); + + xf86SetDesiredModes(pScrn); + + MGAStormSync(pScrn); + MGAStormEngineInit(pScrn); } - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); /* * The next step is to setup the screen's visuals, and initialise the @@ -3356,10 +2481,8 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * pScreen fields. */ - width = pScrn->virtualX; + width = displayWidth = pScrn->displayWidth = pScrn->virtualX; height = pScrn->virtualY; - displayWidth = pScrn->displayWidth; - if(pMga->Rotate) { height = pScrn->virtualX; @@ -3462,8 +2585,10 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pMga->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = MGABlockHandler; +#if 0 if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */ MGADGAInit(pScreen); +#endif if (!pMga->NoAccel) { #ifdef USE_EXA @@ -3476,6 +2601,18 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } + pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + pMga->CurrentLayout.depth = pScrn->depth; + pMga->CurrentLayout.displayWidth = pScrn->displayWidth; + pMga->CurrentLayout.weight.red = pScrn->weight.red; + pMga->CurrentLayout.weight.green = pScrn->weight.green; + pMga->CurrentLayout.weight.blue = pScrn->weight.blue; + pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24; + pMga->CurrentLayout.mode = pScrn->currentMode; + + if (!MGAEnterVT(scrnIndex, 0)) + return FALSE; + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -3491,6 +2628,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); } +#if 0 if(pMga->MergedFB) { /* Rotate and MergedFB are mutiualy exclusive, so we can use this * variable. @@ -3500,6 +2638,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->PointerMoved = MGAMergePointerMoved; } +#endif /* Initialise default colourmap */ if (!miCreateDefColormap(pScreen)) @@ -3541,28 +2680,17 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ShadowFBInit(pScreen, refreshArea); } - if(pMga->SecondCrtc == TRUE && !pMga->MergedFB) { - xf86DPMSInit(pScreen, MGADisplayPowerManagementSetCrtc2, 0); - } - if(pMga->SecondCrtc == FALSE && !pMga->MergedFB) { - xf86DPMSInit(pScreen, MGADisplayPowerManagementSet, 0); - } - if(pMga->MergedFB) { - xf86DPMSInit(pScreen, MGADisplayPowerManagementSetMerged, 0); - } - pScrn->memPhysBase = pMga->FbAddress; pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8); - if(!pMga->MergedFB) { - if(pMga->SecondCrtc == TRUE) { - pScreen->SaveScreen = MGASaveScreenCrtc2; - } else { - pScreen->SaveScreen = MGASaveScreen; - } - } else { /* Merged FB */ - pScreen->SaveScreen = MGASaveScreenMerged; - } + xf86DPMSInit(pScreen, xf86DPMSSet, 0); + + /* Wrap the current CloseScreen function */ + pScreen->SaveScreen = xf86SaveScreen; + pMga->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = MGACloseScreen; + + xf86CrtcScreenInit(pScreen); MGAInitVideo(pScreen); @@ -3578,129 +2706,25 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); } - if (pMga->DualHeadEnabled && pMga->SecondCrtc == FALSE) - pMgaEnt->directRenderingEnabled = pMga->directRenderingEnabled; + pMga->haveQuiescense = 1; #endif - /* Wrap the current CloseScreen function */ - pMga->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = MGACloseScreen; - /* Report any unused options (only for the first generation) */ if (serverGeneration == 1) { xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); } - /* For the second head, work around display problem. */ - if (!pMga->MergedFB && pMga->SecondCrtc) { - MGACrtc2FillStrip(pScrn); - } - - /* Done */ return TRUE; } /* Usually mandatory */ -Bool +static Bool MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { -#ifdef USEMGAHAL - char sCmdIn[256]; - char sCmdOut[256]; - FILE* fdIn; -# ifdef MATROX_WRITEBACK - FILE* fdOut; -# endif -#endif - - if (mode->Flags & 0x80000000) { -#ifdef USEMGAHAL - -# ifdef MATROX_WRITEBACK -# define MWB(x) { x; } -# define MWB_COND(x) x -# else -# define MWB(x) -# define MWB_COND(x) 1 -# endif - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - - MGA_HAL( - fdIn = fopen("/tmp/mgaDriverIn", "rt"); - MWB(fdOut = fopen("/tmp/mgaDriverOut", "wt")) - - if(fdIn && MWB_COND(fdOut)) - { - - fgets(sCmdIn, 255, fdIn); - - if(sCmdIn) - { - - MGAExecuteEscCmd(xf86Screens[scrnIndex], sCmdIn, sCmdOut, mode); - - /* Remove file and close file descriptor */ - remove("/tmp/mgaDriverIn"); - fclose(fdIn); - MWB( - /* Write output data to output file for - calling application */ - fputs(sCmdOut, fdOut); - fclose(fdOut); - ) - mode->Flags &= 0x7FFFFFFF; - return TRUE; - } - else - { - mode->Flags &= 0x7FFFFFFF; - return FALSE; - } - } - else - { - mode->Flags &= 0x7FFFFFFF; - return FALSE; - } - ) -#endif - return FALSE; - } else - return MGAModeInit(xf86Screens[scrnIndex], mode); + return MGASetMode(xf86Screens[scrnIndex], mode); } - - /* Adjusts coordinates to match Panning granularity. - * does nothing if the HALlib is not loaded - */ -void -MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y) -{ -#ifdef USEMGAHAL - MGA_HAL( - MGAPtr pMga = MGAPTR(pScrn); - MGAPtr pMga2; - int xg = 1; - int yg = 1; - if(pMga->pMgaModeInfo && pMga->pMgaModeInfo->ulPanXGran && pMga->pMgaModeInfo->ulPanYGran) { - xg = pMga->pMgaModeInfo->ulPanXGran; - yg = pMga->pMgaModeInfo->ulPanYGran; - } - if(pMga->pScrn2 && (pMga2 = MGAPTR(pMga->pScrn2)) ) { - - if(pMga2->pMgaModeInfo && pMga2->pMgaModeInfo->ulPanXGran && pMga2->pMgaModeInfo->ulPanYGran) { - xg = max(xg,pMga2->pMgaModeInfo->ulPanXGran); - yg = max(yg,pMga2->pMgaModeInfo->ulPanYGran); - } - } - xg=16; /*ncoder: temporary */ - *x -= *x % xg; - *y -= *y % yg; - ); -#endif -} - /* * This function is used to initialize the Start Address - the first @@ -3710,92 +2734,21 @@ MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y) void MGAAdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn; - int Base, tmp, count; +#if 0 + /* FIXME */ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; - MGAFBLayout *pLayout; - MGAPtr pMga; + if (!crtc || !crtc->enabled) + return; - - pScrn = xf86Screens[scrnIndex]; - pMga = MGAPTR(pScrn); - pLayout = &pMga->CurrentLayout; - - /* wanted to improve panning granularity problems without risking - * compatibility issues. Existing code looked hardware dependent. - */ -#ifdef USEMGAHAL - MGA_HAL( - pMga->HALGranularityOffX = x; - pMga->HALGranularityOffY = y; - MGAAdjustGranularity(pScrn,&x,&y); - pMga->HALGranularityOffX = pMga->HALGranularityOffX - x; - pMga->HALGranularityOffY = pMga->HALGranularityOffY - y; - HALSetDisplayStart(pMga->pBoard,x,y,0); - ); + mga_crtc_adjust_frame(crtc, x, y); #endif - MGA_NOT_HAL( - if(pMga->ShowCache && y && pScrn->vtSema) - y += pScrn->virtualY - 1; - - Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >> - (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]); - - if (pLayout->bitsPerPixel == 24) { - if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) - Base &= ~1; /*1 Not sure why */ - Base *= 3; - } - - /* find start of retrace */ - while (INREG8(0x1FDA) & 0x08); - while (!(INREG8(0x1FDA) & 0x08)); - /* wait until we're past the start (fixseg.c in the DDK) */ - count = INREG(MGAREG_VCOUNT) + 2; - while(INREG(MGAREG_VCOUNT) < count); - - OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C); - OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D); - OUTREG8(MGAREG_CRTCEXT_INDEX, 0x00); - tmp = INREG8(MGAREG_CRTCEXT_DATA); - OUTREG8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((Base & 0x0F0000) >> 16)); - ); } -void -MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags) -{ - ScrnInfoPtr pScrn; - int Base; - MGAFBLayout *pLayout; - MGAPtr pMga; - - pScrn = xf86Screens[scrnIndex]; - pMga = MGAPTR(pScrn); - pLayout = &pMga->CurrentLayout; -#ifdef USEMGAHAL - MGA_HAL( - MGAAdjustGranularity(pScrn,&x,&y); - HALSetDisplayStart(pMga->pBoard,x,y,1); - ); -#endif - MGA_NOT_HAL( - if(pMga->ShowCache && y && pScrn->vtSema) - y += pScrn->virtualY - 1; - - /* 3-85 c2offset - * 3-93 c2startadd0 - * 3-96 c2vcount - */ - - Base = (y * pLayout->displayWidth + x) * pLayout->bitsPerPixel >> 3; - Base += pMga->DstOrg; - Base &= 0x01ffffc0; - OUTREG(MGAREG_C2STARTADD0, Base); - ); -} - /* * This is called when VT switching back to the X server. Its job is * to reinitialise the video mode. @@ -3807,10 +2760,8 @@ MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags) static Bool MGAEnterVT(int scrnIndex, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - MGAPtr pMga; - - pMga = MGAPTR(pScrn); + ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + MGAPtr pMga = MGAPTR(scrn); #ifdef XF86DRI if (pMga->directRenderingEnabled) { @@ -3818,17 +2769,18 @@ MGAEnterVT(int scrnIndex, int flags) /* Need to make sure interrupts are enabled */ OUTREG(MGAREG_IEN, pMga->reg_ien); } - DRIUnlock(screenInfo.screens[scrnIndex]); + MGADRIUnlock(scrn); } #endif - if (!MGAModeInit(pScrn, pScrn->currentMode)) - return FALSE; - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + xf86SetDesiredModes(scrn); + + MGAStormSync(scrn); + MGAStormEngineInit(scrn); /* For the second head, work around display problem. */ - if (pMga->SecondCrtc) { - MGACrtc2FillStrip(pScrn); + if (pMga->SecondCrtc) { + MGACrtc2FillStrip(scrn); } return TRUE; @@ -3838,15 +2790,9 @@ static Bool MGAEnterVTFBDev(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; -#ifdef XF86DRI - ScreenPtr pScreen; - MGAPtr pMga; - pMga = MGAPTR(pScrn); - if (pMga->directRenderingEnabled) { - pScreen = screenInfo.screens[scrnIndex]; - DRIUnlock(pScreen); - } +#ifdef XF86DRI + MGADRIUnlock(pScrn); #endif fbdevHWEnterVT(scrnIndex,flags); @@ -3854,16 +2800,6 @@ MGAEnterVTFBDev(int scrnIndex, int flags) return TRUE; } -#define RESTORE_TEXTMODE_ON_DVI(x) \ - if (MGAISGx50(x) && \ - (ISDIGITAL1(x) || ISDIGITAL2(x))) { \ - /* Reset DUALDVI register */ \ - outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0); \ - /* Set Panel mode between 20 and 54 MHz */ \ - outMGAdac(MGA1064_PAN_CTL, 0x7); \ - } - - /* * This is called when VT switching away from the X server. Its job is * to restore the previous (text) mode. @@ -3877,24 +2813,17 @@ MGALeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; vgaHWPtr hwp = VGAHWPTR(pScrn); -#ifdef XF86DRI - MGAPtr pMga = MGAPTR(pScrn); - ScreenPtr pScreen; -#endif + + xf86DrvMsg(scrnIndex, X_INFO, "Leaving VT\n"); MGARestore(pScrn); vgaHWLock(hwp); if (xf86IsPc98()) outb(0xfac, 0x00); + #ifdef XF86DRI - if (pMga->directRenderingEnabled) { - pScreen = screenInfo.screens[scrnIndex]; - DRILock(pScreen, 0); - } -#endif -#ifdef USEMGAHAL - MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); ); + MGADRILock(pScrn); #endif } @@ -3913,13 +2842,6 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; vgaHWPtr hwp = VGAHWPTR(pScrn); MGAPtr pMga = MGAPTR(pScrn); - MGAEntPtr pMgaEnt = NULL; - -#ifdef USEMGAHAL - MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); ); -#endif - if (pMga->MergedFB) - MGACloseScreenMerged(scrnIndex, pScreen); if (pScrn->vtSema) { if (pMga->FBDev) { @@ -3939,44 +2861,6 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) } #endif - if (pMga->DualHeadEnabled) { - DevUnion *pPriv; - pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); - pMgaEnt = pPriv->ptr; - pMgaEnt->refCount--; - } - -#ifdef USEMGAHAL - MGA_HAL( - if(pMga->DualHeadEnabled) { - if(pMgaEnt->refCount == 0) { - /* Both boards have closed there screen */ - MGACloseLibrary(pMga->pBoard); - - if (pMga->pBoard) - xfree(pMga->pBoard); - if (pMga->pClientStruct) - xfree(pMga->pClientStruct); - if (pMga->pMgaModeInfo) - xfree(pMga->pMgaModeInfo); - if (pMga->pMgaHwInfo) - xfree(pMga->pMgaHwInfo); - } - } else { - MGACloseLibrary(pMga->pBoard); - - if (pMga->pBoard) - xfree(pMga->pBoard); - if (pMga->pClientStruct) - xfree(pMga->pClientStruct); - if (pMga->pMgaModeInfo) - xfree(pMga->pMgaModeInfo); - if (pMga->pMgaHwInfo) - xfree(pMga->pMgaHwInfo); - } - ); /* MGA_HAL */ -#endif - #ifdef USE_XAA if (pMga->AccelInfoRec) XAADestroyInfoRec(pMga->AccelInfoRec); @@ -4072,134 +2956,6 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) } -/* - * This routine is required but since we can't easily blank the - * second display without risking powering off the monitor, return - * FALSE and let the X server do something generic. - */ -static Bool -MGASaveScreenCrtc2(ScreenPtr pScreen, int mode) -{ - return FALSE; -} - -/* Do screen blanking */ - -static Bool -MGASaveScreen(ScreenPtr pScreen, int mode) -{ - return vgaHWSaveScreen(pScreen, mode); -} - - -/* - * MGADisplayPowerManagementSet -- - * - * Sets VESA Display Power Management Signaling (DPMS) Mode. - * - * XXX This needs fixing for sync-on-green! - */ -void -MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, - int flags) -{ - MGAPtr pMga = MGAPTR(pScrn); - unsigned char seq1 = 0, crtcext1 = 0; - - switch (PowerManagementMode) - { - case DPMSModeOn: - /* Screen: On; HSync: On, VSync: On */ - seq1 = 0x00; - crtcext1 = 0x00; - break; - case DPMSModeStandby: - /* Screen: Off; HSync: Off, VSync: On */ - seq1 = 0x20; - crtcext1 = 0x10; - break; - case DPMSModeSuspend: - /* Screen: Off; HSync: On, VSync: Off */ - seq1 = 0x20; - crtcext1 = 0x20; - break; - case DPMSModeOff: - /* Screen: Off; HSync: Off, VSync: Off */ - seq1 = 0x20; - crtcext1 = 0x30; - break; - } - - /* XXX Prefer an implementation that doesn't depend on VGA specifics */ - OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */ - seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20; - MGAWAITVSYNC(); - MGAWAITBUSY(); - OUTREG8(MGAREG_SEQ_DATA, seq1); - usleep(20000); - OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */ - crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30; - OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1); -} - - -void -MGADisplayPowerManagementSetCrtc2(ScrnInfoPtr pScrn, int PowerManagementMode, - int flags) -{ - MGAPtr pMga = MGAPTR(pScrn); - CARD32 val = INREG(MGAREG_C2CTL); - - if (PowerManagementMode==DPMSModeOn) { - /* Enable CRTC2 */ - val |= MGAREG_C2CTL_C2_EN; - val &= ~MGAREG_C2CTL_PIXCLKDIS_DISABLE; - OUTREG(MGAREG_C2CTL, val); - /* Restore normal MAVEN values */ - if (pMga->Maven) { - /* if TV MODE -- for later implementation - MAVW(MONEN, 0xb3); - MAVW(MONSET, 0x20); - MAVW(OUTMODE, 0x08); output: SVideo/Composite - MAVW(STABLE, 0x02); makes picture stable? - fixme? linux uses 0x14... - MAVW(TEST, (MAVR(TEST) & 0x10)); - - */ - /* else monitor mode */ - - xf86I2CWriteByte(pMga->Maven, MGAMAV_MONEN, 0xb2); - /* must be set to this in monitor mode */ - xf86I2CWriteByte(pMga->Maven, MGAMAV_MONSET, 0x20); - /* output: monitor mode */ - xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x03); - /* makes picture stable? */ - xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x22); - /* turn off test signal */ - xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x00); - } - } - else { - /* Disable CRTC2 video */ - val |= MGAREG_C2CTL_PIXCLKDIS_DISABLE; - val &= ~MGAREG_C2CTL_C2_EN; - OUTREG(MGAREG_C2CTL, val); - - /* Disable MAVEN display */ - if (pMga->Maven) { - /* In order to blank the 2nd display, we must set some MAVEN registers. - * It seems that not always the same values work on different hardware so - * we try a few different (possibly redundant) ones. */ - /* xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x6a); */ - /* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x03); */ - /* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x10); */ - xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x80); - } - - } -} - - static void MGABlockHandler ( int i, @@ -4345,3 +3101,11 @@ MGAG100BlackMagic(ScrnInfoPtr pScrn) usleep(10); } +static Bool +crtc_config_resize(ScrnInfoPtr scrn, int width, int height) +{ + scrn->virtualX = width; + scrn->virtualY = height; + + return TRUE; +} diff --git a/src/mga_esc.c b/src/mga_esc.c deleted file mode 100644 index 8beffa8..0000000 --- a/src/mga_esc.c +++ /dev/null @@ -1,795 +0,0 @@ -/* $XFree86$ */ -/**************************************************************************** -* mga_esc.c -* -* ESC call implementation -* -* (C) Matrox Graphics, Inc. -*****************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef USEMGAHAL - -/* All drivers should typically include these */ -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Resources.h" - -/* All drivers need this */ - -#include "compiler.h" - -/* Drivers for PCI hardware need this */ -#include "xf86PciInfo.h" - -/* Drivers that need to access the PCI config space directly need this */ -#include "xf86Pci.h" - -/* All drivers initialising the SW cursor need this */ -#include "mipointer.h" - -/* All drivers implementing backing store need this */ -#include "mibstore.h" - -#include "micmap.h" - -#include "xf86DDC.h" -#include "xf86RAC.h" -#include "vbe.h" - -#include "fb.h" -#include "cfb8_32.h" -#include "dixstruct.h" - -#include "mga_reg.h" -#include "mga.h" -#include "mga_macros.h" - -/* ESC */ -LPMGAMODEINFO pMgaModeInfo[2] = {NULL}; -MGAMODEINFO TmpMgaModeInfo[2] = {{0}}; - -/* ESC Implementation */ -static void EscHLeft(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscHRight(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscVUp(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscVDown(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscHLarger(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscHSmaller(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscVTaller(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscVSmaller(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscRefresh(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscRestoreVidParm(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscRead(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscWrite(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscHal(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscTest(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); -static void EscMerged(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode); - -static LPMGAMODEINFO GetModeInfoPtr(ULONG ulScreen); -static void GetVideoParameterStr(LPMGAMODEINFO pModeInfo, char *sResult); -static Bool convertNumber(unsigned long *pulNumber, char *sNumber); - - -static MGAEscFuncRec FunctionTable[] = { - {"hal", EscHal}, - {"test", EscTest}, - {"read", EscRead}, - {"write", EscWrite}, - {"left", EscHLeft}, - {"right", EscHRight}, - {"down", EscVDown}, - {"up", EscVUp}, - {"h+", EscHLarger}, - {"h-", EscHSmaller}, - {"v+", EscVTaller}, - {"v-", EscVSmaller}, - {"refresh", EscRefresh}, - {"undo", EscRestoreVidParm}, - {"merged", EscMerged}, - {NULL,NULL} -}; - - -void MGAFillDisplayModeStruct(DisplayModePtr pMode, LPMGAMODEINFO pModeInfo) -{ - pMode->Clock = pModeInfo->ulPixClock; - - pMode->HDisplay = pModeInfo->ulDispWidth; - pMode->HSyncStart = pModeInfo->ulDispWidth - + pModeInfo->ulHFPorch; - pMode->HSyncEnd = pModeInfo->ulDispWidth - + pModeInfo->ulHFPorch - + pModeInfo->ulHSync; - pMode->HTotal = pModeInfo->ulDispWidth - + pModeInfo->ulHFPorch - + pModeInfo->ulHSync - + pModeInfo->ulHBPorch; - - pMode->VDisplay = pModeInfo->ulDispHeight; - pMode->VSyncStart = pModeInfo->ulDispHeight - + pModeInfo->ulVFPorch; - pMode->VSyncEnd = pModeInfo->ulDispHeight - + pModeInfo->ulVFPorch - + pModeInfo->ulVSync; - pMode->VTotal = pModeInfo->ulDispHeight - + pModeInfo->ulVFPorch - + pModeInfo->ulVSync - + pModeInfo->ulVBPorch; - - pMode->VRefresh = pModeInfo->ulRefreshRate; -} - -static LPMGAMODEINFO GetModeInfoPtr(ULONG ulScreen) -{ - - if ( !TmpMgaModeInfo[ulScreen].ulDispWidth ) - { - TmpMgaModeInfo[ulScreen] = *pMgaModeInfo[ulScreen]; - } - - return &TmpMgaModeInfo[ulScreen]; -} - - -static void GetVideoParameterStr(LPMGAMODEINFO pModeInfo, char *sResult) -{ - sprintf(sResult, "%d %d %d %d %d %d %d %d %d %d %d", - pModeInfo->ulDispWidth, - pModeInfo->ulDispHeight, - pModeInfo->ulBpp, - pModeInfo->ulPixClock, - pModeInfo->ulHFPorch, - pModeInfo->ulHSync, - pModeInfo->ulHBPorch, - pModeInfo->ulVFPorch, - pModeInfo->ulVSync, - pModeInfo->ulVBPorch, - pModeInfo->flSignalMode); -} - - -static float GetVRefresh(LPMGAMODEINFO pModeInfo) -{ - ULONG ulHTotal; - ULONG ulVTotal; - - ulHTotal = - pModeInfo->ulDispWidth + - pModeInfo->ulHFPorch + - pModeInfo->ulHSync + - pModeInfo->ulHBPorch; - - ulVTotal = - pModeInfo->ulDispHeight + - pModeInfo->ulVFPorch + - pModeInfo->ulVSync + - pModeInfo->ulVBPorch; - - return ((float)pModeInfo->ulPixClock * 1000.0) / (ulHTotal * ulVTotal); -} - -static void EscHal(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMGA = MGAPTR(pScrn); - - if(pMGA->HALLoaded) - strcpy(sResult, "YES"); - else - strcpy(sResult, "NO"); - -} - -static void EscTest(ScrnInfoPtr pScrn, unsigned long *param, char -*sResult, DisplayModePtr pMode) -{ - strcpy(sResult, "YES"); -} - -static void EscMerged(ScrnInfoPtr pScrn, unsigned long *param, char -*sResult, DisplayModePtr pMode) -{ - strcpy(sResult, "YES"); -} - -static void EscRead(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - ULONG ulSource, ulAddr, ulData; - UCHAR ucIndex; - - if ( (param[0] & 0xffff) < 2 ) - { - strcpy(sResult, "#error 1"); - return; - } - - - ulSource = param[1] >> 16; - ulAddr = param[1] & 0xffff; - - - switch( ulSource ) - { - case 0: - ulData = INREG(ulAddr); - sprintf(sResult, "MGA[%04X] = 0x%08X", ulAddr, ulData); - break; - case 1: - ucIndex = INREG8(0x3c00); - OUTREG8(0x3c00, (UCHAR)ulAddr); - ulData = (ULONG)INREG8(0x3c0a); - OUTREG8(0x3c00, ucIndex); - sprintf(sResult, "DAC[%02X] = 0x%02X", ulAddr, ulData); - break; - case 2: - ucIndex = INREG8(0x1fd4); - OUTREG8(0x1fd4, (UCHAR)ulAddr); - ulData = (ULONG)INREG8(0x1fd5); - OUTREG8(0x1fd4, ucIndex); - sprintf(sResult, "CRTC[%02X] = 0x%02X", ulAddr, ulData); - break; - case 3: - ucIndex = INREG8(0x1fde); - OUTREG8(0x1fde, (UCHAR)ulAddr); - ulData = (ULONG)INREG8(0x1fdf); - OUTREG8(0x1fde, ucIndex); - sprintf(sResult, "CRTCEXT[%02X] = 0x%02X", ulAddr, ulData); - break; - default: - strcpy(sResult, "ERROR# 2"); - break; - } -} - -static void EscWrite(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - ULONG ulSource, ulAddr, ulData; - UCHAR ucIndex; - - if ( (param[0] & 0xffff) < 3 ) - { - strcpy(sResult, "#error 1"); - return; - } - - ulSource = param[1] >> 16; - ulAddr = param[1] & 0xffff; - ulData = param[2]; - - - switch( ulSource ) - { - case 0: - OUTREG(ulAddr, ulData); - strcpy(sResult, "OK"); - break; - case 1: - ucIndex = INREG8(0x3c00); - OUTREG8(0x3c00, (UCHAR)ulAddr); - OUTREG8(0x3c0a, (UCHAR)ulData); - OUTREG8(0x3c00, ucIndex); - strcpy(sResult, "OK"); - break; - case 2: - ucIndex = INREG8(0x1fd4); - OUTREG8(0x1fd4, (UCHAR)ulAddr); - OUTREG8(0x1fd5, (UCHAR)ulData); - OUTREG8(0x1fd4, ucIndex); - strcpy(sResult, "OK"); - break; - case 3: - ucIndex = INREG8(0x1fde); - OUTREG8(0x1fde, (UCHAR)ulAddr); - OUTREG8(0x1fdf, (UCHAR)ulData); - OUTREG8(0x1fde, ucIndex); - strcpy(sResult, "OK"); - break; - default: - strcpy(sResult, "ERROR# 2"); - break; - } -} - -static void EscHLeft(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - - if (pModeInfo->ulHBPorch > (8 * param[1]) ) - { - pModeInfo->ulHBPorch -=8 * param[1]; - pModeInfo->ulHFPorch +=8 * param[1]; - MGASetMode(pMga->pBoard, pModeInfo); - } - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - - -static void EscHRight(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if (pModeInfo->ulHFPorch > (8 * param[1]) ) - { - pModeInfo->ulHFPorch -=8 * param[1]; - pModeInfo->ulHBPorch +=8 * param[1]; - MGASetMode(pMga->pBoard, pModeInfo); - } - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - - - -static void EscVUp(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if (pModeInfo->ulVBPorch > (param[1]) ) - { - pModeInfo->ulVBPorch -= param[1]; - pModeInfo->ulVFPorch += param[1]; - MGASetMode(pMga->pBoard, pModeInfo); - } - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - - -static void EscVDown(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if (pModeInfo->ulVFPorch >= (param[1]) ) - { - pModeInfo->ulVFPorch -= param[1]; - pModeInfo->ulVBPorch += param[1]; - MGASetMode(pMga->pBoard, pModeInfo); - } - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - - -static void EscHLarger(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - float fRefresh, fPixelClock; - ULONG ulStep; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if ((param[0] & 0xffff) > 1) - { - - ulStep = param[1] * 8; - } - else - { - - ulStep = 8; - } - - fRefresh = GetVRefresh(pModeInfo); - fPixelClock = (float)pModeInfo->ulPixClock; - if (pModeInfo->ulHBPorch >= ulStep ) - { - pModeInfo->ulHBPorch -= ulStep; - } - else - { - pModeInfo->ulHBPorch = 0; - } - pModeInfo->ulPixClock = (ULONG)( (fRefresh * fPixelClock) / GetVRefresh(pModeInfo)); - MGASetMode(pMga->pBoard, pModeInfo); - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - - -static void EscHSmaller(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - float fRefresh, fPixelClock; - ULONG ulStep; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if ((param[0] & 0xffff) > 1) - { - - ulStep = param[1] * 8; - } - else - { - - ulStep = 8; - } - - - fRefresh = GetVRefresh(pModeInfo); - fPixelClock = (float)pModeInfo->ulPixClock; - pModeInfo->ulHBPorch += ulStep; - pModeInfo->ulPixClock = (ULONG)( (fRefresh * fPixelClock) / GetVRefresh(pModeInfo)); - - MGASetMode(pMga->pBoard, pModeInfo); - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - -static void EscVTaller(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - float fRefresh, fPixelClock; - ULONG ulStep; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if ((param[0] & 0xffff) > 1) - { - - ulStep = param[1]; - } - else - { - - ulStep = 1; - } - - fRefresh = GetVRefresh(pModeInfo); - fPixelClock = (float)pModeInfo->ulPixClock; - - if (pModeInfo->ulVBPorch >= ulStep ) - { - pModeInfo->ulVBPorch -= ulStep; - } - else - { - pModeInfo->ulVBPorch = 0; - } - - pModeInfo->ulPixClock = (ULONG)( (fRefresh * fPixelClock) / GetVRefresh(pModeInfo)); - MGASetMode(pMga->pBoard, pModeInfo); - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - -static void EscVSmaller(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - float fRefresh, fPixelClock; - ULONG ulStep; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if ((param[0] & 0xffff) > 1) - { - - ulStep = param[1]; - } - else - { - - ulStep = 1; - } - - - fRefresh = GetVRefresh(pModeInfo); - fPixelClock = (float)pModeInfo->ulPixClock; - pModeInfo->ulVFPorch += ulStep; - pModeInfo->ulPixClock = (ULONG)( (fRefresh * fPixelClock) / GetVRefresh(pModeInfo)); - MGASetMode(pMga->pBoard, pModeInfo); - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - - -static void EscRefresh(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - LPMGAMODEINFO pModeInfo; - float fRefresh, fPixelClock; - - pModeInfo = GetModeInfoPtr(param[0] >> 16); - - if ( !pMgaModeInfo ) - { - strcpy(sResult, "#error 1"); - return; - } - - if ((param[0] & 0xffff) < 2) - { - strcpy(sResult, "#error 1"); - return; - } - - fRefresh = GetVRefresh(pModeInfo); - - fPixelClock = (float)pModeInfo->ulPixClock; - pModeInfo->ulPixClock = (ULONG)( ((float)param[1] * fPixelClock) / fRefresh); - - pModeInfo->ulRefreshRate = param[1]; - - MGASetMode(pMga->pBoard, pModeInfo); - - MGAFillDisplayModeStruct(pMode, pModeInfo); - - GetVideoParameterStr(pModeInfo, sResult); -} - -static void EscRestoreVidParm(ScrnInfoPtr pScrn, unsigned long *param, char *sResult, DisplayModePtr pMode) -{ - MGAPtr pMga = MGAPTR(pScrn); - - TmpMgaModeInfo[param[0] >> 16].ulDispWidth = 0; - MGASetMode(pMga->pBoard, pMgaModeInfo[param[0] >> 16]); - - MGAFillDisplayModeStruct(pMode, pMgaModeInfo[param[0] >> 16]); - - GetVideoParameterStr(pMgaModeInfo[param[0] >> 16], sResult); -} - -static Bool convertNumber(unsigned long *pulNumber, char *sNumber) -{ - unsigned long i, ulDigit, shiftHex; - Bool bResult = TRUE; - - if (sNumber == NULL) - { - return FALSE; - } - - - /* Convert number */ - if ( (sNumber[0] == '0') && (sNumber[1] == 'x') ) - { - shiftHex = 0; - *pulNumber = 0; - - for (i = strlen(sNumber) - 1; i > 1; i--) - { - if (shiftHex > 28) - { - bResult = FALSE; - break; - } - - if ( !isxdigit(sNumber[i]) ) - { - bResult = FALSE; - break; - } - - ulDigit = toupper(sNumber[i]) - '0'; - if (ulDigit > 9) - { - ulDigit -= 7; - } - *pulNumber += ulDigit << shiftHex; - shiftHex += 4; - } - } - else - { - for (i = 0; i < strlen(sNumber); i++) - { - if ( !isdigit(sNumber[i]) ) - { - bResult = FALSE; - break; - } - } - *pulNumber = atoi(sNumber); - } - - return bResult; -} - -static Bool GetEscCommand(char *cmdline, EscCmdStruct *escCmd) -{ - unsigned long i, paramIndex, ulHI; - Bool bResult; - char *pParameter, *function; - - bResult = TRUE; /* success */ - - function = strtok(cmdline, " \t\n,"); - - - escCmd->parameters[0] = 0; - if (function) - { - /* Find Screen */ - if (function[1] == ':' ) - { - escCmd->parameters[0] = (unsigned long)(function[0] - '0') << 16; - strncpy(escCmd->function, function+2, 32); - } - else - { - strncpy(escCmd->function, function, 32); - } - - } - else - { - strcpy(escCmd->function, "#ERROR -1"); - escCmd->parameters[0] = 0; - return FALSE; - } - - paramIndex = 1; - while ( (pParameter = strtok(NULL, " \t\n,")) != NULL ) - { - if (paramIndex > 31) - { - /* 32 parameters supported */ - break; - } - - i = 0; - while(pParameter[i] && pParameter[i] != ':') - { - i++; - } - - if ( pParameter[i] ) - { - pParameter[i] = '\0'; - bResult = convertNumber(&escCmd->parameters[paramIndex], &pParameter[i+1]); - bResult |= convertNumber(&ulHI, pParameter); - escCmd->parameters[paramIndex] &= 0xffff; - escCmd->parameters[paramIndex] += ulHI << 16; - pParameter[i] = ':'; - } - else - { - bResult = convertNumber(&escCmd->parameters[paramIndex], pParameter); - } - - - if (!bResult) - { - break; - } - paramIndex++; - } - - escCmd->parameters[0] += paramIndex; - return bResult; - -} - -void MGAExecuteEscCmd(ScrnInfoPtr pScrn, char *cmdline , char *sResult, DisplayModePtr pMode) -{ - int i = 0; - int ulScreen = 0; - MGAPtr pMga = MGAPTR(pScrn); - EscCmdStruct EscCmd; - - if (pMga->SecondCrtc) - { - ulScreen = 1; - } - else - { - ulScreen = 0; - } - - - if (FunctionTable[0].function && GetEscCommand(cmdline, &EscCmd) ) - { - i = 0; - - while ( FunctionTable[i].function && strcmp(FunctionTable[i].function, EscCmd.function) ) - { - i++; - } - - if (FunctionTable[i].function) - { - EscCmd.parameters[0] &= 0xffff; - EscCmd.parameters[0] |= ulScreen << 16; - - FunctionTable[i].funcptr(pScrn, EscCmd.parameters, sResult, pMode); - } - else - { - strcpy(sResult, "error# -1"); - } - } - else - { - strcpy(sResult, "error# -1"); - } -} -#else -int mga_foo; -#endif diff --git a/src/mga_g450pll.c b/src/mga_g450pll.c index 7407d14..1a9931f 100644 --- a/src/mga_g450pll.c +++ b/src/mga_g450pll.c @@ -191,11 +191,11 @@ static CARD32 G450FindFirstPLLParam(ScrnInfoPtr pScrn, CARD32 ulFout, } -static CARD32 G450WriteMNP(ScrnInfoPtr pScrn, CARD32 ulMNP) +static CARD32 G450WriteMNP(ScrnInfoPtr pScrn, mga_pll_t pll, CARD32 ulMNP) { MGAPtr pMga = MGAPTR(pScrn); - if (!pMga->SecondCrtc) { + if (pll == MGA_PIXEL_PLL) { outMGAdac(MGA1064_PIX_PLLC_M, (CARD8)(ulMNP >> 16)); outMGAdac(MGA1064_PIX_PLLC_N, (CARD8)(ulMNP >> 8)); outMGAdac(MGA1064_PIX_PLLC_P, (CARD8) ulMNP); @@ -207,12 +207,12 @@ static CARD32 G450WriteMNP(ScrnInfoPtr pScrn, CARD32 ulMNP) return TRUE; } -static CARD32 G450ReadMNP(ScrnInfoPtr pScrn) +static CARD32 G450ReadMNP(ScrnInfoPtr pScrn, mga_pll_t pll) { MGAPtr pMga = MGAPTR(pScrn); CARD32 ret = 0; - if (!pMga->SecondCrtc) { + if (pll == MGA_PIXEL_PLL) { ret = (CARD8)inMGAdac(MGA1064_PIX_PLLC_M) << 16; ret |= (CARD8)inMGAdac(MGA1064_PIX_PLLC_N) << 8; ret |= (CARD8)inMGAdac(MGA1064_PIX_PLLC_P); @@ -267,14 +267,14 @@ static CARD32 G450CompareMNP(ScrnInfoPtr pScrn, CARD32 ulFout, CARD32 ulMNP1, } -static CARD32 G450IsPllLocked(ScrnInfoPtr pScrn, Bool *lpbLocked) +static CARD32 G450IsPllLocked(ScrnInfoPtr pScrn, mga_pll_t pll, Bool *lpbLocked) { CARD32 ulFallBackCounter, ulLockCount, ulCount; CARD8 ucPLLStatus; MGAPtr pMga = MGAPTR(pScrn); - if (!pMga->SecondCrtc) + if (pll == MGA_PIXEL_PLL) OUTREG8(0x3c00, MGA1064_PIX_PLL_STAT); else OUTREG8(0x3c00, MGA1064_VID_PLL_STAT); @@ -306,7 +306,7 @@ static CARD32 G450IsPllLocked(ScrnInfoPtr pScrn, Bool *lpbLocked) } -double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out) +double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, mga_pll_t pll, long f_out) { Bool bFoundValidPLL; Bool bLocked; @@ -373,8 +373,7 @@ double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out) bFoundValidPLL = FALSE; ulMNP = 0; - /* For pixel pll */ - if (!pMga->SecondCrtc) { + if (pll == MGA_PIXEL_PLL) { ucMisc = INREG8(0x1FCC); OUTREG8(0x1fc2, (CARD8)(ucMisc | CLKSEL_MGA)); } @@ -410,49 +409,49 @@ double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out) if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP - 0x300); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP - 0x300); + G450IsPllLocked(pScrn, pll, &bLocked); } if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP + 0x300); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP + 0x300); + G450IsPllLocked(pScrn, pll, &bLocked); } if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP - 0x200); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP - 0x200); + G450IsPllLocked(pScrn, pll, &bLocked); } if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP + 0x200); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP + 0x200); + G450IsPllLocked(pScrn, pll, &bLocked); } if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP - 0x100); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP - 0x100); + G450IsPllLocked(pScrn, pll, &bLocked); } if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP + 0x100); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP + 0x100); + G450IsPllLocked(pScrn, pll, &bLocked); } if(bLocked) { - G450WriteMNP(pScrn, ulTryMNP); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP); + G450IsPllLocked(pScrn, pll, &bLocked); } else if(!ulMNP) { - G450WriteMNP(pScrn, ulTryMNP); - G450IsPllLocked(pScrn, &bLocked); + G450WriteMNP(pScrn, pll, ulTryMNP); + G450IsPllLocked(pScrn, pll, &bLocked); if(bLocked) { ulMNP = ulMNPTable[ulIndex]; @@ -471,11 +470,11 @@ double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out) { if(ulMNP) { - G450WriteMNP(pScrn, ulMNP); + G450WriteMNP(pScrn, pll, ulMNP); } else { - G450WriteMNP(pScrn, ulMNPTable[0]); + G450WriteMNP(pScrn, pll, ulMNPTable[0]); } } @@ -483,9 +482,9 @@ double MGAG450SetPLLFreq(ScrnInfoPtr pScrn, long f_out) } long -MGAG450SavePLLFreq(ScrnInfoPtr pScrn) +MGAG450SavePLLFreq(ScrnInfoPtr pScrn, mga_pll_t pll) { - CARD32 ulMNP = G450ReadMNP(pScrn); + CARD32 ulMNP = G450ReadMNP(pScrn, pll); CARD8 ucP; CARD32 freq; @@ -501,9 +500,9 @@ MGAG450SavePLLFreq(ScrnInfoPtr pScrn) #ifdef DEBUG void -MGAG450PrintPLL(ScrnInfoPtr pScrn) +MGAG450PrintPLL(ScrnInfoPtr pScrn, mga_pll_t pll) { - CARD32 ulMNP = G450ReadMNP(pScrn); + CARD32 ulMNP = G450ReadMNP(pScrn, pll); CARD8 ucP; CARD32 freq; diff --git a/src/mga_g_crtc.c b/src/mga_g_crtc.c new file mode 100644 index 0000000..030a6bd --- /dev/null +++ b/src/mga_g_crtc.c @@ -0,0 +1,904 @@ +/* + * Copyright 2007 Tilman Sauerbeck + * + * 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, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them 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 MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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: + * Tilman Sauerbeck <tilman@code-monkey.de> + * + * Sources: + * xf86-video-intel, mga_dacG.c + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" + +/* Drivers for PCI hardware need this */ +#include "xf86PciInfo.h" + +/* Drivers that need to access the PCI config space directly need this */ +#include "xf86Pci.h" + +#include "mga_reg.h" +#include "mga.h" +#include "mga_macros.h" +#include "mga_dacG.h" + +/* + * Only change bits shown in this mask. Ideally reserved bits should be + * zeroed here. Also, don't change the vgaioen bit here since it is + * controlled elsewhere. + * + * XXX These settings need to be checked. + */ +#define OPTION1_MASK 0xFFFFFEFF +#define OPTION2_MASK 0xFFFFFFFF +#define OPTION3_MASK 0xFFFFFFFF + +#define OPTION1_MASK_PRIMARY 0xFFFC0FF + +typedef struct { + unsigned char ExtVga[6]; + unsigned char DacRegs[0x50]; + CARD32 Option; + CARD32 Option2; + CARD32 Option3; + Bool PIXPLLCSaved; + long clock; +} MgaCrtcStateRec, *MgaCrtcStatePtr; + +typedef struct { + MgaCrtcStateRec saved_state; +} MgaCrtcDataRec, *MgaCrtcDataPtr; + +static void crtc_dpms(xf86CrtcPtr crtc, int mode); +static void crtc_save(xf86CrtcPtr crtc); +static void crtc_restore(xf86CrtcPtr crtc); +static Bool crtc_lock(xf86CrtcPtr crtc); +static void crtc_unlock(xf86CrtcPtr crtc); +static Bool crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void crtc_prepare(xf86CrtcPtr crtc); +static void crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y); +static void crtc_commit(xf86CrtcPtr crtc); +static void crtc_destroy(xf86CrtcPtr crtc); + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = crtc_save, + .restore = crtc_restore, + .lock = crtc_lock, + .unlock = crtc_unlock, + .mode_fixup = crtc_mode_fixup, + .prepare = crtc_prepare, + .mode_set = crtc_mode_set, + .commit = crtc_commit, + .destroy = crtc_destroy +}; + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ +} + +static void +MGAG200SEComputePLLParam(long lFo, int *M, int *N, int *P) +{ + unsigned int ulComputedFo; + unsigned int ulFDelta; + unsigned int ulFPermitedDelta; + unsigned int ulFTmpDelta; + unsigned int ulVCOMax, ulVCOMin; + unsigned int ulTestP; + unsigned int ulTestM; + unsigned int ulTestN; + unsigned int ulPLLFreqRef; + + ulVCOMax = 320000; + ulVCOMin = 160000; + ulPLLFreqRef = 25000; + + ulFDelta = 0xFFFFFFFF; + /* Permited delta is 0.5% as VESA Specification */ + ulFPermitedDelta = lFo * 5 / 1000; + + /* Then we need to minimize the M while staying within 0.5% */ + for (ulTestP = 8; ulTestP > 0; ulTestP >>= 1) { + if ((lFo * ulTestP) > ulVCOMax) continue; + if ((lFo * ulTestP) < ulVCOMin) continue; + + for (ulTestN = 17; ulTestN <= 256; ulTestN++) { + for (ulTestM = 1; ulTestM <= 32; ulTestM++) { + ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP); + if (ulComputedFo > lFo) + ulFTmpDelta = ulComputedFo - lFo; + else + ulFTmpDelta = lFo - ulComputedFo; + + if (ulFTmpDelta < ulFDelta) { + ulFDelta = ulFTmpDelta; + *M = ulTestM - 1; + *N = ulTestN - 1; + *P = ulTestP - 1; + } + } + } + } +} + + +/** + * Calculate the PLL settings (m, n, p, s). + * + * For more information, refer to the Matrox "MGA1064SG Developer + * Specification" (document 10524-MS-0100). chapter 5.7.8. "PLLs Clocks + * Generators" + * + * \param f_out Desired clock frequency, measured in kHz. + * \param best_m Value of PLL 'm' register. + * \param best_n Value of PLL 'n' register. + * \param p Value of PLL 'p' register. + * \param s Value of PLL 's' filter register (pix pll clock only). + */ + +static void +MGAGCalcClock(xf86CrtcPtr crtc, long f_out, + int *best_m, int *best_n, int *p, int *s) +{ + MGAPtr pMga = MGAPTR(crtc->scrn); + int m, n; + double f_vco; + double m_err, calc_f; + const double ref_freq = (double) pMga->bios.pll_ref_freq; + int feed_div_min, feed_div_max; + int in_div_min, in_div_max; + int post_div_max; + + switch( pMga->Chipset ) + { + case PCI_CHIP_MGA1064: + feed_div_min = 100; + feed_div_max = 127; + in_div_min = 1; + in_div_max = 31; + post_div_max = 7; + break; + case PCI_CHIP_MGAG400: + case PCI_CHIP_MGAG550: + feed_div_min = 7; + feed_div_max = 127; + in_div_min = 1; + in_div_max = 31; + post_div_max = 7; + break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + case PCI_CHIP_MGAG100: + case PCI_CHIP_MGAG100_PCI: + case PCI_CHIP_MGAG200: + case PCI_CHIP_MGAG200_PCI: + default: + feed_div_min = 7; + feed_div_max = 127; + in_div_min = 1; + in_div_max = 6; + post_div_max = 7; + break; + } + + /* Make sure that f_min <= f_out */ + if ( f_out < ( pMga->bios.pixel.min_freq / 8)) + f_out = pMga->bios.pixel.min_freq / 8; + + /* + * f_pll = f_vco / (p+1) + * Choose p so that + * pMga->bios.pixel.min_freq <= f_vco <= pMga->bios.pixel.max_freq + * we don't have to bother checking for this maximum limit. + */ + f_vco = ( double ) f_out; + for ( *p = 0; *p <= post_div_max && f_vco < pMga->bios.pixel.min_freq; + *p = *p * 2 + 1, f_vco *= 2.0); + + /* Initial amount of error for frequency maximum */ + m_err = f_out; + + /* Search for the different values of ( m ) */ + for ( m = in_div_min ; m <= in_div_max ; m++ ) + { + /* see values of ( n ) which we can't use */ + for ( n = feed_div_min; n <= feed_div_max; n++ ) + { + calc_f = ref_freq * (n + 1) / (m + 1) ; + + /* + * Pick the closest frequency. + */ + if ( abs(calc_f - f_vco) < m_err ) { + m_err = abs(calc_f - f_vco); + *best_m = m; + *best_n = n; + } + } + } + + /* Now all the calculations can be completed */ + f_vco = ref_freq * (*best_n + 1) / (*best_m + 1); + + /* Adjustments for filtering pll feed back */ + if ( (50000.0 <= f_vco) + && (f_vco < 100000.0) ) + *s = 0; + if ( (100000.0 <= f_vco) + && (f_vco < 140000.0) ) + *s = 1; + if ( (140000.0 <= f_vco) + && (f_vco < 180000.0) ) + *s = 2; + if ( (180000.0 <= f_vco) ) + *s = 3; + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "f_out_requ =%ld f_pll_real=%.1f f_vco=%.1f n=0x%x m=0x%x p=0x%x s=0x%x\n", + f_out, (f_vco / (*p + 1)), f_vco, *best_n, *best_m, *p, *s ); +#endif +} + +/* + * MGAGSetPCLK - Set the pixel (PCLK) clock. + */ +static void +MGAGSetPCLK(xf86CrtcPtr crtc, MgaCrtcStatePtr state, long f_out) +{ + MGAPtr pMga = MGAPTR(crtc->scrn); + + /* Pixel clock values */ + int m, n, p, s; + + if (MGAISGx50(pMga)) { + state->clock = f_out; + return; + } + + if (pMga->is_G200SE) { + MGAG200SEComputePLLParam(f_out, &m, &n, &p); + + state->DacRegs[MGA1064_PIX_PLLC_M] = m; + state->DacRegs[MGA1064_PIX_PLLC_N] = n; + state->DacRegs[MGA1064_PIX_PLLC_P] = p; + } else { + /* Do the calculations for m, n, p and s */ + MGAGCalcClock(crtc, f_out, &m, &n, &p, &s ); + + /* Values for the pixel clock PLL registers */ + state->DacRegs[MGA1064_PIX_PLLC_M] = m & 0x1F; + state->DacRegs[MGA1064_PIX_PLLC_N] = n & 0x7F; + state->DacRegs[MGA1064_PIX_PLLC_P] = (p & 0x07) | + ((s & 0x03) << 3); + } +} + +static void +state_set(xf86CrtcPtr crtc, MgaCrtcStatePtr state, + DisplayModePtr mode, int x, int y) +{ + /* + * initial values of the DAC registers + */ + const static unsigned char initDAC[] = { + /* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0, + /* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x18: */ 0x00, 0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20, + /* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 0x28: */ 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x40, + /* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83, + /* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A, + /* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 + }; + + int i; + int hd, hs, he, ht, vd, vs, ve, vt, wd; + int BppShift; + MGAPtr pMga = MGAPTR(crtc->scrn); + MGAFBLayout *pLayout = &pMga->CurrentLayout; + vgaRegPtr vga = &VGAHWPTR(crtc->scrn)->ModeReg; + + BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]; + + for (i = 0; i < sizeof(state->DacRegs); i++) + state->DacRegs[i] = initDAC[i]; + + switch (pMga->Chipset) { + case PCI_CHIP_MGA1064: + state->DacRegs[MGA1064_SYS_PLL_M] = 0x04; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x44; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x18; + state->Option = 0x5F094F21; + state->Option2 = 0x00000000; + break; + case PCI_CHIP_MGAG100: + case PCI_CHIP_MGAG100_PCI: + state->DacRegs[MGA1064_VREF_CTL] = 0x03; + + if (pMga->HasSDRAM) { + if (pMga->OverclockMem) { + /* 220 Mhz */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x06; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x38; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x18; + } else { + /* 203 Mhz */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x01; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x0E; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x18; + } + + state->Option = 0x404991a9; + } else { + if (pMga->OverclockMem) { + /* 143 Mhz */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x06; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x24; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x10; + } else { + /* 124 Mhz */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x04; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x16; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x08; + } + + state->Option = 0x4049d121; + } + + state->Option2 = 0x0000007; + break; + case PCI_CHIP_MGAG400: + case PCI_CHIP_MGAG550: + if (MGAISGx50(pMga)) + break; + + if (pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */ + if (pMga->OverclockMem) { + /* 150/200 */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x05; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x42; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x18; + state->Option3 = 0x019B8419; + state->Option = 0x50574120; + } else { + /* 125/166 */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x02; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x1B; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x18; + state->Option3 = 0x019B8419; + state->Option = 0x5053C120; + } + } else { + if (pMga->OverclockMem) { + /* 125/166 */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x02; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x1B; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x18; + state->Option3 = 0x019B8419; + state->Option = 0x5053C120; + } else { + /* 110/166 */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x13; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x7A; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x08; + state->Option3 = 0x0190a421; + state->Option = 0x50044120; + } + } + + if (pMga->HasSDRAM) + state->Option &= ~(1 << 14); + + state->Option2 = 0x01003000; + break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + state->DacRegs[MGA1064_VREF_CTL] = 0x03; + state->DacRegs[MGA1064_PIX_CLK_CTL] = + MGA1064_PIX_CLK_CTL_SEL_PLL; + + state->DacRegs[MGA1064_MISC_CTL] = + MGA1064_MISC_CTL_DAC_EN | + MGA1064_MISC_CTL_VGA8 | + MGA1064_MISC_CTL_DAC_RAM_CS; + + if (pMga->HasSDRAM) + state->Option = 0x40049120; + + state->Option2 = 0x00008000; + break; + case PCI_CHIP_MGAG200: + case PCI_CHIP_MGAG200_PCI: + default: + if (pMga->OverclockMem) { + /* 143 Mhz */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x06; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x24; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x10; + } else { + /* 124 Mhz */ + state->DacRegs[MGA1064_SYS_PLL_M] = 0x04; + state->DacRegs[MGA1064_SYS_PLL_N] = 0x2D; + state->DacRegs[MGA1064_SYS_PLL_P] = 0x19; + } + + state->Option2 = 0x00008000; + + if (pMga->HasSDRAM) + state->Option = 0x40499121; + else + state->Option = 0x4049cd21; + + break; + } + + /* must always have the pci retries on but rely on + polling to keep them from occuring */ + state->Option &= ~0x20000000; + + switch (pLayout->bitsPerPixel) { + case 8: + state->DacRegs[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits; + break; + case 16: + state->DacRegs[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits; + + if ((pLayout->weight.red == 5) && (pLayout->weight.green == 5) + && (pLayout->weight.blue == 5)) { + state->DacRegs[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits; + } + + break; + case 24: + state->DacRegs[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits; + break; + case 32: + if (pLayout->Overlay8Plus24) { + state->DacRegs[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32bits; + state->DacRegs[MGA1064_COL_KEY_MSK_LSB] = 0xFF; + state->DacRegs[MGA1064_COL_KEY_LSB] = pMga->colorKey; + } else + state->DacRegs[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits; + + break; + default: + FatalError("MGA: unsupported depth\n"); + } + + /* + * This will initialize all of the generic VGA registers. + */ + if (!vgaHWInit(crtc->scrn, mode)) { + ErrorF("oh noes, vgahwinit failed\n"); + return; + } + + /* + * Here all of the MGA registers get filled in. + */ + hd = (mode->HDisplay >> 3) - 1; + hs = (mode->HSyncStart >> 3) - 1; + he = (mode->HSyncEnd >> 3) - 1; + ht = (mode->HTotal >> 3) - 1; + vd = mode->VDisplay - 1; + vs = mode->VSyncStart - 1; + ve = mode->VSyncEnd - 1; + vt = mode->VTotal - 2; + + /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange + * vertical stripes + */ + if ((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04) + ht++; + + if (pLayout->bitsPerPixel == 24) + wd = (pLayout->displayWidth * 3) >> (4 - BppShift); + else + wd = pLayout->displayWidth >> (4 - BppShift); + + state->ExtVga[0] = 0; + state->ExtVga[5] = 0; + + if (mode->Flags & V_INTERLACE) { + state->ExtVga[0] = 0x80; + state->ExtVga[5] = (hs + he - ht) >> 1; + wd <<= 1; + vt &= 0xFFFE; + } + + state->ExtVga[0] |= (wd & 0x300) >> 4; + + state->ExtVga[1] = (((ht - 4) & 0x100) >> 8) | + ((hd & 0x100) >> 7) | + ((hs & 0x100) >> 6) | + (ht & 0x40); + state->ExtVga[2] = ((vt & 0xc00) >> 10) | + ((vd & 0x400) >> 8) | + ((vd & 0xc00) >> 7) | + ((vs & 0xc00) >> 5) | + ((vd & 0x400) >> 3); /* linecomp */ + + if (pLayout->bitsPerPixel == 24) + state->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80; + else + state->ExtVga[3] = ((1 << BppShift) - 1) | 0x80; + + state->ExtVga[4] = 0; + + vga->CRTC[0] = ht - 4; + vga->CRTC[1] = hd; + vga->CRTC[2] = hd; + vga->CRTC[3] = (ht & 0x1F) | 0x80; + vga->CRTC[4] = hs; + vga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F); + vga->CRTC[6] = vt & 0xFF; + vga->CRTC[7] = ((vt & 0x100) >> 8 ) | + ((vd & 0x100) >> 7 ) | + ((vs & 0x100) >> 6 ) | + ((vd & 0x100) >> 5 ) | + ((vd & 0x100) >> 4 ) | /* linecomp */ + ((vt & 0x200) >> 4 ) | + ((vd & 0x200) >> 3 ) | + ((vs & 0x200) >> 2 ); + vga->CRTC[9] = ((vd & 0x200) >> 4) | + ((vd & 0x200) >> 3); /* linecomp */ + + vga->CRTC[16] = vs & 0xFF; + vga->CRTC[17] = (ve & 0x0F) | 0x20; + vga->CRTC[18] = vd & 0xFF; + vga->CRTC[19] = wd & 0xFF; + vga->CRTC[21] = vd & 0xFF; + vga->CRTC[22] = (vt + 1) & 0xFF; + vga->CRTC[24] = vd & 0xFF; /* linecomp */ + + state->DacRegs[MGA1064_CURSOR_BASE_ADR_LOW] = pMga->FbCursorOffset >> 10; + state->DacRegs[MGA1064_CURSOR_BASE_ADR_HI] = pMga->FbCursorOffset >> 18; + + if (pMga->SyncOnGreen) { + state->DacRegs[MGA1064_GEN_CTL] &= + ~MGA1064_GEN_CTL_SYNC_ON_GREEN_DIS; + + state->ExtVga[3] |= 0x40; + } + + /* select external clock */ + vga->MiscOutReg |= 0x0C; + + if (mode->Flags & V_DBLSCAN) + vga->CRTC[9] |= 0x80; + + if (MGAISGx50(pMga)) { + OUTREG(MGAREG_ZORG, 0); + } + + MGAGSetPCLK(crtc, state, mode->Clock); + + /* This disables the VGA memory aperture */ + vga->MiscOutReg &= ~0x02; + +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* Disable byte-swapping for big-endian architectures - the XFree + driver seems to like a little-endian framebuffer -ReneR */ + /* state->Option |= 0x80000000; */ + state->Option &= ~0x80000000; +#endif +} + +/* + * This function restores a video mode. It basically writes out all of + * the registers that have previously been saved in the MgaCrtcStateRec + * data structure. + */ +static void +state_restore(xf86CrtcPtr crtc, MgaCrtcStatePtr state, + vgaRegPtr vga, int vga_flags) +{ + ScrnInfoPtr scrn = crtc->scrn; + MGAPtr pMga = MGAPTR(scrn); + CARD32 optionMask; + int i; + + /* + * Pixel Clock needs to be restored regardless if we use + * HALLib or not. HALlib doesn't do a good job restoring + * VESA modes. MATROX: hint, hint. + * + * FIXME: This seems weird. Verify. + */ + if (MGAISGx50(pMga) && state->clock) { + MGAG450SetPLLFreq(scrn, MGA_PIXEL_PLL, state->clock); + state->PIXPLLCSaved = FALSE; + } + + /* Do not set the memory config for primary cards as it + should be correct already. Only on little endian architectures + since we need to modify the byteswap bit. -ReneR */ +#if X_BYTE_ORDER == X_BIG_ENDIAN + optionMask = OPTION1_MASK; +#else + optionMask = (pMga->Primary) ? OPTION1_MASK_PRIMARY : OPTION1_MASK; +#endif + + /* + * Code is needed to get things back to bank zero. + */ + + /* restore DAC registers + * according to the docs we shouldn't write to reserved regs + */ + for (i = 0; i < sizeof(state->DacRegs); i++) { + if ((i <= 0x03) || + (i == 0x07) || + (i == 0x0b) || + (i == 0x0f) || + ((i >= 0x13) && (i <= 0x17)) || + (i == 0x1b) || + (i == 0x1c) || + ((i >= 0x1f) && (i <= 0x29)) || + ((i >= 0x30) && (i <= 0x37)) || + (MGAISGx50(pMga) && !state->PIXPLLCSaved && + ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) || + (i == 0x4c) || (i == 0x4d) || (i == 0x4e)))) + continue; + if (pMga->is_G200SE + && ((i == 0x2C) || (i == 0x2D) || (i == 0x2E))) + continue; + outMGAdac(i, state->DacRegs[i]); + } + + if (!MGAISGx50(pMga)) { + /* restore pci_option register */ + pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, optionMask, + state->Option); + + if (pMga->Chipset != PCI_CHIP_MGA1064) + pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK, + state->Option2); + + if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) + pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK, + state->Option3); + } + + /* restore CRTCEXT regs */ + for (i = 0; i < 6; i++) + OUTREG16(MGAREG_CRTCEXT_INDEX, (state->ExtVga[i] << 8) | i); + + /* This handles restoring the generic VGA registers. */ + if (pMga->is_G200SE) { + MGAG200SERestoreMode(scrn, vga); + + if (vga_flags & VGA_SR_FONTS) + MGAG200SERestoreFonts(scrn, vga); + } else + vgaHWRestore(scrn, vga, vga_flags); + + MGAGRestorePalette(scrn, vga->DAC); + + /* + * this is needed to properly restore start address + */ + OUTREG16(MGAREG_CRTCEXT_INDEX, (state->ExtVga[0] << 8) | 0); + +#ifdef DEBUG + ErrorF("Setting DAC:"); + for (i = 0; i < sizeof(state->DacRegs); i++) { +#if 1 + if(!(i%16)) ErrorF("\n%02X: ",i); + ErrorF("%02X ", mgaReg->DacRegs[i]); +#else + if(!(i%8)) ErrorF("\n%02X: ",i); + ErrorF("0x%02X, ", mgaReg->DacRegs[i]); +#endif + } + ErrorF("\nOPTION = %08lX\n", mgaReg->Option); + ErrorF("OPTION2 = %08lX\n", mgaReg->Option2); + ErrorF("CRTCEXT:"); + for (i=0; i<6; i++) ErrorF(" %02X", state->ExtVga[i]); + ErrorF("\n"); +#endif +} + +static void +state_save(xf86CrtcPtr crtc, MgaCrtcStatePtr state, int vga_flags) +{ + ScrnInfoPtr scrn = crtc->scrn; + MGAPtr pMga = MGAPTR(scrn); + vgaRegPtr vga = &VGAHWPTR(scrn)->SavedReg; + int i; + + if (MGAISGx50(pMga)) + state->clock = MGAG450SavePLLFreq(scrn, MGA_PIXEL_PLL); + + /* + * Code is needed to get back to bank zero. + */ + OUTREG16(MGAREG_CRTCEXT_INDEX, 0x0004); + + /* + * This function will handle creating the data structure and filling + * in the generic VGA portion. + */ + if (pMga->is_G200SE) { + MGAG200SESaveMode(scrn, vga); + + if (vga_flags & VGA_SR_FONTS) + MGAG200SESaveFonts(scrn, vga); + } else + vgaHWSave(scrn, vga, vga_flags); + + MGAGSavePalette(scrn, vga->DAC); + + /* + * The port I/O code necessary to read in the extended registers. + */ + for (i = 0; i < sizeof(state->DacRegs); i++) + state->DacRegs[i] = inMGAdac(i); + + state->PIXPLLCSaved = TRUE; + + state->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG); + state->Option2 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION2); + + if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) + state->Option3 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION3); + + for (i = 0; i < 6; i++) { + OUTREG8(MGAREG_CRTCEXT_INDEX, i); + state->ExtVga[i] = INREG8(MGAREG_CRTCEXT_DATA); + } + +#ifdef DEBUG + ErrorF("Saved values:\nDAC:"); + for (i = 0; i < sizeof(state->DacRegs); i++) { +#if 1 + if(!(i%16)) ErrorF("\n%02X: ",i); + ErrorF("%02X ", state->DacRegs[i]); +#else + if(!(i%8)) ErrorF("\n%02X: ",i); + ErrorF("0x%02X, ", state->DacRegs[i]); +#endif + } + + ErrorF("\nOPTION = %08lX\n:", state->Option); + ErrorF("OPTION2 = %08lX\nCRTCEXT:", state->Option2); + + for (i=0; i<6; i++) ErrorF(" %02X", state->ExtVga[i]); + ErrorF("\n"); +#endif +} + +static void +crtc_save(xf86CrtcPtr crtc) +{ + MgaCrtcDataPtr data = MGACRTCDATAPTR(crtc); + MGAPtr pMga = MGAPTR(crtc->scrn); + int vga_flags = VGA_SR_MODE; + + if (pMga->Primary) + vga_flags |= VGA_SR_FONTS; + + state_save(crtc, &data->saved_state, vga_flags); +} + +static void +crtc_restore(xf86CrtcPtr crtc) +{ + MgaCrtcDataPtr data = MGACRTCDATAPTR(crtc); + MGAPtr pMga = MGAPTR(crtc->scrn); + vgaHWPtr vga = VGAHWPTR(crtc->scrn); + int vga_flags = VGA_SR_MODE; + + if (pMga->Primary) + vga_flags |= VGA_SR_FONTS; + + state_restore(crtc, &data->saved_state, &vga->SavedReg, vga_flags); +} + +static Bool +crtc_lock(xf86CrtcPtr crtc) +{ +#ifdef XF86DRI + return MGADRILock(crtc->scrn); +#else + return FALSE; +#endif +} + +static void +crtc_unlock(xf86CrtcPtr crtc) +{ +#ifdef XF86DRI + MGADRIUnlock(crtc->scrn); +#endif +} + +static Bool +crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ + crtc->funcs->dpms(crtc, DPMSModeOff); +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjust_mode, int x, int y) +{ + MgaCrtcStateRec state; + vgaHWPtr vga = VGAHWPTR(crtc->scrn); + + memset(&state, 0, sizeof (state)); + + state_set(crtc, &state, mode, x, y); + state_restore(crtc, &state, &vga->ModeReg, VGA_SR_MODE); +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ + crtc->funcs->dpms(crtc, DPMSModeOn); +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + if (crtc->driver_private) + xfree (crtc->driver_private); +} + +Bool +MgaGCrtc1Init(ScrnInfoPtr scrn) +{ + xf86CrtcPtr crtc; + MgaCrtcDataPtr data; + + data = xnfcalloc (sizeof (MgaCrtcDataRec), 1); + if (!data) + return FALSE; + + crtc = xf86CrtcCreate (scrn, &crtc_funcs); + if (!crtc) { + xfree(data); + return FALSE; + } + + crtc->driver_private = data; + + return TRUE; +} diff --git a/src/mga_g_crtc2.c b/src/mga_g_crtc2.c new file mode 100644 index 0000000..74fc313 --- /dev/null +++ b/src/mga_g_crtc2.c @@ -0,0 +1,388 @@ +/* + * Copyright 2007 Tilman Sauerbeck + * + * 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, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them 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 MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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: + * Tilman Sauerbeck <tilman@code-monkey.de> + * Luugi Marsan + * + * Sources: + * xf86-video-intel, mga_dacG.c + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" + +/* Drivers for PCI hardware need this */ +#include "xf86PciInfo.h" + +/* Drivers that need to access the PCI config space directly need this */ +#include "xf86Pci.h" + +#include "mga_reg.h" +#include "mga.h" +#include "mga_macros.h" +#include "mga_dacG.h" + +typedef struct { + long clock; + + CARD32 c2ctl; + CARD32 c2hparam; + CARD32 c2hsync; + CARD32 c2vparam; + CARD32 c2vsync; + CARD32 c2startadd0; + CARD32 c2offset; + CARD32 c2datactl; + + /* DAC registers */ + CARD8 pwr_ctl; +} MgaCrtcState, *MgaCrtcStatePtr; + +typedef struct { + MgaCrtcState saved_state; +} MgaCrtcDataRec, *MgaCrtcDataPtr; + +static void crtc_dpms(xf86CrtcPtr crtc, int mode); +static void crtc_save(xf86CrtcPtr crtc); +static void crtc_restore(xf86CrtcPtr crtc); +static Bool crtc_lock(xf86CrtcPtr crtc); +static void crtc_unlock(xf86CrtcPtr crtc); +static Bool crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void crtc_prepare(xf86CrtcPtr crtc); +static void crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y); +static void crtc_commit(xf86CrtcPtr crtc); +static void crtc_destroy(xf86CrtcPtr crtc); + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = crtc_save, + .restore = crtc_restore, + .lock = crtc_lock, + .unlock = crtc_unlock, + .mode_fixup = crtc_mode_fixup, + .prepare = crtc_prepare, + .mode_set = crtc_mode_set, + .commit = crtc_commit, + .destroy = crtc_destroy +}; + +static void +state_set(xf86CrtcPtr crtc, MgaCrtcStatePtr state, + DisplayModePtr mode, int x, int y) +{ + MGAPtr pMga = MGAPTR(crtc->scrn); + + /* This code will only work for G450/G550, so we can just + * copy the clock. + */ + state->clock = mode->Clock; + + state->c2ctl = INREG(MGAREG_C2CTL); + state->c2ctl |= MGAREG_C2CTL_C2_EN; + + state->c2ctl &= ~MGAREG_C2CTL_CRTCDACSEL_MASK; + state->c2ctl |= MGAREG_C2CTL_CRTCDACSEL_CRTC1; + + state->c2hparam = (((mode->HDisplay - 8) << 16) | + (mode->HTotal - 8)); + state->c2hsync = (((mode->HSyncEnd - 8) << 16) | + (mode->HSyncStart - 8)); + + state->c2vparam = (((mode->VDisplay - 1) << 16) | + (mode->VTotal - 1)); + state->c2vsync = (((mode->VSyncEnd - 1) << 16) | + (mode->VSyncStart - 1)); + + state->c2startadd0 = pMga->DstOrg; + state->c2startadd0 += (y * crtc->scrn->displayWidth + x) * + crtc->scrn->bitsPerPixel / 8; + state->c2startadd0 &= 0x1ffffc0; + + state->c2offset = crtc->scrn->displayWidth; + + state->c2datactl = INREG(MGAREG_C2DATACTL); + state->c2datactl &= 0xffffff00; + + state->c2ctl &= 0xff1fffff; + + switch (crtc->scrn->bitsPerPixel) { + case 15: + state->c2ctl |= 0x200000; + state->c2offset *= 2; + break; + case 16: + state->c2ctl |= 0x400000; + state->c2offset *= 2; + break; + case 32: + state->c2ctl |= 0x800000; + state->c2offset *= 4; + } +} + +static void +state_restore(xf86CrtcPtr crtc, MgaCrtcStatePtr state) +{ + MGAPtr pMga = MGAPTR(crtc->scrn); + + if (state->clock) + MGAG450SetPLLFreq(crtc->scrn, MGA_VIDEO_PLL, state->clock); + + OUTREG(MGAREG_C2HPARAM, state->c2hparam); + OUTREG(MGAREG_C2HSYNC, state->c2hsync); + OUTREG(MGAREG_C2VPARAM, state->c2vparam); + OUTREG(MGAREG_C2VSYNC, state->c2vsync); + OUTREG(MGAREG_C2STARTADD0, state->c2startadd0); + OUTREG(MGAREG_C2OFFSET, state->c2offset); + OUTREG(MGAREG_C2DATACTL, state->c2datactl); + OUTREG(MGAREG_C2CTL, state->c2ctl); +} + +static void +state_save(xf86CrtcPtr crtc, MgaCrtcStatePtr state) +{ + state->clock = MGAG450SavePLLFreq(crtc->scrn, MGA_VIDEO_PLL); + + // output? + //state->sync_ctl = inMGAdac(MGA1064_SYNC_CTL); + + // output? + //state->pwr_ctl = inMGAdac(MGA1064_PWR_CTL); + + /* the crtc2 mode registers are read only, so we cannot + * save them here. + */ +} + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + MGAPtr pMga = MGAPTR(crtc->scrn); + CARD32 c2ctl; + CARD8 misc, gen, pwr_ctl, mask; + + if (mode == DPMSModeOn) { + /* FIXME: + * What exactly are we doing here? :) + * Not sure if this actually belongs to the DAC2 output. + * Also need to set DAC2 sync polarity (see mga_dh.c). + */ + + /* We don't use MISC synch pol, must be 0*/ + misc = inMGAdreg(MGAREG_MISC_READ); + misc &= ~MGAREG_MISC_HSYNCPOL; + misc &= ~MGAREG_MISC_VSYNCPOL; + OUTREG8(MGAREG_MISC_WRITE, misc); + + /* Set Rset to 0.7 V */ + gen = inMGAdac(MGA1064_GEN_IO_CTL); + gen &= ~0x40; + outMGAdac(MGA1064_GEN_IO_CTL, gen); + + gen = inMGAdac( MGA1064_GEN_IO_DATA); + gen &= ~0x40; + outMGAdac(MGA1064_GEN_IO_DATA, gen); + } + + c2ctl = INREG(MGAREG_C2CTL); + + if (mode == DPMSModeOn) + c2ctl &= ~MGAREG_C2CTL_PIXCLKDIS_DISABLE; + else + c2ctl |= MGAREG_C2CTL_PIXCLKDIS_DISABLE; + + OUTREG(MGAREG_C2CTL, c2ctl); + + pwr_ctl = inMGAdac(MGA1064_PWR_CTL); + + /* FIXME: + * Maybe enable VID_PLL in crtc_prepare(), since it needs to be + * enabled if we want to set the video pll m/n/p values. + */ + pwr_ctl |= MGA1064_PWR_CTL_VID_PLL_EN; + + mask = MGA1064_PWR_CTL_CFIFO_EN; + + if (mode == DPMSModeOn) + outMGAdac(MGA1064_PWR_CTL, pwr_ctl | mask); + else + outMGAdac(MGA1064_PWR_CTL, pwr_ctl & ~mask); +} + +static Bool +crtc_lock(xf86CrtcPtr crtc) +{ +#ifdef XF86DRI + return MGADRILock(crtc->scrn); +#else + return FALSE; +#endif +} + +static void +crtc_unlock(xf86CrtcPtr crtc) +{ +#ifdef XF86DRI + MGADRIUnlock(crtc->scrn); +#endif +} + +static void +crtc_save(xf86CrtcPtr crtc) +{ + MgaCrtcDataPtr data = MGACRTCDATAPTR(crtc); + + state_save(crtc, &data->saved_state); +} + +static void +crtc_restore(xf86CrtcPtr crtc) +{ +#if 0 + MGAPtr pMga = MGAPTR(crtc->scrn); + + /* since we cannot save the state in crtc_save(), we just + * return to clone mode here. + */ + + if (pMga->SecondOutput + && (xf86IsEntityShared(crtc->scrn->entityList[0]) || pMga->SecondCrtc) + && !pMga->MergedFB) { + /* Do this branch if + * SecondOutput + * and not Unshared Primary + * and not Merged Mode (usualy means Unshared Primary) + */ + CARD8 disp_ctl = inMGAdac(MGA1064_DISP_CTL); + + disp_ctl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; + disp_ctl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; + + outMGAdac(MGA1064_DISP_CTL, disp_ctl); + } else { + CARD8 disp_ctl = inMGAdac(MGA1064_DISP_CTL); + CARD32 c2ctl = INREG(MGAREG_C2CTL); + + disp_ctl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; + disp_ctl |= MGA1064_DISP_CTL_DAC1OUTSEL_EN; + disp_ctl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; + + /* crtcdacsel -> crtc1 */ + c2ctl &= ~MGAREG_C2CTL_CRTCDACSEL_CRTC2; + c2ctl |= MGAREG_C2CTL_CRTCDACSEL_CRTC1; + + outMGAdac(MGA1064_DISP_CTL, disp_ctl); + OUTREG(MGAREG_C2CTL, c2ctl); + } +#endif +} + +static Bool +crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ + MGAPtr pMga = MGAPTR(crtc->scrn); + CARD32 val; + + /* According to the docs, we should drop the _C2_EN bit + * before programming CRTC2. + */ + val = INREG(MGAREG_C2CTL); + val &= ~MGAREG_C2CTL_C2_EN; + OUTREG(MGAREG_C2CTL, val); + + /* Set CRTC2 to use the video PLL */ + val &= ~MGAREG_C2CTL_PIXCLKSEL_MASK; + val &= ~MGAREG_C2CTL_PIXCLKSELH_MASK; + val |= MGAREG_C2CTL_PIXCLKSEL_VIDEOPLL; + OUTREG(MGAREG_C2CTL, val); + + crtc->funcs->dpms(crtc, DPMSModeOff); +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + MgaCrtcState state; + + memset (&state, 0, sizeof (state)); + + state_set(crtc, &state, mode, x, y); + state_restore(crtc, &state); +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ + crtc->funcs->dpms(crtc, DPMSModeOn); + + /* We don't have to enable _C2_EN here, + * because state_restore() already did that for us. + */ +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + if (crtc->driver_private) + xfree (crtc->driver_private); +} + +Bool +MgaGCrtc2Init(ScrnInfoPtr scrn) +{ + MGAPtr pMga = MGAPTR(scrn); + xf86CrtcPtr crtc; + MgaCrtcDataPtr data; + + /* This code only works for G450/G550 */ + if (!MGAISGx50(pMga)) + return FALSE; + + data = xnfcalloc (sizeof (MgaCrtcDataRec), 1); + if (!data) + return FALSE; + + crtc = xf86CrtcCreate (scrn, &crtc_funcs); + if (!crtc) { + xfree(data); + return FALSE; + } + + crtc->driver_private = data; + + return TRUE; +} diff --git a/src/mga_g_output.c b/src/mga_g_output.c new file mode 100644 index 0000000..a5cf7e0 --- /dev/null +++ b/src/mga_g_output.c @@ -0,0 +1,526 @@ +/* + * Copyright 2007 Tilman Sauerbeck + * + * 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, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them 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 MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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: + * Tilman Sauerbeck <tilman@code-monkey.de> + * + * Sources: + * xf86-video-intel + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "xf86.h" +#include "xf86PciInfo.h" + +#include "mga_reg.h" +#include "mga.h" + +#define MGAOUTPUTDATAPTR(p) ((MgaOutputDataPtr) ((p)->driver_private)) + +typedef struct { + I2CBusPtr ddc_bus; +} MgaOutputDataRec, *MgaOutputDataPtr; + +static void output_dac1_dpms(xf86OutputPtr output, int mode); +static void output_dac2_dpms(xf86OutputPtr output, int mode); +static void output_panel1_dpms(xf86OutputPtr output, int mode); +static void output_panel2_dpms(xf86OutputPtr output, int mode); +static void output_save(xf86OutputPtr output); +static void output_restore(xf86OutputPtr output); +static void output_panel_restore(xf86OutputPtr output); +static int output_mode_valid(xf86OutputPtr output, DisplayModePtr mode); +static Bool output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_prepare(xf86OutputPtr output); +static void output_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_dac2_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_panel1_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_panel2_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode); +static void output_commit(xf86OutputPtr output); +static xf86OutputStatus output_detect(xf86OutputPtr output); +static DisplayModePtr output_get_modes(xf86OutputPtr output); +static void output_destroy(xf86OutputPtr output); + +static const xf86OutputFuncsRec output_dac1_funcs = { + .dpms = output_dac1_dpms, + .save = output_save, + .restore = output_restore, + .mode_valid = output_mode_valid, + .mode_fixup = output_mode_fixup, + .prepare = output_prepare, + .mode_set = output_mode_set, + .commit = output_commit, + .detect = output_detect, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +static const xf86OutputFuncsRec output_dac2_funcs = { + .dpms = output_dac2_dpms, + .save = output_save, + .restore = output_restore, + .mode_valid = output_mode_valid, + .mode_fixup = output_mode_fixup, + .prepare = output_prepare, + .mode_set = output_dac2_mode_set, + .commit = output_commit, + .detect = output_detect, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +static const xf86OutputFuncsRec output_panel1_funcs = { + .dpms = output_panel1_dpms, + .save = output_save, + .restore = output_panel_restore, + .mode_valid = output_mode_valid, + .mode_fixup = output_mode_fixup, + .prepare = output_prepare, + .mode_set = output_panel1_mode_set, + .commit = output_commit, + .detect = output_detect, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +static const xf86OutputFuncsRec output_panel2_funcs = { + .dpms = output_panel2_dpms, + .save = output_save, + .restore = output_panel_restore, + .mode_valid = output_mode_valid, + .mode_fixup = output_mode_fixup, + .prepare = output_prepare, + .mode_set = output_panel2_mode_set, + .commit = output_commit, + .detect = output_detect, + .get_modes = output_get_modes, + .destroy = output_destroy +}; + +static int panel_users = 0; + +static void +output_dac1_dpms(xf86OutputPtr output, int mode) +{ + /* XXX + * . Prefer an implementation that doesn't depend on VGA specifics. + * + * . This will only work for the primary output or maybe only for + * CRTC1? + */ + + MGAPtr pMga = MGAPTR(output->scrn); + CARD8 misc_ctl, disp_ctl, mask; + +#if 0 + CARD8 val, seq1, crtcext1; + + OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */ + OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */ + + seq1 = INREG8(MGAREG_SEQ_DATA); + seq1 &= ~MGAREG_SEQ1_SCREEN_OFF; + + crtcext1 = INREG8(MGAREG_CRTCEXT_DATA); + crtcext1 &= ~MGAREG_CRTCEXT1_HSYNC_OFF; + crtcext1 &= ~MGAREG_CRTCEXT1_VSYNC_OFF; + + switch (mode) { + case DPMSModeOn: + /* nothing to do */ + break; + case DPMSModeStandby: + seq1 |= MGAREG_SEQ1_SCREEN_OFF; + crtcext1 = MGAREG_CRTCEXT1_HSYNC_OFF; + break; + case DPMSModeSuspend: + seq1 |= MGAREG_SEQ1_SCREEN_OFF; + crtcext1 |= MGAREG_CRTCEXT1_VSYNC_OFF; + break; + case DPMSModeOff: + seq1 |= MGAREG_SEQ1_SCREEN_OFF; + crtcext1 |= MGAREG_CRTCEXT1_HSYNC_OFF; + crtcext1 |= MGAREG_CRTCEXT1_VSYNC_OFF; + break; + } + + MGAWAITVSYNC(); + MGAWAITBUSY(); + + OUTREG8(MGAREG_SEQ_DATA, seq1); + + usleep(20000); + + OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1); +#endif + + /* enable/disable DAC. + * + * FIXME: + * does this affect DAC2 too? + */ + misc_ctl = inMGAdac(MGA1064_MISC_CTL); + mask = MGA1064_MISC_CTL_DAC_EN; + + if (mode == DPMSModeOn) + outMGAdac(MGA1064_MISC_CTL, misc_ctl | mask); + else + outMGAdac(MGA1064_MISC_CTL, misc_ctl & ~mask); + + disp_ctl = inMGAdac(MGA1064_DISP_CTL); + mask = MGA1064_DISP_CTL_DAC1OUTSEL_EN; + + if (mode == DPMSModeOn) + outMGAdac(MGA1064_DISP_CTL, disp_ctl | mask); + else + outMGAdac(MGA1064_DISP_CTL, disp_ctl & ~mask); + +} + +static void +output_dac2_dpms(xf86OutputPtr output, int mode) +{ + MGAPtr pMga = MGAPTR(output->scrn); + CARD8 pwr_ctl, mask; + + pwr_ctl = inMGAdac(MGA1064_PWR_CTL); + + mask = MGA1064_PWR_CTL_DAC2_EN; + + /* dropping _RFIFO_EN disables both outputs, so it's probably + * owned by CRTC1. + * MGA1064_PWR_CTL_RFIFO_EN; + */ + + if (mode == DPMSModeOn) + outMGAdac(MGA1064_PWR_CTL, pwr_ctl | mask); + else + outMGAdac(MGA1064_PWR_CTL, pwr_ctl & ~mask); +} + +static void +output_panel1_dpms(xf86OutputPtr output, int mode) +{ + MGAPtr pMga = MGAPTR(output->scrn); + CARD8 pwr_ctl, mask; + + pwr_ctl = inMGAdac(MGA1064_PWR_CTL); + mask = MGA1064_PWR_CTL_PANEL_EN; + + if (mode == DPMSModeOn) { + panel_users |= 1; + outMGAdac(MGA1064_PWR_CTL, pwr_ctl | mask); + } else { + panel_users &= ~1; + + if (!panel_users) + outMGAdac(MGA1064_PWR_CTL, pwr_ctl & ~mask); + } +} + +static void +output_panel2_dpms(xf86OutputPtr output, int mode) +{ + MGAPtr pMga = MGAPTR(output->scrn); + CARD8 pwr_ctl, mask; + + pwr_ctl = inMGAdac(MGA1064_PWR_CTL); + mask = MGA1064_PWR_CTL_PANEL_EN; + + if (mode == DPMSModeOn) { + panel_users |= 2; + + outMGAdac(MGA1064_PWR_CTL, pwr_ctl | mask); + outMGAdac(MGA1064_DVI_PIPE_CTL, 0x20); + } else { + panel_users &= ~2; + + if (!panel_users) + outMGAdac(MGA1064_PWR_CTL, pwr_ctl & ~mask); + + outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0); + } +} + +static void +output_save(xf86OutputPtr output) +{ +} + +static void +output_restore(xf86OutputPtr output) +{ +} + +static void +output_panel_restore(xf86OutputPtr output) +{ + MGAPtr pMga = MGAPTR(output->scrn); + + /* Reset DUALDVI register */ + outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0); + + /* Set Panel mode between 20 and 54 MHz */ + outMGAdac(MGA1064_PAN_CTL, 0x7); +} + +static int +output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) +{ + return MODE_OK; +} + +static Bool +output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +output_prepare(xf86OutputPtr output) +{ + output->funcs->dpms(output, DPMSModeOff); +} + +static void +output_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ +} + +static void +output_dac2_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + MGAPtr pMga = MGAPTR(output->scrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(output->scrn); + CARD8 disp_ctl; + + disp_ctl = inMGAdac(MGA1064_DISP_CTL); + disp_ctl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; + + /* Is this output mapped to CRTC1? */ + if (output->crtc == config->crtc[0]) + disp_ctl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; + else + disp_ctl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC2; + + outMGAdac(MGA1064_DISP_CTL, disp_ctl); +} + +static void +output_commit(xf86OutputPtr output) +{ + output->funcs->dpms(output, DPMSModeOn); +} + +static CARD8 +get_pan_ctl_value(xf86OutputPtr output, DisplayModePtr mode) +{ + MGAPtr pMga = MGAPTR(output->scrn); + + /* these tables are based on code from matroxfb, + * used with permission by Petr Vandrovec. + */ + static int g450_thresholds[] = { + 45000, 65000, 85000, 105000, + 135000, 160000, 175000, -1 + }; + static int g550_thresholds[] = { + 45000, 55000, 70000, 85000, + 10000, 115000, 125000, -1 + }; + int *ptr = (pMga->Chipset == PCI_CHIP_MGAG550) + ? g550_thresholds : g450_thresholds; + CARD8 ret = 0; + + while (*ptr != -1 && *ptr++ < mode->Clock) + ret += 0x08; + + return ret; +} + +static void +output_panel1_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + MGAPtr pMga = MGAPTR(output->scrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(output->scrn); + CARD8 disp_ctl; + + outMGAdac(MGA1064_PAN_CTL, get_pan_ctl_value (output, mode)); + + disp_ctl = inMGAdac(MGA1064_DISP_CTL); + disp_ctl &= ~MGA1064_DISP_CTL_PANOUTSEL_MASK; + + /* Is this output mapped to CRTC1? */ + if (output->crtc == config->crtc[0]) + disp_ctl |= MGA1064_DISP_CTL_PANOUTSEL_CRTC1; + else + disp_ctl |= MGA1064_DISP_CTL_PANOUTSEL_CRTC2RGB; + + outMGAdac(MGA1064_DISP_CTL, disp_ctl); +} + +static void +output_panel2_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ +} + +static xf86OutputStatus +output_detect(xf86OutputPtr output) +{ + MgaOutputDataPtr data = MGAOUTPUTDATAPTR(output); + + /* 0xa0 is DDC EEPROM address */ + if (xf86I2CProbeAddress(data->ddc_bus, 0xa0)) + return XF86OutputStatusConnected; + else + return XF86OutputStatusUnknown; +} + +static DisplayModePtr +output_get_modes(xf86OutputPtr output) +{ + MgaOutputDataPtr data = MGAOUTPUTDATAPTR(output); + xf86MonPtr mon; + + mon = xf86OutputGetEDID(output, data->ddc_bus); + xf86OutputSetEDID(output, mon); + + return xf86OutputGetEDIDModes(output); +} + +static void +output_destroy(xf86OutputPtr output) +{ + if (output->driver_private) + xfree(output->driver_private); +} + +xf86OutputPtr +MgaGOutputDac1Init(ScrnInfoPtr scrn, Bool number) +{ + MGAPtr pMga = MGAPTR(scrn); + xf86OutputPtr output; + MgaOutputDataPtr data; + const char *name = number ? "VGA1" : "VGA"; + + data = xnfcalloc(sizeof(MgaOutputDataRec), 1); + if (!data) + return NULL; + + output = xf86OutputCreate(scrn, &output_dac1_funcs, name); + if (!output) { + xfree(data); + return NULL; + } + + output->driver_private = data; + + data->ddc_bus = pMga->DDC_Bus1; + + return output; +} + +xf86OutputPtr +MgaGOutputDac2Init(ScrnInfoPtr scrn, Bool number) +{ + MGAPtr pMga = MGAPTR(scrn); + xf86OutputPtr output; + MgaOutputDataPtr data; + const char *name = number ? "VGA2" : "VGA"; + + data = xnfcalloc(sizeof(MgaOutputDataRec), 1); + if (!data) + return NULL; + + output = xf86OutputCreate(scrn, &output_dac2_funcs, name); + if (!output) { + xfree(data); + return NULL; + } + + output->driver_private = data; + + data->ddc_bus = pMga->DDC_Bus2; + + return output; +} + +xf86OutputPtr +MgaGOutputPanel1Init(ScrnInfoPtr scrn, Bool number) +{ + MGAPtr pMga = MGAPTR(scrn); + xf86OutputPtr output; + MgaOutputDataPtr data; + const char *name = number ? "DVI1" : "DVI"; + + data = xnfcalloc(sizeof(MgaOutputDataRec), 1); + if (!data) + return NULL; + + output = xf86OutputCreate(scrn, &output_panel1_funcs, name); + if (!output) { + xfree(data); + return NULL; + } + + output->driver_private = data; + + data->ddc_bus = pMga->DDC_Bus1; + + return output; +} + +xf86OutputPtr +MgaGOutputPanel2Init(ScrnInfoPtr scrn, Bool number) +{ + MGAPtr pMga = MGAPTR(scrn); + xf86OutputPtr output; + MgaOutputDataPtr data; + const char *name = number ? "DVI2" : "DVI"; + + data = xnfcalloc(sizeof(MgaOutputDataRec), 1); + if (!data) + return NULL; + + output = xf86OutputCreate(scrn, &output_panel2_funcs, name); + if (!output) { + xfree(data); + return NULL; + } + + output->driver_private = data; + + data->ddc_bus = pMga->DDC_Bus2; + + return output; +} diff --git a/src/mga_halmod.c b/src/mga_halmod.c deleted file mode 100644 index 94e1f18..0000000 --- a/src/mga_halmod.c +++ /dev/null @@ -1,42 +0,0 @@ -/* $XFree86$ */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86Module.h" - -#ifdef XFree86LOADER - -#define HAL_MAJOR_VERSION 1 -#define HAL_MINOR_VERSION 0 -#define HAL_PATCHLEVEL 0 - -static MODULESETUPPROTO(halSetup); - -static XF86ModuleVersionInfo halVersRec = -{ - "mga_hal", - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XORG_VERSION_CURRENT, - HAL_MAJOR_VERSION, HAL_MINOR_VERSION, HAL_PATCHLEVEL, - ABI_CLASS_VIDEODRV, /* This is a video driver */ - ABI_VIDEODRV_VERSION, - MOD_CLASS_NONE, - {0,0,0,0} -}; - -/* - * This is the module init data. - * Its name has to be the driver name followed by ModuleData. - */ -_X_EXPORT XF86ModuleData mga_halModuleData = { &halVersRec, halSetup, NULL }; - -static pointer -halSetup(pointer module, pointer opts, int *errmaj, int *errmin) -{ - return (pointer)1; -} - -#endif /* XFree86LOADER */ diff --git a/src/mga_macros.h b/src/mga_macros.h index 8a3221d..404501f 100644 --- a/src/mga_macros.h +++ b/src/mga_macros.h @@ -62,24 +62,6 @@ while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ #define CHECK_DMA_QUIESCENT(pMGA, pScrn) #endif -#ifdef USEMGAHAL -#define HAL_CHIPSETS (pMga->is_HAL_chipset) - -#define MGA_HAL(x) { \ - MGAPtr pMga = MGAPTR(pScrn); \ - if (pMga->HALLoaded && HAL_CHIPSETS) { x; } \ -} -#define MGA_NOT_HAL(x) { \ - MGAPtr pMga = MGAPTR(pScrn); \ - if (!pMga->HALLoaded || !HAL_CHIPSETS) { x; } \ -} -#else -#define MGA_NOT_HAL(x) { x; } -#endif - #define MGAISGx50(x) ((x)->is_Gx50) -#define MGA_DH_NEEDS_HAL(x) (((x)->Chipset == PCI_CHIP_MGAG400) && \ - ((x)->ChipRev < 0x80)) - #endif /* _MGA_MACROS_H_ */ diff --git a/src/mga_merge.c b/src/mga_merge.c deleted file mode 100644 index aa14dbe..0000000 --- a/src/mga_merge.c +++ /dev/null @@ -1,975 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_merge.c,v 1.4 2003/09/24 02:43:24 dawes Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* All drivers should typically include these */ -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86Resources.h" - -/* All drivers need this */ - -#include "compiler.h" - -/* Drivers for PCI hardware need this */ -#include "xf86PciInfo.h" -#include "mga.h" -#include "mga_macros.h" -#include "mga_reg.h" -#include "mga_merge.h" - -#include "fbdevhw.h" - -static int -StrToRanges(range* r, char* s) { - float num=0.0; - int rangenum=0; - Bool gotdash = FALSE; - Bool nextdash = FALSE; - char* strnum=NULL; - do { - switch(*s) { - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '.': - if(strnum == NULL) { - strnum = s; - gotdash = nextdash; - nextdash = FALSE; - } - - break; - case '-': - case ' ': case 0: - if(strnum == NULL) break; /*is extra seperator */ - if(strnum != NULL) sscanf(strnum,"%f",&num); - if(gotdash) /*if wasn't singlet: correct. */ - r[rangenum-1].hi = num; - else { /*first, assume singlet */ - r[rangenum].lo = num; - r[rangenum].hi = num; - rangenum++; - } - strnum = NULL; - if(*s == '-') - nextdash = (rangenum != 0); /*ignore dash if before any number.*/ - break; - default : - return 0; - } - } while(*(s++) != 0); /* run loop for every char including null terminator.*/ - - return rangenum; -} - - -/* Copys mode i, links the result to dest, and returns it. - * Links i and j in Private record. - * if dest is NULL, return value is copy of i linked to itself. - */ -static DisplayModePtr -CopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest, DisplayModePtr i, DisplayModePtr j, MgaScrn2Rel srel) { - DisplayModePtr mode; - int dx = 0,dy = 0; - /* start with first node */ - mode = xalloc(sizeof(DisplayModeRec)); - memcpy(mode,i, sizeof(DisplayModeRec)); - mode->Private = xalloc(sizeof(MergedDisplayModeRec)); - ((MergedDisplayModePtr)mode->Private)->Monitor1 = i; - ((MergedDisplayModePtr)mode->Private)->Monitor2 = j; - ((MergedDisplayModePtr)mode->Private)->Monitor2Pos = srel; - mode->PrivSize = 0; - - switch(srel) { - case mgaLeftOf: - case mgaRightOf: - dx = min(pScrn->virtualX,i->HDisplay + j->HDisplay) - mode->HDisplay; - dy = min(pScrn->virtualY, max(i->VDisplay,j->VDisplay)) - mode->VDisplay; - break; - case mgaAbove: - case mgaBelow: - dy = min(pScrn->virtualY,i->VDisplay + j->VDisplay) - mode->VDisplay; - dx = min(pScrn->virtualX, max(i->HDisplay,j->HDisplay)) - mode->HDisplay; - break; - case mgaClone: - dx = min(pScrn->virtualX, max(i->HDisplay,j->HDisplay)) - mode->HDisplay; - dy = min(pScrn->virtualY, max(i->VDisplay,j->VDisplay)) - mode->VDisplay; - break; - } - mode->HDisplay += dx; - mode->HSyncStart += dx; - mode->HSyncEnd += dx; - mode->HTotal += dx; - mode->VDisplay += dy; - mode->VSyncStart += dy; - mode->VSyncEnd += dy; - mode->VTotal += dy; - mode->Clock = 0; /* Shows we're in Merge mode. */ - - mode->next = mode; - mode->prev = mode; - - if(dest) { - /* Insert node after "dest" */ - mode->next = dest->next; - dest->next->prev = mode; - mode->prev = dest; - dest->next = mode; - } - - return mode; -} - -static DisplayModePtr -GetModeFromName(char* str, DisplayModePtr i) -{ - DisplayModePtr c = i; - if(!i) return NULL; - do { - if(strcmp(str,c->name) == 0) return c; - c = c->next; - } while(c != i); - return NULL; -} - -/* takes a config file string of MetaModes and generates a MetaModeList */ -static DisplayModePtr -GenerateModeList(ScrnInfoPtr pScrn, char* str, - DisplayModePtr i, DisplayModePtr j, MgaScrn2Rel srel) { - char* strmode = str; - char modename[256]; - Bool gotdash = FALSE; - MgaScrn2Rel sr; - - DisplayModePtr mode1 = NULL; - DisplayModePtr mode2 = NULL; - DisplayModePtr result = NULL; - do { - switch(*str) { - case 0: - case '-': - case ' ': - case ',': - case ';': - if((strmode != str)) {/*we got a mode */ - /* read new entry */ - strncpy(modename,strmode,str - strmode); - modename[str - strmode] = 0; - - if(gotdash) { - if(mode1 == NULL) return NULL; - mode2 = GetModeFromName(modename,j); - if(!mode2) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Mode: \"%s\" is not a supported mode for monitor 2\n",modename); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Skipping metamode \"%s-%s\".\n",mode1->name,modename); - mode1 = NULL; - } - } else { - mode1 = GetModeFromName(modename,i); - if(!mode1) { - char* tmps = str; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Mode: \"%s\" is not a supported mode for monitor 1\n",modename); - /* find if a monitor2 mode follows */ - gotdash = FALSE; - while(*tmps == ' ' || *tmps == ';') tmps++; - if(*tmps == '-' || *tmps == ',') { /* skip the next mode */ - tmps++; - while(*tmps == ' ' || *tmps == ';') tmps++; /*skip spaces */ - while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != ',') tmps++; /*skip modename */ - /* for error message */ - strncpy(modename,strmode,tmps - strmode); - modename[tmps - strmode] = 0; - str = tmps-1; - } - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Skipping metamode \"%s\".\n",modename); - mode1 = NULL; - } - } - gotdash = FALSE; - } - strmode = str+1; /* number starts on next char */ - gotdash |= (*str == '-' || *str == ','); - - if(*str != 0) break; /* if end of string, we wont get a chance to catch a char and run the - default case. do it now */ - - default: - if(!gotdash && mode1) { /* complete previous pair */ - sr = srel; - if(!mode2) { - mode2 = GetModeFromName(mode1->name,j); - sr = mgaClone; - } - if(!mode2) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Mode: \"%s\" is not a supported mode for monitor 2\n",mode1->name); - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Skipping clone mode \"%s\".\n", mode1->name); - mode1 = NULL; - } else { - result = CopyModeNLink(pScrn,result,mode1,mode2,sr); - mode1 = NULL; - mode2 = NULL; - } - } - break; - - } - } while(*(str++) != 0); - return result; -} - - -/* second CRTC init funcitons. Used to check monitor timings and refreshes. - * this function looses lots of maintainability points due to redundancy, - * but it still was the cleanest and least-intrusive way I found. */ - -Bool -MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags) -{ - ScrnInfoPtr pScrn; - MGAPtr pMga; - MGAPtr pMga1; - MessageType from; - int i; - char* s; - ClockRangePtr clockRanges; -#ifdef USEMGAHAL - ULONG status; -#endif - MgaScrn2Rel Monitor2Pos; - - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, "==== Start of second screen initialization ====\n"); - pScrn = xalloc(sizeof(ScrnInfoRec)); - memcpy(pScrn,pScrn1,sizeof(ScrnInfoRec)); - - pScrn->driverPrivate = NULL; - /* Allocate the MGARec driverPrivate */ - if (!MGAGetRec(pScrn)) { - return FALSE; - } - - pMga = MGAPTR(pScrn); -#ifdef USEMGAHAL - pMga->pMgaModeInfo = NULL; /*will be allocated later if NULL*/ -#endif - pMga1 = MGAPTR(pScrn1); - pMga1->pScrn2 = pScrn; - - /* Get the entity, and make sure it is PCI. */ - pMga->pEnt = pMga1->pEnt; - - /* Set pMga->device to the relevant Device section */ - pMga->device = pMga1->device; - - if (flags & PROBE_DETECT) { - MGAProbeDDC(pScrn, pMga->pEnt->index); /*FIXME make shure this probes second monitor */ - return TRUE; - } - - pMga->PciTag = pMga1->PciTag; - - pMga->Primary = pMga1->Primary; - - /* Set pScrn->monitor */ - { - pScrn->monitor = xalloc(sizeof(MonRec)); - /* copy everything we don't care about */ - memcpy(pScrn->monitor,pScrn1->monitor,sizeof(MonRec)); - pScrn->monitor->DDC = NULL; /*FIXME:have to try this */ - if ((s = xf86GetOptValString(pMga1->Options, OPTION_HSYNC2))) { - pScrn->monitor->nHsync = StrToRanges(pScrn->monitor->hsync,s); - } - if ((s = xf86GetOptValString(pMga1->Options, OPTION_VREFRESH2))) { - pScrn->monitor->nVrefresh = StrToRanges(pScrn->monitor->vrefresh,s); - } - - - - } - - pMga->SecondCrtc = TRUE; - pMga->HWCursor = FALSE; - pScrn->AdjustFrame = MGAAdjustMergeFrames; - pScrn1->AdjustFrame = MGAAdjustMergeFrames; - -/* if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) FIXME:have to copy result form scrn1 - if (!xf86SetWeight(pScrn, zeros, zeros)) { -*/ - - /* We use a programamble clock */ - pScrn->progClock = TRUE; - - /* Collect all of the relevant option flags (fill in pScrn->options) */ - pScrn->options = pScrn1->options; - -/* xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pMga->Options);*/ - pMga->Options = pMga1->Options; - - - /* Set the bits per RGB for 8bpp mode */ - if (pScrn->depth == 8) - pScrn->rgbBits = 8; - - /* - * Set the Chipset and ChipRev, allowing config file entries to - * override. - */ - pScrn->chipset = pScrn1->chipset; - pMga->Chipset = pMga1->Chipset; - pMga->ChipRev = pMga1->ChipRev; - -#ifdef XF86DRI - pMga->agpMode = pMga1->agpMode; -#endif - - pMga->NoAccel = pMga1->NoAccel; - pMga->UsePCIRetry = pMga1->UsePCIRetry; - pMga->SyncOnGreen = pMga1->SyncOnGreen; - pMga->ShowCache = pMga1->ShowCache; - pMga->HasSDRAM = pMga1->HasSDRAM; - pMga->MemClk = pMga1->MemClk; - pMga->Overlay8Plus24 = pMga1->Overlay8Plus24; - pMga->colorKey = pMga1->colorKey; - pScrn->colorKey = pScrn1->colorKey; - pScrn->overlayFlags = pScrn1->overlayFlags; - pMga->videoKey = pMga1->videoKey; - /* unsupported options */ - pMga->HWCursor = FALSE; - pMga->ShadowFB = FALSE; - pMga->FBDev = FALSE; - - pMga->OverclockMem = pMga1->OverclockMem; - pMga->TexturedVideo = pMga1->TexturedVideo; - pMga->MergedFB = TRUE; - - pMga->Rotate = 0; - - switch (pMga->Chipset) { - case PCI_CHIP_MGA2064: - case PCI_CHIP_MGA2164: - case PCI_CHIP_MGA2164_AGP: - MGA2064SetupFuncs(pScrn); - break; - case PCI_CHIP_MGA1064: - case PCI_CHIP_MGAG100: - case PCI_CHIP_MGAG100_PCI: - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: - MGAGSetupFuncs(pScrn); - break; - } - - pMga->FbAddress = pMga1->FbAddress; - pMga->FbBaseReg = pMga1->FbBaseReg; - pMga->PciInfo = pMga1->PciInfo; - pMga->IOAddress = pMga1->IOAddress; - pMga->ILOADAddress = pMga1->ILOADAddress; - pMga->BiosFrom = pMga1->BiosFrom; - pMga->BiosAddress = pMga1->BiosAddress; - - /* - * Read the BIOS data struct - */ - - mga_read_and_process_bios( pScrn ); - - /* HW bpp matches reported bpp */ - pMga->HwBpp = pMga1->HwBpp; - - /* - * Reset card if it isn't primary one - */ - if ( (!pMga->Primary && !pMga->FBDev) || xf86IsPc98() ) - MGASoftReset(pScrn); - - - pScrn->videoRam = pScrn1->videoRam; - pMga->FbMapSize = pMga1->FbMapSize; - pMga->SrcOrg = pMga1->SrcOrg; - pMga->DstOrg = pMga1->DstOrg; - - /* Set the bpp shift value */ - pMga->BppShifts[0] = 0; - pMga->BppShifts[1] = 1; - pMga->BppShifts[2] = 0; - pMga->BppShifts[3] = 2; - - /* - * fill MGAdac struct - * Warning: currently, it should be after RAM counting - */ - (*pMga->PreInit)(pScrn); - -#if !defined(__powerpc__) - - /* Read and print the Monitor DDC info */ -/* pScrn->monitor->DDC = MGAdoDDC(pScrn);*/ /*FIXME: have to try this*/ -#endif /* !__powerpc__ */ - - /* - * If the driver can do gamma correction, it should call xf86SetGamma() - * here. - */ - { - Gamma zeros = {0.0, 0.0, 0.0}; - - if (!xf86SetGamma(pScrn, zeros)) { - return FALSE; - } - } - - - /* Set the min pixel clock */ - pMga->MinClock = pMga1->MinClock; /* XXX Guess, need to check this */ - xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "CRTC2: Min pixel clock is %d MHz\n", - pMga->MinClock / 1000); - /* Override on 2nd crtc */ - - if (pMga->ChipRev >= 0x80 || (pMga->Chipset == PCI_CHIP_MGAG550)) { - /* G450, G550 */ - pMga->MaxClock = 234000; - } else { - pMga->MaxClock = 135000; - } - xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "CRTC2: Max pixel clock is %d MHz\n", - pMga->MaxClock / 1000); - /* - * Setup the ClockRanges, which describe what clock ranges are available, - * and what sort of modes they can be used for. - */ - clockRanges = xnfcalloc(sizeof(ClockRange), 1); - clockRanges->next = NULL; - clockRanges->minClock = pMga->MinClock; - clockRanges->maxClock = pMga->MaxClock; - clockRanges->clockIndex = -1; /* programmable */ - clockRanges->interlaceAllowed = TRUE; - clockRanges->doubleScanAllowed = TRUE; -#ifdef USEMGAHAL - MGA_HAL(clockRanges->interlaceAllowed = FALSE); - MGA_HAL(clockRanges->doubleScanAllowed = FALSE); -#endif - clockRanges->interlaceAllowed = FALSE; /*no interlace on CRTC2 */ - - clockRanges->ClockMulFactor = 1; - clockRanges->ClockDivFactor = 1; - /* Only set MemClk if appropriate for the ramdac */ - if (pMga->Dac.SetMemClk) { - if (pMga->MemClk == 0) { - pMga->MemClk = pMga->Dac.MemoryClock; - from = pMga->Dac.MemClkFrom; - } else - from = X_CONFIG; - xf86DrvMsg(pScrn->scrnIndex, from, "CRTC2: MCLK used is %.1f MHz\n", - pMga->MemClk / 1000.0); - } - - /* - * xf86ValidateModes will check that the mode HTotal and VTotal values - * don't exceed the chipset's limit if pScrn->maxHValue and - * pScrn->maxVValue are set. Since our MGAValidMode() already takes - * care of this, we don't worry about setting them here. - */ - { - int Pitches1[] = - {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0}; - int Pitches2[] = - {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664, - 1920, 2048, 0}; - int *linePitches = NULL; - int minPitch = 256; - int maxPitch = 2048; - - switch(pMga->Chipset) { - case PCI_CHIP_MGA2064: - if (!pMga->NoAccel) { - linePitches = xalloc(sizeof(Pitches1)); - memcpy(linePitches, Pitches1, sizeof(Pitches1)); - minPitch = maxPitch = 0; - } - break; - case PCI_CHIP_MGA2164: - case PCI_CHIP_MGA2164_AGP: - case PCI_CHIP_MGA1064: - if (!pMga->NoAccel) { - linePitches = xalloc(sizeof(Pitches2)); - memcpy(linePitches, Pitches2, sizeof(Pitches2)); - minPitch = maxPitch = 0; - } - break; - case PCI_CHIP_MGAG100: - case PCI_CHIP_MGAG100_PCI: - maxPitch = 2048; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - case PCI_CHIP_MGAG200_SE_A_PCI: - case PCI_CHIP_MGAG200_SE_B_PCI: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: - maxPitch = 4096; - break; - } - - pScrn->modePool=NULL; - pScrn->modes = NULL; - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, - pScrn->display->modes, clockRanges, - linePitches, minPitch, maxPitch, - pMga->Roundings[(pScrn->bitsPerPixel >> 3) - 1] * - pScrn->bitsPerPixel, 128, 2048, - pScrn->display->virtualX, - pScrn->display->virtualY, - pMga->FbMapSize, - LOOKUP_BEST_REFRESH); - - if (linePitches) - xfree(linePitches); - } - - - if (i < 1 && pMga->FBDev) { - fbdevHWUseBuildinMode(pScrn); - pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ - i = 1; - } - if (i == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "CRTC2: Validate Modes Failed\n"); - MGAFreeRec(pScrn); - return FALSE; - } - - /* Prune the modes marked as invalid */ - xf86PruneDriverModes(pScrn); - - if (i == 0 || pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "CRTC2: No valid modes found\n"); - MGAFreeRec(pScrn); - return FALSE; - } -#ifdef USEMGAHAL - MGA_HAL( - - pMga->pBoard = pMga1->pBoard; - pMga->pClientStruct = pMga1->pClientStruct; - pMga->pMgaHwInfo = pMga1->pMgaHwInfo; - - - MGAFillModeInfoStruct(pScrn,NULL); - /* Fields usually handled by MGAFillModeInfoStruct, but are unavailable - * because no mode is given - */ - pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX; - pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY; - - if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MGAValidateMode from HALlib found the mode to be invalid.\n" - "\tError: 0x%lx\n", status); - return FALSE; - } - pScrn->displayWidth = pMga->pMgaModeInfo->ulFBPitch; - ); /* MGA_HAL */ -#endif - - /* - * Set the CRTC parameters for all of the modes based on the type - * of mode, and the chipset's interlace requirements. - * - * Calling this is required if the mode->Crtc* values are used by the - * driver and if the driver doesn't provide code to set them. They - * are not pre-initialised at all. - */ -#ifdef USEMGAHAL - MGA_HAL(xf86SetCrtcForModes(pScrn, 0)); -#endif - MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V)); - - /* Set the current mode to the first in the list */ - pScrn->currentMode = pScrn->modes; - - /* Print the list of modes being used */ - xf86PrintModes(pScrn); - - /* Set display resolution */ - xf86SetDpi(pScrn, 0, 0); - - /* - * Compute the byte offset into the linear frame buffer where the - * frame buffer data should actually begin. According to DDK misc.c - * line 1023, if more than 4MB is to be displayed, YDSTORG must be set - * appropriately to align memory bank switching, and this requires a - * corresponding offset on linear frame buffer access. - * This is only needed for WRAM. - */ - - pMga->YDstOrg = pMga1->YDstOrg; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "CRTC2: YDstOrg is set to %d\n", - pMga->YDstOrg); - pMga->FbUsableSize = pMga1->FbUsableSize; - pMga->FbCursorOffset = pMga1->FbCursorOffset; - - pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; - pMga->CurrentLayout.depth = pScrn->depth; - pMga->CurrentLayout.displayWidth = pScrn->displayWidth; - pMga->CurrentLayout.weight.red = pScrn->weight.red; - pMga->CurrentLayout.weight.green = pScrn->weight.green; - pMga->CurrentLayout.weight.blue = pScrn->weight.blue; - pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24; - pMga->CurrentLayout.mode = pScrn->currentMode; - - - Monitor2Pos = mgaRightOf; - if ((s = xf86GetOptValString(pMga1->Options, OPTION_MONITOR2POS))) { - switch(s[0]) { - case 'L': case 'l': case 'G': case 'g': - Monitor2Pos = mgaLeftOf; - break; - case 'R': case 'r': case 'D': case 'd': - Monitor2Pos = mgaRightOf; - break; - - case 'A': case 'a': case 'H': case 'h': - Monitor2Pos = mgaAbove; - break; - - case 'B': case 'b': - Monitor2Pos = mgaBelow; - break; - - case 'C': case 'c': - Monitor2Pos = mgaClone; - break; - default: - Monitor2Pos = mgaRightOf; - break; - } - } - - /* Fool xf86 into thinking we have huge modes */ - /* Keep the original values somewhere */ - pMga1->M1modes = pScrn1->modes; - pMga1->M1currentMode = pScrn1->currentMode; - /* make a copy of the mode list, so we can modify it. */ - if ((s = xf86GetOptValString(pMga1->Options, OPTION_METAMODES))) { - pScrn1->modes = GenerateModeList(pScrn,s,pMga1->M1modes,pScrn->modes,Monitor2Pos); /*FIXME: free this list*/ - if(!pScrn1->modes) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Parse Error reading MetaModes, or No modes left.\n"); - return FALSE; - } - - pScrn1->modes = pScrn1->modes->next; - pScrn1->currentMode = pScrn1->modes; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MetaModes option missing.\n"); - return FALSE; - } - xf86DrvMsg(pScrn1->scrnIndex, X_INFO, "==== End of second screen initialization ====\n"); - return TRUE; -} - -void -MGADisplayPowerManagementSetMerged(ScrnInfoPtr pScrn, int PowerManagementMode, - int flags) -{ - MGADisplayPowerManagementSet(pScrn,PowerManagementMode,flags); - MGADisplayPowerManagementSetCrtc2(pScrn,PowerManagementMode,flags); -} - -typedef struct _region { - int x0,x1,y0,y1; - } region; - -static Bool -InRegion(int x, int y, region r) { - return (r.x0 <= x) && (x < r.x1) && (r.y0 <= y) && (y < r.y1); -} - - -#define BOUND(test,low,hi) { \ - if(test < low) test = low; \ - if(test > hi) test = hi; } -#define REBOUND(low,hi,test) { \ - if(test < low) { \ - hi += test-low; \ - low = test; } \ - if(test > hi) { \ - low += test-hi; \ - hi = test; } } - void -MGAMergePointerMoved(int scrnIndex, int x, int y) -{ - ScrnInfoPtr pScr = xf86Screens[scrnIndex]; - MGAPtr pMga = MGAPTR(pScr); - ScrnInfoPtr pScr2 = pMga->pScrn2; - - region out,in1,in2,f2,f1; - - int deltax,deltay; - - /* for ease. */ - f1.x0 = pMga->M1frameX0; - f1.x1 = pMga->M1frameX1+1; - f1.y0 = pMga->M1frameY0; - f1.y1 = pMga->M1frameY1+1; - f2.x0 = pScr2->frameX0; - f2.x1 = pScr2->frameX1+1; - f2.y0 = pScr2->frameY0; - f2.y1 = pScr2->frameY1+1; - - - /*specify outer clipping region. crossing this causes all frames to move*/ - out.x0 = pScr->frameX0; - out.x1 = pScr->frameX1+1; - out.y0 = pScr->frameY0; - out.y1 = pScr->frameY1+1; - - /* - * specify inner sliding window. beeing outsize both frames, and inside - * the outer cliping window, causes corresponding frame to slide - */ - in1 = out; - in2 = out; - switch(((MergedDisplayModePtr)pScr->currentMode->Private)->Monitor2Pos) { - case mgaLeftOf : - in1.x0 = f1.x0; - in2.x1 = f2.x1; - break; - case mgaRightOf : - in1.x1 = f1.x1; - in2.x0 = f2.x0; - break; - case mgaBelow : - in1.y1 = f1.y1; - in2.y0 = f2.y0; - break; - case mgaAbove : - in1.y0 = f1.y0; - in2.y1 = f2.y1; - break; - case mgaClone : - break; - } - - - deltay = 0; - deltax = 0; - - if(InRegion(x,y,out)) { - if( InRegion(x,y, in1) && !InRegion(x,y, f1) ) { - REBOUND(f1.x0,f1.x1,x); - REBOUND(f1.y0,f1.y1,y); - deltax = 1; /*force frame update */ - } - if( InRegion(x,y, in2) && !InRegion(x,y, f2) ) { - REBOUND(f2.x0,f2.x1,x); - REBOUND(f2.y0,f2.y1,y); - deltax = 1; /*force frame update */ - } - } - else { /*outside outer clipping region*/ - if ( out.x0 > x) { - deltax = x - out.x0; - } - if ( out.x1 < x) { - deltax = x - out.x1; - } - f1.x0 += deltax; - f1.x1 += deltax; - f2.x0 += deltax; - f2.x1 += deltax; - pScr->frameX0 += deltax; - pScr->frameX1 += deltax; - - - if ( out.y0 > y) { - deltay = y - out.y0; - } - if ( out.y1 < y) { - deltay = y - out.y1; - } - f1.y0 += deltay; - f1.y1 += deltay; - f2.y0 += deltay; - f2.y1 += deltay; - pScr->frameY0 += deltay; - pScr->frameY1 += deltay; - } - - - if (deltax != 0 || deltay != 0) { - /* back to reality. */ - pMga->M1frameX0 = f1.x0; - pMga->M1frameY0 = f1.y0; - pScr2->frameX0 = f2.x0; - pScr2->frameY0 = f2.y0; - - /*Adjust Granularity */ - MGAAdjustGranularity(pScr,&pMga->M1frameX0,&pMga->M1frameY0); - MGAAdjustGranularity(pScr,&pScr2->frameX0,&pScr2->frameY0); - MGAAdjustGranularity(pScr,&pScr->frameX0,&pScr->frameY0); - - pMga->M1frameX1 = pMga->M1frameX0 + MDMPTR(pScr)->Monitor1->HDisplay -1; - pMga->M1frameY1 = pMga->M1frameY0 + MDMPTR(pScr)->Monitor1->VDisplay -1; - pScr2->frameX1 = pScr2->frameX0 + MDMPTR(pScr)->Monitor2->HDisplay -1; - pScr2->frameY1 = pScr2->frameY0 + MDMPTR(pScr)->Monitor2->VDisplay -1; - pScr->frameX1 = pScr->frameX0 + pScr->currentMode->HDisplay -1; - pScr->frameY1 = pScr->frameY0 + pScr->currentMode->VDisplay -1; - - MGAAdjustFrame(pScr->scrnIndex, pMga->M1frameX0, pMga->M1frameY0, 0); - MGAAdjustFrameCrtc2(pScr->scrnIndex, pScr2->frameX0, pScr2->frameY0, 0); - } - -/* if(pMga->PointerMoved) - (*pMga->PointerMoved)(scrnIndex, x, y); FIXME: do I need to call old func?*/ - -} - - -void -MGAAdjustMergeFrames(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - MGAPtr pMga = MGAPTR(pScrn1); - ScrnInfoPtr pScrn2 = pMga->pScrn2; - int VTotal = pScrn1->currentMode->VDisplay; - int HTotal = pScrn1->currentMode->HDisplay; - int VMax = VTotal; - int HMax = HTotal; - - BOUND(x,0,pScrn1->virtualX-HTotal); - BOUND(y,0,pScrn1->virtualY-VTotal); - switch(MDMPTR(pScrn1)->Monitor2Pos) { - case mgaLeftOf: - pScrn2->frameX0 = x; - BOUND(pScrn2->frameY0,y,y + VMax - MDMPTR(pScrn1)->Monitor2->VDisplay); - pMga->M1frameX0 = x+MDMPTR(pScrn1)->Monitor2->HDisplay; - BOUND(pMga->M1frameY0,y,y + VMax - MDMPTR(pScrn1)->Monitor1->VDisplay); - break; - case mgaRightOf: - pMga->M1frameX0 = x; - BOUND(pMga->M1frameY0,y,y + VMax - MDMPTR(pScrn1)->Monitor1->VDisplay); - pScrn2->frameX0 = x+MDMPTR(pScrn1)->Monitor1->HDisplay; - BOUND(pScrn2->frameY0,y,y + VMax - MDMPTR(pScrn1)->Monitor2->VDisplay); - break; - case mgaAbove: - BOUND(pScrn2->frameX0,x,x + HMax - MDMPTR(pScrn1)->Monitor2->HDisplay); - pScrn2->frameY0 = y; - BOUND(pMga->M1frameX0,x,x + HMax - MDMPTR(pScrn1)->Monitor1->HDisplay); - pMga->M1frameY0 = y+MDMPTR(pScrn1)->Monitor2->VDisplay; - break; - case mgaBelow: - BOUND(pMga->M1frameX0,x,x + HMax - MDMPTR(pScrn1)->Monitor1->HDisplay); - pMga->M1frameY0 = y; - BOUND(pScrn2->frameX0,x,x + HMax - MDMPTR(pScrn1)->Monitor2->HDisplay); - pScrn2->frameY0 = y+MDMPTR(pScrn1)->Monitor1->VDisplay; - break; - case mgaClone: - BOUND(pMga->M1frameX0,x,x + HMax - MDMPTR(pScrn1)->Monitor1->HDisplay); - BOUND(pMga->M1frameY0,y,y + VMax - MDMPTR(pScrn1)->Monitor1->VDisplay); - BOUND(pScrn2->frameX0,x,x + HMax - MDMPTR(pScrn1)->Monitor2->HDisplay); - BOUND(pScrn2->frameY0,y,y + VMax - MDMPTR(pScrn1)->Monitor2->VDisplay); - break; - } - /* sanity checks. Make shure were not out of bounds */ - BOUND(pMga->M1frameX0,0,pScrn1->virtualX -MDMPTR(pScrn1)->Monitor1->HDisplay); - BOUND(pMga->M1frameY0,0,pScrn1->virtualY -MDMPTR(pScrn1)->Monitor1->VDisplay); - BOUND(pScrn2->frameX0,0,pScrn2->virtualX -MDMPTR(pScrn1)->Monitor2->HDisplay); - BOUND(pScrn2->frameY0,0,pScrn2->virtualY -MDMPTR(pScrn1)->Monitor2->VDisplay); - - pScrn1->frameX0 = x; - pScrn1->frameY0 = y; - - /* check granularity */ - MGAAdjustGranularity(pScrn1,&pMga->M1frameX0,&pMga->M1frameY0); - MGAAdjustGranularity(pScrn1,&pScrn2->frameX0,&pScrn2->frameY0); - MGAAdjustGranularity(pScrn1,&pScrn1->frameX0,&pScrn1->frameY0); - - /* complete shitty redundant info */ - pMga->M1frameX1 = pMga->M1frameX0 + MDMPTR(pScrn1)->Monitor1->HDisplay -1; - pMga->M1frameY1 = pMga->M1frameY0 + MDMPTR(pScrn1)->Monitor1->VDisplay -1; - pScrn2->frameX1 = pScrn2->frameX0 + MDMPTR(pScrn1)->Monitor2->HDisplay -1; - pScrn2->frameY1 = pScrn2->frameY0 + MDMPTR(pScrn1)->Monitor2->VDisplay -1; - pScrn1->frameX1 = pScrn1->frameX0 + pScrn1->currentMode->HDisplay -1; - pScrn1->frameY1 = pScrn1->frameY0 + pScrn1->currentMode->VDisplay -1; - - MGAAdjustFrame(scrnIndex, pMga->M1frameX0, pMga->M1frameY0, flags); - MGAAdjustFrameCrtc2(scrnIndex, pScrn2->frameX0, pScrn2->frameY0, flags); - return; -} - -Bool -MGACloseScreenMerged(int scrnIndex, ScreenPtr pScreen) { - ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; - MGAPtr pMga = MGAPTR(pScrn1); - ScrnInfoPtr pScrn2 = pMga->pScrn2; - - if(pScrn2) { - xfree(pScrn2->monitor); - pScrn2->monitor = NULL; - - xfree(pScrn2); - pMga->pScrn2 = NULL; - } - - if(pScrn1->modes) { - pScrn1->currentMode = pScrn1->modes; - do { - DisplayModePtr p = pScrn1->currentMode->next; - if(pScrn1->currentMode->Private) - xfree(pScrn1->currentMode->Private); - xfree(pScrn1->currentMode); - pScrn1->currentMode = p; - }while( pScrn1->currentMode != pScrn1->modes); - } - - pScrn1->currentMode = pMga->M1currentMode; - pScrn1->modes = pMga->M1modes; - - return TRUE; -} - -Bool -MGASaveScreenMerged(ScreenPtr pScreen, int mode) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - MGAPtr pMga = MGAPTR(pScrn); - BOOL on = xf86IsUnblank(mode); - CARD8 reg; - - if (on) { -/* SetTimdeSinceLastInputEvent();*/ - - /* power on Dac1 */ - reg = inMGAdac(MGA1064_MISC_CTL); - reg |= MGA1064_MISC_CTL_DAC_EN; - outMGAdac(MGA1064_MISC_CTL, reg); - - /* power on Dac2 */ - reg = inMGAdac(MGA1064_PWR_CTL); - reg |= MGA1064_PWR_CTL_DAC2_EN; - outMGAdac(MGA1064_PWR_CTL, reg); - } else { - /* power off Dac1 */ - reg = inMGAdac(MGA1064_MISC_CTL); - reg &= ~MGA1064_MISC_CTL_DAC_EN; - outMGAdac(MGA1064_MISC_CTL, reg); - - /* power off Dac2 */ - reg = inMGAdac(MGA1064_PWR_CTL); - reg &= ~MGA1064_PWR_CTL_DAC2_EN; - outMGAdac(MGA1064_PWR_CTL, reg); - } - - return TRUE; -} - - diff --git a/src/mga_merge.h b/src/mga_merge.h deleted file mode 100644 index f823b23..0000000 --- a/src/mga_merge.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Merged mode stuff */ -/* include file for mga_driver.c DO NOT try to generate a .o with this file.*/ - -void MGADisplayPowerManagementSetMerged(ScrnInfoPtr pScrn, - int PowerManagementMode, - int flags); -void MGAMergePointerMoved(int scrnIndex, int x, int y); -void MGAAdjustMergeFrames(int scrnIndex, int x, int y, int flags); -Bool MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags); -Bool MGACloseScreenMerged(int scrnIndex, ScreenPtr pScreen); -Bool MGASaveScreenMerged(ScreenPtr pScreen, int mode); - -typedef struct _MergedDisplayModeRec { - DisplayModePtr Monitor1; - DisplayModePtr Monitor2; - MgaScrn2Rel Monitor2Pos; -} MergedDisplayModeRec, *MergedDisplayModePtr; - -#define MDMPTR(x) ((MergedDisplayModePtr)(x->currentMode->Private)) diff --git a/src/mga_reg.h b/src/mga_reg.h index 020bb0d..a78de35 100644 --- a/src/mga_reg.h +++ b/src/mga_reg.h @@ -219,8 +219,12 @@ #define MGADWG_PATTERN ( 0x01 << 29 ) #define MGADWG_TRANSC ( 0x01 << 30 ) + #define MGAREG_MISC_WRITE 0x3c2 #define MGAREG_MISC_READ 0x3cc +#define MGAREG_MISC_HSYNCPOL 0x40 +#define MGAREG_MISC_VSYNCPOL 0x80 + #define MGAREG_MISC_IOADSEL (0x1 << 0) #define MGAREG_MISC_RAMMAPEN (0x1 << 1) #define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2) @@ -233,10 +237,15 @@ /* MMIO VGA registers */ #define MGAREG_SEQ_INDEX 0x1fc4 #define MGAREG_SEQ_DATA 0x1fc5 +#define MGAREG_SEQ1_SCREEN_OFF 0x20 + #define MGAREG_CRTC_INDEX 0x1fd4 #define MGAREG_CRTC_DATA 0x1fd5 + #define MGAREG_CRTCEXT_INDEX 0x1fde #define MGAREG_CRTCEXT_DATA 0x1fdf +#define MGAREG_CRTCEXT1_HSYNC_OFF 0x10 +#define MGAREG_CRTCEXT1_VSYNC_OFF 0x20 @@ -434,17 +443,6 @@ #define MGA1064_PAN_CTL 0xa2 -/* Using crtc2 */ -#define MGAREG2_C2CTL 0x10 -#define MGAREG2_C2HPARAM 0x14 -#define MGAREG2_C2HSYNC 0x18 -#define MGAREG2_C2VPARAM 0x1c -#define MGAREG2_C2VSYNC 0x20 -#define MGAREG2_C2STARTADD0 0x28 - -#define MGAREG2_C2OFFSET 0x40 -#define MGAREG2_C2DATACTL 0x4c - #define MGAREG_C2CTL 0x3c10 #define MGAREG_C2CTL_C2_EN 0x01 diff --git a/src/mga_vga.c b/src/mga_vga.c index 8dfc08f..2268017 100644 --- a/src/mga_vga.c +++ b/src/mga_vga.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "misc.h" #include "xf86.h" #include "xf86_OSproc.h" @@ -245,19 +249,18 @@ MGAG200SERestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore) unsigned char scrn; if (restore->MiscOutReg & 0x01) - hwp->IOBase = VGA_IOBASE_COLOR; + hwp->IOBase = VGA_IOBASE_COLOR; else - hwp->IOBase = VGA_IOBASE_MONO; + hwp->IOBase = VGA_IOBASE_MONO; hwp->writeMiscOut(hwp, restore->MiscOutReg); - for (i = 1; i < restore->numSequencer; i++) { - MGAWAITVSYNC(); - MGAWAITBUSY(); - hwp->writeSeq(hwp, i, restore->Sequencer[i]); - usleep(20000); + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, i, restore->Sequencer[i]); + usleep(20000); } scrn = hwp->readSeq(hwp, 0x01); @@ -275,16 +278,18 @@ MGAG200SERestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore) hwp->writeCrtc(hwp, i, restore->CRTC[i]); for (i = 0; i < restore->numGraphics; i++) - hwp->writeGr(hwp, i, restore->Graphics[i]); + hwp->writeGr(hwp, i, restore->Graphics[i]); hwp->enablePalette(hwp); + for (i = 0; i < restore->numAttribute; i++) - hwp->writeAttr(hwp, i, restore->Attribute[i]); + hwp->writeAttr(hwp, i, restore->Attribute[i]); + hwp->disablePalette(hwp); MGAWAITVSYNC(); MGAWAITBUSY(); - hwp->writeSeq(hwp, 1, restore->Sequencer[1]); + hwp->writeSeq(hwp, 1, restore->Sequencer[1]); usleep(20000); } @@ -295,38 +300,41 @@ MGAG200SESaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save) int i; save->MiscOutReg = hwp->readMiscOut(hwp); + if (save->MiscOutReg & 0x01) - hwp->IOBase = VGA_IOBASE_COLOR; + hwp->IOBase = VGA_IOBASE_COLOR; else - hwp->IOBase = VGA_IOBASE_MONO; + hwp->IOBase = VGA_IOBASE_MONO; for (i = 0; i < save->numCRTC; i++) { - save->CRTC[i] = hwp->readCrtc(hwp, i); + save->CRTC[i] = hwp->readCrtc(hwp, i); #ifdef DEBUG - ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]); + ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]); #endif } hwp->enablePalette(hwp); + for (i = 0; i < save->numAttribute; i++) { - save->Attribute[i] = hwp->readAttr(hwp, i); + save->Attribute[i] = hwp->readAttr(hwp, i); #ifdef DEBUG - ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]); + ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]); #endif } + hwp->disablePalette(hwp); for (i = 0; i < save->numGraphics; i++) { - save->Graphics[i] = hwp->readGr(hwp, i); + save->Graphics[i] = hwp->readGr(hwp, i); #ifdef DEBUG - ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]); + ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]); #endif } for (i = 1; i < save->numSequencer; i++) { - save->Sequencer[i] = hwp->readSeq(hwp, i); + save->Sequencer[i] = hwp->readSeq(hwp, i); #ifdef DEBUG - ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]); + ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]); #endif } } @@ -340,32 +348,32 @@ MGAG200SEHWProtect(ScrnInfoPtr pScrn, Bool on) unsigned char tmp; if (pScrn->vtSema) { - if (on) { - /* - * Turn off screen and disable sequencer. - */ - tmp = hwp->readSeq(hwp, 0x01); - - vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */ - MGAWAITVSYNC(); - MGAWAITBUSY(); - hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */ - usleep(20000); - hwp->enablePalette(hwp); + if (on) { + /* + * Turn off screen and disable sequencer. + */ + tmp = hwp->readSeq(hwp, 0x01); + + vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */ + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */ + usleep(20000); + hwp->enablePalette(hwp); } else { - /* - * Reenable sequencer, then turn on screen. - */ - - tmp = hwp->readSeq(hwp, 0x01); + /* + * Reenable sequencer, then turn on screen. + */ + + tmp = hwp->readSeq(hwp, 0x01); - MGAWAITVSYNC(); - MGAWAITBUSY(); - hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */ - usleep(20000); - vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ + MGAWAITVSYNC(); + MGAWAITBUSY(); + hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */ + usleep(20000); + vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ - hwp->disablePalette(hwp); + hwp->disablePalette(hwp); } } } |