2001-02-06 18:23:07

by Petr Vandrovec

[permalink] [raw]
Subject: Re: Matrox G450 problems with 2.4.0 and xfree

On 6 Feb 01 at 13:16, Mike A. Harris wrote:
> On Wed, 31 Jan 2001, Petr Vandrovec wrote:
>
> >> I don't have Windows installed on my machine, but I find that if I
> >> cold boot to 2.2 (RH7) first and start up X (4.0.2 with Matrox driver
^^^^^^^^^^^^^
> >> 1.00.04 compiled in), I am then able to "shutdown -r now" and warm
^^^^^^^^^^^^^^^^^^^
> >
> >Yes, they use same secret code... At least I think...
>
> Are you refering to Windows or Red Hat Linux? I can assure you
> that Red Hat Linux's XFree package doesn't have any secret code
> in it with 110% certainty. Nor will it have in the future.

He is using XF4.0.2 with Matrox large-blob driver, not with XFree one.
I'm 111% sure that this module contains code which is not freely
available to mortals.

XFree4.0.2 mga driver does not work with G450 at all. I'm not sure whether
you (or RedHat) applied G450 patches flying around. But it is still first
head only, no digital LCD...
Best regards,
Petr Vandrovec
[email protected]



2001-02-06 19:19:45

by Mike A. Harris

[permalink] [raw]
Subject: [OT] Re: Matrox G450 problems with 2.4.0 and xfree

On Tue, 6 Feb 2001, Petr Vandrovec wrote:

>> >> I don't have Windows installed on my machine, but I find that if I
>> >> cold boot to 2.2 (RH7) first and start up X (4.0.2 with Matrox driver
> ^^^^^^^^^^^^^
>> >> 1.00.04 compiled in), I am then able to "shutdown -r now" and warm
> ^^^^^^^^^^^^^^^^^^^
>> >
>> >Yes, they use same secret code... At least I think...
>>
>> Are you refering to Windows or Red Hat Linux? I can assure you
>> that Red Hat Linux's XFree package doesn't have any secret code
>> in it with 110% certainty. Nor will it have in the future.
>
>He is using XF4.0.2 with Matrox large-blob driver, not with XFree one.
>I'm 111% sure that this module contains code which is not freely
>available to mortals.

Well then it is NOT the one shipping with Red Hat Linux.

>XFree4.0.2 mga driver does not work with G450 at all. I'm not sure whether
>you (or RedHat) applied G450 patches flying around. But it is still first
>head only, no digital LCD...

I have applied various g450 patches to 4.0.2 from both matrox and
elsewhere, and nobody seems to get it to work correctly. The
Matrox patches were not completely clean, so I might just pull
them if no public patches appear soon. It is not our fault for
broken drivers..

If anyone has open source g450 patches against stock 4.0.2 that
get the thing to work at all, _please_ send me unified diffs, and
I will put them into my next build. I've yet to have my g450 do
anything but turn off my monitor, although a handful of people
claim they get it working to various degrees... I don't have
g450 specs either so..

No binary modules are in the Red Hat XFree86 RPMS though, nor
will there be. Only 100% open source. If the open source
drivers do not work, then the card will not function period, and
will not be supported.


----------------------------------------------------------------------
Mike A. Harris - Linux advocate - Free Software advocate
This message is copyright 2001, all rights reserved.
Views expressed are my own, not necessarily shared by my employer.
----------------------------------------------------------------------
"Facts do not cease to exist because they are ignored."
- Aldous Huxley

2001-02-06 20:07:38

by Rafael E. Herrera

[permalink] [raw]
Subject: Re: [OT] Re: Matrox G450 problems with 2.4.0 and xfree

"Mike A. Harris" wrote:
>
> If anyone has open source g450 patches against stock 4.0.2 that
> get the thing to work at all, _please_ send me unified diffs, and
> I will put them into my next build. I've yet to have my g450 do
> anything but turn off my monitor, although a handful of people
> claim they get it working to various degrees... I don't have
> g450 specs either so..

In my machine I have SuSE 7.0, XF86 4.0.2, a G450, and Matrox's monster
mga driver for XF86 4.0.1. Miraculously, it works in dual head mode. But
as has been mentioned before the sources for the HAL library are not
available.

--
Rafael

2001-02-06 20:53:23

by David Woodhouse

[permalink] [raw]
Subject: Re: [OT] Re: Matrox G450 problems with 2.4.0 and xfree

On Tue, 6 Feb 2001, Mike A. Harris wrote:

> If anyone has open source g450 patches against stock 4.0.2 that
> get the thing to work at all, _please_ send me unified diffs, and
> I will put them into my next build. I've yet to have my g450 do
> anything but turn off my monitor, although a handful of people
> claim they get it working to various degrees... I don't have
> g450 specs either so..

We're getting significantly off-topic for linux-kernel. But the patch
below worked for me in my limited testing - starting the X server twice in
different modes on a colleague's G450.

It's almost, but not quite, identical to the changes in the RH7.1 beta
RPM. It's against (and was tested with) the current CVS, but applies
cleanly to 4.0.2 as well. Almost _functionally_ identical, that is - some
of their original offended me so much it just had to be cleaned up.

diff -uNr mga-preg450/Imakefile mga/Imakefile
--- mga-preg450/Imakefile Sat Feb 3 23:53:49 2001
+++ mga/Imakefile Sun Feb 4 00:05:36 2001
@@ -57,10 +57,10 @@

MGASRCS = mga_driver.c mga_hwcurs.c /* mga_cmap.c */ mga_dac3026.c mga_dacG.c \
mga_storm8.c mga_storm16.c mga_storm24.c mga_storm32.c mga_arc.c \
- mga_dga.c mga_shadow.c mga_video.c $(DRISRCS)
+ mga_dga.c mga_shadow.c mga_video.c mga_g450pll.c $(DRISRCS)
MGAOBJS = mga_driver.o mga_hwcurs.o /* mga_cmap.o */ mga_dac3026.o mga_dacG.o \
mga_storm8.o mga_storm16.o mga_storm24.o mga_storm32.o mga_arc.o \
- mga_dga.o mga_shadow.o mga_video.o $(DRIOBJS)
+ mga_dga.o mga_shadow.o mga_video.o mga_g450pll.o $(DRIOBJS)

SRCS = $(MGASRCS) $(MGAHALSRCS)
OBJS = $(MGAOBJS) $(MGAHALOBJS)
diff -uNr mga-preg450/mga.h mga/mga.h
--- mga-preg450/mga.h Sat Feb 3 23:53:50 2001
+++ mga/mga.h Sun Feb 4 00:06:02 2001
@@ -414,4 +414,5 @@
void MGAInitVideo(ScreenPtr pScreen);
void MGAResetVideo(ScrnInfoPtr pScrn);

+double G450SetPLLFreq(ScrnInfoPtr pScrn, long f_out);
#endif
diff -uNr mga-preg450/mga_dacG.c mga/mga_dacG.c
--- mga-preg450/mga_dacG.c Sat Feb 3 23:53:53 2001
+++ mga/mga_dacG.c Sun Feb 4 00:29:12 2001
@@ -237,6 +237,11 @@
/* The actual frequency output by the clock */
double f_pll;

+ if(MGAISG450(pMga)) {
+ G450SetPLLFreq(pScrn, f_out);
+ return;
+ }
+
/* Do the calculations for m, n, p and s */
f_pll = MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s );

@@ -338,6 +343,9 @@
#ifdef USEMGAHAL
MGA_HAL(break;);
#endif
+ if (MGAISG450(pMga))
+ break;
+
if(pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */
if(pMga->OverclockMem) {
/* 150/200 */
@@ -528,6 +536,10 @@
if (mode->Flags & V_DBLSCAN)
pVga->CRTC[9] |= 0x80;

+ if(MGAISG450(pMga)) {
+ OUTREG(MGAREG_ZORG, 0);
+ }
+
MGAGSetPCLK(pScrn, mode->Clock);
); /* MGA_NOT_HAL */

@@ -656,7 +668,10 @@
(i == 0x1b) ||
(i == 0x1c) ||
((i >= 0x1f) && (i <= 0x29)) ||
- ((i >= 0x30) && (i <= 0x37)) )
+ ((i >= 0x30) && (i <= 0x37)) ||
+ (MGAISG450(pMga) &&
+ ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) ||
+ (i == 0x4c) || (i == 0x4d) || (i == 0x4e))))
continue;
outMGAdac(i, mgaReg->DacRegs[i]);
}
@@ -665,15 +680,17 @@
should be correct already */
optionMask = (pMga->Primary) ? OPTION1_MASK_PRIMARY : OPTION1_MASK;

- /* restore pci_option register */
- pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, optionMask,
- mgaReg->Option);
- if (pMga->Chipset != PCI_CHIP_MGA1064)
- pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK,
- mgaReg->Option2);
- if (pMga->Chipset == PCI_CHIP_MGAG400)
- pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK,
- mgaReg->Option3);
+ if (!MGAISG450(pMga)) {
+ /* restore pci_option register */
+ pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, optionMask,
+ mgaReg->Option);
+ if (pMga->Chipset != PCI_CHIP_MGA1064)
+ pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK,
+ mgaReg->Option2);
+ if (pMga->Chipset == PCI_CHIP_MGAG400)
+ pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK,
+ mgaReg->Option3);
+ }
); /* MGA_NOT_HAL */

/* restore CRTCEXT regs */
diff -uNr mga-preg450/mga_g450pll.c mga/mga_g450pll.c
--- mga-preg450/mga_g450pll.c Thu Jan 1 01:00:00 1970
+++ mga/mga_g450pll.c Sun Feb 4 00:00:04 2001
@@ -0,0 +1,444 @@
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+#include "mga_bios.h"
+#include "mga_reg.h"
+#include "mga.h"
+
+#define DEBUG
+
+#define MNP_TABLE_SIZE 64
+#define CLKSEL_MGA 0x0c
+#define PLLLOCK 0x40
+
+#define outMGAdreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val)
+
+#define outMGAdac(reg, val) \
+ (outMGAdreg(MGA1064_INDEX, reg), outMGAdreg(MGA1064_DATA, val))
+
+static CARD32 G450ApplyPFactor(ScrnInfoPtr pScrn, CARD8 ucP, CARD32 *pulFIn)
+{
+ if(!(ucP & 0x40))
+ {
+ *pulFIn = *pulFIn / (2L << (ucP & 3));
+ }
+
+ return TRUE;
+}
+
+
+static CARD32 G450RemovePFactor(ScrnInfoPtr pScrn, CARD8 ucP, CARD32 *pulFIn)
+{
+ if(!(ucP & 0x40))
+ {
+ *pulFIn = *pulFIn * (2L << (ucP & 3));
+ }
+
+ return TRUE;
+}
+
+
+static CARD32 G450CalculVCO(ScrnInfoPtr pScrn, CARD32 ulMNP, CARD32 *pulF)
+{
+ CARD8 ucM, ucN, ucP;
+
+ ucM = (CARD8)((ulMNP >> 16) & 0xff);
+ ucN = (CARD8)((ulMNP >> 8) & 0xff);
+ ucP = (CARD8)(ulMNP & 0x03);
+
+ *pulF = (27000 * (2 * (ucN + 2)) + ((ucM + 1) >> 1)) / (ucM + 1);
+
+ return TRUE;
+}
+
+
+static CARD32 G450CalculDeltaFreq(ScrnInfoPtr pScrn, CARD32 ulF1,
+ CARD32 ulF2, CARD32 *pulDelta)
+{
+ if(ulF2 < ulF1)
+ {
+ *pulDelta = ((ulF1 - ulF2) * 1000) / ulF1;
+ }
+ else
+ {
+ *pulDelta = ((ulF2 - ulF1) * 1000) / ulF1;
+ }
+
+ return TRUE;
+}
+
+
+
+
+static CARD32 G450FindNextPLLParam(ScrnInfoPtr pScrn, CARD32 ulFout,
+ CARD32 *pulPLLMNP)
+{
+ CARD8 ucM, ucN, ucP, ucS;
+ CARD32 ulVCO, ulVCOMin;
+
+ ucM = (CARD8)((*pulPLLMNP >> 16) & 0xff);
+ ucN = (CARD8)((*pulPLLMNP >> 8) & 0xff);
+ ucP = (CARD8)(*pulPLLMNP & 0x43);
+
+ ulVCOMin = 256000;
+
+ if(ulVCOMin >= (255L * 8000))
+ {
+ ulVCOMin = 230000;
+ }
+
+ if((ucM == 9) && (ucP & 0x40))
+ {
+ *pulPLLMNP = 0xffffffff;
+ } else if (ucM == 9)
+ {
+ if(ucP)
+ {
+ ucP--;
+ }
+ else
+ {
+ ucP = 0x40;
+ }
+ ucM = 0;
+ }
+ else
+ {
+ ucM++;
+ }
+
+ ulVCO = ulFout;
+
+ G450RemovePFactor(pScrn, ucP, &ulVCO);
+
+ if(ulVCO < ulVCOMin)
+ {
+ *pulPLLMNP = 0xffffffff;
+ }
+
+ if(*pulPLLMNP != 0xffffffff)
+ {
+ ucN = (CARD8)(((ulVCO * (ucM+1) + 27000)/(27000 * 2)) - 2);
+
+ ucS = 5;
+ if(ulVCO < 1300000) ucS = 4;
+ if(ulVCO < 1100000) ucS = 3;
+ if(ulVCO < 900000) ucS = 2;
+ if(ulVCO < 700000) ucS = 1;
+ if(ulVCO < 550000) ucS = 0;
+
+ ucP |= (CARD8)(ucS << 3);
+
+ *pulPLLMNP &= 0xff000000;
+ *pulPLLMNP |= (CARD32)ucM << 16;
+ *pulPLLMNP |= (CARD32)ucN << 8;
+ *pulPLLMNP |= (CARD32)ucP;
+ }
+
+ return TRUE;
+}
+
+
+static CARD32 G450FindFirstPLLParam(ScrnInfoPtr pScrn, CARD32 ulFout,
+ CARD32 *pulPLLMNP)
+{
+ CARD8 ucP;
+ CARD32 ulVCO;
+ CARD32 ulVCOMax;
+
+ /* Default value */
+ ulVCOMax = 1300000;
+
+ if(ulFout > (ulVCOMax/2))
+ {
+ ucP = 0x40;
+ ulVCO = ulFout;
+ }
+ else
+ {
+ ucP = 3;
+ ulVCO = ulFout;
+ G450RemovePFactor(pScrn, ucP, &ulVCO);
+ while(ucP && (ulVCO > ulVCOMax))
+ {
+ ucP--;
+ ulVCO = ulFout;
+ G450RemovePFactor(pScrn, ucP, &ulVCO);
+ }
+ }
+
+ if(ulVCO > ulVCOMax)
+ {
+ *pulPLLMNP = 0xffffffff;
+ }
+ else
+ {
+ /* Pixel clock: 1 */
+ *pulPLLMNP = (1 << 24) + 0xff0000 + ucP;
+ G450FindNextPLLParam(pScrn, ulFout, pulPLLMNP);
+ }
+
+ return TRUE;
+
+}
+
+
+static CARD32 G450WriteMNP(ScrnInfoPtr pScrn, CARD32 ulMNP)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Pixel Pll */
+ outMGAdac(MGA1064_PIX_PLLC_M, (CARD8)(ulMNP >> 16));
+ outMGAdac(MGA1064_PIX_PLLC_N, (CARD8)(ulMNP >> 8));
+ outMGAdac(MGA1064_PIX_PLLC_P, (CARD8) ulMNP);
+ OUTREG8(0x3c00, 0x4f);
+ return TRUE;
+}
+
+
+static CARD32 G450CompareMNP(ScrnInfoPtr pScrn, CARD32 ulFout, CARD32 ulMNP1,
+ CARD32 ulMNP2, long *pulResult)
+{
+ CARD32 ulFreq, ulDelta1, ulDelta2;
+
+ G450CalculVCO(pScrn, ulMNP1, &ulFreq);
+ G450ApplyPFactor(pScrn, (CARD8) ulMNP1, &ulFreq);
+ G450CalculDeltaFreq(pScrn, ulFout, ulFreq, &ulDelta1);
+
+ G450CalculVCO(pScrn, ulMNP2, &ulFreq);
+ G450ApplyPFactor(pScrn, (CARD8) ulMNP2, &ulFreq);
+ G450CalculDeltaFreq(pScrn, ulFout, ulFreq, &ulDelta2);
+
+ if(ulDelta1 < ulDelta2)
+ {
+ *pulResult = -1;
+ }
+ else if(ulDelta1 > ulDelta2)
+ {
+ *pulResult = 1;
+ }
+ else
+ {
+ *pulResult = 0;
+ }
+
+ if((ulDelta1 <= 5) && (ulDelta2 <= 5))
+ {
+ if((ulMNP1 & 0xff0000) < (ulMNP2 & 0xff0000))
+ {
+ *pulResult = -1;
+ }
+ else if((ulMNP1 & 0xff0000) > (ulMNP2 & 0xff0000))
+ {
+ *pulResult = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static CARD32 G450IsPllLocked(ScrnInfoPtr pScrn, Bool *lpbLocked)
+{
+ CARD32 ulFallBackCounter, ulLockCount, ulCount;
+ CARD8 ucPLLStatus;
+
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Pixel PLL */
+ OUTREG8(0x3c00, 0x4f);
+
+ ulFallBackCounter = 0;
+
+ do
+ {
+ ucPLLStatus = INREG8(0x3c0a);
+ ulFallBackCounter++;
+ } while(!(ucPLLStatus & PLLLOCK) && (ulFallBackCounter < 1000));
+
+ ulLockCount = 0;
+ if(ulFallBackCounter < 1000)
+ {
+ for(ulCount = 0; ulCount < 100; ulCount++)
+ {
+ ucPLLStatus = INREG8(0x3c0a);
+ if(ucPLLStatus & PLLLOCK)
+ {
+ ulLockCount++;
+ }
+ }
+ }
+
+ *lpbLocked = ulLockCount >= 90;
+
+ return TRUE;
+}
+
+
+double G450SetPLLFreq(ScrnInfoPtr pScrn, long f_out)
+{
+ Bool bFoundValidPLL;
+ Bool bLocked;
+ CARD8 ucMisc;
+ CARD8 ucS;
+ CARD32 ulMaxIndex;
+ CARD32 ulMNP;
+ CARD32 ulMNPTable[MNP_TABLE_SIZE];
+ CARD32 ulIndex;
+ CARD32 ulTryMNP;
+ long lCompareResult;
+
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ G450FindFirstPLLParam(pScrn, f_out, &ulMNP);
+ ulMNPTable[0] = ulMNP;
+ G450FindNextPLLParam(pScrn, f_out, &ulMNP);
+ ulMaxIndex = 1;
+ while(ulMNP != 0xffffffff)
+ {
+ int ulIndex;
+ Bool bSkipValue;
+
+ bSkipValue = FALSE;
+ if(ulMaxIndex == MNP_TABLE_SIZE)
+ {
+ G450CompareMNP(pScrn, f_out, ulMNP, ulMNPTable[MNP_TABLE_SIZE - 1],
+ &lCompareResult);
+
+ if(lCompareResult > 0)
+ {
+ bSkipValue = TRUE;
+ }
+ else
+ {
+ ulMaxIndex--;
+ }
+ }
+
+ if(!bSkipValue)
+ {
+ for(ulIndex = ulMaxIndex; !bSkipValue && (ulIndex > 0); ulIndex--)
+ {
+ G450CompareMNP(pScrn, f_out, ulMNP, ulMNPTable[ulIndex - 1],
+ &lCompareResult);
+
+ if(lCompareResult < 0)
+ {
+ ulMNPTable[ulIndex] = ulMNPTable[ulIndex - 1];
+ }
+ else
+ {
+ break;
+ }
+ }
+ ulMNPTable[ulIndex] = ulMNP;
+ ulMaxIndex++;
+ }
+
+ G450FindNextPLLParam(pScrn, f_out, &ulMNP);
+ }
+
+ bFoundValidPLL = FALSE;
+ ulMNP = 0;
+
+ /* For pixel pll */
+ ucMisc = INREG8(0x1FCC);
+ OUTREG8(0x1fc2, (CARD8)(ucMisc | CLKSEL_MGA));
+
+ for(ulIndex = 0; !bFoundValidPLL && (ulIndex < ulMaxIndex); ulIndex++)
+ {
+ ulTryMNP = ulMNPTable[ulIndex];
+
+ for(ucS = 0; !bFoundValidPLL && (ucS < 0x40); ucS += 8)
+ {
+ ulTryMNP &= 0xffffffc7;
+ ulTryMNP |= (CARD32)ucS;
+
+ bLocked = TRUE;
+ if((ulMNPTable[ulIndex] & 0xff00) < 0x300 ||
+ (ulMNPTable[ulIndex] & 0xff00) > 0x7a00)
+ {
+ bLocked = FALSE;
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP - 0x300);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP + 0x300);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP - 0x200);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP + 0x200);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP - 0x100);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP + 0x100);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+
+ if(bLocked)
+ {
+ G450WriteMNP(pScrn, ulTryMNP);
+ G450IsPllLocked(pScrn, &bLocked);
+ }
+ else if(!ulMNP)
+ {
+ G450WriteMNP(pScrn, ulTryMNP);
+ G450IsPllLocked(pScrn, &bLocked);
+ if(bLocked)
+ {
+ ulMNP = ulMNPTable[ulIndex];
+ }
+ bLocked = FALSE;
+ }
+
+ if(bLocked)
+ {
+ bFoundValidPLL = TRUE;
+ }
+ }
+ }
+
+ if(!bFoundValidPLL)
+ {
+ if(ulMNP)
+ {
+ G450WriteMNP(pScrn, ulMNP);
+ }
+ else
+ {
+ G450WriteMNP(pScrn, ulMNPTable[0]);
+ }
+ }
+
+ return TRUE;
+}
diff -uNr mga-preg450/mga_macros.h mga/mga_macros.h
--- mga-preg450/mga_macros.h Sat Feb 3 23:53:59 2001
+++ mga/mga_macros.h Sun Feb 4 00:24:14 2001
@@ -107,4 +107,6 @@
#define MGA_NOT_HAL(x) { x; }
#endif

+#define MGAISG450(x) ( ((x)->Chipset == PCI_CHIP_MGAG400) && ((x)->ChipRev >= 0x80) )
+
#endif /* _MGA_MACROS_H_ */

--
dwmw2