Commit 705e41f8 authored by Petr Vandrovec's avatar Petr Vandrovec

matroxfb DVI updates:

Handle DVI output on G450/G550.
Powerdown unused portions of G450/G550 DAC.
Split G450/G550 DAC from older DAC1064 handling.
Modify PLL setting when both CRTCs use same pixel clocks.
parent 9f8213f9
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* *
* Hardware accelerated Matrox PCI cards - G450/G550 PLL control. * Hardware accelerated Matrox PCI cards - G450/G550 PLL control.
* *
* (c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz> * (c) 2001-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
* *
* Portions Copyright (c) 2001 Matrox Graphics Inc. * Portions Copyright (c) 2001 Matrox Graphics Inc.
* *
* Version: 1.62 2001/11/29 * Version: 1.64 2002/06/10
* *
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for * License. See the file COPYING in the main directory of this archive for
...@@ -33,6 +33,10 @@ static unsigned int g450_mnp2vco(CPMINFO unsigned int mnp) { ...@@ -33,6 +33,10 @@ static unsigned int g450_mnp2vco(CPMINFO unsigned int mnp) {
return (ACCESS_FBINFO(features).pll.ref_freq * n + (m >> 1)) / m; return (ACCESS_FBINFO(features).pll.ref_freq * n + (m >> 1)) / m;
} }
unsigned int g450_mnp2f(CPMINFO unsigned int mnp) {
return g450_vco2f(mnp, g450_mnp2vco(PMINFO mnp));
}
static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) { static inline unsigned int pll_freq_delta(unsigned int f1, unsigned int f2) {
if (f2 < f1) { if (f2 < f1) {
f2 = f1 - f2; f2 = f1 - f2;
...@@ -52,6 +56,7 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns ...@@ -52,6 +56,7 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns
m = (mnp >> 16) & 0xFF; m = (mnp >> 16) & 0xFF;
p = mnp & 0xFF; p = mnp & 0xFF;
do {
if (m == 0 || m == 0xFF) { if (m == 0 || m == 0xFF) {
if (m == 0) { if (m == 0) {
if (p & 0x40) { if (p & 0x40) {
...@@ -86,6 +91,7 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns ...@@ -86,6 +91,7 @@ static unsigned int g450_nextpll(CPMINFO const struct matrox_pll_limits* pi, uns
m--; m--;
} }
n = ((tvco * (m+1) + ACCESS_FBINFO(features).pll.ref_freq) / (ACCESS_FBINFO(features).pll.ref_freq * 2)) - 2; n = ((tvco * (m+1) + ACCESS_FBINFO(features).pll.ref_freq) / (ACCESS_FBINFO(features).pll.ref_freq * 2)) - 2;
} while (n < 0x03 || n > 0x7A);
return (m << 16) | (n << 8) | p; return (m << 16) | (n << 8) | p;
} }
...@@ -219,7 +225,7 @@ static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsi ...@@ -219,7 +225,7 @@ static void updatehwstate_clk(struct matrox_hw_state* hw, unsigned int mnp, unsi
} }
} }
static inline void g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll) { void matroxfb_g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll) {
if (g450_cmppll(PMINFO mnp, pll)) { if (g450_cmppll(PMINFO mnp, pll)) {
g450_setpll(PMINFO mnp, pll); g450_setpll(PMINFO mnp, pll);
} }
...@@ -385,10 +391,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, ...@@ -385,10 +391,8 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
unsigned int vco; unsigned int vco;
unsigned int delta; unsigned int delta;
if ((mnp & 0xFF00) < 0x0300 || (mnp & 0xFF00) > 0x7A00) {
continue;
}
vco = g450_mnp2vco(PMINFO mnp); vco = g450_mnp2vco(PMINFO mnp);
#if 0
if (pll == M_VIDEO_PLL) { if (pll == M_VIDEO_PLL) {
unsigned int big, small; unsigned int big, small;
...@@ -406,6 +410,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, ...@@ -406,6 +410,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
continue; continue;
} }
} }
#endif
delta = pll_freq_delta(fout, g450_vco2f(mnp, vco)); delta = pll_freq_delta(fout, g450_vco2f(mnp, vco));
for (idx = mnpcount; idx > 0; idx--) { for (idx = mnpcount; idx > 0; idx--) {
/* == is important; due to nextpll algorithm we get /* == is important; due to nextpll algorithm we get
...@@ -426,7 +431,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, ...@@ -426,7 +431,7 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
} }
/* VideoPLL and PixelPLL matched: do nothing... In all other cases we should get at least one frequency */ /* VideoPLL and PixelPLL matched: do nothing... In all other cases we should get at least one frequency */
if (!mnpcount) { if (!mnpcount) {
return 1; return -EBUSY;
} }
{ {
unsigned long flags; unsigned long flags;
...@@ -435,15 +440,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, ...@@ -435,15 +440,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
matroxfb_DAC_lock_irqsave(flags); matroxfb_DAC_lock_irqsave(flags);
mnp = g450_checkcache(PMINFO ci, mnparray[0]); mnp = g450_checkcache(PMINFO ci, mnparray[0]);
if (mnp != NO_MORE_MNP) { if (mnp != NO_MORE_MNP) {
g450_setpll_cond(PMINFO mnp, pll); matroxfb_g450_setpll_cond(PMINFO mnp, pll);
} else { } else {
mnp = g450_findworkingpll(PMINFO pll, mnparray, mnpcount); mnp = g450_findworkingpll(PMINFO pll, mnparray, mnpcount);
g450_addcache(ci, mnparray[0], mnp); g450_addcache(ci, mnparray[0], mnp);
} }
updatehwstate_clk(&ACCESS_FBINFO(hw), mnp, pll); updatehwstate_clk(&ACCESS_FBINFO(hw), mnp, pll);
matroxfb_DAC_unlock_irqrestore(flags); matroxfb_DAC_unlock_irqrestore(flags);
return mnp;
} }
return 0;
} }
/* It must be greater than number of possible PLL values. /* It must be greater than number of possible PLL values.
...@@ -465,8 +470,10 @@ int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll) { ...@@ -465,8 +470,10 @@ int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll) {
} }
EXPORT_SYMBOL(matroxfb_g450_setclk); EXPORT_SYMBOL(matroxfb_g450_setclk);
EXPORT_SYMBOL(g450_mnp2f);
EXPORT_SYMBOL(matroxfb_g450_setpll_cond);
MODULE_AUTHOR("(c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz>"); MODULE_AUTHOR("(c) 2001-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");
MODULE_DESCRIPTION("Matrox G450/G550 PLL driver"); MODULE_DESCRIPTION("Matrox G450/G550 PLL driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -4,5 +4,7 @@ ...@@ -4,5 +4,7 @@
#include "matroxfb_base.h" #include "matroxfb_base.h"
int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll); int matroxfb_g450_setclk(WPMINFO unsigned int fout, unsigned int pll);
unsigned int g450_mnp2f(CPMINFO unsigned int mnp);
void matroxfb_g450_setpll_cond(WPMINFO unsigned int mnp, unsigned int pll);
#endif /* __G450_PLL_H__ */ #endif /* __G450_PLL_H__ */
This diff is collapsed.
...@@ -146,6 +146,8 @@ void DAC1064_global_restore(WPMINFO2); ...@@ -146,6 +146,8 @@ void DAC1064_global_restore(WPMINFO2);
#define M1064_XPWRCTRL 0xA0 #define M1064_XPWRCTRL 0xA0
#define M1064_XPANMODE 0xA2
enum POS1064 { enum POS1064 {
POS1064_XCURADDL=0, POS1064_XCURADDH, POS1064_XCURCTRL, POS1064_XCURADDL=0, POS1064_XCURADDH, POS1064_XCURCTRL,
POS1064_XCURCOL0RED, POS1064_XCURCOL0GREEN, POS1064_XCURCOL0BLUE, POS1064_XCURCOL0RED, POS1064_XCURCOL0GREEN, POS1064_XCURCOL0BLUE,
...@@ -156,7 +158,7 @@ enum POS1064 { ...@@ -156,7 +158,7 @@ enum POS1064 {
POS1064_XGENIOCTRL, POS1064_XGENIODATA, POS1064_XZOOMCTRL, POS1064_XSENSETEST, POS1064_XGENIOCTRL, POS1064_XGENIODATA, POS1064_XZOOMCTRL, POS1064_XSENSETEST,
POS1064_XCRCBITSEL, POS1064_XCRCBITSEL,
POS1064_XCOLKEYMASKL, POS1064_XCOLKEYMASKH, POS1064_XCOLKEYL, POS1064_XCOLKEYH, POS1064_XCOLKEYMASKL, POS1064_XCOLKEYMASKH, POS1064_XCOLKEYL, POS1064_XCOLKEYH,
POS1064_XOUTPUTCONN }; POS1064_XOUTPUTCONN, POS1064_XPANMODE, POS1064_XPWRCTRL };
#endif /* __MATROXFB_DAC1064_H__ */ #endif /* __MATROXFB_DAC1064_H__ */
...@@ -796,6 +796,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -796,6 +796,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
int out; int out;
matroxfb_var2my(var, &mt); matroxfb_var2my(var, &mt);
mt.crtc = MATROXFB_SRC_CRTC1;
/* CRTC1 delays */ /* CRTC1 delays */
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 0: mt.delay = 31 + 0; break; case 0: mt.delay = 31 + 0; break;
...@@ -818,6 +819,8 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con, ...@@ -818,6 +819,8 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
} }
} }
up_read(&ACCESS_FBINFO(altout).lock); up_read(&ACCESS_FBINFO(altout).lock);
ACCESS_FBINFO(crtc1).pixclock = mt.pixclock;
ACCESS_FBINFO(crtc1).mnp = mt.mnp;
ACCESS_FBINFO(hw_switch->init(PMINFO &mt, display)); ACCESS_FBINFO(hw_switch->init(PMINFO &mt, display));
if (display->type == FB_TYPE_TEXT) { if (display->type == FB_TYPE_TEXT) {
if (fontheight(display)) if (fontheight(display))
......
...@@ -288,6 +288,8 @@ static inline void mga_iounmap(vaddr_t va) { ...@@ -288,6 +288,8 @@ static inline void mga_iounmap(vaddr_t va) {
struct my_timming { struct my_timming {
unsigned int pixclock; unsigned int pixclock;
int mnp;
unsigned int crtc;
unsigned int HDisplay; unsigned int HDisplay;
unsigned int HSyncStart; unsigned int HSyncStart;
unsigned int HSyncEnd; unsigned int HSyncEnd;
...@@ -364,6 +366,10 @@ struct mavenregs { ...@@ -364,6 +366,10 @@ struct mavenregs {
u_int16_t hcorr; u_int16_t hcorr;
}; };
struct matrox_crtc2 {
u_int32_t ctl;
};
struct matrox_hw_state { struct matrox_hw_state {
u_int32_t MXoptionReg; u_int32_t MXoptionReg;
unsigned char DACclk[6]; unsigned char DACclk[6];
...@@ -381,10 +387,7 @@ struct matrox_hw_state { ...@@ -381,10 +387,7 @@ struct matrox_hw_state {
/* TVOut only */ /* TVOut only */
struct mavenregs maven; struct mavenregs maven;
/* CRTC2 only */ struct matrox_crtc2 crtc2;
/* u_int32_t TBD */
unsigned int vidclk;
}; };
struct matrox_accel_data { struct matrox_accel_data {
...@@ -441,6 +444,12 @@ struct matrox_fb_info { ...@@ -441,6 +444,12 @@ struct matrox_fb_info {
struct pci_dev* pcidev; struct pci_dev* pcidev;
struct { struct {
unsigned int pixclock;
int mnp;
} crtc1;
struct {
unsigned int pixclock;
int mnp;
struct matroxfb_dh_fb_info* info; struct matroxfb_dh_fb_info* info;
struct rw_semaphore lock; struct rw_semaphore lock;
} crtc2; } crtc2;
......
...@@ -142,7 +142,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, ...@@ -142,7 +142,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mt->VSyncEnd >>= 1; mt->VSyncEnd >>= 1;
mt->VTotal >>= 1; mt->VTotal >>= 1;
} }
mga_outl(0x3C10, tmp | 0x10000000); /* depth and so on... 0x10000000 is VIDRST polarity */ tmp |= 0x10000000; /* 0x10000000 is VIDRST polarity */
mga_outl(0x3C14, ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8)); mga_outl(0x3C14, ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8));
mga_outl(0x3C18, ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8)); mga_outl(0x3C18, ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8));
mga_outl(0x3C1C, ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1)); mga_outl(0x3C1C, ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1));
...@@ -150,7 +150,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, ...@@ -150,7 +150,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mga_outl(0x3C24, ((mt->VSyncStart) << 16) | (mt->HSyncStart)); /* preload */ mga_outl(0x3C24, ((mt->VSyncStart) << 16) | (mt->HSyncStart)); /* preload */
{ {
u_int32_t linelen = p->var.xres_virtual * (p->var.bits_per_pixel >> 3); u_int32_t linelen = p->var.xres_virtual * (p->var.bits_per_pixel >> 3);
if (mt->interlaced) { if (tmp & 0x02000000) {
/* field #0 is smaller, so... */ /* field #0 is smaller, so... */
mga_outl(0x3C2C, pos); /* field #1 vmemory start */ mga_outl(0x3C2C, pos); /* field #1 vmemory start */
mga_outl(0x3C28, pos + linelen); /* field #0 vmemory start */ mga_outl(0x3C28, pos + linelen); /* field #0 vmemory start */
...@@ -160,19 +160,36 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info, ...@@ -160,19 +160,36 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
} }
mga_outl(0x3C40, linelen); mga_outl(0x3C40, linelen);
} }
mga_outl(0x3C4C, 0); /* data control */
if (tmp & 0x02000000) {
int i;
mga_outl(0x3C10, tmp & ~0x02000000);
for (i = 0; i < 2; i++) {
unsigned int nl;
unsigned int lastl = 0;
while ((nl = mga_inl(0x3C48) & 0xFFF) >= lastl) {
lastl = nl;
}
}
}
mga_outl(0x3C10, tmp);
ACCESS_FBINFO(hw).crtc2.ctl = tmp;
tmp = 0x0FFF0000; /* line compare */ tmp = 0x0FFF0000; /* line compare */
if (mt->sync & FB_SYNC_HOR_HIGH_ACT) if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
tmp |= 0x00000100; tmp |= 0x00000100;
if (mt->sync & FB_SYNC_VERT_HIGH_ACT) if (mt->sync & FB_SYNC_VERT_HIGH_ACT)
tmp |= 0x00000200; tmp |= 0x00000200;
mga_outl(0x3C44, tmp); mga_outl(0x3C44, tmp);
mga_outl(0x3C4C, 0); /* data control */
} }
static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) { static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) {
MINFO_FROM(m2info->primary_dev); MINFO_FROM(m2info->primary_dev);
mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */ mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */
ACCESS_FBINFO(hw).crtc2.ctl = 0x00000004;
} }
static void matroxfb_dh_cfbX_init(struct matroxfb_dh_fb_info* m2info, static void matroxfb_dh_cfbX_init(struct matroxfb_dh_fb_info* m2info,
...@@ -417,6 +434,7 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con, ...@@ -417,6 +434,7 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
int cnt; int cnt;
matroxfb_var2my(var, &mt); matroxfb_var2my(var, &mt);
mt.crtc = MATROXFB_SRC_CRTC2;
/* CRTC2 delay */ /* CRTC2 delay */
mt.delay = 34; mt.delay = 34;
...@@ -432,6 +450,8 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con, ...@@ -432,6 +450,8 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
} }
} }
} }
ACCESS_FBINFO(crtc2).pixclock = mt.pixclock;
ACCESS_FBINFO(crtc2).mnp = mt.mnp;
up_read(&ACCESS_FBINFO(altout).lock); up_read(&ACCESS_FBINFO(altout).lock);
if (cnt) { if (cnt) {
matroxfb_dh_restore(m2info, &mt, p, mode, pos); matroxfb_dh_restore(m2info, &mt, p, mode, pos);
......
...@@ -20,16 +20,28 @@ ...@@ -20,16 +20,28 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
static int matroxfb_g450_compute(void* md, struct my_timming* mt) { static int matroxfb_g450_compute(void* md, struct my_timming* mt) {
#define minfo ((struct matrox_fb_info*)md) MINFO_FROM(md);
ACCESS_FBINFO(hw).vidclk = mt->pixclock;
#undef minfo if (mt->mnp < 0) {
/* We must program clocks before CRTC2, otherwise interlaced mode
startup may fail */
mt->mnp = matroxfb_g450_setclk(PMINFO mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
mt->pixclock = g450_mnp2f(PMINFO mt->mnp);
}
return 0; return 0;
} }
static int matroxfb_g450_program(void* md) { static int matroxfb_g450_program(void* md) {
#define minfo ((struct matrox_fb_info*)md) return 0;
matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(hw).vidclk, M_VIDEO_PLL); }
#undef minfo
static int g450_dvi_compute(void* md, struct my_timming* mt) {
MINFO_FROM(md);
if (mt->mnp < 0) {
mt->mnp = matroxfb_g450_setclk(PMINFO mt->pixclock, (mt->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
mt->pixclock = g450_mnp2f(PMINFO mt->mnp);
}
return 0; return 0;
} }
...@@ -39,6 +51,11 @@ static struct matrox_altout matroxfb_g450_altout = { ...@@ -39,6 +51,11 @@ static struct matrox_altout matroxfb_g450_altout = {
.program = matroxfb_g450_program, .program = matroxfb_g450_program,
}; };
static struct matrox_altout matroxfb_g450_dvi = {
.name = "DVI output",
.compute = g450_dvi_compute,
};
void matroxfb_g450_connect(WPMINFO2) { void matroxfb_g450_connect(WPMINFO2) {
if (ACCESS_FBINFO(devflags.g450dac)) { if (ACCESS_FBINFO(devflags.g450dac)) {
down_write(&ACCESS_FBINFO(altout.lock)); down_write(&ACCESS_FBINFO(altout.lock));
...@@ -46,6 +63,10 @@ void matroxfb_g450_connect(WPMINFO2) { ...@@ -46,6 +63,10 @@ void matroxfb_g450_connect(WPMINFO2) {
ACCESS_FBINFO(outputs[1]).data = MINFO; ACCESS_FBINFO(outputs[1]).data = MINFO;
ACCESS_FBINFO(outputs[1]).output = &matroxfb_g450_altout; ACCESS_FBINFO(outputs[1]).output = &matroxfb_g450_altout;
ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
ACCESS_FBINFO(outputs[2]).src = MATROXFB_SRC_CRTC1;
ACCESS_FBINFO(outputs[2]).data = MINFO;
ACCESS_FBINFO(outputs[2]).output = &matroxfb_g450_dvi;
ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock)); up_write(&ACCESS_FBINFO(altout.lock));
} }
} }
...@@ -57,6 +78,10 @@ void matroxfb_g450_shutdown(WPMINFO2) { ...@@ -57,6 +78,10 @@ void matroxfb_g450_shutdown(WPMINFO2) {
ACCESS_FBINFO(outputs[1]).output = NULL; ACCESS_FBINFO(outputs[1]).output = NULL;
ACCESS_FBINFO(outputs[1]).data = NULL; ACCESS_FBINFO(outputs[1]).data = NULL;
ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR; ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
ACCESS_FBINFO(outputs[2]).src = MATROXFB_SRC_NONE;
ACCESS_FBINFO(outputs[2]).output = NULL;
ACCESS_FBINFO(outputs[2]).data = NULL;
ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock)); up_write(&ACCESS_FBINFO(altout.lock));
} }
} }
...@@ -64,6 +89,6 @@ void matroxfb_g450_shutdown(WPMINFO2) { ...@@ -64,6 +89,6 @@ void matroxfb_g450_shutdown(WPMINFO2) {
EXPORT_SYMBOL(matroxfb_g450_connect); EXPORT_SYMBOL(matroxfb_g450_connect);
EXPORT_SYMBOL(matroxfb_g450_shutdown); EXPORT_SYMBOL(matroxfb_g450_shutdown);
MODULE_AUTHOR("(c) 2000-2001 Petr Vandrovec <vandrove@vc.cvut.cz>"); MODULE_AUTHOR("(c) 2000-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");
MODULE_DESCRIPTION("Matrox G450 secondary output driver"); MODULE_DESCRIPTION("Matrox G450/G550 output driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -146,6 +146,7 @@ void matroxfb_var2my(struct fb_var_screeninfo* var, struct my_timming* mt) { ...@@ -146,6 +146,7 @@ void matroxfb_var2my(struct fb_var_screeninfo* var, struct my_timming* mt) {
if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */ if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */
mt->pixclock = 1000000000 / pixclock; mt->pixclock = 1000000000 / pixclock;
if (mt->pixclock < 1) mt->pixclock = 1; if (mt->pixclock < 1) mt->pixclock = 1;
mt->mnp = -1;
mt->dblscan = var->vmode & FB_VMODE_DOUBLE; mt->dblscan = var->vmode & FB_VMODE_DOUBLE;
mt->interlaced = var->vmode & FB_VMODE_INTERLACED; mt->interlaced = var->vmode & FB_VMODE_INTERLACED;
mt->HDisplay = var->xres; mt->HDisplay = var->xres;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment