1c35d236eSmrg/*
2c35d236eSmrg * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk>
3c35d236eSmrg *
4c35d236eSmrg * Permission to use, copy, modify, distribute, and sell this software and its
5c35d236eSmrg * documentation for any purpose is hereby granted without fee, provided that
6c35d236eSmrg * the above copyright notice appear in all copies and that both that
7c35d236eSmrg * copyright notice and this permission notice appear in supporting
8c35d236eSmrg * documentation, and that the name of Alan Hourihane not be used in
9c35d236eSmrg * advertising or publicity pertaining to distribution of the software without
10c35d236eSmrg * specific, written prior permission.  Alan Hourihane makes no representations
11c35d236eSmrg * about the suitability of this software for any purpose.  It is provided
12c35d236eSmrg * "as is" without express or implied warranty.
13c35d236eSmrg *
14c35d236eSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15c35d236eSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16c35d236eSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17c35d236eSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18c35d236eSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19c35d236eSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20c35d236eSmrg * PERFORMANCE OF THIS SOFTWARE.
21c35d236eSmrg *
22c35d236eSmrg * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23c35d236eSmrg *           Dirk Hohndel,   <hohndel@suse.de>
24c35d236eSmrg *	     Stefan Dirsch,  <sndirsch@suse.de>
25c35d236eSmrg *	     Helmut Fahrion, <hf@suse.de>
26c35d236eSmrg *	     Michel Dänzer,  <michdaen@iiic.ethz.ch>
27c35d236eSmrg *
28c35d236eSmrg * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
29c35d236eSmrg * Siemens Nixdorf Informationssysteme
30c35d236eSmrg */
31c35d236eSmrg
32c35d236eSmrg#ifdef HAVE_CONFIG_H
33c35d236eSmrg#include "config.h"
34c35d236eSmrg#endif
35c35d236eSmrg
36c35d236eSmrg#include <X11/Xarch.h>
37c35d236eSmrg#include "xf86.h"
38c35d236eSmrg#include "xf86_OSproc.h"
39c35d236eSmrg
40c35d236eSmrg#include "xf86Pci.h"
41c35d236eSmrg
42c35d236eSmrg#include "glint_regs.h"
43c35d236eSmrg#include "glint.h"
44c35d236eSmrg
45c35d236eSmrg#define INITIALFREQERR 100000
46c35d236eSmrg#define MINCLK 110000		/* VCO frequency range */
47c35d236eSmrg#define MAXCLK 250000
48c35d236eSmrg
49c35d236eSmrgstatic unsigned long
50c35d236eSmrgPM2DAC_CalculateMNPCForClock
51c35d236eSmrg(
52c35d236eSmrg unsigned long reqclock,		/* In kHz units */
53c35d236eSmrg unsigned long refclock,		/* In kHz units */
54c35d236eSmrg unsigned char *rm, 			/* M Out */
55c35d236eSmrg unsigned char *rn, 			/* N Out */
56c35d236eSmrg unsigned char *rp			/* P Out */
57c35d236eSmrg )
58c35d236eSmrg{
59c35d236eSmrg    unsigned char	m, n, p;
60c35d236eSmrg    unsigned long	f;
61c35d236eSmrg    long		freqerr, lowestfreqerr = INITIALFREQERR;
62c35d236eSmrg    unsigned long  	clock,actualclock = 0;
63c35d236eSmrg
64c35d236eSmrg    for (n = 2; n <= 14; n++) {
65c35d236eSmrg        for (m = 2; m != 0; m++) { /* this is a char, so this counts to 255 */
66c35d236eSmrg	    f = refclock * m / n;
67c35d236eSmrg	    if ( (f < MINCLK) || (f > MAXCLK) )
68c35d236eSmrg	    	continue;
69c35d236eSmrg	    for (p = 0; p <= 4; p++) {
70c35d236eSmrg	    	clock = f >> p;
71c35d236eSmrg		freqerr = reqclock - clock;
72c35d236eSmrg		if (freqerr < 0)
73c35d236eSmrg		    freqerr = -freqerr;
74c35d236eSmrg		if (freqerr < lowestfreqerr) {
75c35d236eSmrg		    *rn = n;
76c35d236eSmrg		    *rm = m;
77c35d236eSmrg		    *rp = p;
78c35d236eSmrg		    lowestfreqerr = freqerr;
79c35d236eSmrg		    actualclock = clock;
80c35d236eSmrg#ifdef DEBUG
81c35d236eSmrg	ErrorF("Best %ld diff %ld\n",actualclock,freqerr);
82c35d236eSmrg#endif
83c35d236eSmrg		}
84c35d236eSmrg	    }
85c35d236eSmrg	}
86c35d236eSmrg    }
87c35d236eSmrg
88c35d236eSmrg    return(actualclock);
89c35d236eSmrg}
90c35d236eSmrg
91c35d236eSmrgBool
92c35d236eSmrgPermedia2Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
93c35d236eSmrg{
94c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
95c35d236eSmrg    GLINTRegPtr pReg = &pGlint->ModeReg[0];
96c35d236eSmrg    CARD32 temp1, temp2, temp3, temp4;
97c35d236eSmrg
9811d4e95aSmacallan#if X_BYTE_ORDER == X_BIG_ENDIAN
9911d4e95aSmacallan    switch (pGlint->HwBpp) {
10011d4e95aSmacallan    case 8:
10111d4e95aSmacallan    case 24:
10211d4e95aSmacallan	    temp1 = 0x00;
10311d4e95aSmacallan	    break;
10411d4e95aSmacallan
10511d4e95aSmacallan    case 15:
10611d4e95aSmacallan    case 16:
10711d4e95aSmacallan	    temp1 = 0x02;
10811d4e95aSmacallan	    break;
10911d4e95aSmacallan
11011d4e95aSmacallan    case 32:
11111d4e95aSmacallan	    temp1 = 0x01;
11211d4e95aSmacallan	    break;
11311d4e95aSmacallan    default:
11411d4e95aSmacallan	    break;
11511d4e95aSmacallan    };
11611d4e95aSmacallan#endif /* BIG_ENDIAN */
11711d4e95aSmacallan    pReg->glintRegs[Aperture0 >> 3] = temp1;
11811d4e95aSmacallan    pReg->glintRegs[Aperture1 >> 3] = temp1;
119c35d236eSmrg    pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF;
120c35d236eSmrg    pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF;
121c35d236eSmrg
122c35d236eSmrg    pReg->glintRegs[DFIFODis >> 3] = 0;
123c35d236eSmrg    pReg->glintRegs[FIFODis >> 3] = 1;
124c35d236eSmrg
125c35d236eSmrg    if (pGlint->UseBlockWrite)
126c35d236eSmrg	pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21;
127c35d236eSmrg
128c35d236eSmrg
129c35d236eSmrg    temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
130c35d236eSmrg    temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
131c35d236eSmrg    temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
132c35d236eSmrg    temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
133c35d236eSmrg
134c35d236eSmrg    pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
135c35d236eSmrg    pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
136c35d236eSmrg    pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1);
137c35d236eSmrg    pReg->glintRegs[PMHbEnd >> 3] =
138c35d236eSmrg			Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay);
139c35d236eSmrg    pReg->glintRegs[PMScreenStride >> 3] =
140c35d236eSmrg			Shiftbpp(pScrn,pScrn->displayWidth>>1);
141c35d236eSmrg
1425c69f917Smrg    pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal - 1;
1435c69f917Smrg    pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4 - 1;
1445c69f917Smrg    pReg->glintRegs[PMVsStart >> 3] = temp2 - 1;
145c35d236eSmrg    pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
146c35d236eSmrg
147c35d236eSmrg    /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick
148c35d236eSmrg       both sync lines to active high here and if needed invert them
149c35d236eSmrg       using the RAMDAC's MCR below. */
150c35d236eSmrg    pReg->glintRegs[PMVideoControl >> 3] =
151c35d236eSmrg	(1 << 5) | (1 << 3) | 1;
152c35d236eSmrg
153c35d236eSmrg    if (pScrn->bitsPerPixel > 8) {
154c35d236eSmrg	/* When != 8bpp then we stick the RAMDAC into 64bit mode */
155c35d236eSmrg	/* And reduce the horizontal timings by half */
156c35d236eSmrg	pReg->glintRegs[PMVideoControl >> 3] |= 1<<16;
157c35d236eSmrg    	pReg->glintRegs[PMHTotal >> 3] >>= 1;
158c35d236eSmrg	pReg->glintRegs[PMHsEnd >> 3] >>= 1;
159c35d236eSmrg	pReg->glintRegs[PMHsStart >> 3] >>= 1;
160c35d236eSmrg	pReg->glintRegs[PMHbEnd >> 3] >>= 1;
161c35d236eSmrg    }
162c35d236eSmrg
163c35d236eSmrg    pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC);
164c35d236eSmrg    pReg->glintRegs[PMScreenBase >> 3] = 0;
165c35d236eSmrg    pReg->glintRegs[PMHTotal >> 3] -= 1;
166c35d236eSmrg
167c35d236eSmrg    pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD;
168c35d236eSmrg
169c35d236eSmrg    pReg->DacRegs[PM2DACIndexMDCR] = 0x00; /* Disable Overlay */
170c35d236eSmrg
171c35d236eSmrg    {
172c35d236eSmrg	/* Get the programmable clock values */
173c35d236eSmrg    	unsigned char m,n,p;
174c35d236eSmrg
175c35d236eSmrg	(void) PM2DAC_CalculateMNPCForClock(mode->Clock,pGlint->RefClock,
176c35d236eSmrg								&m,&n,&p);
177c35d236eSmrg	pReg->DacRegs[PM2DACIndexClockAM] = m;
178c35d236eSmrg	pReg->DacRegs[PM2DACIndexClockAN] = n;
179c35d236eSmrg	pReg->DacRegs[PM2DACIndexClockAP] = p|0x08;
180c35d236eSmrg    }
181c35d236eSmrg
182c35d236eSmrg    if (pScrn->rgbBits == 8)
183c35d236eSmrg	pReg->DacRegs[PM2DACIndexMCR] = 0x02; /* 8bit DAC */
184c35d236eSmrg    else
185c35d236eSmrg        pReg->DacRegs[PM2DACIndexMCR] = 0x00; /* 6bit DAC */
186c35d236eSmrg
187c35d236eSmrg    if (!(mode->Flags & V_PHSYNC))
188c35d236eSmrg        pReg->DacRegs[PM2DACIndexMCR] |= 0x04; /* invert hsync */
189c35d236eSmrg    if (!(mode->Flags & V_PVSYNC))
190c35d236eSmrg        pReg->DacRegs[PM2DACIndexMCR] |= 0x08; /* invert vsync */
191c35d236eSmrg
192c35d236eSmrg    switch (pScrn->bitsPerPixel)
193c35d236eSmrg    {
194c35d236eSmrg    case 8:
195c35d236eSmrg	pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_GRAPHICS |
196c35d236eSmrg					PM2DAC_CI8;
197c35d236eSmrg    	break;
198c35d236eSmrg    case 16:
199c35d236eSmrg	if (pScrn->depth == 15) {
200c35d236eSmrg	      pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR|
201c35d236eSmrg				        PM2DAC_GRAPHICS | PM2DAC_5551;
202c35d236eSmrg	} else {
203c35d236eSmrg	    pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR|
204c35d236eSmrg				 	PM2DAC_GRAPHICS | PM2DAC_565;
205c35d236eSmrg	}
206c35d236eSmrg    	break;
207c35d236eSmrg    case 24:
208c35d236eSmrg	pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR|
209c35d236eSmrg				 	PM2DAC_GRAPHICS | PM2DAC_PACKED;
210c35d236eSmrg    	break;
211c35d236eSmrg    case 32:
212c35d236eSmrg	pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB |
213c35d236eSmrg				 	PM2DAC_GRAPHICS | PM2DAC_8888;
214c35d236eSmrg	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
215c35d236eSmrg	    pReg->DacRegs[PM2DACIndexColorKeyControl] = 0x11;
216c35d236eSmrg	    pReg->DacRegs[PM2DACIndexColorKeyOverlay] = pScrn->colorKey;
217c35d236eSmrg	} else
218c35d236eSmrg	    pReg->DacRegs[PM2DACIndexCMR] |= PM2DAC_TRUECOLOR;
219c35d236eSmrg    	break;
220c35d236eSmrg    }
221c35d236eSmrg
222c35d236eSmrg    return(TRUE);
223c35d236eSmrg}
224c35d236eSmrg
225c35d236eSmrgvoid
226c35d236eSmrgPermedia2Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
227c35d236eSmrg{
228c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
229c35d236eSmrg    int i;
230c35d236eSmrg
231c35d236eSmrg    /* We can't rely on the vgahw layer copying the font information
232c35d236eSmrg     * back properly, due to problems with MMIO access to VGA space
233c35d236eSmrg     * so we memcpy the information using the slow routines */
234c35d236eSmrg    xf86SlowBcopy((CARD8*)pGlint->FbBase, (CARD8*)pGlint->VGAdata, 65536);
235c35d236eSmrg
236c35d236eSmrg    glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0);
237c35d236eSmrg    glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1);
238c35d236eSmrg    glintReg->glintRegs[PMFramebufferWriteMask >> 3] =
239c35d236eSmrg					GLINT_READ_REG(PMFramebufferWriteMask);
240c35d236eSmrg    glintReg->glintRegs[PMBypassWriteMask >> 3]  = GLINT_READ_REG(PMBypassWriteMask);
241c35d236eSmrg    glintReg->glintRegs[DFIFODis >> 3]  = GLINT_READ_REG(DFIFODis);
242c35d236eSmrg    glintReg->glintRegs[FIFODis >> 3]  = GLINT_READ_REG(FIFODis);
243c35d236eSmrg    /* We only muck about with PMMemConfig, if user wants to */
244c35d236eSmrg    if (pGlint->UseBlockWrite)
245c35d236eSmrg	glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig);
246c35d236eSmrg    glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal);
247c35d236eSmrg    glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd);
248c35d236eSmrg    glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd);
249c35d236eSmrg    glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride);
250c35d236eSmrg    glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart);
251c35d236eSmrg    glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd);
252c35d236eSmrg    glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal);
253c35d236eSmrg    glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd);
254c35d236eSmrg    glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart);
255c35d236eSmrg    glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd);
256c35d236eSmrg    glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase);
257c35d236eSmrg    glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl);
258c35d236eSmrg    glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
259c35d236eSmrg    glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig);
260c35d236eSmrg
261c35d236eSmrg    for (i=0;i<768;i++) {
262c35d236eSmrg    	Permedia2ReadAddress(pScrn, i);
263c35d236eSmrg	glintReg->cmap[i] = Permedia2ReadData(pScrn);
264c35d236eSmrg    }
265c35d236eSmrg
266c35d236eSmrg    glintReg->DacRegs[PM2DACIndexColorKeyOverlay] =
267c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexColorKeyOverlay);
268c35d236eSmrg    glintReg->DacRegs[PM2DACIndexColorKeyControl] =
269c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexColorKeyControl);
270c35d236eSmrg    glintReg->DacRegs[PM2DACIndexMCR] =
271c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexMCR);
272c35d236eSmrg    glintReg->DacRegs[PM2DACIndexMDCR] =
273c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexMDCR);
274c35d236eSmrg    glintReg->DacRegs[PM2DACIndexCMR] =
275c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexCMR);
276c35d236eSmrg
277c35d236eSmrg    glintReg->DacRegs[PM2DACIndexClockAM] =
278c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexClockAM);
279c35d236eSmrg    glintReg->DacRegs[PM2DACIndexClockAN] =
280c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexClockAN);
281c35d236eSmrg    glintReg->DacRegs[PM2DACIndexClockAP] =
282c35d236eSmrg				Permedia2InIndReg(pScrn, PM2DACIndexClockAP);
283c35d236eSmrg}
284c35d236eSmrg
285c35d236eSmrgvoid
286c35d236eSmrgPermedia2Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
287c35d236eSmrg{
288c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
289c35d236eSmrg    int i;
290c35d236eSmrg
291c35d236eSmrg    /* We can't rely on the vgahw layer copying the font information
292c35d236eSmrg     * back properly, due to problems with MMIO access to VGA space
293c35d236eSmrg     * so we memcpy the information using the slow routines */
294c35d236eSmrg    if (pGlint->STATE)
295c35d236eSmrg	xf86SlowBcopy((CARD8*)pGlint->VGAdata, (CARD8*)pGlint->FbBase, 65536);
296c35d236eSmrg
297c35d236eSmrg#if 0
298c35d236eSmrg    GLINT_SLOW_WRITE_REG(0, ResetStatus);
299c35d236eSmrg    while(GLINT_READ_REG(ResetStatus) != 0) {
300c35d236eSmrg	xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n");
301c35d236eSmrg    };
302c35d236eSmrg#endif
303c35d236eSmrg
304c35d236eSmrg    GLINT_SLOW_WRITE_REG(0xFF, PM2DACReadMask);
305c35d236eSmrg
306c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
307c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
308c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3],
309c35d236eSmrg							PMFramebufferWriteMask);
310c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3],
311c35d236eSmrg							PMBypassWriteMask);
312c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
313c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
314c35d236eSmrg    /* We only muck about with PMMemConfig, if user wants to */
315c35d236eSmrg    if (pGlint->UseBlockWrite)
316c35d236eSmrg    	GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig);
317c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3],
318c35d236eSmrg								PMVideoControl);
319c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd);
320c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase);
321c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl);
322c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3],
323c35d236eSmrg								PMScreenStride);
324c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal);
325c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd);
326c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart);
327c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd);
328c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal);
329c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd);
330c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart);
331c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd);
332c35d236eSmrg    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig);
333c35d236eSmrg
334c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyOverlay, 0x00,
335c35d236eSmrg					glintReg->DacRegs[PM2DACIndexColorKeyOverlay]);
336c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyControl, 0x00,
337c35d236eSmrg					glintReg->DacRegs[PM2DACIndexColorKeyControl]);
338c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexMCR, 0x00,
339c35d236eSmrg					glintReg->DacRegs[PM2DACIndexMCR]);
340c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexMDCR, 0x00,
341c35d236eSmrg					glintReg->DacRegs[PM2DACIndexMDCR]);
342c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexCMR, 0x00,
343c35d236eSmrg					glintReg->DacRegs[PM2DACIndexCMR]);
344c35d236eSmrg
345c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexClockAM, 0x00,
346c35d236eSmrg					glintReg->DacRegs[PM2DACIndexClockAM]);
347c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexClockAN, 0x00,
348c35d236eSmrg					glintReg->DacRegs[PM2DACIndexClockAN]);
349c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACIndexClockAP, 0x00,
350c35d236eSmrg					glintReg->DacRegs[PM2DACIndexClockAP]);
351c35d236eSmrg
352c35d236eSmrg    for (i=0;i<768;i++) {
353c35d236eSmrg    	Permedia2WriteAddress(pScrn, i);
354c35d236eSmrg        Permedia2WriteData(pScrn, glintReg->cmap[i]);
355c35d236eSmrg    }
356c35d236eSmrg}
357c35d236eSmrg
358c35d236eSmrgstatic void
359c35d236eSmrgPermedia2ShowCursor(ScrnInfoPtr pScrn)
360c35d236eSmrg{
361c35d236eSmrg    /* Enable cursor - X11 mode */
362c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x43);
363c35d236eSmrg}
364c35d236eSmrg
365c35d236eSmrgstatic void
366c35d236eSmrgPermedia2HideCursor(ScrnInfoPtr pScrn)
367c35d236eSmrg{
368c35d236eSmrg    /* Disable cursor */
369c35d236eSmrg    Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00);
370c35d236eSmrg}
371c35d236eSmrg
372c35d236eSmrgstatic void
373c35d236eSmrgPermedia2LoadCursorImage(
374c35d236eSmrg    ScrnInfoPtr pScrn,
375c35d236eSmrg    unsigned char *src
376c35d236eSmrg)
377c35d236eSmrg{
378c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
379c35d236eSmrg    int i;
380c35d236eSmrg
381c35d236eSmrg    GLINT_SLOW_WRITE_REG(0x00, PM2DACWriteAddress);
382c35d236eSmrg    for (i=0; i<1024; i++) {
383c35d236eSmrg	GLINT_SLOW_WRITE_REG(*(src++), PM2DACCursorData);
384c35d236eSmrg    }
385c35d236eSmrg}
386c35d236eSmrg
387c35d236eSmrgstatic void
388c35d236eSmrgPermedia2SetCursorPosition(
389c35d236eSmrg   ScrnInfoPtr pScrn,
390c35d236eSmrg   int x, int y
391c35d236eSmrg)
392c35d236eSmrg{
393c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
394c35d236eSmrg
395c35d236eSmrg    x += 64;
396c35d236eSmrg    y += 64;
397c35d236eSmrg
398c35d236eSmrg    /* Output position - "only" 11 bits of location documented */
399c35d236eSmrg
400c35d236eSmrg    GLINT_WRITE_REG(x & 0xFF,	   PM2DACCursorXLsb);
401c35d236eSmrg    GLINT_WRITE_REG((x>>8) & 0x07, PM2DACCursorXMsb);
402c35d236eSmrg    GLINT_WRITE_REG(y & 0xFF,	   PM2DACCursorYLsb);
403c35d236eSmrg    GLINT_WRITE_REG((y>>8) & 0x07, PM2DACCursorYMsb);
404c35d236eSmrg}
405c35d236eSmrg
406c35d236eSmrgstatic void
407c35d236eSmrgPermedia2SetCursorColors(
408c35d236eSmrg   ScrnInfoPtr pScrn,
409c35d236eSmrg   int bg, int fg
410c35d236eSmrg)
411c35d236eSmrg{
412c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
413c35d236eSmrg    /* The Permedia2 cursor is always 8 bits so shift 8, not 10 */
414c35d236eSmrg
415c35d236eSmrg    GLINT_SLOW_WRITE_REG(1, PM2DACCursorColorAddress);
416c35d236eSmrg    /* Background color */
417c35d236eSmrg    GLINT_SLOW_WRITE_REG(bg >> 0, PM2DACCursorColorData);
418c35d236eSmrg    GLINT_SLOW_WRITE_REG(bg >> 8, PM2DACCursorColorData);
419c35d236eSmrg    GLINT_SLOW_WRITE_REG(bg >> 16, PM2DACCursorColorData);
420c35d236eSmrg
421c35d236eSmrg    /* Foreground color */
422c35d236eSmrg    GLINT_SLOW_WRITE_REG(fg >> 0, PM2DACCursorColorData);
423c35d236eSmrg    GLINT_SLOW_WRITE_REG(fg >> 8, PM2DACCursorColorData);
424c35d236eSmrg    GLINT_SLOW_WRITE_REG(fg >> 16, PM2DACCursorColorData);
425c35d236eSmrg}
426c35d236eSmrg
427c35d236eSmrgstatic Bool
428c35d236eSmrgPermedia2UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
429c35d236eSmrg{
430c35d236eSmrg    return TRUE;
431c35d236eSmrg}
432c35d236eSmrg
433c35d236eSmrgBool
434c35d236eSmrgPermedia2HWCursorInit(ScreenPtr pScreen)
435c35d236eSmrg{
4365c69f917Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
437c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
438c35d236eSmrg    xf86CursorInfoPtr infoPtr;
439c35d236eSmrg
440c35d236eSmrg    infoPtr = xf86CreateCursorInfoRec();
441c35d236eSmrg    if(!infoPtr) return FALSE;
442c35d236eSmrg
443c35d236eSmrg    pGlint->CursorInfoRec = infoPtr;
444c35d236eSmrg
445c35d236eSmrg    infoPtr->MaxWidth = 64;
446c35d236eSmrg    infoPtr->MaxHeight = 64;
447c35d236eSmrg    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
448c35d236eSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
449c35d236eSmrg		HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
450c35d236eSmrg#endif
451c35d236eSmrg		HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
452c35d236eSmrg    infoPtr->SetCursorColors = Permedia2SetCursorColors;
453c35d236eSmrg    infoPtr->SetCursorPosition = Permedia2SetCursorPosition;
454c35d236eSmrg    infoPtr->LoadCursorImage = Permedia2LoadCursorImage;
455c35d236eSmrg    infoPtr->HideCursor = Permedia2HideCursor;
456c35d236eSmrg    infoPtr->ShowCursor = Permedia2ShowCursor;
457c35d236eSmrg    infoPtr->UseHWCursor = Permedia2UseHWCursor;
458c35d236eSmrg
459c35d236eSmrg    return(xf86InitCursor(pScreen, infoPtr));
460c35d236eSmrg}
461c35d236eSmrg
462c35d236eSmrg/* I2C Functions */
463c35d236eSmrg
464c35d236eSmrgvoid
465c35d236eSmrgPermedia2I2CUDelay(I2CBusPtr b, int usec)
466c35d236eSmrg{
467c35d236eSmrg    GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr;
468c35d236eSmrg    CARD32 ct1 = GLINT_READ_REG(PMCount);
469c35d236eSmrg    CARD32 ct2 = usec * 100;
470c35d236eSmrg
471c35d236eSmrg    if (GLINT_READ_REG(PMCount) != ct1)
472c35d236eSmrg	while ((GLINT_READ_REG(PMCount) - ct1) < ct2);
473c35d236eSmrg}
474c35d236eSmrg
475c35d236eSmrgvoid
476c35d236eSmrgPermedia2I2CPutBits(I2CBusPtr b, int scl, int sda)
477c35d236eSmrg{
478c35d236eSmrg    GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr;
479c35d236eSmrg    int r = (pGlint->DDCBus == b) ? PMDDCData : VSSerialBusControl;
4806f68ce78Smrg
481933f9f8fSmacallan    CARD32 v = 0;
4826f68ce78Smrg
483c35d236eSmrg    if (scl > 0) v |= ClkOut;
484c35d236eSmrg    if (sda > 0) v |= DataOut;
485c35d236eSmrg
486c35d236eSmrg    GLINT_WRITE_REG(v, r);
487c35d236eSmrg}
488c35d236eSmrg
489c35d236eSmrgvoid
490c35d236eSmrgPermedia2I2CGetBits(I2CBusPtr b, int *scl, int *sda)
491c35d236eSmrg{
492c35d236eSmrg    GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr;
493c35d236eSmrg    CARD32 v = GLINT_READ_REG((pGlint->DDCBus == b) ?
494c35d236eSmrg	    PMDDCData : VSSerialBusControl);
495c35d236eSmrg
496c35d236eSmrg    *scl = (v & ClkIn) > 0;
497c35d236eSmrg    *sda = (v & DataIn) > 0;
498c35d236eSmrg}
499c35d236eSmrg
500c35d236eSmrgvoid
501c35d236eSmrgPermedia2PreInit(ScrnInfoPtr pScrn)
502c35d236eSmrg{
503c35d236eSmrg#if defined(__alpha__)
504c35d236eSmrg    GLINTPtr pGlint = GLINTPTR(pScrn);
505c35d236eSmrg
506c35d236eSmrg    /*
507c35d236eSmrg     * On Alpha, we have to init secondary PM2 cards, since
508c35d236eSmrg     * int10 cannot be run on the OEMed cards with VGA disable
509c35d236eSmrg     * jumpers.
510c35d236eSmrg     */
511c35d236eSmrg    if (!xf86IsPrimaryPci(pGlint->PciInfo)) {
512c35d236eSmrg	if ( IS_GLORIASYNERGY ) {
513c35d236eSmrg
514c35d236eSmrg	    /* PM2DAC_CalculateMNPCForClock(80000, 14318, &m, &n, &p); */
515c35d236eSmrg	    Permedia2OutIndReg(pScrn, PM2DACIndexMemClockM, 0x00, 0x7b);
516c35d236eSmrg	    Permedia2OutIndReg(pScrn, PM2DACIndexMemClockN, 0x00, 0x0b);
517c35d236eSmrg	    Permedia2OutIndReg(pScrn, PM2DACIndexMemClockP, 0x00, 0x09);
518c35d236eSmrg
519c35d236eSmrg	    GLINT_SLOW_WRITE_REG( 0x20, PMBootAddress);
520c35d236eSmrg	    GLINT_SLOW_WRITE_REG( 0xe6002021, PMMemConfig);
521c35d236eSmrg	}
522c35d236eSmrg    }
523c35d236eSmrg#endif /* __alpha__ */
524c35d236eSmrg}
525