ark_accel.c revision 3e51e026
1/*
2 *      Copyright 2000  Ani Joshi <ajoshi@unixbox.com>
3 *
4 *      XFree86 4.x driver for ARK Logic chipset
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that copyright
9 * notice and this permission notice appear in supporting documentation and
10 * that the name of Ani Joshi not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission.  Ani Joshi makes no representations
13 * about the suitability of this software for any purpose.  It is provided
14 * "as-is" without express or implied warranty.
15 *
16 * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 *
24 *
25 *      Based on the 3.3.x driver by:
26 *              Harm Hanemaayer <H.Hanemaayer@inter.nl.net>
27 *
28 */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <X11/Xarch.h>
35#include "xf86.h"
36#include "xf86_OSproc.h"
37#include "compiler.h"
38
39#include "ark.h"
40#include "ark_reg.h"
41
42#ifdef HAVE_XAA_H
43static int curx, cury, cmd_flags;
44
45static void ARKSync(ScrnInfoPtr pScrn)
46{
47	unsigned long port = 0x3cb;
48#if ABI_VIDEODRV_VERSION < 12
49	port += pScrn->domainIOBase + 0x3cb;
50#endif
51
52	for (;;) {
53		if (!(inb(port) & 0x40))
54			break;
55	}
56}
57
58
59static void ARKSetupForSolidFill(ScrnInfoPtr pScrn, int color,
60				 int rop, unsigned int planemask)
61{
62	ARKPtr pARK = ARKPTR(pScrn);
63
64	OUTREG16(FG_COLOR, color);
65	/* ARK color mix matches X raster-ops */
66	OUTREG16(COLOR_MIX_SEL, (rop | (rop << 8)));
67	switch (pScrn->bitsPerPixel) {
68		case 8:
69			if ((planemask & 0xff) == 0xff)
70				cmd_flags = DISABLE_PLANEMASK;
71			else {
72				OUTREG16(WRITE_PLANEMASK, planemask);
73				cmd_flags = 0;
74			}
75			break;
76		case 16:
77			if ((planemask & 0xffff) == 0xffff)
78				cmd_flags = DISABLE_PLANEMASK;
79			else {
80				OUTREG16(WRITE_PLANEMASK, planemask);
81				cmd_flags = 0;
82			}
83			break;
84		case 32:
85			OUTREG16(FG_COLOR_HI, color >> 16);
86			if ((planemask & 0xffffff) == 0xffffff)
87				cmd_flags = DISABLE_PLANEMASK;
88			else {
89				OUTREG16(WRITE_PLANEMASK, planemask);
90				cmd_flags = 0;
91			}
92			break;
93	}
94
95	curx = cury = -1;
96}
97
98
99static void ARKSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x,
100				       int y, int w, int h)
101{
102	ARKPtr pARK = ARKPTR(pScrn);
103	int dst_addr;
104
105	OUTREG(WIDTH, ((h - 1) << 16) | (w - 1));
106	if (x != curx || y != cury) {
107		dst_addr = y * pScrn->displayWidth + x;
108		OUTREG(DST_ADDR, dst_addr);
109		curx = x;
110		cury = y;
111	}
112	OUTREG16(COMMAND, SELECT_BG_COLOR | SELECT_FG_COLOR |
113			  STENCIL_ONES | DISABLE_CLIPPING | BITBLT |
114			  cmd_flags);
115	cury += h;
116}
117
118
119
120static void ARKSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
121					  int ydir, int rop, unsigned int planemask,
122					  int trans_color)
123{
124	ARKPtr pARK = ARKPTR(pScrn);
125
126	cmd_flags = 0;
127	if (trans_color != -1) {
128		if (pScrn->bitsPerPixel <= 16)
129			OUTREG16(TRANS_COLOR, trans_color);
130		else {
131			OUTREG16(TRANS_COLOR, trans_color & 0xffff);
132			OUTREG16(TRANS_COLOR_HI, trans_color >> 16);
133		}
134		cmd_flags = STENCIL_GENERATED;
135		OUTREG16(COLOR_MIX_SEL, rop | 0x0500);
136	} else {
137		OUTREG16(COLOR_MIX_SEL, rop | (rop << 8));
138	}
139
140	if (ydir < 0)
141		cmd_flags |= UP;
142	if (xdir < 0)
143		cmd_flags |= LEFT;
144
145	/* yes, quite ugly */
146	if ((pScrn->bitsPerPixel == 8 && (planemask & 0xff) == 0xff) ||
147	    (pScrn->bitsPerPixel == 16 && (planemask & 0xffff) == 0xffff) ||
148	    (pScrn->bitsPerPixel == 32 && (planemask & 0xffffff) == 0xffffff))
149		cmd_flags |= DISABLE_PLANEMASK;
150	else
151		OUTREG16(WRITE_PLANEMASK, planemask);
152
153}
154
155
156
157static void ARKSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
158					    int x1, int y1,
159					    int x2, int y2,
160					    int w, int h)
161{
162	ARKPtr pARK = ARKPTR(pScrn);
163	int src_addr, dst_addr;
164
165	if (cmd_flags & UP) {
166		src_addr = (y1 + h - 1) * pScrn->displayWidth;
167		dst_addr = (y2 + h - 1) * pScrn->displayWidth;
168	} else {
169		src_addr = y1 * pScrn->displayWidth;
170		dst_addr = y2 * pScrn->displayWidth;
171	}
172	if (cmd_flags & LEFT) {
173		src_addr += x1 + w - 1;
174		dst_addr += x2 + w - 1;
175	} else {
176		src_addr += x1;
177		dst_addr += x2;
178	}
179
180	OUTREG(SRC_ADDR, src_addr);
181	OUTREG(DST_ADDR, dst_addr);
182	OUTREG(WIDTH, ((h - 1) << 16) | (w - 1));
183	OUTREG16(COMMAND, BG_BITMAP | FG_BITMAP | DISABLE_CLIPPING |
184			  BITBLT | cmd_flags);
185}
186
187#endif
188
189Bool ARKAccelInit(ScreenPtr pScreen)
190{
191#ifdef HAVE_XAA_H
192	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
193	ARKPtr pARK = ARKPTR(pScrn);
194	XAAInfoRecPtr pXAA;
195
196	if (!(pXAA = XAACreateInfoRec()))
197		return FALSE;
198
199	pXAA->Flags = LINEAR_FRAMEBUFFER;
200
201	pXAA->Sync = ARKSync;
202	pXAA->SetupForSolidFill = ARKSetupForSolidFill;
203	pXAA->SubsequentSolidFillRect = ARKSubsequentSolidFillRect;
204	pXAA->ScreenToScreenCopyFlags = 0;
205	pXAA->SetupForScreenToScreenCopy = ARKSetupForScreenToScreenCopy;
206	pXAA->SubsequentScreenToScreenCopy = ARKSubsequentScreenToScreenCopy;
207
208	OUTREG16(COLOR_MIX_SEL, 0x0303);
209	if (pARK->Chipset == PCI_CHIP_1000PV) {
210		OUTREG16(WRITE_PLANEMASK, 0xffff);
211		OUTREG16(TRANS_COLOR_MSK, 0xffff);
212	} else {
213		OUTREG16(TRANS_COLOR, 0xffff);
214		OUTREG16(TRANS_COLOR, 0xffffffff >> 16);
215	}
216	if (pARK->Chipset == PCI_CHIP_1000PV && pScrn->bitsPerPixel == 32) {
217		OUTREG16(STENCIL_PITCH, pScrn->displayWidth * 2);
218		OUTREG16(SRC_PITCH, pScrn->displayWidth * 2);
219		OUTREG16(DST_PITCH, pScrn->displayWidth * 2);
220	} else {
221		OUTREG16(STENCIL_PITCH, pScrn->displayWidth);
222		OUTREG16(SRC_PITCH, pScrn->displayWidth);
223		OUTREG16(DST_PITCH, pScrn->displayWidth);
224	}
225
226	OUTREG16(BITMAP_CONFIG, LINEAR_STENCIL_ADDR | LINEAR_SRC_ADDR |
227				LINEAR_DST_ADDR);
228
229	return XAAInit(pScreen, pXAA);
230#else
231        return FALSE;
232#endif
233}
234