Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
544393fe TW |
2 | * SiS 300/540/630[S]/730[S], |
3 | * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX], | |
4 | * XGI V3XT/V5/V8, Z7 | |
5 | * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3 | |
1da177e4 LT |
6 | * |
7 | * 2D acceleration part | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2 of the named License, | |
12 | * or any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA | |
22 | * | |
23 | * Based on the X driver's sis300_accel.h which is | |
24 | * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria | |
25 | * and sis310_accel.h which is | |
26 | * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria | |
27 | * | |
28 | * Author: Thomas Winischhofer <thomas@winischhofer.net>: | |
29 | * (see http://www.winischhofer.net/ | |
30 | * for more information and updates) | |
31 | */ | |
32 | ||
33 | #ifndef _SISFB_ACCEL_H | |
34 | #define _SISFB_ACCEL_H | |
35 | ||
36 | /* Guard accelerator accesses with spin_lock_irqsave? Works well without. */ | |
37 | #undef SISFB_USE_SPINLOCKS | |
38 | ||
39 | #ifdef SISFB_USE_SPINLOCKS | |
40 | #include <linux/spinlock.h> | |
41 | #define CRITBEGIN spin_lock_irqsave(&ivideo->lockaccel, critflags); | |
42 | #define CRITEND spin_unlock_irqrestore(&ivideo->lockaccel, critflags); | |
43 | #define CRITFLAGS unsigned long critflags; | |
44 | #else | |
45 | #define CRITBEGIN | |
46 | #define CRITEND | |
47 | #define CRITFLAGS | |
48 | #endif | |
49 | ||
50 | /* Definitions for the SIS engine communication. */ | |
51 | ||
52 | #define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */ | |
53 | #define BR(x) (0x8200 | (x) << 2) | |
54 | #define PBR(x) (0x8300 | (x) << 2) | |
55 | ||
56 | /* SiS300 engine commands */ | |
57 | #define BITBLT 0x00000000 /* Blit */ | |
58 | #define COLOREXP 0x00000001 /* Color expand */ | |
59 | #define ENCOLOREXP 0x00000002 /* Enhanced color expand */ | |
60 | #define MULTIPLE_SCANLINE 0x00000003 /* ? */ | |
61 | #define LINE 0x00000004 /* Draw line */ | |
62 | #define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */ | |
63 | #define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */ | |
64 | ||
65 | /* Additional engine commands for 315 */ | |
66 | #define ALPHA_BLEND 0x00000007 /* Alpha blend ? */ | |
67 | #define A3D_FUNCTION 0x00000008 /* 3D command ? */ | |
68 | #define CLEAR_Z_BUFFER 0x00000009 /* ? */ | |
69 | #define GRADIENT_FILL 0x0000000A /* Gradient fill */ | |
70 | ||
71 | /* source select */ | |
72 | #define SRCVIDEO 0x00000000 /* source is video RAM */ | |
73 | #define SRCSYSTEM 0x00000010 /* source is system memory */ | |
74 | #define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */ | |
75 | #define SRCAGP 0x00000020 /* source is AGP memory (?) */ | |
76 | ||
77 | /* Pattern flags */ | |
78 | #define PATFG 0x00000000 /* foreground color */ | |
79 | #define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */ | |
80 | #define PATMONO 0x00000080 /* mono pattern */ | |
81 | ||
82 | /* blitting direction (300 series only) */ | |
83 | #define X_INC 0x00010000 | |
84 | #define X_DEC 0x00000000 | |
85 | #define Y_INC 0x00020000 | |
86 | #define Y_DEC 0x00000000 | |
87 | ||
88 | /* Clipping flags */ | |
89 | #define NOCLIP 0x00000000 | |
90 | #define NOMERGECLIP 0x04000000 | |
91 | #define CLIPENABLE 0x00040000 | |
92 | #define CLIPWITHOUTMERGE 0x04040000 | |
93 | ||
94 | /* Transparency */ | |
95 | #define OPAQUE 0x00000000 | |
96 | #define TRANSPARENT 0x00100000 | |
97 | ||
98 | /* ? */ | |
99 | #define DSTAGP 0x02000000 | |
100 | #define DSTVIDEO 0x02000000 | |
101 | ||
102 | /* Subfunctions for Color/Enhanced Color Expansion (315 only) */ | |
103 | #define COLOR_TO_MONO 0x00100000 | |
104 | #define AA_TEXT 0x00200000 | |
105 | ||
106 | /* Some general registers for 315 series */ | |
107 | #define SRC_ADDR 0x8200 | |
108 | #define SRC_PITCH 0x8204 | |
109 | #define AGP_BASE 0x8206 /* color-depth dependent value */ | |
110 | #define SRC_Y 0x8208 | |
111 | #define SRC_X 0x820A | |
112 | #define DST_Y 0x820C | |
113 | #define DST_X 0x820E | |
114 | #define DST_ADDR 0x8210 | |
115 | #define DST_PITCH 0x8214 | |
116 | #define DST_HEIGHT 0x8216 | |
117 | #define RECT_WIDTH 0x8218 | |
118 | #define RECT_HEIGHT 0x821A | |
119 | #define PAT_FGCOLOR 0x821C | |
120 | #define PAT_BGCOLOR 0x8220 | |
121 | #define SRC_FGCOLOR 0x8224 | |
122 | #define SRC_BGCOLOR 0x8228 | |
123 | #define MONO_MASK 0x822C | |
124 | #define LEFT_CLIP 0x8234 | |
125 | #define TOP_CLIP 0x8236 | |
126 | #define RIGHT_CLIP 0x8238 | |
127 | #define BOTTOM_CLIP 0x823A | |
128 | #define COMMAND_READY 0x823C | |
129 | #define FIRE_TRIGGER 0x8240 | |
130 | ||
131 | #define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */ | |
132 | ||
133 | /* Transparent bitblit registers */ | |
134 | #define TRANS_DST_KEY_HIGH PAT_FGCOLOR | |
135 | #define TRANS_DST_KEY_LOW PAT_BGCOLOR | |
136 | #define TRANS_SRC_KEY_HIGH SRC_FGCOLOR | |
137 | #define TRANS_SRC_KEY_LOW SRC_BGCOLOR | |
138 | ||
139 | /* Store queue length in par */ | |
140 | #define CmdQueLen ivideo->cmdqueuelength | |
141 | ||
142 | /* ------------- SiS 300 series -------------- */ | |
143 | ||
144 | /* BR(16) (0x8240): | |
145 | ||
146 | bit 31 2D engine: 1 is idle, | |
147 | bit 30 3D engine: 1 is idle, | |
148 | bit 29 Command queue: 1 is empty | |
149 | bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0] | |
150 | bits 15:0: Current command queue length | |
151 | ||
152 | */ | |
153 | ||
154 | #define SiS300Idle \ | |
155 | { \ | |
156 | while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \ | |
157 | while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \ | |
158 | while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \ | |
159 | CmdQueLen = MMIO_IN16(ivideo->mmio_vbase, 0x8240); \ | |
160 | } | |
161 | /* (do three times, because 2D engine seems quite unsure about whether or not it's idle) */ | |
162 | ||
163 | #define SiS300SetupSRCBase(base) \ | |
164 | if(CmdQueLen <= 0) SiS300Idle;\ | |
165 | MMIO_OUT32(ivideo->mmio_vbase, BR(0), base);\ | |
166 | CmdQueLen--; | |
167 | ||
168 | #define SiS300SetupSRCPitch(pitch) \ | |
169 | if(CmdQueLen <= 0) SiS300Idle;\ | |
170 | MMIO_OUT16(ivideo->mmio_vbase, BR(1), pitch);\ | |
171 | CmdQueLen--; | |
172 | ||
173 | #define SiS300SetupSRCXY(x,y) \ | |
174 | if(CmdQueLen <= 0) SiS300Idle;\ | |
175 | MMIO_OUT32(ivideo->mmio_vbase, BR(2), (x)<<16 | (y) );\ | |
176 | CmdQueLen--; | |
177 | ||
178 | #define SiS300SetupDSTBase(base) \ | |
179 | if(CmdQueLen <= 0) SiS300Idle;\ | |
180 | MMIO_OUT32(ivideo->mmio_vbase, BR(4), base);\ | |
181 | CmdQueLen--; | |
182 | ||
183 | #define SiS300SetupDSTXY(x,y) \ | |
184 | if(CmdQueLen <= 0) SiS300Idle;\ | |
185 | MMIO_OUT32(ivideo->mmio_vbase, BR(3), (x)<<16 | (y) );\ | |
186 | CmdQueLen--; | |
187 | ||
188 | #define SiS300SetupDSTRect(x,y) \ | |
189 | if(CmdQueLen <= 0) SiS300Idle;\ | |
190 | MMIO_OUT32(ivideo->mmio_vbase, BR(5), (y)<<16 | (x) );\ | |
191 | CmdQueLen--; | |
192 | ||
193 | #define SiS300SetupDSTColorDepth(bpp) \ | |
194 | if(CmdQueLen <= 0) SiS300Idle;\ | |
195 | MMIO_OUT16(ivideo->mmio_vbase, BR(1)+2, bpp);\ | |
196 | CmdQueLen--; | |
197 | ||
198 | #define SiS300SetupRect(w,h) \ | |
199 | if(CmdQueLen <= 0) SiS300Idle;\ | |
200 | MMIO_OUT32(ivideo->mmio_vbase, BR(6), (h)<<16 | (w) );\ | |
201 | CmdQueLen--; | |
202 | ||
203 | #define SiS300SetupPATFG(color) \ | |
204 | if(CmdQueLen <= 0) SiS300Idle;\ | |
205 | MMIO_OUT32(ivideo->mmio_vbase, BR(7), color);\ | |
206 | CmdQueLen--; | |
207 | ||
208 | #define SiS300SetupPATBG(color) \ | |
209 | if(CmdQueLen <= 0) SiS300Idle;\ | |
210 | MMIO_OUT32(ivideo->mmio_vbase, BR(8), color);\ | |
211 | CmdQueLen--; | |
212 | ||
213 | #define SiS300SetupSRCFG(color) \ | |
214 | if(CmdQueLen <= 0) SiS300Idle;\ | |
215 | MMIO_OUT32(ivideo->mmio_vbase, BR(9), color);\ | |
216 | CmdQueLen--; | |
217 | ||
218 | #define SiS300SetupSRCBG(color) \ | |
219 | if(CmdQueLen <= 0) SiS300Idle;\ | |
220 | MMIO_OUT32(ivideo->mmio_vbase, BR(10), color);\ | |
221 | CmdQueLen--; | |
222 | ||
223 | /* 0x8224 src colorkey high */ | |
224 | /* 0x8228 src colorkey low */ | |
225 | /* 0x821c dest colorkey high */ | |
226 | /* 0x8220 dest colorkey low */ | |
227 | #define SiS300SetupSRCTrans(color) \ | |
228 | if(CmdQueLen <= 1) SiS300Idle;\ | |
229 | MMIO_OUT32(ivideo->mmio_vbase, 0x8224, color);\ | |
230 | MMIO_OUT32(ivideo->mmio_vbase, 0x8228, color);\ | |
231 | CmdQueLen -= 2; | |
232 | ||
233 | #define SiS300SetupDSTTrans(color) \ | |
234 | if(CmdQueLen <= 1) SiS300Idle;\ | |
235 | MMIO_OUT32(ivideo->mmio_vbase, 0x821C, color); \ | |
236 | MMIO_OUT32(ivideo->mmio_vbase, 0x8220, color); \ | |
237 | CmdQueLen -= 2; | |
238 | ||
239 | #define SiS300SetupMONOPAT(p0,p1) \ | |
240 | if(CmdQueLen <= 1) SiS300Idle;\ | |
241 | MMIO_OUT32(ivideo->mmio_vbase, BR(11), p0);\ | |
242 | MMIO_OUT32(ivideo->mmio_vbase, BR(12), p1);\ | |
243 | CmdQueLen -= 2; | |
244 | ||
245 | #define SiS300SetupClipLT(left,top) \ | |
246 | if(CmdQueLen <= 0) SiS300Idle;\ | |
247 | MMIO_OUT32(ivideo->mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\ | |
248 | CmdQueLen--; | |
249 | ||
250 | #define SiS300SetupClipRB(right,bottom) \ | |
251 | if(CmdQueLen <= 0) SiS300Idle;\ | |
252 | MMIO_OUT32(ivideo->mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\ | |
253 | CmdQueLen--; | |
254 | ||
255 | /* General */ | |
256 | #define SiS300SetupROP(rop) \ | |
257 | ivideo->CommandReg = (rop) << 8; | |
258 | ||
259 | #define SiS300SetupCMDFlag(flags) \ | |
260 | ivideo->CommandReg |= (flags); | |
261 | ||
262 | #define SiS300DoCMD \ | |
263 | if(CmdQueLen <= 1) SiS300Idle;\ | |
264 | MMIO_OUT32(ivideo->mmio_vbase, BR(15), ivideo->CommandReg); \ | |
265 | MMIO_OUT32(ivideo->mmio_vbase, BR(16), 0);\ | |
266 | CmdQueLen -= 2; | |
267 | ||
268 | /* -------------- SiS 315/330 series --------------- */ | |
269 | ||
270 | /* Q_STATUS: | |
271 | bit 31 = 1: All engines idle and all queues empty | |
272 | bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty | |
273 | bit 29 = 1: 2D engine is idle | |
274 | bit 28 = 1: 3D engine is idle | |
275 | bit 27 = 1: HW command queue empty | |
276 | bit 26 = 1: 2D queue empty | |
277 | bit 25 = 1: 3D queue empty | |
278 | bit 24 = 1: SW command queue empty | |
279 | bits 23:16: 2D counter 3 | |
280 | bits 15:8: 2D counter 2 | |
281 | bits 7:0: 2D counter 1 | |
282 | */ | |
283 | ||
284 | #define SiS310Idle \ | |
285 | { \ | |
286 | while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ | |
287 | while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ | |
544393fe TW |
288 | while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ |
289 | while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ | |
1da177e4 LT |
290 | CmdQueLen = 0; \ |
291 | } | |
292 | ||
293 | #define SiS310SetupSRCBase(base) \ | |
294 | if(CmdQueLen <= 0) SiS310Idle;\ | |
295 | MMIO_OUT32(ivideo->mmio_vbase, SRC_ADDR, base);\ | |
296 | CmdQueLen--; | |
297 | ||
298 | #define SiS310SetupSRCPitch(pitch) \ | |
299 | if(CmdQueLen <= 0) SiS310Idle;\ | |
300 | MMIO_OUT16(ivideo->mmio_vbase, SRC_PITCH, pitch);\ | |
301 | CmdQueLen--; | |
302 | ||
303 | #define SiS310SetupSRCXY(x,y) \ | |
304 | if(CmdQueLen <= 0) SiS310Idle;\ | |
305 | MMIO_OUT32(ivideo->mmio_vbase, SRC_Y, (x)<<16 | (y) );\ | |
306 | CmdQueLen--; | |
307 | ||
308 | #define SiS310SetupDSTBase(base) \ | |
309 | if(CmdQueLen <= 0) SiS310Idle;\ | |
310 | MMIO_OUT32(ivideo->mmio_vbase, DST_ADDR, base);\ | |
311 | CmdQueLen--; | |
312 | ||
313 | #define SiS310SetupDSTXY(x,y) \ | |
314 | if(CmdQueLen <= 0) SiS310Idle;\ | |
315 | MMIO_OUT32(ivideo->mmio_vbase, DST_Y, (x)<<16 | (y) );\ | |
316 | CmdQueLen--; | |
317 | ||
318 | #define SiS310SetupDSTRect(x,y) \ | |
319 | if(CmdQueLen <= 0) SiS310Idle;\ | |
320 | MMIO_OUT32(ivideo->mmio_vbase, DST_PITCH, (y)<<16 | (x) );\ | |
321 | CmdQueLen--; | |
322 | ||
323 | #define SiS310SetupDSTColorDepth(bpp) \ | |
324 | if(CmdQueLen <= 0) SiS310Idle;\ | |
325 | MMIO_OUT16(ivideo->mmio_vbase, AGP_BASE, bpp);\ | |
326 | CmdQueLen--; | |
327 | ||
328 | #define SiS310SetupRect(w,h) \ | |
329 | if(CmdQueLen <= 0) SiS310Idle;\ | |
330 | MMIO_OUT32(ivideo->mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\ | |
331 | CmdQueLen--; | |
332 | ||
333 | #define SiS310SetupPATFG(color) \ | |
334 | if(CmdQueLen <= 0) SiS310Idle;\ | |
335 | MMIO_OUT32(ivideo->mmio_vbase, PAT_FGCOLOR, color);\ | |
336 | CmdQueLen--; | |
337 | ||
338 | #define SiS310SetupPATBG(color) \ | |
339 | if(CmdQueLen <= 0) SiS310Idle;\ | |
340 | MMIO_OUT32(ivideo->mmio_vbase, PAT_BGCOLOR, color);\ | |
341 | CmdQueLen--; | |
342 | ||
343 | #define SiS310SetupSRCFG(color) \ | |
344 | if(CmdQueLen <= 0) SiS310Idle;\ | |
345 | MMIO_OUT32(ivideo->mmio_vbase, SRC_FGCOLOR, color);\ | |
346 | CmdQueLen--; | |
347 | ||
348 | #define SiS310SetupSRCBG(color) \ | |
349 | if(CmdQueLen <= 0) SiS310Idle;\ | |
350 | MMIO_OUT32(ivideo->mmio_vbase, SRC_BGCOLOR, color);\ | |
351 | CmdQueLen--; | |
352 | ||
353 | #define SiS310SetupSRCTrans(color) \ | |
354 | if(CmdQueLen <= 1) SiS310Idle;\ | |
355 | MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_HIGH, color);\ | |
356 | MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_LOW, color);\ | |
357 | CmdQueLen -= 2; | |
358 | ||
359 | #define SiS310SetupDSTTrans(color) \ | |
360 | if(CmdQueLen <= 1) SiS310Idle;\ | |
361 | MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_HIGH, color); \ | |
362 | MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_LOW, color); \ | |
363 | CmdQueLen -= 2; | |
364 | ||
365 | #define SiS310SetupMONOPAT(p0,p1) \ | |
366 | if(CmdQueLen <= 1) SiS310Idle;\ | |
367 | MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK, p0);\ | |
368 | MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK+4, p1);\ | |
369 | CmdQueLen -= 2; | |
370 | ||
371 | #define SiS310SetupClipLT(left,top) \ | |
372 | if(CmdQueLen <= 0) SiS310Idle;\ | |
373 | MMIO_OUT32(ivideo->mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\ | |
374 | CmdQueLen--; | |
375 | ||
376 | #define SiS310SetupClipRB(right,bottom) \ | |
377 | if(CmdQueLen <= 0) SiS310Idle;\ | |
378 | MMIO_OUT32(ivideo->mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\ | |
379 | CmdQueLen--; | |
380 | ||
381 | #define SiS310SetupROP(rop) \ | |
382 | ivideo->CommandReg = (rop) << 8; | |
383 | ||
384 | #define SiS310SetupCMDFlag(flags) \ | |
385 | ivideo->CommandReg |= (flags); | |
386 | ||
387 | #define SiS310DoCMD \ | |
388 | if(CmdQueLen <= 1) SiS310Idle;\ | |
389 | MMIO_OUT32(ivideo->mmio_vbase, COMMAND_READY, ivideo->CommandReg); \ | |
390 | MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \ | |
391 | CmdQueLen -= 2; | |
392 | ||
393 | ||
394 | int sisfb_initaccel(struct sis_video_info *ivideo); | |
395 | void sisfb_syncaccel(struct sis_video_info *ivideo); | |
396 | ||
397 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) | |
398 | void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty, | |
399 | int dstx, int height, int width); | |
400 | void fbcon_sis_revc(struct display *p, int srcy, int srcx); | |
401 | void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy, | |
402 | int srcx, int height, int width); | |
403 | void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy, | |
404 | int srcx, int height, int width); | |
405 | void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy, | |
406 | int srcx, int height, int width); | |
407 | #endif | |
408 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) | |
544393fe | 409 | int fbcon_sis_sync(struct fb_info *info); |
1da177e4 LT |
410 | void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect); |
411 | void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area); | |
412 | #endif | |
413 | ||
414 | #endif |