1 /*********************************************************************
2 *  	G450: This is for Dual Head.
3 *       Matrox Graphics
4 *       Author : Luugi Marsan
5 **********************************************************************/
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 /* All drivers should typically include these */
12 #include "xf86.h"
13 #include "xf86_OSproc.h"
14 
15 /* Drivers that need to access the PCI config space directly need this */
16 #include "xf86Pci.h"
17 
18 #include "mga_reg.h"
19 #include "mga.h"
20 
21 #define MNP_TABLE_SIZE 64
22 #define CLKSEL_MGA     0x0c
23 #define PLLLOCK        0x40
24 
25 /* Misc field*/
26 #define IOADDSEL        0x01
27 #define RAMMAPEN        0x02
28 #define CLKSEL_25175    0x00
29 #define CLKSEL_28322    0x04
30 #define CLKSEL_MGA      0x0c
31 #define VIDEODIS        0x10
32 #define HPGODDEV        0x20
33 #define HSYNCPOL        0x40
34 #define VSYNCPOL        0x80
35 
36 /* XSYNCCTRL field */
37 #define XSYNCCTRL_DAC1HSPOL_SHIFT                   2
38 #define XSYNCCTRL_DAC1HSPOL_MASK                    (1 << XSYNCCTRL_DAC1HSPOL_SHIFT)
39 #define XSYNCCTRL_DAC1HSPOL_NEG                     (1 << XSYNCCTRL_DAC1HSPOL_SHIFT)
40 #define XSYNCCTRL_DAC1HSPOL_POS                     0
41 #define XSYNCCTRL_DAC1VSPOL_SHIFT                   3
42 #define XSYNCCTRL_DAC1VSPOL_MASK                    (1 << XSYNCCTRL_DAC1VSPOL_SHIFT)
43 #define XSYNCCTRL_DAC1VSPOL_NEG                     (1 << XSYNCCTRL_DAC1VSPOL_SHIFT)
44 #define XSYNCCTRL_DAC1VSPOL_POS                     0
45 #define XSYNCCTRL_DAC2HSPOL_SHIFT                   6
46 #define XSYNCCTRL_DAC2HSPOL_MASK                    (1 << XSYNCCTRL_DAC2HSPOL_SHIFT)
47 #define XSYNCCTRL_DAC2HSPOL_NEG                     (1 << XSYNCCTRL_DAC2HSPOL_SHIFT)
48 #define XSYNCCTRL_DAC2HSPOL_POS                     0
49 #define XSYNCCTRL_DAC2VSPOL_SHIFT                   7
50 #define XSYNCCTRL_DAC2VSPOL_MASK                    (1 << XSYNCCTRL_DAC2VSPOL_SHIFT)
51 #define XSYNCCTRL_DAC2VSPOL_NEG                     (1 << XSYNCCTRL_DAC2VSPOL_SHIFT)
52 #define XSYNCCTRL_DAC2VSPOL_POS                     0
53 #define XSYNCCTRL_DAC1HSOFF_SHIFT                   0
54 #define XSYNCCTRL_DAC1HSOFF_MASK                    (1 << XSYNCCTRL_DAC1HSOFF_SHIFT)
55 #define XSYNCCTRL_DAC1HSOFF_OFF                     (1 << XSYNCCTRL_DAC1HSOFF_SHIFT)
56 #define XSYNCCTRL_DAC1HSOFF_ON                      1
57 #define XSYNCCTRL_DAC1VSOFF_SHIFT                   1
58 #define XSYNCCTRL_DAC1VSOFF_MASK                    (1 << XSYNCCTRL_DAC1VSOFF_SHIFT)
59 #define XSYNCCTRL_DAC1VSOFF_OFF                     (1 << XSYNCCTRL_DAC1VSOFF_SHIFT)
60 #define XSYNCCTRL_DAC1VSOFF_ON                      0
61 #define XSYNCCTRL_DAC2HSOFF_SHIFT                   4
62 #define XSYNCCTRL_DAC2HSOFF_MASK                    (1 << XSYNCCTRL_DAC2HSOFF_SHIFT)
63 #define XSYNCCTRL_DAC2HSOFF_OFF                     (1 << XSYNCCTRL_DAC2HSOFF_SHIFT)
64 #define XSYNCCTRL_DAC2HSOFF_ON                      0
65 #define XSYNCCTRL_DAC2VSOFF_SHIFT                   5
66 #define XSYNCCTRL_DAC2VSOFF_MASK                    (1 << XSYNCCTRL_DAC2VSOFF_SHIFT)
67 #define XSYNCCTRL_DAC2VSOFF_OFF                     (1 << XSYNCCTRL_DAC2VSOFF_SHIFT)
68 #define XSYNCCTRL_DAC2VSOFF_ON                      0
69 
70 #define POS_HSYNC                  0x00000004
71 #define POS_VSYNC                  0x00000008
72 
73 
74 /* Set CRTC 2*/
75 /* Uses the mode given by xfree86 to setup the registry */
76 /* Does not write to the hard yet */
MGACRTC2Get(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo)77 void MGACRTC2Get(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo)
78 {
79 
80 
81     MGAPtr pMga = MGAPTR(pScrn);
82     MGARegPtr pReg = &pMga->ModeReg;
83 
84     xMODEINFO tmpModeInfo;
85     CARD32 ulHTotal;
86     CARD32 ulHDispEnd;
87     CARD32 ulHBlkStr;
88     CARD32 ulHSyncStr;
89     CARD32 ulHSyncEnd;
90     CARD32 ulVTotal;
91     CARD32 ulVDispEnd;
92     CARD32 ulVBlkStr;
93     CARD32 ulVSyncStr;
94     CARD32 ulVSyncEnd;
95     CARD32 ulOffset;
96     CARD32 ulCtl2;
97     CARD32 ulDataCtl2;
98     CARD32 ulDispHeight = pModeInfo->ulDispHeight;
99 
100 #ifdef DEBUG
101     ErrorF("ENTER MGACRTC2Get\n");
102 #endif
103 
104     tmpModeInfo = *pModeInfo;
105 
106 
107     /*  First compute the Values */
108 
109     ulHTotal = tmpModeInfo.ulDispWidth +
110         tmpModeInfo.ulHFPorch +
111         tmpModeInfo.ulHBPorch +
112         tmpModeInfo.ulHSync;
113 
114     ulHDispEnd = tmpModeInfo.ulDispWidth;
115     ulHBlkStr  = ulHDispEnd;
116     ulHSyncStr = ulHBlkStr + tmpModeInfo.ulHFPorch;
117     ulHSyncEnd = ulHSyncStr + tmpModeInfo.ulHSync;
118 
119     ulVTotal =  ulDispHeight +
120         tmpModeInfo.ulVFPorch +
121         tmpModeInfo.ulVBPorch +
122         tmpModeInfo.ulVSync;
123 
124 
125     ulVDispEnd = ulDispHeight;
126     ulVBlkStr = ulVDispEnd;
127     ulVSyncStr = ulVBlkStr + tmpModeInfo.ulVFPorch;
128     ulVSyncEnd = ulVSyncStr + tmpModeInfo.ulVSync;
129 
130     ulOffset = tmpModeInfo.ulFBPitch;
131 
132 
133 
134     ulCtl2 = INREG(MGAREG_C2CTL);
135     ulDataCtl2 = INREG(MGAREG_C2DATACTL);
136 
137     ulCtl2      &= 0xFF1FFFFF;
138     ulDataCtl2  &= 0xFFFFFF00;
139 
140     switch (tmpModeInfo.ulBpp)
141     {
142     case 15:    ulCtl2      |= 0x00200000;
143         ulOffset <<= 1;
144         break;
145     case 16:    ulCtl2      |= 0x00400000;
146         ulOffset <<= 1;
147         break;
148     case 32:    ulCtl2      |= 0x00800000;
149         ulOffset <<= 2;
150         break;
151     }
152 
153 
154     pReg->crtc2[ MGAREG2_C2CTL ] = ulCtl2;
155     pReg->crtc2[ MGAREG2_C2DATACTL ] = ulDataCtl2;
156 
157     /* Horizontal Value*/
158     pReg->crtc2[MGAREG2_C2HPARAM] = (((ulHDispEnd-8) << 16) | (ulHTotal-8)) ;
159     pReg->crtc2[MGAREG2_C2HSYNC] = (((ulHSyncEnd-8) << 16) | (ulHSyncStr-8)) ;
160 
161 
162     /*Vertical Value*/
163     pReg->crtc2[MGAREG2_C2VPARAM] = (((ulVDispEnd-1) << 16) | (ulVTotal-1))  ;
164     pReg->crtc2[MGAREG2_C2VSYNC] =  (((ulVSyncEnd-1) << 16) | (ulVSyncStr-1)) ;
165 
166     /** Offset value*/
167 
168     pReg->crtc2[MGAREG2_C2OFFSET] = ulOffset;
169 
170 #ifdef DEBUG
171     ErrorF("EXIT MGACRTC2Get\n");
172 #endif
173 
174 }
175 
176 /* Set CRTC 2*/
177 /* Writes to the hardware */
MGACRTC2Set(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo)178 void MGACRTC2Set(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo)
179 {
180 
181 
182     MGAPtr pMga = MGAPTR(pScrn);
183     MGARegPtr pReg = &pMga->ModeReg;
184 
185 #ifdef DEBUG
186     ErrorF("ENTER MGACRTC2Set\n");
187 #endif
188 
189 
190     /* This writes to the registers manually */
191     OUTREG(MGAREG_C2CTL, pReg->crtc2[MGAREG2_C2CTL]);
192     OUTREG(MGAREG_C2DATACTL,pReg->crtc2[MGAREG2_C2DATACTL]);
193 
194 
195     /* Horizontal Value*/
196     OUTREG(MGAREG_C2HPARAM, pReg->crtc2[MGAREG2_C2HPARAM]);
197     OUTREG(MGAREG_C2HSYNC, pReg->crtc2[MGAREG2_C2HSYNC]);
198 
199 
200     /*Vertical Value*/
201     OUTREG(MGAREG_C2VPARAM, pReg->crtc2[MGAREG2_C2VPARAM]);
202     OUTREG(MGAREG_C2VSYNC,  pReg->crtc2[MGAREG2_C2VSYNC]);
203 
204     /** Offset value*/
205 
206     OUTREG(MGAREG_C2OFFSET, pReg->crtc2[MGAREG2_C2OFFSET]);
207 #ifdef DEBUG
208     ErrorF("EXIT MGACRTC2Set\n");
209 #endif
210 
211 }
212 
213 
214 /* Set CRTC2 on the right output */
MGAEnableSecondOutPut(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo)215 void MGAEnableSecondOutPut(ScrnInfoPtr pScrn, xMODEINFO *pModeInfo)
216 {
217     CARD8   ucByte, ucXDispCtrl;
218     CARD32   ulC2CTL;
219     MGAPtr pMga = MGAPTR(pScrn);
220     MGARegPtr pReg;
221     pReg = &pMga->ModeReg;
222 #ifdef DEBUG
223     ErrorF("ENTER MGAEnableSecondOutPut\n");
224 #endif
225 
226 
227     /*  Route Video PLL on second CRTC */
228     ulC2CTL = INREG( MGAREG_C2CTL);
229 
230     /*--- Disable Pixel clock oscillations On Crtc1 */
231     OUTREG( MGAREG_C2CTL, ulC2CTL | MGAREG_C2CTL_PIXCLKDIS_MASK);
232     /*--- Have to wait minimum time (2 acces will be ok) */
233     (void) INREG( MGAREG_Status);
234     (void) INREG( MGAREG_Status);
235 
236 
237     ulC2CTL &= ~MGAREG_C2CTL_PIXCLKSEL_MASK;
238     ulC2CTL &= ~MGAREG_C2CTL_PIXCLKSELH_MASK;
239 
240     ulC2CTL |= MGAREG_C2CTL_PIXCLKSEL_VIDEOPLL;
241 
242 
243     OUTREG( MGAREG_C2CTL, ulC2CTL);
244 
245     /*--- Enable Pixel clock oscillations on CRTC2*/
246     ulC2CTL &= ~MGAREG_C2CTL_PIXCLKDIS_MASK;
247     OUTREG( MGAREG_C2CTL, ulC2CTL);
248 
249 
250     /* We don't use MISC synch pol, must be 0*/
251     ucByte = INREG8( MGAREG_MEM_MISC_READ);
252 
253     OUTREG8(MGAREG_MEM_MISC_WRITE, (CARD8)(ucByte & ~(HSYNCPOL| VSYNCPOL) ));
254 
255 
256 
257 
258     /* Set Rset to 0.7 V*/
259     ucByte = inMGAdac(MGA1064_GEN_IO_CTL);
260     ucByte &= ~0x40;
261     pReg->DacRegs[MGA1064_GEN_IO_CTL] = ucByte;
262     outMGAdac (MGA1064_GEN_IO_CTL, ucByte);
263 
264     ucByte = inMGAdac( MGA1064_GEN_IO_DATA);
265     ucByte &= ~0x40;
266     pReg->DacRegs[MGA1064_GEN_IO_DATA]= ucByte;
267     outMGAdac (MGA1064_GEN_IO_DATA, ucByte);
268 
269     /* Since G550 can swap outputs at BIOS initialisation, we must check which
270      * DAC is 'logically' used as the secondary (don't assume its DAC2 anymore) */
271 
272     ulC2CTL = INREG(MGAREG_C2CTL);
273     ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL);
274 
275     ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK;
276 
277     if (!pMga->SecondOutput) {
278         /* Route Crtc2 on Output1 */
279         ucXDispCtrl |=  MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1;
280         ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC2;
281     }
282     else {
283         /* Route Crtc2 on Output2*/
284         ucXDispCtrl |=  MGA1064_DISP_CTL_DAC2OUTSEL_CRTC2;
285         ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_MASK;
286     }
287 
288     /* Enable CRTC2*/
289     ulC2CTL |= MGAREG_C2CTL_C2_EN;
290 
291     pReg->dac2[ MGA1064_DISP_CTL - 0x80] =  ucXDispCtrl;
292 
293 
294 
295     OUTREG( MGAREG_C2CTL,  ulC2CTL);
296 
297    /* Set DAC2 Synch polarity*/
298     ucByte = inMGAdac( MGA1064_SYNC_CTL);
299     ucByte &= ~(XSYNCCTRL_DAC2HSPOL_MASK | XSYNCCTRL_DAC2VSPOL_MASK);
300     if ( !(pModeInfo->flSignalMode & POS_HSYNC) )
301     {
302         ucByte |= XSYNCCTRL_DAC2HSPOL_NEG;
303     }
304     if ( !(pModeInfo->flSignalMode & POS_VSYNC) )
305     {
306         ucByte |= XSYNCCTRL_DAC2VSPOL_NEG;
307     }
308 
309    /* Enable synch output*/
310     ucByte &= ~(XSYNCCTRL_DAC2HSOFF_MASK | XSYNCCTRL_DAC2VSOFF_MASK);
311     pReg->dac2[ MGA1064_SYNC_CTL - 0x80] = ucByte;
312 
313    /* Power up DAC2, Fifo.
314     * The TMDS is powered down here, which is likely wrong.
315     */
316     pReg->dac2[MGA1064_PWR_CTL - 0x80] =
317         MGA1064_PWR_CTL_DAC2_EN |
318         MGA1064_PWR_CTL_VID_PLL_EN |
319         MGA1064_PWR_CTL_RFIFO_EN |
320         MGA1064_PWR_CTL_CFIFO_EN;
321 
322 
323 #ifdef DEBUG
324     ErrorF("EXIT MGAEnableSecondOutPut\n");
325 #endif
326 }
327 
328 
329 
330 
331 
MGACRTC2GetPitch(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo)332 void MGACRTC2GetPitch (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo)
333 {
334     CARD32 ulOffset;
335     MGAPtr pMga = MGAPTR(pScrn);
336     MGARegPtr pReg;
337 
338     pReg = &pMga->ModeReg;
339 #ifdef DEBUG
340     ErrorF("ENTER MGACRTC2GetPitch\n");
341 #endif
342 
343 
344     switch(pModeInfo->ulBpp)
345     {
346         case 15:
347         case 16:
348             ulOffset = pModeInfo->ulFBPitch * 2;
349             break;
350         case 32:
351             ulOffset = pModeInfo->ulFBPitch * 4;
352             break;
353 	default:	/* Muffle compiler */
354             ulOffset = pModeInfo->ulFBPitch;
355 	    break;
356     }
357 
358     pReg->crtc2[MGAREG2_C2OFFSET] = ulOffset;
359 
360 #ifdef DEBUG
361     ErrorF("EXIT MGACRTC2GetPitch\n");
362 #endif
363 
364 }
365 
MGACRTC2SetPitch(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo)366 void MGACRTC2SetPitch (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo)
367 {
368 
369     MGAPtr pMga = MGAPTR(pScrn);
370     MGARegPtr pReg;
371     pReg = &pMga->ModeReg;
372 
373 #ifdef DEBUG
374     ErrorF("ENTER CRCT2SetPitch\n");
375 #endif
376 
377 
378     OUTREG(MGAREG_C2OFFSET,  pReg->crtc2[MGAREG2_C2OFFSET]);
379 #ifdef DEBUG
380     ErrorF("EXIT CRCT2SetPitch\n");
381 #endif
382 
383 }
384 
385 
386     /* Set Display Start*/
387     /* base in bytes*/
MGACRTC2GetDisplayStart(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo,CARD32 base,CARD32 ulX,CARD32 ulY)388 void MGACRTC2GetDisplayStart (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo, CARD32 base, CARD32 ulX, CARD32 ulY)
389 {
390 
391     CARD32 ulAddress;
392    MGAPtr pMga = MGAPTR(pScrn);
393     MGARegPtr pReg;
394     pReg = &pMga->ModeReg;
395 
396 #ifdef DEBUG
397     ErrorF("ENTER MGACRTC2GetDisplayStart\n");
398 #endif
399 
400 
401     pReg = &pMga->ModeReg;
402 
403    ulAddress       = (pModeInfo->ulFBPitch * ulY + ulX);
404     switch(pModeInfo->ulBpp)
405     {
406         case 15:
407         case 16:
408             ulAddress <<= 1;
409             break;
410         case 32:
411             ulAddress <<= 2;
412             break;
413     }
414 
415     pReg->crtc2[MGAREG2_C2STARTADD0] = ulAddress + base;
416 #ifdef DEBUG
417     ErrorF("EXIT MGACRTC2GetDisplayStart\n");
418 #endif
419 
420 }
421 
MGACRTC2SetDisplayStart(ScrnInfoPtr pScrn,xMODEINFO * pModeInfo,CARD32 base,CARD32 ulX,CARD32 ulY)422 void MGACRTC2SetDisplayStart (ScrnInfoPtr pScrn, xMODEINFO *pModeInfo, CARD32 base, CARD32 ulX, CARD32 ulY)
423 {
424     MGAPtr pMga = MGAPTR(pScrn);
425     MGARegPtr pReg;
426     pReg = &pMga->ModeReg;
427 #ifdef DEBUG
428     ErrorF("ENTER MGACRTC2SetDisplayStart\n");
429 #endif
430 
431     OUTREG(MGAREG_C2STARTADD0,  pReg->crtc2[MGAREG2_C2STARTADD0]);
432 #ifdef DEBUG
433     ErrorF("EXIT MGACRTC2SetDisplayStart\n");
434 #endif
435 
436 }
437 
438 
439 
440 
441 
442 
443 
444 
445 
446 
447 
448