tx_dac.c revision 4f6cd06f
1/*
2 * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk>
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *           Dirk Hohndel,   <hohndel@suse.de>
24 *	     Stefan Dirsch,  <sndirsch@suse.de>
25 *	     Helmut Fahrion, <hf@suse.de>
26 *
27 * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
28 * Siemens Nixdorf Informationssysteme
29 */
30/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c,v 1.15tsi Exp $ */
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "xf86.h"
37#include "xf86_OSproc.h"
38
39#include "xf86PciInfo.h"
40#include "xf86Pci.h"
41
42#include "IBM.h"
43#include "TI.h"
44#include "glint_regs.h"
45#include "glint.h"
46
47Bool
48TXInit(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg)
49{
50    GLINTPtr pGlint = GLINTPTR(pScrn);
51    RamDacHWRecPtr pRamDac = RAMDACHWPTR(pScrn);
52    RamDacRegRecPtr ramdacReg = &pRamDac->ModeReg;
53    CARD32 temp1, temp2, temp3, temp4;
54
55    if (pGlint->numMultiDevices == 2) {
56	STOREREG(GCSRAperture, GCSRSecondaryGLINTMapEn);
57    }
58
59    if (pGlint->MultiAperture) {
60        /*
61         * Setup HW
62         *
63         * Note: The order of discovery for the MX devices is dependent
64         * on which way the resource allocation code decides to scan the
65         * bus.  This setup assumes the first MX found owns the even
66         * scanlines.  Should the implementation change an scan the bus
67         * in the opposite direction, then simple invert the indices for
68         * MultiPciInfo below.  If this is setup wrong, the bug will appear
69         * as incorrect scanline interleaving when software rendering.
70         */
71	STOREREG(GMultGLINTAperture, pGlint->realWidth);
72	STOREREG(GMultGLINT1, PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM) & 0xFF800000);
73	STOREREG(GMultGLINT2, PCI_REGION_BASE(pGlint->MultiPciInfo[1], 2, REGION_MEM) & 0xFF800000);
74    }
75
76    if (IS_GMX2000 || IS_GLORIAXXL) {
77    	pReg->glintRegs[LBMemoryEDO >> 3] = GLINT_READ_REG(LBMemoryEDO);
78    	pReg->glintRegs[LBMemoryEDO >> 3] &= ~(LBEDOMask |
79					   LBEDOBankSizeMask |
80					   LBTwoPageDetectorMask);
81    	pReg->glintRegs[LBMemoryEDO >> 3] |= (LBEDOEnabled |
82					  LBEDOBankSize4M |
83					  LBTwoPageDetector);
84    	pReg->glintRegs[LBMemoryCtl >> 3] = GLINT_READ_REG(LBMemoryCtl);
85    	pReg->glintRegs[LBMemoryCtl >> 3] &= ~(LBNumBanksMask |
86					   LBPageSizeMask |
87					   LBRASCASLowMask |
88					   LBRASPrechargeMask |
89					   LBCASLowMask |
90					   LBPageModeMask |
91					   LBRefreshCountMask);
92    	pReg->glintRegs[LBMemoryCtl >> 3] |= (LBNumBanks2 |
93					  LBPageSize1024 |
94					  LBRASCASLow2 |
95					  LBRASPrecharge2 |
96					  LBCASLow1 |
97					  LBPageModeEnabled |
98					  (0x20 << LBRefreshCountShift));
99    }
100
101    STOREREG(Aperture0, 0);
102    STOREREG(Aperture1, 0);
103
104    STOREREG(DFIFODis, GLINT_READ_REG(DFIFODis) & 0xFFFFFFFE);
105    STOREREG(FIFODis, GLINT_READ_REG(FIFODis) | 0x01);
106
107    temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
108    temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
109    temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
110    temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
111
112    STOREREG(VTGHLimit, Shiftbpp(pScrn, mode->CrtcHTotal));
113    STOREREG(VTGHSyncEnd, Shiftbpp(pScrn, temp1 + temp3));
114    STOREREG(VTGHSyncStart, Shiftbpp(pScrn, temp1));
115    STOREREG(VTGHBlankEnd,
116			Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay));
117
118    STOREREG(VTGVLimit, mode->CrtcVTotal);
119    STOREREG(VTGVSyncEnd, temp2 + temp4);
120    STOREREG(VTGVSyncStart, temp2);
121    STOREREG(VTGVBlankEnd, mode->CrtcVTotal - mode->CrtcVDisplay);
122
123    if (IS_GMX2000) {
124	STOREREG(VTGPolarity, 0xba);
125    } else {
126	STOREREG(VTGPolarity, (((mode->Flags & V_PHSYNC ? 0:2)<<2) |
127			   ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0)));
128    }
129
130    STOREREG(VClkCtl, 0);
131    STOREREG(VTGVGateStart, mode->CrtcVTotal - mode->CrtcVDisplay - 1);
132    STOREREG(VTGVGateEnd, mode->CrtcVTotal - mode->CrtcVDisplay);
133
134    /* This is ugly */
135    if (pGlint->UseFireGL3000) {
136    	STOREREG(VTGSerialClk, 0x05);
137	STOREREG(VTGHGateStart,
138		    Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1));
139    	STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1);
140	STOREREG(FBModeSel, 0x907);
141	STOREREG(VTGModeCtl, 0x00);
142    } else
143    if (IS_GMX2000) {
144    	STOREREG(VTGSerialClk, 0x02);
145	STOREREG(VTGHGateStart,
146		    Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1));
147    	STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1);
148	STOREREG(FBModeSel, 0x907);
149	STOREREG(VTGModeCtl, 0x04);
150    } else {
151    	STOREREG(VTGSerialClk, 0x05);
152	STOREREG(VTGHGateStart,
153		    Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay) - 2);
154    	STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 2);
155	STOREREG(FBModeSel, 0x0A07);
156	STOREREG(VTGModeCtl, 0x44);
157    }
158
159    if (IS_GMX2000 || IS_GLORIAXXL) {
160    	STOREREG(FBMemoryCtl, 0x800); /* Optimum memory timings */
161    } else {
162    	STOREREG(FBMemoryCtl, GLINT_READ_REG(FBMemoryCtl));
163    }
164
165    /* Override FBModeSel for 300SX chip */
166    if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) ||
167        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
168	 (pGlint->MultiChip == PCI_CHIP_300SX)) ) {
169	switch (pScrn->bitsPerPixel) {
170	    case 8:
171		STOREREG(FBModeSel, 0x905);
172		break;
173	    case 16:
174		STOREREG(FBModeSel, 0x903);
175		break;
176	    case 32:
177		STOREREG(FBModeSel, 0x901);
178		break;
179	}
180    }
181
182    switch (pGlint->RamDac->RamDacType) {
183    case IBM526DB_RAMDAC:
184    case IBM526_RAMDAC:
185    {
186	/* Get the programmable clock values */
187    	unsigned long m=0,n=0,p=0,c=0;
188
189	(void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
190			1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
191
192	STORERAMDAC(IBMRGB_m0, m);
193	STORERAMDAC(IBMRGB_n0, n);
194	STORERAMDAC(IBMRGB_p0, p);
195	STORERAMDAC(IBMRGB_c0, c);
196
197	STORERAMDAC(IBMRGB_pll_ctrl1, 0x05);
198	STORERAMDAC(IBMRGB_pll_ctrl2, 0x00);
199
200	p = 1;
201	(void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
202			0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
203
204	STORERAMDAC(IBMRGB_sysclk, 0x05);
205	STORERAMDAC(IBMRGB_sysclk_m, m);
206	STORERAMDAC(IBMRGB_sysclk_n, n);
207	STORERAMDAC(IBMRGB_sysclk_p, p);
208	STORERAMDAC(IBMRGB_sysclk_c, c);
209    }
210    STORERAMDAC(IBMRGB_misc1, SENS_DSAB_DISABLE | VRAM_SIZE_64);
211    STORERAMDAC(IBMRGB_misc2, COL_RES_8BIT | PORT_SEL_VRAM | PCLK_SEL_PLL);
212    STORERAMDAC(IBMRGB_misc3, 0);
213    STORERAMDAC(IBMRGB_misc_clock, 1);
214    STORERAMDAC(IBMRGB_sync, 0);
215    STORERAMDAC(IBMRGB_hsync_pos, 0);
216    STORERAMDAC(IBMRGB_pwr_mgmt, 0);
217    STORERAMDAC(IBMRGB_dac_op, 0);
218    STORERAMDAC(IBMRGB_pal_ctrl, 0);
219
220    break;
221    case IBM640_RAMDAC:
222    {
223	/* Get the programmable clock values */
224    	unsigned long m=0,n=0,p=0,c=0;
225
226	(void) IBMramdac640CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
227			1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
228
229	STORERAMDAC(RGB640_PLL_N, n);
230	STORERAMDAC(RGB640_PLL_M, m);
231	STORERAMDAC(RGB640_PLL_P, p<<1);
232	STORERAMDAC(RGB640_PLL_CTL, c | IBM640_PLL_EN);
233	STORERAMDAC(RGB640_AUX_PLL_CTL, 0); /* Disable AUX PLL */
234    }
235    STORERAMDAC(RGB640_PIXEL_INTERLEAVE, 0x00);
236
237    temp1 = IBM640_RDBK | IBM640_VRAM;
238    if (pScrn->rgbBits == 8)
239    	temp1 |= IBM640_PSIZE8;
240    STORERAMDAC(RGB640_VGA_CONTROL, temp1);
241
242    STORERAMDAC(RGB640_DAC_CONTROL, IBM640_DACENBL | IBM640_SHUNT);
243    STORERAMDAC(RGB640_OUTPUT_CONTROL, IBM640_RDAI | IBM640_WATCTL);
244    STORERAMDAC(RGB640_SYNC_CONTROL, 0x00);
245    STORERAMDAC(RGB640_VRAM_MASK0, 0xFF);
246    STORERAMDAC(RGB640_VRAM_MASK1, 0xFF);
247    STORERAMDAC(RGB640_VRAM_MASK2, 0x0F);
248
249    STOREREG(VTGModeCtl, 0x04);
250    break;
251
252    case TI3026_RAMDAC:
253    case TI3030_RAMDAC:
254    {
255	/* Get the programmable clock values */
256	unsigned long m=0,n=0,p=0;
257	unsigned long clock;
258	unsigned long q, VCO = 0;
259
260	clock = TIramdacCalculateMNPForClock(pGlint->RefClock,
261		mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p);
262
263	STORERAMDAC(TIDAC_PIXEL_N, ((n & 0x3f) | 0xC0));
264	STORERAMDAC(TIDAC_PIXEL_M,  (m & 0x3f));
265	STORERAMDAC(TIDAC_PIXEL_P, ((p & 0x03) | 0xbc));
266	STORERAMDAC(TIDAC_PIXEL_VALID, TRUE);
267
268    	if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC))
269            n = 65 - ((64 << 2) / pScrn->bitsPerPixel);
270	else
271            n = 65 - ((128 << 2) / pScrn->bitsPerPixel);
272	m = 61;
273	p = 0;
274	for (q = 0; q < 8; q++) {
275	    if (q > 0) p = 3;
276	    for ( ; p < 4; p++) {
277		VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1);
278		if (VCO >= 110000) { break; }
279	    }
280	    if (VCO >= 110000) { break; }
281	}
282	STORERAMDAC(TIDAC_clock_ctrl, (q | 0x38));
283
284	STORERAMDAC(TIDAC_LOOP_N, ((n & 0x3f) | 0xC0));
285	STORERAMDAC(TIDAC_LOOP_M,  (m & 0x3f));
286	STORERAMDAC(TIDAC_LOOP_P, ((p & 0x03) | 0xF0));
287	STORERAMDAC(TIDAC_LOOP_VALID, TRUE);
288    }
289    if (pGlint->RamDac->RamDacType == (TI3030_RAMDAC))
290	STOREREG(VTGModeCtl, 0x04);
291    break;
292    }
293
294    /* Now use helper routines to setup bpp for this driver */
295    (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg);
296
297    return(TRUE);
298}
299
300void
301TXSave(ScrnInfoPtr pScrn, GLINTRegPtr pReg)
302{
303    GLINTPtr pGlint = GLINTPTR(pScrn);
304
305    if (pGlint->numMultiDevices == 2) {
306	SAVEREG(GCSRAperture);
307    }
308
309    if (pGlint->MultiAperture) {
310	SAVEREG(GMultGLINTAperture);
311	SAVEREG(GMultGLINT1);
312	SAVEREG(GMultGLINT2);
313    }
314
315    SAVEREG(Aperture0);
316    SAVEREG(Aperture1);
317
318    SAVEREG(DFIFODis);
319
320    if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) {
321	SAVEREG(FIFODis);
322	SAVEREG(VTGModeCtl);
323    }
324
325    SAVEREG(VClkCtl);
326    SAVEREG(VTGPolarity);
327    SAVEREG(VTGHLimit);
328    SAVEREG(VTGHBlankEnd);
329    SAVEREG(VTGHSyncStart);
330    SAVEREG(VTGHSyncEnd);
331    SAVEREG(VTGVLimit);
332    SAVEREG(VTGVBlankEnd);
333    SAVEREG(VTGVSyncStart);
334    SAVEREG(VTGVSyncEnd);
335    SAVEREG(VTGVGateStart);
336    SAVEREG(VTGVGateEnd);
337    SAVEREG(VTGSerialClk);
338    SAVEREG(FBModeSel);
339    SAVEREG(VTGHGateStart);
340    SAVEREG(VTGHGateEnd);
341    SAVEREG(FBMemoryCtl);
342
343    if (IS_GMX2000 || IS_GLORIAXXL) {
344    	SAVEREG(LBMemoryEDO);
345    	SAVEREG(LBMemoryCtl);
346    }
347}
348
349void
350TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr pReg)
351{
352    GLINTPtr pGlint = GLINTPTR(pScrn);
353
354    if (pGlint->numMultiDevices == 2) {
355	RESTOREREG(GCSRAperture);
356    }
357
358    if (pGlint->MultiAperture) {
359	RESTOREREG(GMultGLINTAperture);
360	RESTOREREG(GMultGLINT1);
361	RESTOREREG(GMultGLINT2);
362    }
363
364    RESTOREREG(Aperture0);
365    RESTOREREG(Aperture1);
366
367    RESTOREREG(DFIFODis);
368
369    if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) {
370	RESTOREREG(FIFODis);
371	RESTOREREG(VTGModeCtl);
372    }
373
374    RESTOREREG(VTGPolarity);
375    RESTOREREG(VClkCtl);
376    RESTOREREG(VTGSerialClk);
377    RESTOREREG(VTGHLimit);
378    RESTOREREG(VTGHSyncStart);
379    RESTOREREG(VTGHSyncEnd);
380    RESTOREREG(VTGHBlankEnd);
381    RESTOREREG(VTGVLimit);
382    RESTOREREG(VTGVSyncStart);
383    RESTOREREG(VTGVSyncEnd);
384    RESTOREREG(VTGVBlankEnd);
385    RESTOREREG(VTGVGateStart);
386    RESTOREREG(VTGVGateEnd);
387    RESTOREREG(FBModeSel);
388    RESTOREREG(VTGHGateStart);
389    RESTOREREG(VTGHGateEnd);
390    RESTOREREG(FBMemoryCtl);
391
392    if (IS_GMX2000 || IS_GLORIAXXL) {
393    	RESTOREREG(LBMemoryEDO);
394    	RESTOREREG(LBMemoryCtl);
395    }
396}
397