1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/imstt/imstt_accel.c,v 1.5 2001/04/05 21:29:14 dawes Exp $ */
2
3/*
4 *	Copyright 2000	Ani Joshi <ajoshi@unixbox.com>
5 *
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that copyright
10 * notice and this permission notice appear in supporting documentation and
11 * that the name of Ani Joshi not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission.  Ani Joshi makes no representations
14 * about the suitability of this software for any purpose.  It is provided
15 * "as-is" without express or implied warranty.
16 *
17 * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 *
25 */
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <X11/Xarch.h>
32#include "xf86.h"
33#include "compiler.h"
34#include "xf86_OSproc.h"
35#include "xaa.h"
36#include "xf86PciInfo.h"
37
38#include "imstt.h"
39#include "imstt_reg.h"
40
41
42
43static void IMSTTSync(ScrnInfoPtr pScrn)
44{
45	IMSTTPtr iptr = IMSTTPTR(pScrn);
46/*	IMSTTMMIO_VARS(); */
47
48	while(INREG(IMSTT_SSTATUS) & 0x80);
49	while(INREG(IMSTT_SSTATUS) & 0x40);
50
51	return;
52}
53
54
55static void IMSTTSetupForSolidFill(ScrnInfoPtr pScrn, int color,
56				   int rop, unsigned int planemask)
57{
58	IMSTTPtr iptr = IMSTTPTR(pScrn);
59/*	IMSTTMMIO_VARS(); */
60
61	switch (pScrn->depth) {
62		case 8:
63			iptr->color = color | (color << 8) | (color << 16) | (color << 24);
64			break;
65		case 15:
66		case 16:
67			iptr->color = color | (color << 8) | (color << 16);
68			break;
69		default:
70			iptr->color = color;
71			break;
72	}
73}
74
75
76static void IMSTTSubsequentSolidFillRect(ScrnInfoPtr pScrn,
77					 int x, int y, int w, int h)
78{
79	IMSTTPtr iptr = IMSTTPTR(pScrn);
80/*	IMSTTMMIO_VARS(); */
81
82	x *= (pScrn->bitsPerPixel >> 3);
83	y *= iptr->ll;
84	w *= (pScrn->bitsPerPixel >> 3);
85	h--;
86	w--;
87
88	while(INREG(IMSTT_SSTATUS) & 0x80);
89	OUTREG(IMSTT_DSA, x + y);
90	OUTREG(IMSTT_CNT, (h << 16) | w);
91	OUTREG(IMSTT_DP_OCTL, iptr->ll);
92	OUTREG(IMSTT_SP, iptr->ll);
93	OUTREG(IMSTT_BI, 0xffffffff);
94	OUTREG(IMSTT_MBC, 0xffffffff);
95	OUTREG(IMSTT_CLR, iptr->color);
96
97	if (iptr->rev == 2)
98		OUTREG(IMSTT_BLTCTL, 0x200000);
99	else
100		OUTREG(IMSTT_BLTCTL, 0x840);
101
102	while(INREG(IMSTT_SSTATUS) & 0x80);
103	while(INREG(IMSTT_SSTATUS) & 0x40);
104}
105
106
107static void IMSTTSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
108					    int ydir, int rop, unsigned int planemask,
109					    int trans_color)
110{
111	IMSTTPtr iptr = IMSTTPTR(pScrn);
112/*	IMSTTMMIO_VARS(); */
113	unsigned long sp, dp, ll;
114
115	iptr->bltctl = 0x05;
116
117	ll = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3);
118	ll = iptr->ll;
119
120	sp = ll << 16;
121
122	if (xdir < 0) {
123		iptr->bltctl |= 0x80;
124		iptr->cnt = 1;
125	} else {
126		iptr->cnt = 0;
127	}
128
129	if (ydir < 0) {
130		sp |= -(ll) & 0xffff;
131		dp = -(ll) & 0xffff;
132		iptr->ydir = 1;
133	} else {
134		sp |= ll;
135		dp = ll;
136		iptr->ydir = 0;
137	}
138
139	iptr->sp = sp;
140	iptr->dp = dp;
141	iptr->ll = ll;
142}
143
144
145static void IMSTTSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
146					      int x1, int y1,
147					      int x2, int y2,
148					      int w, int h)
149{
150	IMSTTPtr iptr = IMSTTPTR(pScrn);
151/*	IMSTTMMIO_VARS(); */
152	unsigned long cnt;
153
154	x1 *= (pScrn->bitsPerPixel >> 3);
155	x2 *= (pScrn->bitsPerPixel >> 3);
156	w *= (pScrn->bitsPerPixel >> 3);
157	w--;
158	h--;
159	cnt = h << 16;
160
161	if (iptr->cnt) {
162		x1 += w;
163		x2 += w;
164		cnt |= -(w) & 0xffff;
165	}
166	else
167		cnt |= w;
168
169	if (iptr->ydir) {
170		y1 += h;
171		y2 += h;
172	}
173
174	OUTREG(IMSTT_S1SA, y1 * iptr->ll + x1);
175	OUTREG(IMSTT_SP, iptr->sp);
176	OUTREG(IMSTT_DSA, y2 * iptr->ll + x2);
177	OUTREG(IMSTT_CNT, cnt);
178	OUTREG(IMSTT_DP_OCTL, iptr->dp);
179	OUTREG(IMSTT_BLTCTL, iptr->bltctl);
180	while(INREG(IMSTT_SSTATUS) & 0x80);
181	while(INREG(IMSTT_SSTATUS) & 0x40);
182}
183
184
185
186Bool IMSTTAccelInit(ScreenPtr pScreen)
187{
188	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
189	IMSTTPtr iptr = IMSTTPTR(pScrn);
190	XAAInfoRecPtr xaaptr;
191
192	if (!(xaaptr = iptr->AccelInfoRec = XAACreateInfoRec()))
193		return FALSE;
194
195	iptr->ll = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3);
196
197	switch (pScrn->bitsPerPixel) {
198		case 16:
199			iptr->screen_width = iptr->pitch >> 1;
200			break;
201		case 24:
202		case 32:
203			iptr->screen_width = iptr->pitch >> 2;
204			break;
205		default:
206			iptr->screen_width = iptr->pitch = iptr->ll;
207			break;
208	}
209
210	xaaptr->Flags = (PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER);
211
212	xaaptr->Sync = IMSTTSync;
213
214	if (pScrn->bitsPerPixel == 8) {
215		/* FIXME fills are broken > 8bpp, iptr->color needs to be setup right */
216		xaaptr->SetupForSolidFill = IMSTTSetupForSolidFill;
217		xaaptr->SubsequentSolidFillRect = IMSTTSubsequentSolidFillRect;
218	}
219
220	xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
221	xaaptr->SetupForScreenToScreenCopy = IMSTTSetupForScreenToScreenCopy;
222	xaaptr->SubsequentScreenToScreenCopy = IMSTTSubsequentScreenToScreenCopy;
223
224	return XAAInit(pScreen, xaaptr);
225}
226
227