From: Petr V. <van...@vc...> - 2001-10-05 20:18:59
|
Hi, patch below allows kernel 2.4.10-ac5 to use my G550. It should also apply to Linus's post 2.4.10 kernels. It will work if you have connected analog VGA monitor to either of G550 outputs (mine has one analog and one digital + small part which allows connecting VGA monitor to this digital output), with only one small trap - you MUST compile-in G450 support if you have connected your monitor to secondary output (that's why people reported that driver does not work on G550...). In future I'll probably hide G450 option, hardwiring it to yes. As I do not have any digital flat panel (anybody has spare one?), I have no idea what it does with DFP. But I assume that it does not work... You should also download matroxset (ftp://platan.vc.cvut.cz/pub/linux/matrox-latest), as X are likely to switch your outputs off if you are not careful... Driver probably does not work if your BIOS/firmware did not initialize G550's memory subsystem. If you have datasheets, feel free to send them to me. Same applies if you know frequency parameters for secondary PLL - as I cannot believe that I should do it way in which G550 driver on CD does it (program PLL, if it does not work compute another PLL parameters and try again for 40 possible combinations). Thanks, Petr Vandrovec van...@vc... diff -urdN linux/drivers/video/matrox/i2c-matroxfb.c linux/drivers/video/matrox/i2c-matroxfb.c --- linux/drivers/video/matrox/i2c-matroxfb.c Fri Oct 5 17:00:42 2001 +++ linux/drivers/video/matrox/i2c-matroxfb.c Fri Oct 5 19:46:37 2001 @@ -282,8 +282,8 @@ return NULL; matroxfb_DAC_lock_irqsave(flags); - matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0x00); - matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0xFF); + matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0xFF); + matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0x00); matroxfb_DAC_unlock_irqrestore(flags); memset(m2info, 0, sizeof(*m2info)); diff -urdN linux/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c --- linux/drivers/video/matrox/matroxfb_base.c Fri Oct 5 17:00:43 2001 +++ linux/drivers/video/matrox/matroxfb_base.c Fri Oct 5 19:13:32 2001 @@ -988,8 +988,6 @@ #undef minfo } -static int matroxfb_switch(int con, struct fb_info *info); - static int matroxfb_get_vblank(CPMINFO struct fb_vblank *vblank) { unsigned int sts1; @@ -1183,7 +1181,7 @@ fb_ioctl: matroxfb_ioctl, }; -static int matroxfb_switch(int con, struct fb_info *info) +int matroxfb_switch(int con, struct fb_info *info) { #define minfo ((struct matrox_fb_info*)info) struct fb_cmap* cmap; @@ -1414,11 +1412,11 @@ #define DEVF_VIDEO64BIT 0x0001 #define DEVF_SWAPS 0x0002 #define DEVF_SRCORG 0x0004 -/* #define DEVF_recycled 0x0008 */ +#define DEVF_BOTHDACS 0x0008 /* put CRTC1 on both outputs by default */ #define DEVF_CROSS4MB 0x0010 #define DEVF_TEXT4B 0x0020 #define DEVF_DDC_8_2 0x0040 -/* #define DEVF_recycled 0x0080 */ +#define DEVF_G550DAC 0x0080 #define DEVF_SUPPORT32MB 0x0100 #define DEVF_ANY_VXRES 0x0200 #define DEVF_TEXT16B 0x0400 @@ -1434,6 +1432,7 @@ #define DEVF_G400 (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2) /* if you'll find how to drive DFP... */ #define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG) +#define DEVF_G550 (DEVF_G450 | DEVF_G550DAC | DEVF_BOTHDACS) static struct board { unsigned short vendor, device, rev, svid, sid; @@ -1477,13 +1476,13 @@ "Mystique 220 (PCI)"}, #endif #ifdef CONFIG_FB_MATROX_G100 - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_PCI, DEVF_G100, 230000, &vbG100, "MGA-G100 (PCI)"}, - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, 0, 0, DEVF_G100, 230000, @@ -1561,24 +1560,30 @@ 230000, &vbG200, "G200 (AGP)"}, - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0x80, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP, DEVF_G400, 360000, &vbG400, "Millennium G400 MAX (AGP)"}, - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0x80, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80, 0, 0, DEVF_G400, 300000, &vbG400, "G400 (AGP)"}, - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0xFF, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0xFF, 0, 0, DEVF_G450, 500000, /* ??? vco goes up to 900MHz... */ &vbG400, - "G450 (AGP)"}, + "G450"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, 0xFF, + 0, 0, + DEVF_G550, + 500000, + &vbG400, + "G550"}, #endif {0, 0, 0xFF, 0, 0, @@ -1641,8 +1646,18 @@ if (dfp) ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_DFP; } + if (b->flags & DEVF_BOTHDACS) { +#ifdef CONFIG_FB_MATROX_G450 + ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY; + ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_SECONDARY; +#else + printk(KERN_INFO "Only digital output of G550 is now working (in analog mode). Enable G450 support in\n" + printk(KERN_INFO "kernel configuration if you have analog monitor connected to G550 analog output.\n" +#endif + } ACCESS_FBINFO(devflags.dfp_type) = dfp_type; ACCESS_FBINFO(devflags.g450dac) = b->flags & DEVF_G450DAC; + ACCESS_FBINFO(devflags.g550dac) = b->flags & DEVF_G550DAC; ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); @@ -2140,7 +2155,7 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, #endif #ifdef CONFIG_FB_MATROX_G100 - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -2148,7 +2163,9 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, #endif {0, 0, @@ -2638,6 +2655,7 @@ module_exit(matrox_done); EXPORT_SYMBOL(matroxfb_register_driver); EXPORT_SYMBOL(matroxfb_unregister_driver); +EXPORT_SYMBOL(matroxfb_switch); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff -urdN linux/drivers/video/matrox/matroxfb_base.h linux/drivers/video/matrox/matroxfb_base.h --- linux/drivers/video/matrox/matroxfb_base.h Fri Oct 5 17:00:43 2001 +++ linux/drivers/video/matrox/matroxfb_base.h Fri Oct 5 19:13:23 2001 @@ -146,21 +146,6 @@ #ifndef PCI_SS_VENDOR_ID_MATROX #define PCI_SS_VENDOR_ID_MATROX PCI_VENDOR_ID_MATROX #endif -#ifndef PCI_DEVICE_ID_MATROX_G200_PCI -#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 -#endif -#ifndef PCI_DEVICE_ID_MATROX_G200_AGP -#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 -#endif -#ifndef PCI_DEVICE_ID_MATROX_G100 -#define PCI_DEVICE_ID_MATROX_G100 0x1000 -#endif -#ifndef PCI_DEVICE_ID_MATROX_G100_AGP -#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001 -#endif -#ifndef PCI_DEVICE_ID_MATROX_G400_AGP -#define PCI_DEVICE_ID_MATROX_G400_AGP 0x0525 -#endif #ifndef PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP #define PCI_SS_ID_MATROX_GENERIC 0xFF00 @@ -533,6 +518,7 @@ /* 0 except for 6MB Millenium */ int memtype; int g450dac; + int g550dac; int dfp_type; } devflags; struct display_switch dispsw; @@ -812,6 +798,7 @@ extern int matroxfb_DAC_in(CPMINFO int reg); extern struct list_head matroxfb_list; extern void matroxfb_var2my(struct fb_var_screeninfo* fvsi, struct my_timming* mt); +extern int matroxfb_switch(int con, struct fb_info *); #ifdef MATROXFB_USE_SPINLOCKS #define CRITBEGIN spin_lock_irqsave(&ACCESS_FBINFO(lock.accel), critflags); diff -urdN linux/drivers/video/matrox/matroxfb_crtc2.c linux/drivers/video/matrox/matroxfb_crtc2.c --- linux/drivers/video/matrox/matroxfb_crtc2.c Fri May 25 16:54:50 2001 +++ linux/drivers/video/matrox/matroxfb_crtc2.c Fri Oct 5 18:05:39 2001 @@ -700,15 +700,13 @@ m2info->mmio.len = ACCESS_FBINFO(mmio.len); /* - * If we have two outputs, connect CRTC2 to it... + * If we have unused output, connect CRTC2 to it... */ - if (ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_SECONDARY) { + if ((ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_SECONDARY) && + !(ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) && + !(ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)) { ACCESS_FBINFO(output.sh) |= MATROXFB_OUTPUT_CONN_SECONDARY; - ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_SECONDARY; - if (ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_DFP) { - ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_DFP; - ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_DFP; - } + ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_DFP; } matroxfb_dh_set_var(&matroxfb_dh_defined, -2, &m2info->fbcon); diff -urdN linux/drivers/video/matrox/matroxfb_g450.c linux/drivers/video/matrox/matroxfb_g450.c --- linux/drivers/video/matrox/matroxfb_g450.c Thu Jun 28 00:10:55 2001 +++ linux/drivers/video/matrox/matroxfb_g450.c Fri Oct 5 19:12:42 2001 @@ -1,3 +1,15 @@ +/* + * + * DAC driver for G450 and G550. + * + * (c) 1998-2001 Petr Vandrovec <van...@vc...> + * + * Version: 1.52 2001/10/05 + * + * See matroxfb_base.c for contributors. + * + */ + #include "matroxfb_g450.h" #include "matroxfb_misc.h" #include "matroxfb_DAC1064.h" @@ -31,36 +43,53 @@ 3 }; +static const struct matrox_pll_features g550_pll = { + 135000, + 27000, + 4, 127, + 0, 9, + 3 +}; + static void DAC1064_calcclock(unsigned int freq, unsigned int fmax, - unsigned int* in, unsigned int* feed, unsigned int* post) { + unsigned int* in, unsigned int* feed, unsigned int* post, + unsigned int timmings) { unsigned int fvco; unsigned int p; - fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p); - /* 0 => 100 ... 275 MHz - 1 => 243 ... 367 MHz - 2 => 320 ... 475 MHz - 3 => 453 ... 556 MHz - 4 => 540 ... 594 MHz - 5 => 588 ... 621 MHz - 6 => 626 ... 637 MHz - 7 => 631 ... 642 MHz + switch (timmings) { + default: + fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p); + /* 0 => 100 ... 275 MHz + 1 => 243 ... 367 MHz + 2 => 320 ... 475 MHz + 3 => 453 ... 556 MHz + 4 => 540 ... 594 MHz + 5 => 588 ... 621 MHz + 6 => 626 ... 637 MHz + 7 => 631 ... 642 MHz - As you can see, never choose frequency > 621 MHz, there is unavailable gap... - Just to be sure, currently driver uses 110 ... 500 MHz range. - */ - if (fvco <= 260000) - ; - else if (fvco <= 350000) - p |= 0x08; - else if (fvco <= 460000) - p |= 0x10; - else if (fvco <= 550000) - p |= 0x18; - else if (fvco <= 590000) - p |= 0x20; - else - p |= 0x28; + As you can see, never choose frequency > 621 MHz, there is unavailable gap... + Just to be sure, currently driver uses 110 ... 500 MHz range. + */ + if (fvco <= 260000) + ; + else if (fvco <= 350000) + p |= 0x08; + else if (fvco <= 460000) + p |= 0x10; + else if (fvco <= 550000) + p |= 0x18; + else if (fvco <= 590000) + p |= 0x20; + else + p |= 0x28; + break; + case 1: + fvco = matroxfb_PLL_calcclock(&g550_pll, freq, fmax, in, feed, &p); + /* p |= 0x00; */ + break; + } *post = p; return; } @@ -70,7 +99,7 @@ struct mavenregs* m) { unsigned int a, b, c; - DAC1064_calcclock(mt->pixclock, 500000, &a, &b, &c); + DAC1064_calcclock(mt->pixclock, 300000, &a, &b, &c, m2info->timmings); m->regs[0x80] = a; m->regs[0x81] = b; m->regs[0x82] = c; @@ -139,6 +168,7 @@ ACCESS_FBINFO(altout.output) = &matroxfb_g450_altout; up_write(&ACCESS_FBINFO(altout.lock)); ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY; + matroxfb_switch(ACCESS_FBINFO(currcon), (struct fb_info*)MINFO); return 0; } @@ -171,6 +201,11 @@ } memset(m2info, 0, sizeof(*m2info)); m2info->primary_dev = MINFO; + if (ACCESS_FBINFO(devflags.g550dac)) { + m2info->timmings = 1; + } else { + m2info->timmings = 0; + } if (matroxfb_g450_connect(m2info)) { kfree(m2info); printk(KERN_ERR "matroxfb_g450: G450 DAC failed to initialize\n"); @@ -198,7 +233,7 @@ matroxfb_unregister_driver(&g450); } -MODULE_AUTHOR("(c) 2000 Petr Vandrovec <van...@vc...>"); +MODULE_AUTHOR("(c) 2000-2001 Petr Vandrovec <van...@vc...>"); MODULE_DESCRIPTION("Matrox G450/G550 DAC driver"); module_init(matroxfb_g450_init); module_exit(matroxfb_g450_exit); diff -urdN linux/drivers/video/matrox/matroxfb_g450.h linux/drivers/video/matrox/matroxfb_g450.h --- linux/drivers/video/matrox/matroxfb_g450.h Fri Dec 29 22:07:23 2000 +++ linux/drivers/video/matrox/matroxfb_g450.h Fri Oct 5 19:14:18 2001 @@ -6,6 +6,7 @@ struct matroxfb_g450_info { struct matrox_fb_info* primary_dev; + unsigned int timmings; }; #endif /* __MATROXFB_MAVEN_H__ */ |