diff options
author | Paul A. Clarke <pc@us.ibm.com> | 2006-05-20 17:59:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-21 15:59:16 -0400 |
commit | 6d39bedc47fbf18a940f5843981767c221d22cfe (patch) | |
tree | 900a15248ace2b0b7946b19acb49e3c696ce953e /drivers/video/matrox/g450_pll.c | |
parent | d64b1c878fc1e384ae53d1d40034239bc33848f4 (diff) |
[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: Paul A. Clarke <pc@us.ibm.com>
Signed-off-by: Ian Romanick <idr@us.ibm.com>
Signed-off-by: Petr Vandrovec <petr@vandrovec.name>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/matrox/g450_pll.c')
-rw-r--r-- | drivers/video/matrox/g450_pll.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c index 8073a73f6f35..440272ad10e7 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/matrox/g450_pll.c | |||
@@ -316,14 +316,24 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
316 | case M_PIXEL_PLL_B: | 316 | case M_PIXEL_PLL_B: |
317 | case M_PIXEL_PLL_C: | 317 | case M_PIXEL_PLL_C: |
318 | { | 318 | { |
319 | u_int8_t tmp; | 319 | u_int8_t tmp, xpwrctrl; |
320 | unsigned long flags; | 320 | unsigned long flags; |
321 | 321 | ||
322 | matroxfb_DAC_lock_irqsave(flags); | 322 | matroxfb_DAC_lock_irqsave(flags); |
323 | |||
324 | xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL); | ||
325 | matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN); | ||
326 | mga_outb(M_SEQ_INDEX, M_SEQ1); | ||
327 | mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF); | ||
323 | tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL); | 328 | tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL); |
329 | tmp |= M1064_XPIXCLKCTRL_DIS; | ||
324 | if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { | 330 | if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) { |
325 | matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP); | 331 | tmp |= M1064_XPIXCLKCTRL_PLL_UP; |
326 | } | 332 | } |
333 | matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp); | ||
334 | matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0); | ||
335 | matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl); | ||
336 | |||
327 | matroxfb_DAC_unlock_irqrestore(flags); | 337 | matroxfb_DAC_unlock_irqrestore(flags); |
328 | } | 338 | } |
329 | { | 339 | { |
@@ -418,6 +428,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll, | |||
418 | frequency to higher - with <= lowest wins, while | 428 | frequency to higher - with <= lowest wins, while |
419 | with < highest one wins */ | 429 | with < highest one wins */ |
420 | if (delta <= deltaarray[idx-1]) { | 430 | if (delta <= deltaarray[idx-1]) { |
431 | /* all else being equal except VCO, | ||
432 | * choose VCO not near (within 1/16th or so) VCOmin | ||
433 | * (freqs near VCOmin aren't as stable) | ||
434 | */ | ||
435 | if (delta == deltaarray[idx-1] | ||
436 | && vco != g450_mnp2vco(PMINFO mnparray[idx-1]) | ||
437 | && vco < (pi->vcomin * 17 / 16)) { | ||
438 | break; | ||
439 | } | ||
421 | mnparray[idx] = mnparray[idx-1]; | 440 | mnparray[idx] = mnparray[idx-1]; |
422 | deltaarray[idx] = deltaarray[idx-1]; | 441 | deltaarray[idx] = deltaarray[idx-1]; |
423 | } else { | 442 | } else { |