This patch adds the detection of G450/G550 vs. G400 via /proc/bus/pci.
It stops looking after the first suitable entry is found. So it should
work fine unless someone has some G400 and some G450/G550 cards in the
same machine :) Apply it on top of the first G450 patch.
I don't have any more improvements for the code unless bugs are found.
People, please test the code on all cards and report success/failure.
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
diff -urN DirectFB-g450proj/gfxdrivers/matrox/matrox_crtc2.c
DirectFB-g450-detect/gfxdrivers/matrox/matrox_crtc2.c
--- DirectFB-g450proj/gfxdrivers/matrox/matrox_crtc2.c Wed Dec 18 17:08:33 2002
+++ DirectFB-g450-detect/gfxdrivers/matrox/matrox_crtc2.c Thu Dec 19 00:07:28
+2002
@@ -117,8 +117,6 @@
bool ntsc = dfb_config->matrox_ntsc;
DFBResult res;
- /* FIXME: G450/G550 detection */
- mav->g450 = 1;
if ((res = maven_init( mav, mdrv )) != DFB_OK)
return res;
diff -urN DirectFB-g450proj/gfxdrivers/matrox/matrox_maven.c
DirectFB-g450-detect/gfxdrivers/matrox/matrox_maven.c
--- DirectFB-g450proj/gfxdrivers/matrox/matrox_maven.c Wed Dec 18 17:12:41 2002
+++ DirectFB-g450-detect/gfxdrivers/matrox/matrox_maven.c Thu Dec 19 02:07:16
+2002
@@ -22,6 +22,7 @@
*/
#include <stdio.h>
+#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
@@ -314,191 +315,91 @@
DFBResult maven_init( MatroxMavenData *mav,
MatroxDriverData *mdrv )
{
- const __u8 ntscregs[64] = {
- 0x21, 0xF0, 0x7C, 0x1F, /* 00-03 */
- 0x00, /* 04 */
- 0x00,
- 0x00,
- 0x00,
- 0x7E, /* 08 */
- 0x43, /* 09 */
- 0x7E, /* 0A */
- 0x3D, /* 0B */
- 0x00, /* 0C */
- 0x00,
- 0x46, 0x03, /* 0E-0F */
- 0x3C, 0x02, /* 10-11 */
- 0x17, /* 12 */
- 0x21, /* 13 */
- 0x1B, /* 14 */
- 0x1B, /* 15 */
- 0x24, /* 16 */
- 0x83, 0x01, /* 17-18 */
- 0x00, /* 19 */
- 0x0F, /* 1A */
- 0x0F, /* 1B */
- 0x60, /* 1C */
- 0x05, /* 1D */
- 0xC4, 0x02, /* 1E-1F */
- 0x8E, /* 20 */
- 0x04, /* 21 */
- 0x8E, /* 22 */
- 0x01, /* 23 */
- 0x02, /* 24 */
- 0x00, /* 25 */
- 0x0A, /* 26 */
- 0x05, /* 27 */
- 0x00, /* 28 */
- 0x10, /* 29 */
- 0xFF, 0x03, /* 2A-2B */
- 0x18, /* 2C */
- 0x0F, 0x78, /* 2D-2E */
- 0x00, 0x00, /* 2F-30 */
- 0xB4, 0x00, /* 31-32 */
- 0x14, /* 33 */
- 0x02, /* 34 */
- 0x1C, /* 35 */
- 0x00,
- 0xA3, /* 37 */
- 0xC8, /* 38 */
- 0x15, /* 39 */
- 0x05, /* 3A */
- 0x15, /* 3B */
- 0x3C, 0x00, /* 3C-3D */
- 0x00, /* 3E */
- 0x00
- };
- const __u8 palregs[64] = {
- 0x2A, 0x09, 0x8A, 0xCB, /* 00-03 */
- 0x00, /* 04 */
- 0x00,
- 0x00,
- 0x00,
- 0x7E, /* 08 */
- 0x3C, /* 09 */
- 0x82, /* 0A */
- 0x2E, /* 0B */
- 0x21, /* 0C */
- 0x00,
- 0x3F, 0x03, /* 0E-0F */
- 0x3F, 0x03, /* 10-11 */
- 0x1A, /* 12 */
- 0x2A, /* 13 */
- 0x1C, /* 14 */
- 0x3D, /* 15 */
- 0x14, /* 16 */
- 0x9C, 0x01, /* 17-18 */
- 0x00, /* 19 */
- 0xFE, /* 1A */
- 0x7E, /* 1B */
- 0x60, /* 1C */
- 0x05, /* 1D */
- 0xC4, 0x01, /* 1E-1F */
- 0x95, /* 20 */
- 0x07, /* 21 */
- 0x95, /* 22 */
- 0x00, /* 23 */
- 0x00, /* 24 */
- 0x00, /* 25 */
- 0x08, /* 26 */
- 0x04, /* 27 */
- 0x00, /* 28 */
- 0x1A, /* 29 */
- 0x55, 0x01, /* 2A-2B */
- 0x20, /* 2C */
- 0x07, 0x7E, /* 2D-2E */
- 0x02, 0x54, /* 2F-30 */
- 0xB4, 0x00, /* 31-32 */
- 0x14, /* 33 */
- 0x49, /* 34 */
- 0x1D, /* 35 */
- 0x00,
- 0xA3, /* 37 */
- 0xC8, /* 38 */
- 0x22, /* 39 */
- 0x02, /* 3A */
- 0x22, /* 3B */
- 0x3F, 0x03, /* 3C-3D */
- 0x00, /* 3E */
- 0x00,
- };
+ char line[512];
+ int fd, found;
+ FILE *file;
- if (dfb_config->matrox_ntsc)
- memcpy( mav->regs, ntscregs, 64 );
- else
- memcpy( mav->regs, palregs, 64 );
+ /* Determine chip type (G400 or G450/G550) */
+ {
+ unsigned int devfn, devid, rev;
- /* FIXME: G450/G550 detection */
+ found = 0;
- if (mav->g450) {
- if (dfb_config->matrox_ntsc) {
- mav->regs[0x09] = 0x44;
- mav->regs[0x0A] = 0x76;
- mav->regs[0x0B] = 0x49;
- mav->regs[0x0C] = 0x00;
- mav->regs[0x0E] = 0x3E;
- mav->regs[0x0F] = 0x00;
- mav->regs[0x10] = 0x32;
- mav->regs[0x11] = 0x00;
- mav->regs[0x1E] = 0xD9;
- mav->regs[0x1F] = 0x01;
- mav->regs[0x20] = 0xAE;
- mav->regs[0x22] = 0xAE;
- mav->regs[0x29] = 0x11;
- mav->regs[0x2C] = 0x20;
- mav->regs[0x33] = 0x14;
- mav->regs[0x35] = 0x00;
- mav->regs[0x37] = 0xBD;
- mav->regs[0x38] = 0xDA;
- mav->regs[0x3C] = 0x42;
- mav->regs[0x3D] = 0x03;
- } else {
- mav->regs[0x09] = 0x3A;
- mav->regs[0x0A] = 0x8A;
- mav->regs[0x0B] = 0x38;
- mav->regs[0x0C] = 0x28;
- mav->regs[0x0E] = 0x38;
- mav->regs[0x0F] = 0x00;
- mav->regs[0x10] = 0x38;
- mav->regs[0x11] = 0x00;
- mav->regs[0x1E] = 0xDB;
- mav->regs[0x1F] = 0x03;
- mav->regs[0x20] = 0xBB;
- mav->regs[0x22] = 0xBB;
- mav->regs[0x29] = 0x1A;
- mav->regs[0x2C] = 0x18;
- mav->regs[0x33] = 0x16;
- mav->regs[0x35] = 0x00;
- mav->regs[0x37] = 0xB9;
- mav->regs[0x38] = 0xDD;
- mav->regs[0x3C] = 0x46;
- mav->regs[0x3D] = 0x00;
+ file = fopen( "/proc/bus/pci/devices", "r" );
+ if (!file) {
+ PERRORMSG( "DirectFB/Matrox/Maven: "
+ "Error opening `/proc/bus/pci/devices'!\n" );
+ return errno2dfb( errno );
+ }
+ while (fgets( line, 512, file )) {
+ sscanf( line,
+ "%x %x %*x %*x %*x %*x"
+ "%*x %*x %*x %*x %*x"
+ "%*x %*x %*x %*x %*x"
+ "%*x",
+ &devfn, &devid );
+
+ /* vendor */
+ if ((devid >> 16) != 0x102B)
+ continue;
+
+ /* device */
+ if ((devid & 0xFFFF) == 0x2527) {
+ /* G550 */
+ mav->g450 = 1;
+ found = 1;
+ break;
+ } else if ((devid & 0xFFFF) == 0x0525) {
+ /* G400 or G450 -> check revision */
+ snprintf( line, 512,
+ "/proc/bus/pci/%02x/%02x.%x",
+ devfn >> 8,
+ (devfn >> 3) & 0x1F,
+ devfn & 0x07 );
+
+ fd = open( line, O_RDONLY );
+ if (fd < 0)
+ continue;
+
+ if (lseek( fd, 0x08, SEEK_SET ) != 0x08) {
+ close( fd );
+ continue;
+ }
+ if (read( fd, &rev, 1 ) != 1) {
+ close( fd );
+ continue;
+ }
+ close( fd );
+
+ if ((rev & 0xFF) >= 0x80)
+ mav->g450 = 1;
+ else
+ mav->g450 = 0;
+
+ found = 1;
+ break;
+ }
+ }
+ fclose( file );
+
+ if (!found) {
+ ERRORMSG( "DirectFB/Matrox/Maven: "
+ "Can't determine if chip is G400 or G450/G550!\n" );
+ return DFB_UNSUPPORTED;
}
- } else {
- /* gamma */
- mav->regs[0x83] = 0x00;
- mav->regs[0x84] = 0x00;
- mav->regs[0x85] = 0x00;
- mav->regs[0x86] = 0x1F;
- mav->regs[0x87] = 0x10;
- mav->regs[0x88] = 0x10;
- mav->regs[0x89] = 0x10;
- mav->regs[0x8A] = 0x64;
- mav->regs[0x8B] = 0xC8;
}
+ /* Locate G400 maven /dev/i2c file */
if (!mav->g450) {
- char line[256];
- FILE *file;
- int fd, found = 0;
+ found = 0;
- /* Locate maven /dev/i2c entry */
file = fopen( "/proc/bus/i2c", "r" );
if (!file) {
- PERRORMSG( "DirectFB/Matrox/Maven: Error opening `/proc/bus/i2c'!\n" );
+ PERRORMSG( "DirectFB/Matrox/Maven: "
+ "Error opening `/proc/bus/i2c'!\n" );
return errno2dfb( errno );
}
- while (fgets( line, 256, file )) {
+ while (fgets( line, 512, file )) {
if (strstr( line, "MAVEN" )) {
char *p = line;
while (!isspace( *p ))
@@ -513,7 +414,8 @@
fclose( file );
if (!found) {
- ERRORMSG( "DirectFB/Matrox/Maven: Can't find MAVEN in
/proc/bus/i2c!\n" );
+ ERRORMSG( "DirectFB/Matrox/Maven: "
+ "Can't find MAVEN in /proc/bus/i2c!\n" );
return DFB_UNSUPPORTED;
}
@@ -531,6 +433,180 @@
return errno2dfb( errno );
}
close( fd );
+ }
+
+ /* Maven registers */
+ {
+ const __u8 ntscregs[64] = {
+ 0x21, 0xF0, 0x7C, 0x1F, /* 00-03 */
+ 0x00, /* 04 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7E, /* 08 */
+ 0x43, /* 09 */
+ 0x7E, /* 0A */
+ 0x3D, /* 0B */
+ 0x00, /* 0C */
+ 0x00,
+ 0x46, 0x03, /* 0E-0F */
+ 0x3C, 0x02, /* 10-11 */
+ 0x17, /* 12 */
+ 0x21, /* 13 */
+ 0x1B, /* 14 */
+ 0x1B, /* 15 */
+ 0x24, /* 16 */
+ 0x83, 0x01, /* 17-18 */
+ 0x00, /* 19 */
+ 0x0F, /* 1A */
+ 0x0F, /* 1B */
+ 0x60, /* 1C */
+ 0x05, /* 1D */
+ 0xC4, 0x02, /* 1E-1F */
+ 0x8E, /* 20 */
+ 0x04, /* 21 */
+ 0x8E, /* 22 */
+ 0x01, /* 23 */
+ 0x02, /* 24 */
+ 0x00, /* 25 */
+ 0x0A, /* 26 */
+ 0x05, /* 27 */
+ 0x00, /* 28 */
+ 0x10, /* 29 */
+ 0xFF, 0x03, /* 2A-2B */
+ 0x18, /* 2C */
+ 0x0F, 0x78, /* 2D-2E */
+ 0x00, 0x00, /* 2F-30 */
+ 0xB4, 0x00, /* 31-32 */
+ 0x14, /* 33 */
+ 0x02, /* 34 */
+ 0x1C, /* 35 */
+ 0x00,
+ 0xA3, /* 37 */
+ 0xC8, /* 38 */
+ 0x15, /* 39 */
+ 0x05, /* 3A */
+ 0x15, /* 3B */
+ 0x3C, 0x00, /* 3C-3D */
+ 0x00, /* 3E */
+ 0x00
+ };
+ const __u8 palregs[64] = {
+ 0x2A, 0x09, 0x8A, 0xCB, /* 00-03 */
+ 0x00, /* 04 */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x7E, /* 08 */
+ 0x3C, /* 09 */
+ 0x82, /* 0A */
+ 0x2E, /* 0B */
+ 0x21, /* 0C */
+ 0x00,
+ 0x3F, 0x03, /* 0E-0F */
+ 0x3F, 0x03, /* 10-11 */
+ 0x1A, /* 12 */
+ 0x2A, /* 13 */
+ 0x1C, /* 14 */
+ 0x3D, /* 15 */
+ 0x14, /* 16 */
+ 0x9C, 0x01, /* 17-18 */
+ 0x00, /* 19 */
+ 0xFE, /* 1A */
+ 0x7E, /* 1B */
+ 0x60, /* 1C */
+ 0x05, /* 1D */
+ 0xC4, 0x01, /* 1E-1F */
+ 0x95, /* 20 */
+ 0x07, /* 21 */
+ 0x95, /* 22 */
+ 0x00, /* 23 */
+ 0x00, /* 24 */
+ 0x00, /* 25 */
+ 0x08, /* 26 */
+ 0x04, /* 27 */
+ 0x00, /* 28 */
+ 0x1A, /* 29 */
+ 0x55, 0x01, /* 2A-2B */
+ 0x20, /* 2C */
+ 0x07, 0x7E, /* 2D-2E */
+ 0x02, 0x54, /* 2F-30 */
+ 0xB4, 0x00, /* 31-32 */
+ 0x14, /* 33 */
+ 0x49, /* 34 */
+ 0x1D, /* 35 */
+ 0x00,
+ 0xA3, /* 37 */
+ 0xC8, /* 38 */
+ 0x22, /* 39 */
+ 0x02, /* 3A */
+ 0x22, /* 3B */
+ 0x3F, 0x03, /* 3C-3D */
+ 0x00, /* 3E */
+ 0x00,
+ };
+
+ if (dfb_config->matrox_ntsc)
+ memcpy( mav->regs, ntscregs, 64 );
+ else
+ memcpy( mav->regs, palregs, 64 );
+
+ if (mav->g450) {
+ if (dfb_config->matrox_ntsc) {
+ mav->regs[0x09] = 0x44;
+ mav->regs[0x0A] = 0x76;
+ mav->regs[0x0B] = 0x49;
+ mav->regs[0x0C] = 0x00;
+ mav->regs[0x0E] = 0x3E;
+ mav->regs[0x0F] = 0x00;
+ mav->regs[0x10] = 0x32;
+ mav->regs[0x11] = 0x00;
+ mav->regs[0x1E] = 0xD9;
+ mav->regs[0x1F] = 0x01;
+ mav->regs[0x20] = 0xAE;
+ mav->regs[0x22] = 0xAE;
+ mav->regs[0x29] = 0x11;
+ mav->regs[0x2C] = 0x20;
+ mav->regs[0x33] = 0x14;
+ mav->regs[0x35] = 0x00;
+ mav->regs[0x37] = 0xBD;
+ mav->regs[0x38] = 0xDA;
+ mav->regs[0x3C] = 0x42;
+ mav->regs[0x3D] = 0x03;
+ } else {
+ mav->regs[0x09] = 0x3A;
+ mav->regs[0x0A] = 0x8A;
+ mav->regs[0x0B] = 0x38;
+ mav->regs[0x0C] = 0x28;
+ mav->regs[0x0E] = 0x38;
+ mav->regs[0x0F] = 0x00;
+ mav->regs[0x10] = 0x38;
+ mav->regs[0x11] = 0x00;
+ mav->regs[0x1E] = 0xDB;
+ mav->regs[0x1F] = 0x03;
+ mav->regs[0x20] = 0xBB;
+ mav->regs[0x22] = 0xBB;
+ mav->regs[0x29] = 0x1A;
+ mav->regs[0x2C] = 0x18;
+ mav->regs[0x33] = 0x16;
+ mav->regs[0x35] = 0x00;
+ mav->regs[0x37] = 0xB9;
+ mav->regs[0x38] = 0xDD;
+ mav->regs[0x3C] = 0x46;
+ mav->regs[0x3D] = 0x00;
+ }
+ } else {
+ /* gamma */
+ mav->regs[0x83] = 0x00;
+ mav->regs[0x84] = 0x00;
+ mav->regs[0x85] = 0x00;
+ mav->regs[0x86] = 0x1F;
+ mav->regs[0x87] = 0x10;
+ mav->regs[0x88] = 0x10;
+ mav->regs[0x89] = 0x10;
+ mav->regs[0x8A] = 0x64;
+ mav->regs[0x8B] = 0xC8;
+ }
}
return DFB_OK;