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