tx_dac.c revision c35d236e
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,
73			pGlint->MultiPciInfo[0]->memBase[2] & 0xFF800000);
74	STOREREG(GMultGLINT2,
75			pGlint->MultiPciInfo[1]->memBase[2] & 0xFF800000);
76    }
77
78    if (IS_GMX2000 || IS_GLORIAXXL) {
79    	pReg->glintRegs[LBMemoryEDO >> 3] = GLINT_READ_REG(LBMemoryEDO);
80    	pReg->glintRegs[LBMemoryEDO >> 3] &= ~(LBEDOMask |
81					   LBEDOBankSizeMask |
82					   LBTwoPageDetectorMask);
83    	pReg->glintRegs[LBMemoryEDO >> 3] |= (LBEDOEnabled |
84					  LBEDOBankSize4M |
85					  LBTwoPageDetector);
86    	pReg->glintRegs[LBMemoryCtl >> 3] = GLINT_READ_REG(LBMemoryCtl);
87    	pReg->glintRegs[LBMemoryCtl >> 3] &= ~(LBNumBanksMask |
88					   LBPageSizeMask |
89					   LBRASCASLowMask |
90					   LBRASPrechargeMask |
91					   LBCASLowMask |
92					   LBPageModeMask |
93					   LBRefreshCountMask);
94    	pReg->glintRegs[LBMemoryCtl >> 3] |= (LBNumBanks2 |
95					  LBPageSize1024 |
96					  LBRASCASLow2 |
97					  LBRASPrecharge2 |
98					  LBCASLow1 |
99					  LBPageModeEnabled |
100					  (0x20 << LBRefreshCountShift));
101    }
102
103    STOREREG(Aperture0, 0);
104    STOREREG(Aperture1, 0);
105
106    STOREREG(DFIFODis, GLINT_READ_REG(DFIFODis) & 0xFFFFFFFE);
107    STOREREG(FIFODis, GLINT_READ_REG(FIFODis) | 0x01);
108
109    temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
110    temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
111    temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
112    temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
113
114    STOREREG(VTGHLimit, Shiftbpp(pScrn, mode->CrtcHTotal));
115    STOREREG(VTGHSyncEnd, Shiftbpp(pScrn, temp1 + temp3));
116    STOREREG(VTGHSyncStart, Shiftbpp(pScrn, temp1));
117    STOREREG(VTGHBlankEnd,
118			Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay));
119
120    STOREREG(VTGVLimit, mode->CrtcVTotal);
121    STOREREG(VTGVSyncEnd, temp2 + temp4);
122    STOREREG(VTGVSyncStart, temp2);
123    STOREREG(VTGVBlankEnd, mode->CrtcVTotal - mode->CrtcVDisplay);
124
125    if (IS_GMX2000) {
126	STOREREG(VTGPolarity, 0xba);
127    } else {
128	STOREREG(VTGPolarity, (((mode->Flags & V_PHSYNC ? 0:2)<<2) |
129			   ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0)));
130    }
131
132    STOREREG(VClkCtl, 0);
133    STOREREG(VTGVGateStart, mode->CrtcVTotal - mode->CrtcVDisplay - 1);
134    STOREREG(VTGVGateEnd, mode->CrtcVTotal - mode->CrtcVDisplay);
135
136    /* This is ugly */
137    if (pGlint->UseFireGL3000) {
138    	STOREREG(VTGSerialClk, 0x05);
139	STOREREG(VTGHGateStart,
140		    Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1));
141    	STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1);
142	STOREREG(FBModeSel, 0x907);
143	STOREREG(VTGModeCtl, 0x00);
144    } else
145    if (IS_GMX2000) {
146    	STOREREG(VTGSerialClk, 0x02);
147	STOREREG(VTGHGateStart,
148		    Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay - 1));
149    	STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 1);
150	STOREREG(FBModeSel, 0x907);
151	STOREREG(VTGModeCtl, 0x04);
152    } else {
153    	STOREREG(VTGSerialClk, 0x05);
154	STOREREG(VTGHGateStart,
155		    Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay) - 2);
156    	STOREREG(VTGHGateEnd, Shiftbpp(pScrn, mode->CrtcHTotal) - 2);
157	STOREREG(FBModeSel, 0x0A07);
158	STOREREG(VTGModeCtl, 0x44);
159    }
160
161    if (IS_GMX2000 || IS_GLORIAXXL) {
162    	STOREREG(FBMemoryCtl, 0x800); /* Optimum memory timings */
163    } else {
164    	STOREREG(FBMemoryCtl, GLINT_READ_REG(FBMemoryCtl));
165    }
166
167    /* Override FBModeSel for 300SX chip */
168    if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_300SX) ||
169        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_DELTA) &&
170	 (pGlint->MultiChip == PCI_CHIP_300SX)) ) {
171	switch (pScrn->bitsPerPixel) {
172	    case 8:
173		STOREREG(FBModeSel, 0x905);
174		break;
175	    case 16:
176		STOREREG(FBModeSel, 0x903);
177		break;
178	    case 32:
179		STOREREG(FBModeSel, 0x901);
180		break;
181	}
182    }
183
184    switch (pGlint->RamDac->RamDacType) {
185    case IBM526DB_RAMDAC:
186    case IBM526_RAMDAC:
187    {
188	/* Get the programmable clock values */
189    	unsigned long m=0,n=0,p=0,c=0;
190
191	(void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
192			1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
193
194	STORERAMDAC(IBMRGB_m0, m);
195	STORERAMDAC(IBMRGB_n0, n);
196	STORERAMDAC(IBMRGB_p0, p);
197	STORERAMDAC(IBMRGB_c0, c);
198
199	STORERAMDAC(IBMRGB_pll_ctrl1, 0x05);
200	STORERAMDAC(IBMRGB_pll_ctrl2, 0x00);
201
202	p = 1;
203	(void) IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
204			0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
205
206	STORERAMDAC(IBMRGB_sysclk, 0x05);
207	STORERAMDAC(IBMRGB_sysclk_m, m);
208	STORERAMDAC(IBMRGB_sysclk_n, n);
209	STORERAMDAC(IBMRGB_sysclk_p, p);
210	STORERAMDAC(IBMRGB_sysclk_c, c);
211    }
212    STORERAMDAC(IBMRGB_misc1, SENS_DSAB_DISABLE | VRAM_SIZE_64);
213    STORERAMDAC(IBMRGB_misc2, COL_RES_8BIT | PORT_SEL_VRAM | PCLK_SEL_PLL);
214    STORERAMDAC(IBMRGB_misc3, 0);
215    STORERAMDAC(IBMRGB_misc_clock, 1);
216    STORERAMDAC(IBMRGB_sync, 0);
217    STORERAMDAC(IBMRGB_hsync_pos, 0);
218    STORERAMDAC(IBMRGB_pwr_mgmt, 0);
219    STORERAMDAC(IBMRGB_dac_op, 0);
220    STORERAMDAC(IBMRGB_pal_ctrl, 0);
221
222    break;
223    case IBM640_RAMDAC:
224    {
225	/* Get the programmable clock values */
226    	unsigned long m=0,n=0,p=0,c=0;
227
228	(void) IBMramdac640CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
229			1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
230
231	STORERAMDAC(RGB640_PLL_N, n);
232	STORERAMDAC(RGB640_PLL_M, m);
233	STORERAMDAC(RGB640_PLL_P, p<<1);
234	STORERAMDAC(RGB640_PLL_CTL, c | IBM640_PLL_EN);
235	STORERAMDAC(RGB640_AUX_PLL_CTL, 0); /* Disable AUX PLL */
236    }
237    STORERAMDAC(RGB640_PIXEL_INTERLEAVE, 0x00);
238
239    temp1 = IBM640_RDBK | IBM640_VRAM;
240    if (pScrn->rgbBits == 8)
241    	temp1 |= IBM640_PSIZE8;
242    STORERAMDAC(RGB640_VGA_CONTROL, temp1);
243
244    STORERAMDAC(RGB640_DAC_CONTROL, IBM640_DACENBL | IBM640_SHUNT);
245    STORERAMDAC(RGB640_OUTPUT_CONTROL, IBM640_RDAI | IBM640_WATCTL);
246    STORERAMDAC(RGB640_SYNC_CONTROL, 0x00);
247    STORERAMDAC(RGB640_VRAM_MASK0, 0xFF);
248    STORERAMDAC(RGB640_VRAM_MASK1, 0xFF);
249    STORERAMDAC(RGB640_VRAM_MASK2, 0x0F);
250
251    STOREREG(VTGModeCtl, 0x04);
252    break;
253
254    case TI3026_RAMDAC:
255    case TI3030_RAMDAC:
256    {
257	/* Get the programmable clock values */
258	unsigned long m=0,n=0,p=0;
259	unsigned long clock;
260	unsigned long q, VCO = 0;
261
262	clock = TIramdacCalculateMNPForClock(pGlint->RefClock,
263		mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p);
264
265	STORERAMDAC(TIDAC_PIXEL_N, ((n & 0x3f) | 0xC0));
266	STORERAMDAC(TIDAC_PIXEL_M,  (m & 0x3f));
267	STORERAMDAC(TIDAC_PIXEL_P, ((p & 0x03) | 0xbc));
268	STORERAMDAC(TIDAC_PIXEL_VALID, TRUE);
269
270    	if (pGlint->RamDac->RamDacType == (TI3026_RAMDAC))
271            n = 65 - ((64 << 2) / pScrn->bitsPerPixel);
272	else
273            n = 65 - ((128 << 2) / pScrn->bitsPerPixel);
274	m = 61;
275	p = 0;
276	for (q = 0; q < 8; q++) {
277	    if (q > 0) p = 3;
278	    for ( ; p < 4; p++) {
279		VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1);
280		if (VCO >= 110000) { break; }
281	    }
282	    if (VCO >= 110000) { break; }
283	}
284	STORERAMDAC(TIDAC_clock_ctrl, (q | 0x38));
285
286	STORERAMDAC(TIDAC_LOOP_N, ((n & 0x3f) | 0xC0));
287	STORERAMDAC(TIDAC_LOOP_M,  (m & 0x3f));
288	STORERAMDAC(TIDAC_LOOP_P, ((p & 0x03) | 0xF0));
289	STORERAMDAC(TIDAC_LOOP_VALID, TRUE);
290    }
291    if (pGlint->RamDac->RamDacType == (TI3030_RAMDAC))
292	STOREREG(VTGModeCtl, 0x04);
293    break;
294    }
295
296    /* Now use helper routines to setup bpp for this driver */
297    (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg);
298
299    return(TRUE);
300}
301
302void
303TXSave(ScrnInfoPtr pScrn, GLINTRegPtr pReg)
304{
305    GLINTPtr pGlint = GLINTPTR(pScrn);
306
307    if (pGlint->numMultiDevices == 2) {
308	SAVEREG(GCSRAperture);
309    }
310
311    if (pGlint->MultiAperture) {
312	SAVEREG(GMultGLINTAperture);
313	SAVEREG(GMultGLINT1);
314	SAVEREG(GMultGLINT2);
315    }
316
317    SAVEREG(Aperture0);
318    SAVEREG(Aperture1);
319
320    SAVEREG(DFIFODis);
321
322    if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) {
323	SAVEREG(FIFODis);
324	SAVEREG(VTGModeCtl);
325    }
326
327    SAVEREG(VClkCtl);
328    SAVEREG(VTGPolarity);
329    SAVEREG(VTGHLimit);
330    SAVEREG(VTGHBlankEnd);
331    SAVEREG(VTGHSyncStart);
332    SAVEREG(VTGHSyncEnd);
333    SAVEREG(VTGVLimit);
334    SAVEREG(VTGVBlankEnd);
335    SAVEREG(VTGVSyncStart);
336    SAVEREG(VTGVSyncEnd);
337    SAVEREG(VTGVGateStart);
338    SAVEREG(VTGVGateEnd);
339    SAVEREG(VTGSerialClk);
340    SAVEREG(FBModeSel);
341    SAVEREG(VTGHGateStart);
342    SAVEREG(VTGHGateEnd);
343    SAVEREG(FBMemoryCtl);
344
345    if (IS_GMX2000 || IS_GLORIAXXL) {
346    	SAVEREG(LBMemoryEDO);
347    	SAVEREG(LBMemoryCtl);
348    }
349}
350
351void
352TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr pReg)
353{
354    GLINTPtr pGlint = GLINTPTR(pScrn);
355
356    if (pGlint->numMultiDevices == 2) {
357	RESTOREREG(GCSRAperture);
358    }
359
360    if (pGlint->MultiAperture) {
361	RESTOREREG(GMultGLINTAperture);
362	RESTOREREG(GMultGLINT1);
363	RESTOREREG(GMultGLINT2);
364    }
365
366    RESTOREREG(Aperture0);
367    RESTOREREG(Aperture1);
368
369    RESTOREREG(DFIFODis);
370
371    if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_300SX) {
372	RESTOREREG(FIFODis);
373	RESTOREREG(VTGModeCtl);
374    }
375
376    RESTOREREG(VTGPolarity);
377    RESTOREREG(VClkCtl);
378    RESTOREREG(VTGSerialClk);
379    RESTOREREG(VTGHLimit);
380    RESTOREREG(VTGHSyncStart);
381    RESTOREREG(VTGHSyncEnd);
382    RESTOREREG(VTGHBlankEnd);
383    RESTOREREG(VTGVLimit);
384    RESTOREREG(VTGVSyncStart);
385    RESTOREREG(VTGVSyncEnd);
386    RESTOREREG(VTGVBlankEnd);
387    RESTOREREG(VTGVGateStart);
388    RESTOREREG(VTGVGateEnd);
389    RESTOREREG(FBModeSel);
390    RESTOREREG(VTGHGateStart);
391    RESTOREREG(VTGHGateEnd);
392    RESTOREREG(FBMemoryCtl);
393
394    if (IS_GMX2000 || IS_GLORIAXXL) {
395    	RESTOREREG(LBMemoryEDO);
396    	RESTOREREG(LBMemoryCtl);
397    }
398}
399