Commit 6d39bedc authored by Paul A. Clarke's avatar Paul A. Clarke Committed by Linus Torvalds

[PATCH] matroxfb: fix DVI setup to be more compatible

There has been a longstanding problem with the Matrox G450 and perhaps
other similar cards, with modes "above" 1280x1024-60 on ppc/ppc64 boxes
running Linux.  Higher resolutions and/or higher refresh rates resulted in
a very noticably "jittery" display, and sometimes no display, depending on
the physical monitor.  This patch fixes that problem on the systems I have
easy access to...

I've tested with SLES9SP3 (2.6.5+ kernel) and 2.6.16-rc6 custom kernels on
an IBM eServer p5 520 w/G450 (a.k.a GXT135P on IBM's ppc64 systems), and a
colleague of mine (Ian Romanick) tested it successfully on an Apple ppc32
box (w/GXT135P).  I also tested it on IA32 box I have with a GXT135P to
verify that it didn't obviously break anything.  In my testing, I covered
single-card, single and dual-head setups using both HD15 and DVI-D signals,
on both the IA32 and ppc64 boxes.  While everything appeared fine on both
boxes, I did encounter one problem: I can't get any signal on the DVI-D
output on the ppc64 box.  However, this is also the case without my patch.

I just noticed that screen-blanking only occurs on the primary display as
well.
Signed-off-by: default avatarPaul A. Clarke <pc@us.ibm.com>
Signed-off-by: default avatarIan Romanick <idr@us.ibm.com>
Signed-off-by: default avatarPetr Vandrovec <petr@vandrovec.name>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d64b1c87
......@@ -316,14 +316,24 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
case M_PIXEL_PLL_B:
case M_PIXEL_PLL_C:
{
u_int8_t tmp;
u_int8_t tmp, xpwrctrl;
unsigned long flags;
matroxfb_DAC_lock_irqsave(flags);
xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL);
matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN);
mga_outb(M_SEQ_INDEX, M_SEQ1);
mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF);
tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL);
tmp |= M1064_XPIXCLKCTRL_DIS;
if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) {
matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP);
tmp |= M1064_XPIXCLKCTRL_PLL_UP;
}
matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp);
matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0);
matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl);
matroxfb_DAC_unlock_irqrestore(flags);
}
{
......@@ -418,6 +428,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
frequency to higher - with <= lowest wins, while
with < highest one wins */
if (delta <= deltaarray[idx-1]) {
/* all else being equal except VCO,
* choose VCO not near (within 1/16th or so) VCOmin
* (freqs near VCOmin aren't as stable)
*/
if (delta == deltaarray[idx-1]
&& vco != g450_mnp2vco(PMINFO mnparray[idx-1])
&& vco < (pi->vcomin * 17 / 16)) {
break;
}
mnparray[idx] = mnparray[idx-1];
deltaarray[idx] = deltaarray[idx-1];
} else {
......
......@@ -40,6 +40,7 @@ void DAC1064_global_restore(WPMINFO2);
#define M1064_XCURCOL1RED 0x0C
#define M1064_XCURCOL1GREEN 0x0D
#define M1064_XCURCOL1BLUE 0x0E
#define M1064_XDVICLKCTRL 0x0F
#define M1064_XCURCOL2RED 0x10
#define M1064_XCURCOL2GREEN 0x11
#define M1064_XCURCOL2BLUE 0x12
......@@ -144,6 +145,7 @@ void DAC1064_global_restore(WPMINFO2);
#define M1064_XVIDPLLN 0x8F
#define M1064_XPWRCTRL 0xA0
#define M1064_XPWRCTRL_PANELPDN 0x04
#define M1064_XPANMODE 0xA2
......
......@@ -672,6 +672,8 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv);
#define M_SEQ_INDEX 0x1FC4
#define M_SEQ_DATA 0x1FC5
#define M_SEQ1 0x01
#define M_SEQ1_SCROFF 0x20
#define M_MISC_REG_READ 0x1FCC
......
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