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