smi_accel.c revision 09885543
1/* Header:   //Mercury/Projects/archives/XFree86/4.0/smi_accel.c-arc   1.16   03 Jan 2001 13:29:06   Frido  $ */
2
3/*
4Copyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
5Copyright (C) 2000 Silicon Motion, Inc.  All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of
8this software and associated documentation files (the "Software"), to deal in
9the Software without restriction, including without limitation the rights to
10use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11of the Software, and to permit persons to whom the Software is furnished to do
12so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
19NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the names of the XFree86 Project and
25Silicon Motion shall not be used in advertising or otherwise to promote the
26sale, use or other dealings in this Software without prior written
27authorization from the XFree86 Project and silicon Motion.
28*/
29/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_accel.c,v 1.7tsi Exp $ */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "smi.h"
36
37void
38SMI_GEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
39{
40    SMIPtr pSmi = SMIPTR(pScrn);
41    CARD8 tmp;
42
43    ENTER_PROC("SMI_GEReset");
44
45    if (from_timeout) {
46	if (pSmi->GEResetCnt++ < 10 || xf86GetVerbosity() > 1) {
47	    xf86DrvMsg(pScrn->scrnIndex,X_INFO,"\tSMI_GEReset called from %s line %d\n", file, line);
48	}
49    } else {
50	WaitIdleEmpty();
51    }
52
53    tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15);
54    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15, tmp | 0x30);
55
56    WaitIdleEmpty();
57
58    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15, tmp);
59    SMI_EngineReset(pScrn);
60
61    LEAVE_PROC("SMI_GEReset");
62}
63
64/* The sync function for the GE */
65void
66SMI_AccelSync(ScrnInfoPtr pScrn)
67{
68    SMIPtr pSmi = SMIPTR(pScrn);
69
70    ENTER_PROC("SMI_AccelSync");
71
72    WaitIdleEmpty(); /* #161 */
73
74    LEAVE_PROC("SMI_AccelSync");
75}
76
77void
78SMI_EngineReset(ScrnInfoPtr pScrn)
79{
80    SMIPtr pSmi = SMIPTR(pScrn);
81    CARD32 DEDataFormat = 0;
82    int i;
83    int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 };
84
85    ENTER_PROC("SMI_EngineReset");
86
87    pSmi->Stride = (pSmi->width * pSmi->Bpp + 15) & ~15;
88
89    switch (pScrn->bitsPerPixel) {
90    case 8:
91	DEDataFormat = 0x00000000;
92	break;
93    case 16:
94	pSmi->Stride >>= 1;
95	DEDataFormat = 0x00100000;
96	break;
97    case 24:
98	DEDataFormat = 0x00300000;
99	break;
100    case 32:
101	pSmi->Stride >>= 2;
102	DEDataFormat = 0x00200000;
103	break;
104    }
105
106    for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++) {
107	if (pSmi->rotate) {
108	    if (xyAddress[i] == pSmi->height) {
109		DEDataFormat |= i << 16;
110		break;
111	    }
112	} else {
113	    if (xyAddress[i] == pSmi->width) {
114		DEDataFormat |= i << 16;
115		break;
116	    }
117	}
118    }
119
120    WaitIdleEmpty();
121    WRITE_DPR(pSmi, 0x10, (pSmi->Stride << 16) | pSmi->Stride);
122    WRITE_DPR(pSmi, 0x1C, DEDataFormat);
123    WRITE_DPR(pSmi, 0x24, 0xFFFFFFFF);
124    WRITE_DPR(pSmi, 0x28, 0xFFFFFFFF);
125    WRITE_DPR(pSmi, 0x3C, (pSmi->Stride << 16) | pSmi->Stride);
126    WRITE_DPR(pSmi, 0x40, pSmi->FBOffset >> 3);
127    WRITE_DPR(pSmi, 0x44, pSmi->FBOffset >> 3);
128
129    SMI_DisableClipping(pScrn);
130
131    LEAVE_PROC("SMI_EngineReset");
132}
133
134/******************************************************************************/
135/*  Clipping								      */
136/******************************************************************************/
137
138void
139SMI_SetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right,
140			 int bottom)
141{
142    SMIPtr pSmi = SMIPTR(pScrn);
143
144    ENTER_PROC("SMI_SetClippingRectangle");
145    DEBUG((VERBLEV, "left=%d top=%d right=%d bottom=%d\n", left, top, right,
146	   bottom));
147
148    /* CZ 26.10.2001: this code prevents offscreen pixmaps being drawn ???
149	left   = max(left, 0);
150	top    = max(top, 0);
151	right  = min(right, pSmi->width);
152	bottom = min(bottom, pSmi->height);
153    */
154
155    if (pScrn->bitsPerPixel == 24) {
156	left  *= 3;
157	right *= 3;
158
159	if (pSmi->Chipset == SMI_LYNX) {
160	    top    *= 3;
161	    bottom *= 3;
162	}
163    }
164
165    pSmi->ScissorsLeft = (top << 16) | (left & 0xFFFF) | 0x2000;
166    pSmi->ScissorsRight = (bottom << 16) | (right & 0xFFFF);
167
168    pSmi->ClipTurnedOn = FALSE;
169
170    WaitQueue(2);
171    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
172    WRITE_DPR(pSmi, 0x30, pSmi->ScissorsRight);
173
174    LEAVE_PROC("SMI_SetClippingRectangle");
175}
176
177void
178SMI_DisableClipping(ScrnInfoPtr pScrn)
179{
180    SMIPtr pSmi = SMIPTR(pScrn);
181
182    ENTER_PROC("SMI_DisableClipping");
183
184    pSmi->ScissorsLeft = 0;
185    if (pScrn->bitsPerPixel == 24) {
186	if (pSmi->Chipset == SMI_LYNX) {
187	    pSmi->ScissorsRight = ((pSmi->height * 3) << 16) | (pSmi->width * 3);
188	} else {
189	    pSmi->ScissorsRight = (pSmi->height << 16) | (pSmi->width * 3);
190	}
191    } else {
192	pSmi->ScissorsRight = (pSmi->height << 16) | pSmi->width;
193    }
194
195    pSmi->ClipTurnedOn = FALSE;
196
197    WaitQueue(2);
198    WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
199    WRITE_DPR(pSmi, 0x30, pSmi->ScissorsRight);
200
201    LEAVE_PROC("SMI_DisableClipping");
202}
203
204