diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2014-01-17 16:04:26 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-03-14 10:36:04 +1000 |
commit | 62ba63f687d7b99aff7c88ffd2774f15a2471ce0 (patch) | |
tree | 230f5d0ce7fbbd8d2e70366983e1f3a7d608d4c9 | |
parent | f647727a2c1d4c2a9261c411cd3df71c3c9f0c06 (diff) |
xf86-video-mga: set the pan_ctl register
On my Matrox G550 most videomodes in Xorg didn't work. I found out that it
works if Xorg pixel clock is similar to the pixel clock set on framebuffer
console.
Further analysis showed that the Linux framebuffer driver sets the pan_ctl
register (the register 0xa2) according to the pixel clock, the Xorg driver
doesn't set it.
I copied the code to set the pan_ctl register from the Linux kernel to the
Xorg driver, and most videomodes in Xorg work.
The pan_ctl register is required for both analog and digital output.
The pan_ctl register is saved and restored, this is required so that we
restore text-mode screen or Linux framebuffer correctly.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | src/mga.h | 1 | ||||
-rw-r--r-- | src/mga_dacG.c | 39 |
2 files changed, 40 insertions, 0 deletions
@@ -218,6 +218,7 @@ typedef struct { CARD32 Option2; CARD32 Option3; long Clock; + unsigned char Pan_Ctl; Bool PIXPLLCSaved; unsigned char PllM; unsigned char PllN; diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 9a80193..f307488 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -849,6 +849,43 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) if(MGAISGx50(pMga)) { pReg->Clock = f_out; + if (pMga->Chipset == PCI_CHIP_MGAG550) { + if (f_out < 45000) { + pReg->Pan_Ctl = 0x00; + } else if (f_out < 55000) { + pReg->Pan_Ctl = 0x08; + } else if (f_out < 70000) { + pReg->Pan_Ctl = 0x10; + } else if (f_out < 85000) { + pReg->Pan_Ctl = 0x18; + } else if (f_out < 100000) { + pReg->Pan_Ctl = 0x20; + } else if (f_out < 115000) { + pReg->Pan_Ctl = 0x28; + } else if (f_out < 125000) { + pReg->Pan_Ctl = 0x30; + } else { + pReg->Pan_Ctl = 0x38; + } + } else { + if (f_out < 45000) { + pReg->Pan_Ctl = 0x00; + } else if (f_out < 65000) { + pReg->Pan_Ctl = 0x08; + } else if (f_out < 85000) { + pReg->Pan_Ctl = 0x10; + } else if (f_out < 105000) { + pReg->Pan_Ctl = 0x18; + } else if (f_out < 135000) { + pReg->Pan_Ctl = 0x20; + } else if (f_out < 160000) { + pReg->Pan_Ctl = 0x28; + } else if (f_out < 175000) { + pReg->Pan_Ctl = 0x30; + } else { + pReg->Pan_Ctl = 0x38; + } + } return; } @@ -1395,6 +1432,7 @@ MGA_NOT_HAL( * To test this we check for Clock == 0. */ MGAG450SetPLLFreq(pScrn, mgaReg->Clock); + outMGAdac(MGA1064_PAN_CTL, mgaReg->Pan_Ctl); mgaReg->PIXPLLCSaved = FALSE; } @@ -1583,6 +1621,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, * VESA modes (s.o.). MATROX: hint, hint. */ if (MGAISGx50(pMga)) { + mgaReg->Pan_Ctl = inMGAdac(MGA1064_PAN_CTL); mgaReg->Clock = MGAG450SavePLLFreq(pScrn); } |