diff options
-rw-r--r-- | mga_PInS.txt | 232 | ||||
-rw-r--r-- | src/mga.h | 60 | ||||
-rw-r--r-- | src/mga_arc.c | 1 | ||||
-rw-r--r-- | src/mga_bios.c | 521 | ||||
-rw-r--r-- | src/mga_dac3026.c | 100 | ||||
-rw-r--r-- | src/mga_dacG.c | 98 | ||||
-rw-r--r-- | src/mga_dga.c | 29 | ||||
-rw-r--r-- | src/mga_dh.c | 13 | ||||
-rw-r--r-- | src/mga_dri.c | 2 | ||||
-rw-r--r-- | src/mga_driver.c | 177 | ||||
-rw-r--r-- | src/mga_g450pll.c | 12 | ||||
-rw-r--r-- | src/mga_hwcurs.c | 3 | ||||
-rw-r--r-- | src/mga_merge.c | 9 | ||||
-rw-r--r-- | src/mga_shadow.c | 3 | ||||
-rw-r--r-- | src/mga_storm.c | 1 | ||||
-rw-r--r-- | src/mga_video.c | 1 |
16 files changed, 885 insertions, 377 deletions
diff --git a/mga_PInS.txt b/mga_PInS.txt new file mode 100644 index 0000000..bd2ec80 --- /dev/null +++ b/mga_PInS.txt @@ -0,0 +1,232 @@ +Version 1: + +Offset Type Description + + 0 uint16_t Length of the PInS data, in bytes. This must be 64. + 2 uint16_t Product ID. Possible values are: + 0: MGA-S1P20 (2MB base with 175MHz RAMDAC) + 1: MGA-S1P21 (2MB base with 220MHz RAMDAC) + 2: Reserved + 3: Reserved + 4: MGA-S1P40 (4MB base with 175MHz RAMDAC) + 5: MGA-S1P41 (4MB base with 220MHz RAMDAC) + 4 char[8] Serial number of the board. NUL terminated string. + 12 uint16_t Manufacturing date of the board (at product test). + Format (stored little-endian) yyyyyyymmmmddddd. + 14 uint16_t Identification of manufacturing site. + 16 uint16_t Number and revision level of the PCB. Format (stored + little-endian): nnnnnnnnnnnrrrrr, where n = PCB number + ex:576 (from 0->2047) and r = PCB revision (from 0->31). + 18 uint16_t Identification of any PMBs. + 20 uint8_t RAMDAC speed (0=175MHz, 1=220MHz). + 21 uint8_t RAMDAC type (0=TVP3026, 1=TVP3027). + 22 uint16_t Maximum PCLK of the ramdac. + 24 uint16_t Maximum LDCLK supported by the WRAM memory. + 26 uint16_t Maximum MCLK of base board. + 28 uint16_t Maximum MCLK of 4Mb board. + 30 uint16_t Maximum MCLK of 8Mb board. + 32 uint16_t Maximum MCLK of board with multimedia module. + 34 uint16_t Diagnostic test pass frequency. + 36 uint16_t Default VGA mode1 pixel frequency. + 38 uint16_t Default VGA mode2 pixel frequency. + 40 uint16_t Date of last BIOS programming / update. + 42 uint16_t Number of times BIOS has been programmed. + 44 uint32_t Support for up to 32 hardware/software options. + 48 uint32_t Support for up to 32 hardware/software features. + 52 uint16_t Definition of VGA mode MCLK. + 54 uint16_t Indicate the revision level of this header struct. + 56 char[7] Unused. + 63 uint8_t Check-sum byte. + + +Version 2: + +Unless otherwise noted, all clock speeds stored in this version of the PInS +data are stored as the clock speed in MHz minus 100. To convert a stored +clock speed, C, to kHz, use ((C + 100) * 1000). + +Offset Type Description + 0 uint16_t PInS structure signature. This must be the 16-bit + value (stored little-endian) 0x412E. + 2 uint8_t Length of the PInS data, in bytes. For version 2, this + must be 64. + 3 uint8_t Reserved. + 4 uint16_t Version of the structure. For version 2, this must be the + value (stored little-endian) 0x02XX. + 6 uint16_t Date of last BIOS programming / update. + 8 uint16_t Number of times BIOS has been programmed. + 10 uint16_t Product ID. + 12 char[16] Serial number of the board. NUL terminated string. + 28 char[6] Parts list identification. NUL terminated string. + 34 uint16_t Number and revision level of the PCB. Format (stored + little-endian): nnnnnnnnnnnrrrrr, where n = PCB number + ex:576 (from 0->2047) and r = PCB revision (from 0->31). + 36 uint32_t Support for up to 32 hardware/software features. + 40 uint8_t RAMDAC type. + 41 uint8_t RAMDAC speed. Stored using standard clock encoding (see + above). + 42 uint8_t PclkMax + 43 uint8_t Memory clock. Stored using standard clock encoding (see + above). + 44 uint8_t Maximum MCLK of base board. + 45 uint8_t Maximum MCLK of 4Mb board. + 46 uint8_t Maximum MCLK of 8Mb board. + 47 uint8_t Maximum MCLK of board with multimedia module. + 48 uint8_t TestClk + 49 uint8_t Default VGA mode1 pixel frequency. + 50 uint8_t Default VGA mode2 pixel frequency. + 51 uint8_t MCTLWTST + 52 uint8_t VidCtrl + 53 uint8_t Maximum MCLK of 12Mb board. + 54 uint8_t Maximum MCLK of 16Mb board. + 55 char[8] Unused + 63 uint8_t Check-sum byte + + +Version 3: + +Unless otherwise noted, all clock speeds stored in this version of the PInS +data are stored as the clock speed in MHz minus 100. To convert a stored +clock speed, C, to kHz, use ((C + 100) * 1000). + +Offset Type Description + 0 uint16_t PInS structure signature. This must be the 16-bit + value (stored little-endian) 0x412E. + 2 uint8_t Length of the PInS data, in bytes. For version 3, this + must be 64. + 3 uint8_t Reserved. + 4 uint16_t Version of the structure. For version 3, this must be the + value (stored little-endian) 0x03XX. + 6 uint16_t Date of last BIOS programming / update. + 8 uint16_t Number of times BIOS has been programmed. + 10 uint16_t Product ID. + 12 char[16] Serial number of the board. NUL terminated string. + 28 char[6] Parts list identification. NUL terminated string. + 34 uint16_t Number and revision level of the PCB. Format (stored + little-endian): nnnnnnnnnnnrrrrr, where n = PCB number + ex:576 (from 0->2047) and r = PCB revision (from 0->31). + 36 uint8_t RAMDAC speed. Stored using standard clock encoding (see + above). + 37 char[15] Unknown? + 52 uint32_t OPTION? Stored little-endian. + Bits Meaning + 0 - 4 Unknown? + 5 0 = Reference PLL speed is 27.050MHz. + 1 = Reference PLL speed is 14.318MHz. + 6 - 31 Unknown? + 56 uint16_t MEMRDBK? + 58 uint32_t OPTION2? + 62 char Unused + 63 uint8_t Check-sum byte + + +Version 4: + +Unless otherwise noted, all clock speeds stored in this version of the PInS +data are stored as the clock speed in MHz divided by 4. To convert a stored +clock speed, C, to kHz, use ((C * 4) * 1000). + +Offset Type Description + 0 uint16_t PInS structure signature. This must be the 16-bit + value (stored little-endian) 0x412E. + 2 uint8_t Length of the PInS data, in bytes. For version 4, this + must be 128. + 3 uint8_t Reserved. + 4 uint16_t Version of the structure. For version 4, this must be the + value (stored little-endian) 0x04XX. + 6 uint16_t Date of last BIOS programming / update. + 8 uint16_t Number of times BIOS has been programmed. + 10 uint16_t Product ID. + 12 char[16] Serial number of the board. NUL terminated string. + 28 char[6] Parts list identification. NUL terminated string. + 34 uint16_t Number and revision level of the PCB. Format (stored + little-endian): nnnnnnnnnnnrrrrr, where n = PCB number + ex:576 (from 0->2047) and r = PCB revision (from 0->31). + 36 char Unknown? + 37 char Unknown? + 38 uint8_t VCO max for system PLL + 39 uint8_t VCO max for pixel PLL + 40 char[13] Unknown? + 53 uint8_t OPTION? + 54 char[11] Unknown? + 65 uint8_t System PLL? Stored using standard clock encoding (see + above). + 66 char Unknown? + 67 uint32_t OPTION3? This offset seems wrong, but that's what + matroxfb does. + 71 char[15] Unknown? + 86 uint16_t MEMRDBK? + 88 char[4] Unknown? + 92 uint32_t OPTIONx? + Bits Meaning + 0 0 = Reference PLL speed is 27.050MHz. + 1 = Reference PLL speed is 14.318MHz. + 1 - 31 Unknown? + 96 char[21] Unknown? +127 uint8_t Check-sum byte + + +Version 5: + +Unless otherwise noted, all clock speeds stored in this version of the PInS +data are stored as the clock speed in MHz divided by 6 for version 0x500 or +by 8 for all other versions. To convert a stored clock speed, C, to kHz, on +version 0x0500, use ((C * 6) * 1000). For all other versions, use ((C * 8) * +1000). + +Offset Type Description + 0 uint16_t PInS structure signature. This must be the 16-bit + value (stored little-endian) 0x412E. + 2 uint8_t Length of the PInS data, in bytes. For version 5, this + must be 128. + 3 uint8_t Reserved. + 4 uint16_t Version of the structure. For version 5, this must be the + value (stored little-endian) 0x05XX. + 6 uint16_t Date of last BIOS programming / update. + 8 uint16_t Number of times BIOS has been programmed. + 10 uint16_t Product ID. + 12 char[16] Serial number of the board. NUL terminated string. + 28 char[6] Parts list identification. NUL terminated string. + 34 uint16_t Number and revision level of the PCB. Format (stored + little-endian): nnnnnnnnnnnrrrrr, where n = PCB number + ex:576 (from 0->2047) and r = PCB revision (from 0->31). + 36 uint8_t VCO max for system PLL. Stored using standard clock + encoding (see above). + 37 uint8_t VCO max for video PLL. Stored using standard clock + encoding (see above). + 38 uint8_t VCO max for pixel PLL. Stored using standard clock + encoding (see above). + 39 char[9] Unknown? + 48 uint32_t OPTION1? + 52 uint32_t OPTION2? + 56 char[38] Unknown? + 94 uint32_t OPTION3? + 98 uint32_t MCTLWTST? +102 uint32_t MEMMISC? +106 uint32_t MEMRDBK? +110 uint32_t OPTIONx? + Bits Meaning + 0 0 = Reference PLL speed is 27.050MHz. + 1 = Reference PLL speed is 14.318MHz. + 1 - 31 Unknown? +114 uint16_t MEMINFO? + Bits Meaning + 0 - 4 Unknown + 5 - 6 0 = SDR memory installed? + 1 = DDR memory installed + 2 = Unknown + 3 = Unknown + 7 Unknown + 8 EMRSWEN? + 9 Has DLL? + 10 Core uses MCTLWTST? + 11 - 15 MCTLWTST values for core? +116 char[5] Unknown? +121 uint8_t VCO min for system PLL. Stored using standard clock + encoding (see above). +122 uint8_t VCO min for video PLL. Stored using standard clock + encoding (see above). +123 uint8_t VCO min for pixel PLL. Stored using standard clock + encoding (see above). +124 char[3] Unknown? +127 uint8_t Check-sum byte @@ -288,6 +288,61 @@ typedef struct { ScrnInfoPtr pScrn_2; } MGAEntRec, *MGAEntPtr; +/** + * Track the range of a voltage controlled osciliator (VCO). + */ +struct mga_VCO { + /** + * Minimum selectable frequency for this VCO, measured in kHz. + */ + unsigned min_freq; + + /** + * Maximum selectable frequency for this VCO, measured in kHz. + * + * If this value is zero, then the VCO is not available. + */ + unsigned max_freq; +}; + +/** + * Card information derrived from BIOS PInS data. + */ +struct mga_bios_values { + /** + * \name Voltage Controlled Oscilators + * \brief Track information about the various VCOs. + * + * MGA cards have between one and three VCOs that can be used to drive the + * various clocks. On older cards, only \c mga_bios_values::pixel VCO is + * available. On newer cards, such as the G450 and G550, all three are + * available. If \c mga_VCO::max_freq is zero, the VCO is not available. + */ + /*@{*/ + struct mga_VCO system; /**< System VCO. */ + struct mga_VCO pixel; /**< Pixel VCO. */ + struct mga_VCO video; /**< Video VCO. */ + /*@}*/ + + /** + * Memory clock speed, measured in kHz. + */ + unsigned mem_clock; + + /** + * PLL reference frequency value. On older cards this is ~14MHz, and on + * newer cards it is ~27MHz. + */ + unsigned pll_ref_freq; + + /** + * Some older MGA cards have a "fast bitblt" mode. This is determined + * by a capability bit stored in the PInS data. + */ + Bool fast_bitblt; +}; + + typedef struct { #ifdef USEMGAHAL LPCLIENTDATA pClientStruct; @@ -296,8 +351,7 @@ typedef struct { LPMGAHWINFO pMgaHwInfo; #endif EntityInfoPtr pEnt; - MGABiosInfo Bios; - MGABios2Info Bios2; + struct mga_bios_values bios; CARD8 BiosOutputMode; pciVideoPtr PciInfo; PCITAG PciTag; @@ -497,7 +551,7 @@ Bool MGAGetRec(ScrnInfoPtr pScrn); void MGAProbeDDC(ScrnInfoPtr pScrn, int index); void MGASoftReset(ScrnInfoPtr pScrn); void MGAFreeRec(ScrnInfoPtr pScrn); -void MGAReadBios(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); diff --git a/src/mga_arc.c b/src/mga_arc.c index aca9f26..61ab077 100644 --- a/src/mga_arc.c +++ b/src/mga_arc.c @@ -44,7 +44,6 @@ in this Software without prior written authorization from The Open Group. #include "xf86Pci.h" -#include "mga_bios.h" #include "mga.h" #include "mga_reg.h" #include "mga_macros.h" diff --git a/src/mga_bios.c b/src/mga_bios.c new file mode 100644 index 0000000..c2aacbc --- /dev/null +++ b/src/mga_bios.c @@ -0,0 +1,521 @@ +/* + * (C) Copyright IBM Corporation 2005 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file mga_bios.c + * Routines for processing the PInS data stored in the MGA BIOS. + * + * The structure of this code was inspired by similar routines in the Linux + * kernel matroxfb code. Specifically, the routines in matroxfb_misc.c. In + * addition, that code was used in place of documentation about the structure + * of the PInS data for non-G450 cards. + * + * \author Ian Romanick <idr@us.ibm.com> + */ + +/* All drivers should typically include these */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" + +/* All drivers need this */ +#include "xf86_ansic.h" + +#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" + +#include "Xmd.h" + +#include "mga.h" + + +/** + * Read a little-endian, unaligned data value and return as 16-bit. + */ +static __inline__ CARD16 get_u16( const CARD8 * data ) +{ + CARD16 temp; + + temp = data[1]; + temp <<= 8; + temp += data[0]; + return temp; +} + + +/** + * Read a little-endian, unaligned data value and return as 32-bit. + */ +static __inline__ CARD32 get_u32( const CARD8 * data ) +{ + CARD32 temp; + + + temp = data[3]; + temp <<= 8; + temp += data[2]; + temp <<= 8; + temp += data[1]; + temp <<= 8; + temp += data[0]; + + return temp; +} + + +/** + * Initialize reasonable defaults for values that normally come form the BIOS. + * + * For each generation of hardware, provide reasonable default values, based + * on the type of hardware and chipset revision, for various values that are + * normally read from the PInS structure in the BIOS. This provides a backup + * in case the PInS structure cannot be found. + * + * \param pMga Pointer to the MGA-private data. + * \param bios Pointer to the structure that holds values read from the BIOS. + * + * \todo + * Determine if different default values should be used for G400 and G450 + * cards. These cards have the same PCI ID, but can be identified by a + * different chip revision. The G450 cards have a revision of 3 or higher. + */ + +static void mga_initialize_bios_values( MGAPtr pMga, + struct mga_bios_values * bios ) +{ + (void) memset( bios, 0, sizeof( *bios ) ); + + bios->pixel.min_freq = 50000; + + switch( pMga->Chipset ) { + case PCI_CHIP_MGA2064: + case PCI_CHIP_MGA2164: + case PCI_CHIP_MGA2164_AGP: + bios->pixel.max_freq = 220000; + + bios->pll_ref_freq = 14318; + bios->mem_clock = 50000; + break; + + case PCI_CHIP_MGA1064: + /* There used to be code in MGARamdacInit (mga_dacG.c) that would + * set this to 170000 if the chip revision was less than 3. Is that + * needed here? + */ + + bios->system.max_freq = 230000; + bios->pixel.max_freq = 230000; + + bios->pll_ref_freq = 14318; + bios->mem_clock = 50000; + break; + + case PCI_CHIP_MGAG100_PCI: + case PCI_CHIP_MGAG100: + case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200: + bios->system.max_freq = 230000; + bios->pixel.max_freq = 230000; + + bios->system.min_freq = 50000; + + bios->pll_ref_freq = 27050; + bios->mem_clock = 50000; + break; + + case PCI_CHIP_MGAG400: + bios->system.max_freq = 252000; + bios->pixel.max_freq = 252000; + + bios->system.min_freq = 50000; + + bios->pll_ref_freq = 27050; + bios->mem_clock = 200000; + break; + + case PCI_CHIP_MGAG550: + bios->system.min_freq = 256000; + bios->pixel.min_freq = 256000; + bios->video.min_freq = 256000; + bios->system.max_freq = 600000; + bios->pixel.max_freq = 600000; + bios->video.max_freq = 600000; + + bios->pll_ref_freq = 27050; + bios->mem_clock = 284000; + break; + } +} + + +/** + * Parse version 0x01XX of the BIOS PInS structure. + * + * Version 0x01XX of the BIOS PInS structure is only found in Millenium cards. + * + * \todo + * There used to be an "OverclockMem" option that would scale the memory clock + * by 12 instead 10. Add support for this back in. + */ +static void mga_parse_bios_ver_1( struct mga_bios_values * bios, + const CARD8 * bios_data ) +{ + unsigned maxdac; + + if ( get_u16( & bios_data[24] ) ) { + maxdac = get_u16( & bios_data[24] ) * 10; + } + else { + /* There is some disagreement here between the Linux kernel matroxfb + * driver and the old X.org mga driver. matroxfb has case-statements + * for 0 and 1 (with the values below), and the mga driver has + * case-statements for 1 and 2 (with the values below). The default + * value for the mga driver is 17500, but the default value for the + * matroxfb driver is 240000. + */ + + switch( bios_data[22] ) { + case 0: maxdac = 175000; break; + case 1: maxdac = 220000; break; + case 2: maxdac = 250000; break; + default: maxdac = 240000; break; + } + } + + if ( get_u16( & bios_data[28] ) ) { + bios->mem_clock = get_u16( & bios_data[28] ) * 10; + } + + if ( (bios_data[48] & 0x01) == 0 ) { + bios->fast_bitblt = TRUE; + } + + bios->pixel.max_freq = maxdac; +} + + +/** + * Parse version 0x02XX of the BIOS PInS structure. + * + * Version 0x02XX of the BIOS PInS structure is only found in Millenium II + * and Mystique cards. + */ +static void mga_parse_bios_ver_2( struct mga_bios_values * bios, + const CARD8 * bios_data ) +{ + if ( bios_data[41] != 0xff ) { + const unsigned maxdac = (bios_data[41] + 100) * 1000; + + bios->pixel.max_freq = maxdac; + bios->system.max_freq = maxdac; + } + + if ( bios_data[43] != 0xff ) { + const unsigned system_pll = (bios_data[43] + 100) * 1000; + bios->mem_clock = system_pll; + } +} + + +/** + * Parse version 0x03XX of the BIOS PInS structure. + * + * Version 0x03XX of the BIOS PInS structure is only found in G100 and G200 + * cards. + */ +static void mga_parse_bios_ver_3( struct mga_bios_values * bios, + const CARD8 * bios_data ) +{ + if ( bios_data[36] != 0xff ) { + const unsigned maxdac = (bios_data[36] + 100) * 1000; + + bios->pixel.max_freq = maxdac; + bios->system.max_freq = maxdac; + } + + if ( (bios_data[52] & 0x01) != 0 ) { + bios->pll_ref_freq = 14318; + } +} + + +/** + * Parse version 0x04XX of the BIOS PInS structure. + * + * Version 0x04XX of the BIOS PInS structure is only found in G400 cards. + */ +static void mga_parse_bios_ver_4( struct mga_bios_values * bios, + const CARD8 * bios_data ) +{ + if ( bios_data[39] != 0xff ) { + const unsigned maxdac = bios_data[39] * 4 * 1000; + + bios->pixel.max_freq = maxdac; + bios->system.max_freq = maxdac; + } + + if ( bios_data[38] != 0xff ) { + const unsigned maxdac = bios_data[38] * 4 * 1000; + + bios->system.max_freq = maxdac; + } + + if ( (bios_data[92] & 0x01) != 0 ) { + bios->pll_ref_freq = 14318; + } + + if ( bios_data[65] != 0xff ) { + const unsigned system_pll = bios_data[65] * 4 * 1000; + bios->mem_clock = system_pll; + } +} + + +/** + * Parse version 0x05XX of the BIOS PInS structure. + * + * Version 0x05XX of the BIOS PInS structure is only found in G450 and G550 + * cards. + */ +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; + + + if ( bios_data[38] != 0xff ) { + const unsigned maxdac = bios_data[38] * scale; + + bios->pixel.max_freq = maxdac; + bios->system.max_freq = maxdac; + bios->video.max_freq = maxdac; + } + + if ( bios_data[36] != 0xff ) { + const unsigned maxdac = bios_data[36] * scale; + + bios->system.max_freq = maxdac; + bios->video.max_freq = maxdac; + } + + if ( bios_data[37] != 0xff ) { + const unsigned maxdac = bios_data[37] * scale; + + bios->video.max_freq = maxdac; + } + + + if ( bios_data[123] != 0xff ) { + const unsigned mindac = bios_data[123] * scale; + + bios->pixel.min_freq = mindac; + bios->system.min_freq = mindac; + bios->video.min_freq = mindac; + } + + if ( bios_data[121] != 0xff ) { + const unsigned mindac = bios_data[121] * scale; + + bios->system.min_freq = mindac; + bios->video.min_freq = mindac; + } + + if ( bios_data[122] != 0xff ) { + const unsigned mindac = bios_data[122] * scale; + + bios->video.min_freq = mindac; + } + + + if ( bios_data[92] != 0xff ) { + const unsigned system_pll = bios_data[92] * 4 * 1000; + bios->mem_clock = system_pll; + } + + if ( (bios_data[110] & 0x01) != 0 ) { + bios->pll_ref_freq = 14318; + } +} + + +/** + * Read the BIOS data from the card and initialize internal values. + */ + +Bool mga_read_and_process_bios( ScrnInfoPtr pScrn ) +{ + CARD8 bios_data[0x10000]; + unsigned offset; + MGAPtr pMga = MGAPTR(pScrn); + Bool pciBIOS = TRUE; + int rlen; + static const unsigned expected_length[] = { 0, 64, 64, 64, 128, 128 }; + unsigned version; + unsigned pins_len; + const CARD8 * pins_data; + + + /* Initialize the stored BIOS data to some reasonable values for the + * card at hand. This is done now so that even if the PInS data block + * isn't found or can't be read we'll still have some reasonable values + * to use. + */ + + mga_initialize_bios_values( pMga, & pMga->bios ); + + + /* If the BIOS address was probed, it was found from the PCI config space + * If it was given in the config file, try to guess when it looks like it + * might be controlled by the PCI config space. + */ + + if (pMga->BiosFrom == X_DEFAULT) { + pciBIOS = FALSE; + } + else if (pMga->BiosFrom == X_CONFIG && pMga->BiosAddress < 0x100000) { + pciBIOS = TRUE; + } + + if (pciBIOS) { + rlen = xf86ReadPciBIOS(0, pMga->PciTag, pMga->FbBaseReg, + bios_data, sizeof(bios_data)); + } + else { + rlen = xf86ReadDomainMemory(pMga->PciTag, pMga->BiosAddress, + sizeof(bios_data), bios_data); + } + + if (rlen < (bios_data[2] << 9)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not retrieve video BIOS!\n"); + return FALSE; + } + + /* Get the output mode set by the BIOS */ + pMga->BiosOutputMode = bios_data[0x7ff1]; + + /* Get the video BIOS info block */ + if (strncmp((char *)(&bios_data[45]), "MATROX", 6)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS info block not detected!\n"); + return FALSE; + } + +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* The offset information that is included in the BIOS on PC Matrox cards + * is not there on PowerPC cards. Instead, we have to search the BIOS + * image for the magic signature. This is the 16-bit value 0x412d. This + * value is followed by the length of the PInS block. We know that this + * must (currently) be either 0x80 or 0x40. + * + * Happy hunting. + */ + for (offset = 0 ; offset < 0x7ffc ; offset++) { + if ((bios_data[offset] == 0x2e) && (bios_data[offset+1] == 0x41) + && ((bios_data[offset+2] == 0x80) || (bios_data[offset+2] == 0x40))) { + break; + } + } + + if (offset == 0x7ffc) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS PInS data not found!\n"); + return FALSE; + } +#else + /* Get the info block offset */ + offset = (unsigned)((bios_data[0x7ffd] << 8) | bios_data[0x7ffc]); +#endif + + /* Let the world know what we are up to */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Video BIOS info block at offset 0x%05lX\n", + (long)(offset)); + + + /* Determine the version of the PInS block. This will determine how the + * data is processed. Only the first version of the PInS data structure + * did *NOT* have the initial 0x412e (in little-endian order!) signature. + */ + + pins_data = & bios_data[ offset ]; + if ( (pins_data[0] == 0x2e) && (pins_data[1] == 0x41) ) { + version = pins_data[5]; + pins_len = pins_data[2]; + } + else { + version = 1; + pins_len = get_u16( pins_data ); + } + + + if ( (version < 1) || (version > 5) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PInS data version (%u) not supported.\n", version); + return FALSE; + } + + if ( pins_len != expected_length[ version ] ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PInS data length (%u) does not match expected length (%u)" + " for version %u.X.\n", + pins_len, expected_length[ version ], version); + return FALSE; + } + + switch( version ) { + case 1: mga_parse_bios_ver_1( & pMga->bios, pins_data ); break; + case 2: mga_parse_bios_ver_2( & pMga->bios, pins_data ); break; + case 3: mga_parse_bios_ver_3( & pMga->bios, pins_data ); break; + case 4: mga_parse_bios_ver_4( & pMga->bios, pins_data ); break; + case 5: mga_parse_bios_ver_5( & pMga->bios, pins_data ); break; + } + +#ifdef DEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "system VCO = [%u, %u]\n", + pMga->bios.system.min_freq, pMga->bios.system.max_freq); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "pixel VCO = [%u, %u]\n", + pMga->bios.pixel.min_freq, pMga->bios.pixel.max_freq); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "video VCO = [%u, %u]\n", + pMga->bios.video.min_freq, pMga->bios.video.max_freq); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "memory clock = %ukHz\n", pMga->bios.mem_clock); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PLL reference frequency = %ukHz\n", + pMga->bios.pll_ref_freq); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%s fast bitblt\n", + (pMga->bios.fast_bitblt) ? "Has" : "Does not have"); +#endif + + return TRUE; +} diff --git a/src/mga_dac3026.c b/src/mga_dac3026.c index ecd0605..3efdf3c 100644 --- a/src/mga_dac3026.c +++ b/src/mga_dac3026.c @@ -47,7 +47,6 @@ /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" #include "mga_macros.h" @@ -1079,100 +1078,13 @@ MGA3026RamdacInit(ScrnInfoPtr pScrn) MGAdac->LoadPalette = MGA3026LoadPalette; MGAdac->RestorePalette = MGA3026RestorePalette; + MGAdac->maxPixelClock = pMga->bios.pixel.max_freq; MGAdac->ClockFrom = X_PROBED; - if ( pMga->Chipset == PCI_CHIP_MGA2064 && pMga->Bios2.PinID == 0 ) - { - switch( pMga->Bios.RamdacType & 0xff ) - { - case 1: MGAdac->maxPixelClock = 220000; - break; - case 2: MGAdac->maxPixelClock = 250000; - break; - default: - MGAdac->maxPixelClock = 175000; - MGAdac->ClockFrom = X_DEFAULT; - break; - } - /* Set MCLK based on amount of memory */ - if(pMga->OverclockMem) { - if ( pScrn->videoRam < 4096 ) - MGAdac->MemoryClock = pMga->Bios.ClkBase * 12; - else if ( pScrn->videoRam < 8192 ) - MGAdac->MemoryClock = pMga->Bios.Clk4MB * 12; - else - MGAdac->MemoryClock = pMga->Bios.Clk8MB * 12; - MGAdac->MemClkFrom = X_CONFIG; - MGAdac->SetMemClk = TRUE; -#if 0 - ErrorF("BIOS Memory clock settings: 2Mb %d, 4Mb %d, 8MB %d\n", - pMga->Bios.ClkBase, pMga->Bios.Clk4MB, pMga->Bios.Clk8MB); -#endif - } else { - if ( pScrn->videoRam < 4096 ) - MGAdac->MemoryClock = pMga->Bios.ClkBase * 10; - else if ( pScrn->videoRam < 8192 ) - MGAdac->MemoryClock = pMga->Bios.Clk4MB * 10; - else - MGAdac->MemoryClock = pMga->Bios.Clk8MB * 10; - MGAdac->MemClkFrom = X_PROBED; - MGAdac->SetMemClk = TRUE; - } - } - else - { - if ( pMga->Bios2.PinID ) /* make sure BIOS is available */ - { - if ( pMga->Bios2.PclkMax != 0xff ) - { - MGAdac->maxPixelClock = (pMga->Bios2.PclkMax + 100) * 1000; - } - else - MGAdac->maxPixelClock = 220000; - - /* make sure we are not overdriving the GE for the amount of WRAM */ - switch ( pScrn->videoRam ) - { - case 4096: - if (pMga->Bios2.Clk4MB != 0xff) - pMga->Bios2.ClkGE = pMga->Bios2.Clk4MB; - break; - case 8192: - if (pMga->Bios2.Clk8MB != 0xff) - pMga->Bios2.ClkGE = pMga->Bios2.Clk8MB; - break; - case 12288: - if (pMga->Bios2.Clk12MB != 0xff) - pMga->Bios2.ClkGE = pMga->Bios2.Clk12MB; - break; - case 16384: - if (pMga->Bios2.Clk16MB != 0xff) - pMga->Bios2.ClkGE = pMga->Bios2.Clk16MB; - break; - default: - break; - } - if ( pMga->Bios2.ClkGE != 0xff && pMga->Bios2.ClkMem == 0xff ) - pMga->Bios2.ClkMem = pMga->Bios2.ClkGE; - else if ( pMga->Bios2.ClkGE == 0xff && pMga->Bios2.ClkMem != 0xff ) - ; /* don't need to do anything */ - else if ( pMga->Bios2.ClkGE == pMga->Bios2.ClkMem && pMga->Bios2.ClkGE != 0xff ) - pMga->Bios2.ClkMem = pMga->Bios2.ClkGE; - else - pMga->Bios2.ClkMem = 60; - - MGAdac->MemoryClock = pMga->Bios2.ClkMem * 1000; - MGAdac->MemClkFrom = X_PROBED; - MGAdac->SetMemClk = TRUE; - } /* BIOS enabled initialization */ - else - { - /* bios is not available, initialize to rational figures */ - MGAdac->MemoryClock = 60000; /* 60 MHz WRAM */ - MGAdac->maxPixelClock = 220000; /* 220 MHz */ - MGAdac->ClockFrom = X_DEFAULT; - } - } /* 2164 specific initialization */ + MGAdac->MemoryClock = pMga->bios.mem_clock; + MGAdac->MemClkFrom = X_PROBED; + MGAdac->SetMemClk = TRUE; + /* safety check */ if ( (MGAdac->MemoryClock < 40000) || @@ -1201,7 +1113,7 @@ MGA3026RamdacInit(ScrnInfoPtr pScrn) pMga->Roundings[3] = 128 >> pMga->BppShifts[3]; /* Set Fast bitblt flag */ - pMga->HasFBitBlt = !(pMga->Bios.FeatFlag & 0x00000001); + pMga->HasFBitBlt = pMga->bios.fast_bitblt; } void MGA3026LoadPalette( diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 4dc93e4..4ec5d5b 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -22,7 +22,6 @@ /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" #include "mga_macros.h" @@ -57,45 +56,29 @@ static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr); static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); static Bool MGAG_i2cInit(ScrnInfoPtr pScrn); -/* - * MGAGCalcClock - Calculate the PLL settings (m, n, p, s). - * - * DESCRIPTION - * For more information, refer to the Matrox - * "MGA1064SG Developer Specification (document 10524-MS-0100). - * chapter 5.7.8. "PLLs Clocks Generators" +/** + * Calculate the PLL settings (m, n, p, s). * - * 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. - * s OUT Value of PLL 's' filter register - * (pix pll clock only). + * For more information, refer to the Matrox "MGA1064SG Developer + * Specification" (document 10524-MS-0100). chapter 5.7.8. "PLLs Clocks + * Generators" * - * HISTORY - * August 18, 1998 - Radoslaw Kapitan - * Adapted for G200 DAC - * - * February 28, 1997 - Guy DESBIEF - * Adapted for MGA1064SG DAC. - * based on MGACalcClock written by [aem] Andrew E. Mileski + * \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). */ -/* The following values are in kHz */ -#define MGA_MIN_VCO_FREQ 50000 -#define MGA_MAX_VCO_FREQ 310000 - -static double +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_pll, f_vco; + double f_vco; double m_err, calc_f; - double ref_freq; + 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; @@ -103,7 +86,6 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, switch( pMga->Chipset ) { case PCI_CHIP_MGA1064: - ref_freq = 14318.18; feed_div_min = 100; feed_div_max = 127; in_div_min = 1; @@ -112,7 +94,6 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, break; case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: - ref_freq = 27050.5; feed_div_min = 7; feed_div_max = 127; in_div_min = 1; @@ -124,10 +105,6 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: default: - if (pMga->Bios2.PinID && (pMga->Bios2.VidCtrl & 0x20)) - ref_freq = 14318.18; - else - ref_freq = 27050.5; feed_div_min = 7; feed_div_max = 127; in_div_min = 1; @@ -137,16 +114,17 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, } /* Make sure that f_min <= f_out */ - if ( f_out < ( MGA_MIN_VCO_FREQ / 8)) - f_out = MGA_MIN_VCO_FREQ / 8; + 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 MGA_MIN_VCO_FREQ <= f_vco <= MGA_MAX_VCO_FREQ + * 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 < MGA_MIN_VCO_FREQ; + 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 */ @@ -187,14 +165,10 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, if ( (180000.0 <= f_vco) ) *s = 3; - f_pll = f_vco / ( *p + 1 ); - #ifdef DEBUG ErrorF( "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_pll, f_vco, *best_n, *best_m, *p, *s ); #endif - - return f_pll; } /* @@ -215,7 +189,7 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) } /* Do the calculations for m, n, p and s */ - (void) MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); + MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); /* Values for the pixel clock PLL registers */ pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; @@ -1279,36 +1253,10 @@ MGAGRamdacInit(ScrnInfoPtr pScrn) MGAdac->LoadPalette = MGAGLoadPalette; MGAdac->RestorePalette = MGAGRestorePalette; - if ( pMga->Bios2.PinID && pMga->Bios2.PclkMax != 0xFF ) - { - MGAdac->maxPixelClock = (pMga->Bios2.PclkMax + 100) * 1000; - MGAdac->ClockFrom = X_PROBED; - } - else - { - switch( pMga->Chipset ) - { - case PCI_CHIP_MGA1064: - if ( pMga->ChipRev < 3 ) - MGAdac->maxPixelClock = 170000; - else - MGAdac->maxPixelClock = 220000; - break; - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG550: - /* We don't know the new pins format but we know that - the maxclock / 4 is where the RamdacType was in the - old pins format */ - MGAdac->maxPixelClock = pMga->Bios2.RamdacType * 4000; - if(MGAdac->maxPixelClock < 300000) - MGAdac->maxPixelClock = 300000; - break; - default: - MGAdac->maxPixelClock = 250000; - } - MGAdac->ClockFrom = X_DEFAULT; - } - + + MGAdac->maxPixelClock = pMga->bios.pixel.max_freq; + MGAdac->ClockFrom = X_PROBED; + /* Disable interleaving and set the rounding value */ pMga->Interleave = FALSE; diff --git a/src/mga_dga.c b/src/mga_dga.c index d6735b1..a08619f 100644 --- a/src/mga_dga.c +++ b/src/mga_dga.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c,v 1.16 2002/09/16 18:05:55 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c,v 1.14 1999/11/02 23:12:00 mvojkovi Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -7,7 +7,6 @@ #include "xf86PciInfo.h" #include "xaa.h" #include "xaalocal.h" -#include "mga_bios.h" #include "mga.h" #include "mga_reg.h" #include "dgaproc.h" @@ -264,6 +263,30 @@ BitsSet(unsigned long data) return set; } +/* + * This is not strictly required - but it will load a 'sane' + * palette when starting DGA. + */ +static void +mgaDGASetPalette(ScrnInfoPtr pScrn) +{ + MGAPtr pMga = MGAPTR(pScrn); + MGARamdacPtr MGAdac = &pMga->Dac; + unsigned char DAC[256*3]; + int i; + + if (!MGAdac->RestorePalette) + return; + + for (i = 0; i < 256; i++) { + DAC[i*3] = i; + DAC[i*3 + 1] = i; + DAC[i*3 + 2] = i; + } + MGAdac->RestorePalette(pScrn, DAC); +} + + static Bool MGA_SetMode( ScrnInfoPtr pScrn, @@ -299,6 +322,8 @@ MGA_SetMode( /* MGAModeInit() will set the mode field */ pScrn->SwitchMode(index, pMode->mode, 0); + /* not strictly required but nice */ + mgaDGASetPalette(pScrn); } return TRUE; diff --git a/src/mga_dh.c b/src/mga_dh.c index 79c8510..63ddf80 100644 --- a/src/mga_dh.c +++ b/src/mga_dh.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dh.c,v 1.4 2002/01/11 15:42:57 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dh.c,v 1.4tsi Exp $ */ /********************************************************************* * G450: This is for Dual Head. * Matrox Graphics @@ -17,7 +17,6 @@ /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" @@ -151,13 +150,11 @@ void MGACRTC2Get(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) CARD32 ulHTotal; CARD32 ulHDispEnd; CARD32 ulHBlkStr; - CARD32 ulHBlkEnd; CARD32 ulHSyncStr; CARD32 ulHSyncEnd; CARD32 ulVTotal; CARD32 ulVDispEnd; CARD32 ulVBlkStr; - CARD32 ulVBlkEnd; CARD32 ulVSyncStr; CARD32 ulVSyncEnd; CARD32 ulOffset; @@ -181,7 +178,6 @@ void MGACRTC2Get(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) ulHDispEnd = tmpModeInfo.ulDispWidth; ulHBlkStr = ulHDispEnd; - ulHBlkEnd = ulHBlkStr + tmpModeInfo.ulHBPorch + tmpModeInfo.ulHFPorch + tmpModeInfo.ulHSync; ulHSyncStr = ulHBlkStr + tmpModeInfo.ulHFPorch; ulHSyncEnd = ulHSyncStr + tmpModeInfo.ulHSync; @@ -193,7 +189,6 @@ void MGACRTC2Get(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) ulVDispEnd = ulDispHeight; ulVBlkStr = ulVDispEnd; - ulVBlkEnd = ulVBlkStr + tmpModeInfo.ulVBPorch + tmpModeInfo.ulVFPorch + tmpModeInfo.ulVSync; ulVSyncStr = ulVBlkStr + tmpModeInfo.ulVFPorch; ulVSyncEnd = ulVSyncStr + tmpModeInfo.ulVSync; @@ -285,7 +280,7 @@ void MGACRTC2Set(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) void MGAEnableSecondOutPut(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) { CARD8 ucByte, ucXDispCtrl; - CARD32 ulC2CTL, ulStatusReg; + CARD32 ulC2CTL; MGAPtr pMga = MGAPTR(pScrn); MGARegPtr pReg; pReg = &pMga->ModeReg; @@ -300,8 +295,8 @@ void MGAEnableSecondOutPut(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo) /*--- Disable Pixel clock oscillations On Crtc1 */ OUTREG( MGAREG_C2CTL, ulC2CTL | C2CTL_PIXCLKDIS_MASK); /*--- Have to wait minimum time (2 acces will be ok) */ - ulStatusReg = INREG( MGAREG_Status); - ulStatusReg = INREG( MGAREG_Status); + (void) INREG( MGAREG_Status); + (void) INREG( MGAREG_Status); ulC2CTL &= ~(C2CTL_PIXCLKSEL_MASK | C2CTL_PIXCLKSELH_MASK); diff --git a/src/mga_dri.c b/src/mga_dri.c index 11f3f03..67ca068 100644 --- a/src/mga_dri.c +++ b/src/mga_dri.c @@ -47,7 +47,6 @@ #include <inttypes.h> -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" #include "mga_macros.h" @@ -65,7 +64,6 @@ #include "GL/glxtokens.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" #include "mga_macros.h" diff --git a/src/mga_driver.c b/src/mga_driver.c index da82b79..65a7721 100644 --- a/src/mga_driver.c +++ b/src/mga_driver.c @@ -666,169 +666,6 @@ MGAProbe(DriverPtr drv, int flags) /* - * Should aim towards not relying on this. - */ - -/* - * MGAReadBios - Read the video BIOS info block. - * - * DESCRIPTION - * Warning! This code currently does not detect a video BIOS. - * In the future, support for motherboards with the mga2064w - * will be added (no video BIOS) - this is not a huge concern - * for me today though. (XXX) - * - * EXTERNAL REFERENCES - * vga256InfoRec.BIOSbase IN Physical address of video BIOS. - * MGABios OUT The video BIOS info block. - * - * HISTORY - * August 31, 1997 - [ajv] Andrew van der Stock - * Fixed to understand Mystique and Millennium II - * - * January 11, 1997 - [aem] Andrew E. Mileski - * Set default values for GCLK (= MCLK / pre-scale ). - * - * October 7, 1996 - [aem] Andrew E. Mileski - * Written and tested. - */ - -void -MGAReadBios(ScrnInfoPtr pScrn) -{ - CARD8 BIOS[0x10000]; - CARD16 offset; - CARD8 chksum; - CARD8 *pPINSInfo; - MGAPtr pMga; - MGABiosInfo *pBios; - MGABios2Info *pBios2; - Bool pciBIOS = TRUE; - int rlen; - - pMga = MGAPTR(pScrn); - pBios = &pMga->Bios; - pBios2 = &pMga->Bios2; - - /* - * If the BIOS address was probed, it was found from the PCI config - * space. If it was given in the config file, try to guess when it - * looks like it might be controlled by the PCI config space. - */ - if (pMga->BiosFrom == X_DEFAULT) - pciBIOS = FALSE; - else if (pMga->BiosFrom == X_CONFIG && pMga->BiosAddress < 0x100000) - pciBIOS = TRUE; - - if (pciBIOS) - rlen = xf86ReadPciBIOS(0, pMga->PciTag, pMga->FbBaseReg, - BIOS, sizeof(BIOS)); - else - rlen = xf86ReadDomainMemory(pMga->PciTag, pMga->BiosAddress, - sizeof(BIOS), BIOS); - - if (rlen < (BIOS[2] << 9)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Could not retrieve video BIOS!\n"); - return; - } - - /* Get the output mode set by the BIOS */ - pMga->BiosOutputMode = BIOS[0x7ff1]; - - /* Get the video BIOS info block */ - if (strncmp((char *)(&BIOS[45]), "MATROX", 6)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS info block not detected!\n"); - return; - } - - /* Get the info block offset */ - offset = (BIOS[0x7ffd] << 8) | BIOS[0x7ffc]; - - /* Let the world know what we are up to */ - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Video BIOS info block at offset 0x%05lX\n", - (long)(offset)); - -#define MGADoBIOSRead(offset, buf, len) memcpy(buf, &BIOS[offset], len) - - /* Copy the info block */ - /* XXX What about big-endianness? */ - switch (pMga->Chipset){ - case PCI_CHIP_MGA2064: - MGADoBIOSRead(offset, - ( CARD8 * ) & pBios->StructLen, sizeof( MGABiosInfo )); - break; - default: - MGADoBIOSRead(offset, - ( CARD8 * ) & pBios2->PinID, sizeof( MGABios2Info )); - break; - } - - /* matrox millennium-2 and mystique pins info */ - if ( pBios2->PinID == 0x412e ) { - int i; - /* check that the pins info is correct */ - if ( pBios2->StructLen != 0x40 ) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS info block not detected!\n"); - pBios2->PinID = 0; - return; - } - /* check that the chksum is correct */ - chksum = 0; - pPINSInfo = (CARD8 *) &pBios2->PinID; - - for (i=0; i < pBios2->StructLen; i++) { - chksum += *pPINSInfo; - pPINSInfo++; - } - - if ( chksum ) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS info block did not checksum!\n"); - pBios2->PinID = 0; - return; - } - - /* last check */ - if ( pBios2->StructRev == 0 ) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Video BIOS info block does not have a valid revision!\n"); - pBios2->PinID = 0; - return; - } - - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Found and verified enhanced Video BIOS info block\n"); - - /* Set default MCLK values (scaled by 100 kHz) */ - if ( pBios2->ClkMem == 0 ) - pBios2->ClkMem = 50; - if ( pBios2->Clk4MB == 0 ) - pBios2->Clk4MB = pBios->ClkBase; - if ( pBios2->Clk8MB == 0 ) - pBios2->Clk8MB = pBios->Clk4MB; - pBios->StructLen = 0; /* not in use */ -#ifdef DEBUG - for (i = 0; i < 0x40; i++) - ErrorF("Pins[0x%02x] is 0x%02x\n", i, - ((unsigned char *)pBios2)[i]); -#endif - } else { - /* Set default MCLK values (scaled by 10 kHz) */ - if ( pBios->ClkBase == 0 ) - pBios->ClkBase = 4500; - if ( pBios->Clk4MB == 0 ) - pBios->Clk4MB = pBios->ClkBase; - if ( pBios->Clk8MB == 0 ) - pBios->Clk8MB = pBios->Clk4MB; - pBios2->PinID = 0; /* not in use */ - } -} - -/* * MGASoftReset -- * * Resets drawing engine @@ -1063,7 +900,7 @@ MGAdoDDC(ScrnInfoPtr pScrn) /* Its the first head... */ if (pMga->DDC_Bus1) { MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex,pMga->DDC_Bus1); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", MonInfo); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", (void *) MonInfo); xf86PrintEDID(MonInfo); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n"); } @@ -1074,7 +911,7 @@ MGAdoDDC(ScrnInfoPtr pScrn) MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, pMga->DDC1SetSpeed, pMga->ddc1Read ) ; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", MonInfo); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", (void *) MonInfo); xf86PrintEDID( MonInfo ); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n"); } @@ -1086,7 +923,7 @@ MGAdoDDC(ScrnInfoPtr pScrn) vbeFree(pVbe); if (MonInfo){ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE DDC Monitor info: %p\n", MonInfo); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE DDC Monitor info: %p\n", (void *) MonInfo); xf86PrintEDID( MonInfo ); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of VBE DDC Monitor info\n\n"); } @@ -1833,7 +1670,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } } -#if !defined(__powerpc__) + /* * Find the BIOS base. Get it from the PCI config if possible. Otherwise * use the VGA default. Allow the config file to override this. @@ -1883,7 +1720,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) "BIOS not found, skipping read\n"); else #endif - MGAReadBios(pScrn); + mga_read_and_process_bios( pScrn ); + /* Since the BIOS can swap DACs during the initialisation of G550, we need to * store which DAC this instance of the driver is taking care of. This is done @@ -1902,9 +1740,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, - "MGABios.RamdacType = 0x%x\n", pMga->Bios.RamdacType); -#endif /* !__powerpc__ */ /* HW bpp matches reported bpp */ pMga->HwBpp = pScrn->bitsPerPixel; diff --git a/src/mga_g450pll.c b/src/mga_g450pll.c index 6176549..e4d8467 100644 --- a/src/mga_g450pll.c +++ b/src/mga_g450pll.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_g450pll.c,v 1.8 2002/09/16 18:05:56 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_g450pll.c,v 1.8tsi Exp $ */ /* All drivers should typically include these */ #include "xf86.h" @@ -11,7 +11,6 @@ /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" @@ -43,11 +42,10 @@ static CARD32 G450RemovePFactor(ScrnInfoPtr pScrn, CARD8 ucP, CARD32 *pulFIn) static CARD32 G450CalculVCO(ScrnInfoPtr pScrn, CARD32 ulMNP, CARD32 *pulF) { - CARD8 ucM, ucN, ucP; + CARD8 ucM, ucN; ucM = (CARD8)((ulMNP >> 16) & 0xff); ucN = (CARD8)((ulMNP >> 8) & 0xff); - ucP = (CARD8)(ulMNP & 0x03); *pulF = (27000 * (2 * (ucN + 2)) + ((ucM + 1) >> 1)) / (ucM + 1); @@ -193,9 +191,6 @@ static CARD32 G450FindFirstPLLParam(ScrnInfoPtr pScrn, CARD32 ulFout, static CARD32 G450WriteMNP(ScrnInfoPtr pScrn, CARD32 ulMNP) { MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; - - pReg = &pMga->ModeReg; if (!pMga->SecondCrtc) { outMGAdac(MGA1064_PIX_PLLC_M, (CARD8)(ulMNP >> 16)); @@ -212,11 +207,8 @@ static CARD32 G450WriteMNP(ScrnInfoPtr pScrn, CARD32 ulMNP) static CARD32 G450ReadMNP(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); - MGARegPtr pReg; CARD32 ret = 0; - pReg = &pMga->ModeReg; - if (!pMga->SecondCrtc) { ret = (CARD8)inMGAdac(MGA1064_PIX_PLLC_M) << 16; ret |= (CARD8)inMGAdac(MGA1064_PIX_PLLC_N) << 8; diff --git a/src/mga_hwcurs.c b/src/mga_hwcurs.c index 8b4e66b..35d98b8 100644 --- a/src/mga_hwcurs.c +++ b/src/mga_hwcurs.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c,v 1.9 1999/03/14 03:22:00 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c,v 1.8tsi Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -7,7 +7,6 @@ #include "xf86Pci.h" #include "xf86PciInfo.h" -#include "mga_bios.h" #include "mga.h" #include "mga_reg.h" diff --git a/src/mga_merge.c b/src/mga_merge.c index 986b0cb..a1378e9 100644 --- a/src/mga_merge.c +++ b/src/mga_merge.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_merge.c,v 1.3 2003/08/23 15:03:03 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_merge.c,v 1.4 2003/09/24 02:43:24 dawes Exp $ */ /* All drivers should typically include these */ #include "xf86.h" @@ -204,7 +204,7 @@ GenerateModeList(ScrnInfoPtr pScrn, char* str, 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"); + "Skipping clone mode \"%s\".\n", mode1->name); mode1 = NULL; } else { result = CopyModeNLink(pScrn,result,mode1,mode2,sr); @@ -374,7 +374,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags) * Read the BIOS data struct */ - MGAReadBios(pScrn); + mga_read_and_process_bios( pScrn ); /* HW bpp matches reported bpp */ pMga->HwBpp = pMga1->HwBpp; @@ -428,7 +428,8 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags) pMga->MinClock / 1000); /* Override on 2nd crtc */ - if (pMga->ChipRev >= 0x80) { /* G450 */ + if (pMga->ChipRev >= 0x80 || (pMga->Chipset == PCI_CHIP_MGAG550)) { + /* G450, G550 */ pMga->MaxClock = 234000; } else { pMga->MaxClock = 135000; diff --git a/src/mga_shadow.c b/src/mga_shadow.c index b1c228b..1f9f872 100644 --- a/src/mga_shadow.c +++ b/src/mga_shadow.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c,v 1.3 2000/02/08 13:13:18 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c,v 1.1 1999/08/14 10:49:48 dawes Exp $ */ /* Copyright (c) 1999, The XFree86 Project Inc. @@ -11,7 +11,6 @@ #include "xf86_ansic.h" #include "xf86PciInfo.h" #include "xf86Pci.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" #include "shadowfb.h" diff --git a/src/mga_storm.c b/src/mga_storm.c index 7661596..735011e 100644 --- a/src/mga_storm.c +++ b/src/mga_storm.c @@ -27,7 +27,6 @@ #include "GL/glxtokens.h" #endif -#include "mga_bios.h" #include "mga.h" #include "mga_reg.h" #include "mga_map.h" diff --git a/src/mga_video.c b/src/mga_video.c index 6429ad7..3ffdfe7 100644 --- a/src/mga_video.c +++ b/src/mga_video.c @@ -10,7 +10,6 @@ #include "xf86fbman.h" #include "regionstr.h" -#include "mga_bios.h" #include "mga_reg.h" #include "mga.h" #include "mga_macros.h" |