1/*
2 * 2D Acceleration for SiS 315 and Xabre series
3 * Definitions for the SIS engine communication.
4 *
5 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1) Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3) The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Author:  	Thomas Winischhofer <thomas@winischhofer.net>
30 *
31 * 2003/08/18: Added VRAM queue support
32 *
33 */
34
35/* SiS315 and 330 engine commands */
36#define BITBLT                  0x00000000  /* Blit */
37#define COLOREXP                0x00000001  /* Color expand */
38#define ENCOLOREXP              0x00000002  /* Enhanced color expand (315 only?) */
39#define MULTIPLE_SCANLINE       0x00000003  /* 315 only, not 330 */
40#define LINE                    0x00000004  /* Draw line */
41#define TRAPAZOID_FILL          0x00000005  /* Fill trapezoid */
42#define TRANSPARENT_BITBLT      0x00000006  /* Transparent Blit */
43#define ALPHA_BLEND		0x00000007  /* Alpha blended BitBlt */
44#define A3D_FUNCTION		0x00000008  /* 3D command ? */
45#define	CLEAR_Z_BUFFER		0x00000009  /* ? */
46#define GRADIENT_FILL		0x0000000A  /* Gradient fill */
47#define STRETCH_BITBLT		0x0000000B  /* Stretched BitBlit */
48
49#define YUVRGB_BLIT_325		0x0000000C
50#define YUVRGB_BLIT_330		0x00000003
51
52/* Command bits */
53
54/* Source selection */
55#define SRCVIDEO                0x00000000  /* source is video RAM */
56#define SRCSYSTEM               0x00000010  /* source is system memory */
57#define SRCCPUBLITBUF           SRCSYSTEM   /* source is CPU-driven BitBuffer (for color expand) */
58#define SRCAGP                  0x00000020  /* source is AGP memory (?) */
59
60/* Pattern source selection */
61#define PATFG                   0x00000000  /* foreground color */
62#define PATPATREG               0x00000040  /* pattern in pattern buffer (0x8300) */
63#define PATMONO                 0x00000080  /* mono pattern */
64
65/* Clipping flags */
66#define NOCLIP                  0x00000000
67#define NOMERGECLIP             0x04000000
68#define CLIPENABLE              0x00040000
69#define CLIPWITHOUTMERGE        0x04040000
70
71/* Subfunctions for BitBlt: Transparency */
72#define OPAQUE                  0x00000000
73#define TRANSPARENT             0x00100000
74
75/* Subfunctions for Alpha Blended BitBlt */
76#define A_CONSTANTALPHA         0x00000000
77#define A_PERPIXELALPHA		0x00080000
78#define A_NODESTALPHA		0x00100000
79#define A_3DFULLSCENE		0x00180000
80
81/* Destination */
82#define DSTAGP                  0x02000000
83#define DSTVIDEO                0x00000000
84
85/* Subfunctions for Color/Enhanced Color Expansion */
86#define COLOR_TO_MONO		0x00100000
87#define AA_TEXT			0x00200000
88
89/* Line */
90#define LINE_STYLE              0x00800000
91#define NO_RESET_COUNTER        0x00400000
92#define NO_LAST_PIXEL           0x00200000
93
94/* Trapezoid (315 only?) */
95#define T_XISMAJORL             0x00800000  /* X axis is driving axis (left) */
96#define T_XISMAJORR             0x08000000  /* X axis is driving axis (right) */
97#define T_L_Y_INC               0x00000020  /* left edge direction Y */
98#define T_L_X_INC               0x00000010  /* left edge direction X */
99#define T_R_Y_INC               0x00400000  /* right edge direction Y */
100#define T_R_X_INC               0x00200000  /* right edge direction X */
101
102/* YUV to RGB blit */
103#define YUV_FORMAT_YUY2		0x00000000
104#define YUV_FORMAT_YVYU		0x00002000
105#define YUV_FORMAT_UYVY		0x00004000
106#define YUV_FORMAT_VYUY		0x00006000
107#define YUV_FORMAT_NV12		0x00008000  /* Only supported one */
108#define YUV_FORMAT_NV21		0x0000A000
109
110#define YUV_CMD_YUV		0x00800000
111
112/* Scanline trigger (315 only, not 330) */
113#define SCANLINE_TR_CRT1        0x00000000
114#define SCANLINE_TR_CRT2        0x01000000
115#define SCANLINE_TRIGGER_ENABLE 0x80000000
116
117/* Some general registers */
118#define SRC_ADDR		0x8200
119#define SRC_PITCH		0x8204
120#define AGP_BASE		0x8206 /* color-depth dependent value */
121#define SRC_Y			0x8208
122#define SRC_X			0x820A
123#define DST_Y			0x820C
124#define DST_X			0x820E
125#define DST_ADDR		0x8210
126#define DST_PITCH		0x8214
127#define DST_HEIGHT		0x8216
128#define RECT_WIDTH		0x8218
129#define RECT_HEIGHT		0x821A
130#define PAT_FGCOLOR		0x821C
131#define PAT_BGCOLOR		0x8220
132#define SRC_FGCOLOR		0x8224
133#define SRC_BGCOLOR		0x8228
134#define MONO_MASK		0x822C
135#define LEFT_CLIP		0x8234
136#define TOP_CLIP		0x8236
137#define RIGHT_CLIP		0x8238
138#define BOTTOM_CLIP		0x823A
139#define COMMAND_READY		0x823C
140#define FIRE_TRIGGER      	0x8240
141
142#define PATTERN_REG		0x8300  /* 384 bytes pattern buffer */
143
144/* Line registers */
145#define LINE_X0			SRC_Y
146#define LINE_X1			DST_Y
147#define LINE_Y0			SRC_X
148#define LINE_Y1			DST_X
149#define LINE_COUNT		RECT_WIDTH
150#define LINE_STYLE_PERIOD	RECT_HEIGHT
151#define LINE_STYLE_0		MONO_MASK
152#define LINE_STYLE_1		0x8230
153#define LINE_XN			PATTERN_REG
154#define LINE_YN			PATTERN_REG+2
155
156/* Transparent bitblit registers */
157#define TRANS_DST_KEY_HIGH	PAT_FGCOLOR
158#define TRANS_DST_KEY_LOW	PAT_BGCOLOR
159#define TRANS_SRC_KEY_HIGH	SRC_FGCOLOR
160#define TRANS_SRC_KEY_LOW	SRC_BGCOLOR
161
162#define ALPHA_ALPHA		PAT_FGCOLOR
163
164/* Trapezoid registers */
165#define TRAP_YH			SRC_Y    /* 0x8208 */
166#define TRAP_LR			DST_Y    /* 0x820C */
167#define TRAP_DL			0x8244
168#define TRAP_DR			0x8248
169#define TRAP_EL			0x824C
170#define TRAP_ER			0x8250
171
172/* Queue */
173#define Q_BASE_ADDR		0x85C0  /* Base address of software queue */
174#define Q_WRITE_PTR		0x85C4  /* Current write pointer */
175#define Q_READ_PTR		0x85C8  /* Current read pointer */
176#define Q_STATUS		0x85CC  /* queue status */
177
178/* VRAM queue operation command header definitions */
179#define SIS_SPKC_HEADER 	0x16800000L
180#define SIS_BURST_HEADER0	0x568A0000L
181#define SIS_BURST_HEADER1	0x62100000L
182#define SIS_PACKET_HEARER0 	0x968A0000L
183#define SIS_PACKET_HEADER1	0x62100000L
184#define SIS_NIL_CMD		0x168F0000L
185
186#define SIS_PACKET12_HEADER0	0x968A000CL
187#define SIS_PACKET12_HEADER1	0x62100010L
188#define SIS_PACKET12_LENGTH	80
189
190/* Macros to do useful things with the SiS315/330 BitBLT engine */
191
192/* Q_STATUS:
193   bit 31 = 1: All engines idle and all queues empty
194   bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
195   bit 29 = 1: 2D engine is idle
196   bit 28 = 1: 3D engine is idle
197   bit 27 = 1: HW command queue empty
198   bit 26 = 1: 2D queue empty
199   bit 25 = 1: 3D queue empty
200   bit 24 = 1: SW command queue empty
201   bits 23:16: 2D counter 3
202   bits 15:8:  2D counter 2
203   bits 7:0:   2D counter 1
204*/
205
206/* As sis_dri.c and dual head mode relocate the cmd-q len to the sarea/entity,
207 * don't use it directly here */
208#define CmdQueLen (*(pSiS->cmdQueueLenPtr))
209
210#define SiSQEmpty \
211  { \
212     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x0400) != 0x0400) {}; \
213     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x0400) != 0x0400) {}; \
214  }
215
216#define SiSResetCmd		pSiS->CommandReg = 0;
217
218#define SiSSetupCMDFlag(flags)  pSiS->CommandReg |= (flags);
219
220/* --- VRAM mode --- */
221
222#define SiSGetSwWP() (CARD32)(*(pSiS->cmdQ_SharedWritePort))
223#define SiSGetHwRP() (CARD32)(SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR))
224
225#define SiSFlushCmdBuf  \
226  if(pSiS->NeedFlush) { \
227     CARD32 ttt = ((SiSGetSwWP()) - 4) & pSiS->cmdQueueSizeMask;	\
228     pointer tt = (char *)pSiS->cmdQueueBase + ttt; 			\
229     dummybuf = SIS_RQINDEX(0);						\
230  }
231
232#define SiSSyncWP    \
233  SiSFlushCmdBuf;    \
234  SIS_MMIO_OUT32(pSiS->IOBase, Q_WRITE_PTR, (CARD32)(*(pSiS->cmdQ_SharedWritePort)));
235
236#define SiSSetHwWP(p) \
237  *(pSiS->cmdQ_SharedWritePort) = (p);   	\
238  SIS_MMIO_OUT32(pSiS->IOBase, Q_WRITE_PTR, (p));
239
240#define SiSSetSwWP(p) *(pSiS->cmdQ_SharedWritePort) = (p);
241
242#define SiSCheckQueue(amount)
243
244#if 0
245      { \
246	CARD32 mcurrent, i=0, ttt = SiSGetSwWP(); \
247	if((ttt + amount) >= pSiS->cmdQueueSize) { \
248	   do { \
249	      mcurrent = SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR); \
250	      i++; \
251	   } while((mcurrent > ttt) || (mcurrent < ((ttt + amount) & pSiS->cmdQueueSizeMask))); \
252	} else { \
253	   do { \
254	      mcurrent = SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR); \
255	      i++; \
256	   } while((mcurrent > ttt) && (mcurrent < (ttt + amount))); \
257	} \
258      }
259#endif
260
261#define SiSUpdateQueue \
262      SiSWriteQueue(tt); \
263      ttt += 16; \
264      ttt &= pSiS->cmdQueueSizeMask; \
265      if(!ttt) { \
266	 while(SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR) < pSiS->cmdQueueSize_div4) {} \
267      } else if(ttt == pSiS->cmdQueueSize_div4) { \
268	 CARD32 temppp; \
269	 do { \
270	    temppp = SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR); \
271	 } while(temppp >= ttt && temppp <= pSiS->cmdQueueSize_div2); \
272      } else if(ttt == pSiS->cmdQueueSize_div2) { \
273	 CARD32 temppp; \
274	 do { \
275	    temppp = SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR); \
276	 } while(temppp >= ttt && temppp <= pSiS->cmdQueueSize_4_3); \
277      } else if(ttt == pSiS->cmdQueueSize_4_3) { \
278	 while(SIS_MMIO_IN32(pSiS->IOBase, Q_READ_PTR) > ttt) {} \
279      }
280
281/* Write-updates MUST be 128bit aligned. */
282#define SiSNILandUpdateSWQueue \
283      SIS_WQINDEX(2) = (CARD32)(SIS_NIL_CMD); \
284      SIS_WQINDEX(3) = (CARD32)(SIS_NIL_CMD); \
285      SiSUpdateQueue; \
286      SiSSetSwWP(ttt);
287
288#ifdef SISVRAMQ
289
290#define SiSIdle \
291  { \
292     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
293     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
294     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
295     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
296  }
297
298#define SiSSetupSRCDSTBase(srcbase,dstbase) \
299      { \
300	 CARD32 ttt = SiSGetSwWP(); \
301	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
302	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_ADDR); \
303	 SIS_WQINDEX(1) = (CARD32)(srcbase); 			\
304	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + DST_ADDR); \
305	 SIS_WQINDEX(3) = (CARD32)(dstbase); 			\
306	 SiSUpdateQueue \
307	 SiSSetSwWP(ttt); \
308      }
309
310#define SiSSetupSRCDSTXY(sx,sy,dx,dy) \
311      { \
312	 CARD32 ttt = SiSGetSwWP(); \
313	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
314	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_Y); 	\
315	 SIS_WQINDEX(1) = (CARD32)(((sx)<<16) | (sy));		\
316	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + DST_Y); 	\
317	 SIS_WQINDEX(3) = (CARD32)(((dx)<<16) | (dy)); 		\
318	 SiSUpdateQueue \
319	 SiSSetSwWP(ttt); \
320      }
321
322#define SiSSetupDSTXYRect(x,y,w,h) \
323      { \
324	 CARD32 ttt = SiSGetSwWP(); \
325	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
326	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + DST_Y); 		\
327	 SIS_WQINDEX(1) = (CARD32)(((x)<<16) | (y));	 		\
328	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + RECT_WIDTH); 	\
329	 SIS_WQINDEX(3) = (CARD32)(((h)<<16) | (w));			\
330	 SiSUpdateQueue \
331	 SiSSetSwWP(ttt); \
332      }
333
334#define SiSSetupSRCPitchDSTRect(pitch,x,y) \
335      { \
336	 CARD32 ttt = SiSGetSwWP(); \
337	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
338	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_PITCH); 	\
339	 SIS_WQINDEX(1) = (CARD32)(pitch);				\
340	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + DST_PITCH); 	\
341	 SIS_WQINDEX(3) = (CARD32)(((y)<<16) | (x));			\
342	 SiSUpdateQueue \
343	 SiSSetSwWP(ttt); \
344      }
345
346#define SiSSetupSRCBase(base) \
347      { \
348	 CARD32 ttt = SiSGetSwWP(); \
349	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
350	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_ADDR); 	\
351	 SIS_WQINDEX(1) = (CARD32)(base); 				\
352	 SiSNILandUpdateSWQueue \
353      }
354
355#define SiSSetupSRCPitch(pitch) \
356      { \
357	 CARD32 ttt = SiSGetSwWP(); \
358	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
359	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_PITCH); 	\
360	 SIS_WQINDEX(1) = (CARD32)(pitch);				\
361	 SiSNILandUpdateSWQueue \
362      }
363
364#define SiSSetupSRCXY(x,y) \
365      { \
366	 CARD32 ttt = SiSGetSwWP(); \
367	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
368	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_Y); 	\
369	 SIS_WQINDEX(1) = (CARD32)(((x)<<16) | (y));		\
370	 SiSNILandUpdateSWQueue \
371      }
372
373#define SiSSetupDSTBase(base) \
374      { \
375	 CARD32 ttt = SiSGetSwWP(); \
376	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
377	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + DST_ADDR); 	\
378	 SIS_WQINDEX(1) = (CARD32)(base);				\
379	 SiSNILandUpdateSWQueue \
380      }
381
382#define SiSSetupDSTXY(x,y) \
383      { \
384	 CARD32 ttt = SiSGetSwWP(); \
385	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
386	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + DST_Y); 	\
387	 SIS_WQINDEX(1) = (CARD32)(((x)<<16) | (y));	 	\
388	 SiSNILandUpdateSWQueue \
389      }
390
391#define SiSSetupDSTRect(x,y) \
392      { \
393	 CARD32 ttt = SiSGetSwWP(); \
394	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
395	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + DST_PITCH); 	\
396	 SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x));		\
397	 SiSNILandUpdateSWQueue \
398      }
399
400#define SiSSetupDSTRectBurstHeader(x,y,reg,num) \
401      { \
402	 CARD32 ttt = SiSGetSwWP(); \
403	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
404	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + DST_PITCH);	\
405	 SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x));			\
406	 SIS_WQINDEX(2) = (CARD32)(SIS_BURST_HEADER0 + reg); 		\
407	 SIS_WQINDEX(3) = (CARD32)(SIS_BURST_HEADER1 + num); 		\
408	 SiSUpdateQueue \
409	 SiSSetSwWP(ttt); \
410      }
411
412#define SiSSetupDSTColorDepth(bpp) \
413      pSiS->CommandReg = (((CARD32)(bpp)) & (GENMASK(17:16)));
414
415#define SiSSetupPATFGDSTRect(color,x,y) \
416      { \
417	 CARD32 ttt = SiSGetSwWP(); \
418	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
419	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + PAT_FGCOLOR); 	\
420	 SIS_WQINDEX(1) = (CARD32)(color);	 			\
421	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + DST_PITCH); 	\
422	 SIS_WQINDEX(3) = (CARD32)(((y)<<16) | (x));			\
423	 SiSUpdateQueue \
424	 SiSSetSwWP(ttt); \
425      }
426
427#define SiSSetupSRCFGDSTRect(color,x,y) \
428      { \
429	 CARD32 ttt = SiSGetSwWP(); \
430	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
431	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_FGCOLOR); 	\
432	 SIS_WQINDEX(1) = (CARD32)(color);	 			\
433	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + DST_PITCH); 	\
434	 SIS_WQINDEX(3) = (CARD32)(((y)<<16) | (x));			\
435	 SiSUpdateQueue \
436	 SiSSetSwWP(ttt); \
437      }
438
439#define SiSSetupRectSRCPitch(w,h,pitch) \
440      { \
441	 CARD32 ttt = SiSGetSwWP(); \
442	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
443	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + RECT_WIDTH); 	\
444	 SIS_WQINDEX(1) = (CARD32)(((h)<<16) | (w));			\
445	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + SRC_PITCH); 	\
446	 SIS_WQINDEX(3) = (CARD32)(pitch);				\
447	 SiSUpdateQueue \
448	 SiSSetSwWP(ttt); \
449      }
450
451#define SiSSetupRect(w,h) \
452      { \
453	 CARD32 ttt = SiSGetSwWP(); \
454	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
455	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + RECT_WIDTH); 	\
456	 SIS_WQINDEX(1) = (CARD32)(((h)<<16) | (w));			\
457	 SiSNILandUpdateSWQueue \
458      }
459
460#define SiSSetupPATFG(color) \
461      { \
462	 CARD32 ttt = SiSGetSwWP(); \
463	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
464	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + PAT_FGCOLOR); 	\
465	 SIS_WQINDEX(1) = (CARD32)(color);	 			\
466	 SiSNILandUpdateSWQueue \
467      }
468
469#define SiSSetupPATBG(color) \
470      { \
471	 CARD32 ttt = SiSGetSwWP(); \
472	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
473	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + PAT_BGCOLOR);	\
474	 SIS_WQINDEX(1) = (CARD32)(color);	 			\
475	 SiSNILandUpdateSWQueue \
476      }
477
478#define SiSSetupSRCFG(color) \
479      { \
480	 CARD32 ttt = SiSGetSwWP(); \
481	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
482	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_FGCOLOR);	\
483	 SIS_WQINDEX(1) = (CARD32)(color);	 			\
484	 SiSNILandUpdateSWQueue \
485      }
486
487#define SiSSetupSRCBG(color) \
488      { \
489	 CARD32 ttt = SiSGetSwWP(); \
490	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
491	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + SRC_BGCOLOR);	\
492	 SIS_WQINDEX(1) = (CARD32)(color);	 			\
493	 SiSNILandUpdateSWQueue \
494      }
495
496#define SiSSetupSRCTrans(color) \
497      { \
498	 CARD32 ttt = SiSGetSwWP(); \
499	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
500	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + TRANS_SRC_KEY_HIGH);	\
501	 SIS_WQINDEX(1) = (CARD32)(color);	 				\
502	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + TRANS_SRC_KEY_LOW);	\
503	 SIS_WQINDEX(3) = (CARD32)(color);					\
504	 SiSUpdateQueue \
505	 SiSSetSwWP(ttt); \
506      }
507
508#define SiSSetupDSTTrans(color) \
509      { \
510	 CARD32 ttt = SiSGetSwWP(); \
511	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
512	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + TRANS_DST_KEY_HIGH);	\
513	 SIS_WQINDEX(1) = (CARD32)(color);	 				\
514	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + TRANS_DST_KEY_LOW);	\
515	 SIS_WQINDEX(3) = (CARD32)(color);					\
516	 SiSUpdateQueue \
517	 SiSSetSwWP(ttt); \
518      }
519
520#define SiSSetupMONOPAT(p0,p1) \
521      { \
522	 CARD32 ttt = SiSGetSwWP(); \
523	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
524	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + MONO_MASK);		\
525	 SIS_WQINDEX(1) = (CARD32)(p0);	 				\
526	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + MONO_MASK + 4);	\
527	 SIS_WQINDEX(3) = (CARD32)(p1);					\
528	 SiSUpdateQueue \
529	 SiSSetSwWP(ttt); \
530      }
531
532#define SiSSetupClip(left,top,right,bottom) \
533      { \
534	 CARD32 ttt = SiSGetSwWP(); \
535	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
536	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + LEFT_CLIP);	\
537	 SIS_WQINDEX(1) = (CARD32)(((left) & 0xFFFF) | ((top)<<16));   	\
538	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + RIGHT_CLIP);	\
539	 SIS_WQINDEX(3) = (CARD32)(((right) & 0xFFFF)|((bottom)<<16)); 	\
540	 SiSUpdateQueue \
541	 SiSSetSwWP(ttt); \
542      }
543
544#define SiSSetupDSTBaseDoCMD(base) \
545      { \
546	 CARD32 ttt = SiSGetSwWP(); \
547	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
548	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + DST_ADDR); 	\
549	 SIS_WQINDEX(1) = (CARD32)(base);				\
550	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + COMMAND_READY);	\
551	 SIS_WQINDEX(3) = (CARD32)(pSiS->CommandReg); 			\
552	 if(pSiS->NeedFlush) dummybuf = SIS_RQINDEX(3);   		\
553	 SiSUpdateQueue \
554	 SiSSetHwWP(ttt); \
555      }
556
557#define SiSSetRectDoCMD(w,h) \
558      { \
559	 CARD32 ttt = SiSGetSwWP(); \
560	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
561	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + RECT_WIDTH); 	\
562	 SIS_WQINDEX(1) = (CARD32)(((h)<<16) | (w));	 		\
563	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + COMMAND_READY);	\
564	 SIS_WQINDEX(3) = (CARD32)(pSiS->CommandReg); 			\
565	 if(pSiS->NeedFlush) dummybuf = SIS_RQINDEX(3);  		\
566	 SiSUpdateQueue 	\
567	 SiSSetHwWP(ttt); 	\
568      }
569
570#define SiSSetupROP(rop) \
571      pSiS->CommandReg |= (rop) << 8;
572
573#define SiSDoCMD \
574      { \
575	 CARD32 ttt = SiSGetSwWP(); \
576	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
577	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + COMMAND_READY);	\
578	 SIS_WQINDEX(1) = (CARD32)(pSiS->CommandReg); 			\
579	 SIS_WQINDEX(2) = (CARD32)(SIS_NIL_CMD); 			\
580	 SIS_WQINDEX(3) = (CARD32)(SIS_NIL_CMD); 			\
581	 if(pSiS->NeedFlush) dummybuf = SIS_RQINDEX(3);  		\
582	 SiSUpdateQueue \
583	 SiSSetHwWP(ttt); \
584      }
585
586#define SiSDualPipe(disable) \
587      { \
588	 CARD32 ttt = SiSGetSwWP(); \
589	 CARD32 _tmp = SIS_MMIO_IN32(pSiS->IOBase, FIRE_TRIGGER) & ~(1 << 10);	\
590	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
591	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + FIRE_TRIGGER);	\
592	 SIS_WQINDEX(1) = (CARD32)(_tmp | ((disable & 1) << 10)); 	\
593	 SIS_WQINDEX(2) = (CARD32)(SIS_NIL_CMD); 			\
594	 SIS_WQINDEX(3) = (CARD32)(SIS_NIL_CMD); 			\
595	 if(pSiS->NeedFlush) dummybuf = SIS_RQINDEX(3);  		\
596	 SiSUpdateQueue \
597	 SiSSetHwWP(ttt); \
598      }
599
600/* Line */
601
602#define SiSSetupX0Y0X1Y1(x1,y1,x2,y2) \
603      { \
604	 CARD32 ttt = SiSGetSwWP(); \
605	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
606	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + LINE_X0);	\
607	 SIS_WQINDEX(1) = (CARD32)(((y1)<<16) | (x1)); 		\
608	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + LINE_X1);	\
609	 SIS_WQINDEX(3) = (CARD32)(((y2)<<16) | (x2)); 		\
610	 SiSUpdateQueue \
611	 SiSSetSwWP(ttt); \
612      }
613
614#define SiSSetupX0Y0(x,y) \
615      { \
616	 CARD32 ttt = SiSGetSwWP(); \
617	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
618	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + LINE_X0);	\
619	 SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x)); 		\
620	 SiSNILandUpdateSWQueue \
621      }
622
623#define SiSSetupX1Y1(x,y) \
624      { \
625	 CARD32 ttt = SiSGetSwWP(); \
626	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
627	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + LINE_X1);	\
628	 SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (x)); 		\
629	 SiSNILandUpdateSWQueue \
630      }
631
632#define SiSSetupLineCountPeriod(c, p) \
633      { \
634	 CARD32 ttt = SiSGetSwWP(); \
635	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
636	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + LINE_COUNT);	\
637	 SIS_WQINDEX(1) = (CARD32)(((p) << 16) | (c)); 			\
638	 SiSNILandUpdateSWQueue \
639      }
640
641#define SiSSetupStyle(ls,hs) \
642      { \
643	 CARD32 ttt = SiSGetSwWP(); \
644	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
645	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + LINE_STYLE_0);	\
646	 SIS_WQINDEX(1) = (CARD32)(ls);					\
647	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + LINE_STYLE_1);	\
648	 SIS_WQINDEX(3) = (CARD32)(hs); 				\
649	 SiSUpdateQueue \
650	 SiSSetSwWP(ttt); \
651      }
652
653/* Trapezoid */
654
655#define SiSSetupYHLR(y,h,left,right) \
656      { \
657	 CARD32 ttt = SiSGetSwWP(); \
658	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
659	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + TRAP_YH);	\
660	 SIS_WQINDEX(1) = (CARD32)(((y)<<16) | (h)); 		\
661	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + TRAP_LR);	\
662	 SIS_WQINDEX(3) = (CARD32)(((right)<<16) | (left));	\
663	 SiSUpdateQueue \
664	 SiSSetSwWP(ttt); \
665      }
666
667
668#define SiSSetupdLdR(dxL,dyL,fxR,dyR) \
669      { \
670	 CARD32 ttt = SiSGetSwWP(); \
671	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
672	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + TRAP_DL);	\
673	 SIS_WQINDEX(1) = (CARD32)(((dyL)<<16) | (dxL)); 	\
674	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + TRAP_DR);	\
675	 SIS_WQINDEX(3) = (CARD32)(((dyR)<<16) | (dxR)); 	\
676	 SiSUpdateQueue \
677	 SiSSetSwWP(ttt); \
678      }
679
680#define SiSSetupELER(eL,eR) \
681      { \
682	 CARD32 ttt = SiSGetSwWP(); \
683	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
684	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + TRAP_EL);	\
685	 SIS_WQINDEX(1) = (CARD32)(eL);	 			\
686	 SIS_WQINDEX(2) = (CARD32)(SIS_SPKC_HEADER + TRAP_ER);	\
687	 SIS_WQINDEX(3) = (CARD32)(eR); 			\
688	 SiSUpdateQueue \
689	 SiSSetSwWP(ttt); \
690      }
691
692/* (Constant) Alpha blended BitBlt (alpha = 8 bit) */
693
694#define SiSSetupAlpha(alpha) \
695      { \
696	 CARD32 ttt = SiSGetSwWP(); \
697	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
698	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + ALPHA_ALPHA);	\
699	 SIS_WQINDEX(1) = (CARD32)(alpha);	 			\
700	 SiSNILandUpdateSWQueue \
701      }
702
703#define SiSSetPattern(num, value) \
704      { \
705	 CARD32 ttt = SiSGetSwWP(); \
706	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
707	 SIS_WQINDEX(0) = (CARD32)(SIS_SPKC_HEADER + (PATTERN_REG + (num * 4)));	\
708	 SIS_WQINDEX(1) = (CARD32)(value); 						\
709	 SiSNILandUpdateSWQueue \
710      }
711
712#define SiSSetupPatternRegBurst(pat1, pat2, pat3, pat4) \
713      { \
714	 CARD32 ttt = SiSGetSwWP(); \
715	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
716	 SIS_WQINDEX(0) = (CARD32)(pat1);		\
717	 SIS_WQINDEX(1) = (CARD32)(pat2);		\
718	 SIS_WQINDEX(2) = (CARD32)(pat3);		\
719	 SIS_WQINDEX(3) = (CARD32)(pat4);		\
720	 SiSUpdateQueue \
721	 SiSSetSwWP(ttt); \
722      }
723
724typedef struct _SiS_Packet12_YUV {
725      CARD32 P12_Header0;
726      CARD32 P12_Header1;
727      CARD16 P12_UVPitch;	/* 8200 UV if planar, Y if packed */
728      CARD16 P12_Unused0;	/* 8202 */
729      CARD16 P12_YPitch;	/* 8204 Y if planar */
730      CARD16 P12_AGPBase;	/* 8206 */
731      CARD16 P12_Unused1;	/* 8208 */
732      CARD16 P12_Unused2;	/* 820a */
733      CARD16 P12_DstY;		/* 820c */
734      CARD16 P12_DstX;		/* 820e */
735      CARD32 P12_DstAddr;	/* 8210 */
736      CARD16 P12_DstPitch;	/* 8214 */
737      CARD16 P12_DstHeight;	/* 8216 */
738      CARD16 P12_RectWidth;	/* 8218 */
739      CARD16 P12_RectHeight;	/* 821a */
740      CARD32 P12_Unused3;	/* 821c */
741      CARD32 P12_Unused4;	/* 8220 */
742      CARD32 P12_UVSrcAddr;	/* 8224 UV if planar, Y if packed */
743      CARD32 P12_YSrcAddr;	/* 8228 Y if planar */
744      CARD32 P12_Unused5;	/* 822c */
745      CARD32 P12_Unused6;	/* 8230 */
746      CARD16 P12_ClipLeft;	/* 8234 */
747      CARD16 P12_ClipTop;	/* 8236 */
748      CARD16 P12_ClipRight;	/* 8238 */
749      CARD16 P12_ClipBottom;	/* 823a */
750      CARD32 P12_Command;	/* 823c */
751      CARD32 P12_Null1;
752      CARD32 P12_Null2;
753} SiS_Packet12_YUV;
754
755#define SiSWritePacketPart(part1, part2, part3, part4) \
756      { \
757	 CARD32 ttt = SiSGetSwWP(); \
758	 pointer tt = (char *)pSiS->cmdQueueBase + ttt; \
759	 SIS_WQINDEX(0) = (CARD32)(part1);	\
760	 SIS_WQINDEX(1) = (CARD32)(part2);	\
761	 SIS_WQINDEX(2) = (CARD32)(part3);	\
762	 SIS_WQINDEX(3) = (CARD32)(part4);	\
763	 SiSUpdateQueue \
764	 SiSSetSwWP(ttt); \
765      }
766
767#endif  /* VRAM mode */
768
769/* ---- MMIO mode ---- */
770
771#ifndef SISVRAMQ
772
773/* We assume a length of 4 bytes per command; since 512K of
774 * of RAM are allocated, the number of commands is easily
775 * calculated (and written to the address pointed to by
776 * CmdQueueLenPtr, since sis_dri.c relocates this)
777 * UPDATE: using the command queue without syncing totally
778 * (ie assuming a QueueLength of 0) decreases system latency
779 * dramatically on the integrated chipsets (sound gets interrupted,
780 * etc.). We now sync every time... this is a little slower,
781 * but it keeps the rest of the box somewhat alive.
782 * This was the reason for switching to VRAM queue mode.
783 */
784#define SiSIdle \
785  { \
786     if(pSiS->ChipFlags & SiSCF_Integrated) { \
787	CmdQueLen = 0; \
788     } else { \
789	CmdQueLen = ((512 * 1024) / 4) - 64; \
790     } \
791     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
792     while( (SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {}; \
793  }
794
795#define SiSSetupSRCBase(base) \
796      if (CmdQueLen <= 0)  SiSIdle; \
797      SIS_MMIO_OUT32(pSiS->IOBase, SRC_ADDR, base); \
798      CmdQueLen--;
799
800#define SiSSetupSRCPitch(pitch) \
801      if (CmdQueLen <= 0)  SiSIdle; \
802      SIS_MMIO_OUT16(pSiS->IOBase, SRC_PITCH, pitch); \
803      CmdQueLen--;
804
805#define SiSSetupSRCXY(x,y) \
806      if (CmdQueLen <= 0)  SiSIdle;\
807      SIS_MMIO_OUT32(pSiS->IOBase, SRC_Y, (x)<<16 | (y) );\
808      CmdQueLen--;
809
810#define SiSSetupDSTBase(base) \
811      if (CmdQueLen <= 0)  SiSIdle;\
812      SIS_MMIO_OUT32(pSiS->IOBase, DST_ADDR, base);\
813      CmdQueLen--;
814
815#define SiSSetupDSTXY(x,y) \
816      if (CmdQueLen <= 0)  SiSIdle;\
817      SIS_MMIO_OUT32(pSiS->IOBase, DST_Y, (x)<<16 | (y) );\
818      CmdQueLen--;
819
820#define SiSSetupDSTRect(x,y) \
821      if (CmdQueLen <= 0)  SiSIdle;\
822      SIS_MMIO_OUT32(pSiS->IOBase, DST_PITCH, (y)<<16 | (x) );\
823      CmdQueLen--;
824
825#define SiSSetupDSTColorDepth(bpp) \
826      if (CmdQueLen <= 0)  SiSIdle;\
827      SIS_MMIO_OUT16(pSiS->IOBase, AGP_BASE, bpp);\
828      CmdQueLen--;
829
830#define SiSSetupRect(w,h) \
831      if(CmdQueLen <= 0)  SiSIdle;\
832      SIS_MMIO_OUT32(pSiS->IOBase, RECT_WIDTH, (h)<<16 | (w) );\
833      CmdQueLen--;
834
835#define SiSSetupPATFG(color) \
836      if(CmdQueLen <= 0)  SiSIdle;\
837      SIS_MMIO_OUT32(pSiS->IOBase, PAT_FGCOLOR, color);\
838      CmdQueLen--;
839
840#define SiSSetupPATBG(color) \
841      if(CmdQueLen <= 0)  SiSIdle;\
842      SIS_MMIO_OUT32(pSiS->IOBase, PAT_BGCOLOR, color);\
843      CmdQueLen--;
844
845#define SiSSetupSRCFG(color) \
846      if(CmdQueLen <= 0)  SiSIdle;\
847      SIS_MMIO_OUT32(pSiS->IOBase, SRC_FGCOLOR, color);\
848      CmdQueLen--;
849
850#define SiSSetupSRCBG(color) \
851      if(CmdQueLen <= 0)  SiSIdle; \
852      SIS_MMIO_OUT32(pSiS->IOBase, SRC_BGCOLOR, color); \
853      CmdQueLen--;
854
855#define SiSSetupSRCTrans(color) \
856      if(CmdQueLen <= 1)  SiSIdle;\
857      SIS_MMIO_OUT32(pSiS->IOBase, TRANS_SRC_KEY_HIGH, color);\
858      SIS_MMIO_OUT32(pSiS->IOBase, TRANS_SRC_KEY_LOW, color);\
859      CmdQueLen -= 2;
860
861#define SiSSetupDSTTrans(color) \
862      if(CmdQueLen <= 1)  SiSIdle;\
863      SIS_MMIO_OUT32(pSiS->IOBase, TRANS_DST_KEY_HIGH, color); \
864      SIS_MMIO_OUT32(pSiS->IOBase, TRANS_DST_KEY_LOW, color); \
865      CmdQueLen -= 2;
866
867#define SiSSetupMONOPAT(p0,p1) \
868      if(CmdQueLen <= 1)  SiSIdle;\
869      SIS_MMIO_OUT32(pSiS->IOBase, MONO_MASK, p0);\
870      SIS_MMIO_OUT32(pSiS->IOBase, MONO_MASK+4, p1);\
871      CmdQueLen=CmdQueLen-2;
872
873#define SiSSetupClipLT(left,top) \
874      if(CmdQueLen <= 0)  SiSIdle;\
875      SIS_MMIO_OUT32(pSiS->IOBase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16); \
876      CmdQueLen--;
877
878#define SiSSetupClipRB(right,bottom) \
879      if(CmdQueLen <= 0) SiSIdle; \
880      SIS_MMIO_OUT32(pSiS->IOBase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16); \
881      CmdQueLen--;
882
883#define SiSSetupROP(rop) \
884      pSiS->CommandReg = (rop) << 8;
885
886#define SiSDoCMD \
887      if (CmdQueLen <= 1)  SiSIdle;\
888      SIS_MMIO_OUT32(pSiS->IOBase, COMMAND_READY, pSiS->CommandReg); \
889      SIS_MMIO_OUT32(pSiS->IOBase, FIRE_TRIGGER, 0); \
890      CmdQueLen -= 2;
891
892/* Line */
893
894#define SiSSetupX0Y0(x,y) \
895      if (CmdQueLen <= 0)  SiSIdle;\
896      SIS_MMIO_OUT32(pSiS->IOBase, LINE_X0, (y)<<16 | (x) );\
897      CmdQueLen--;
898
899#define SiSSetupX1Y1(x,y) \
900      if (CmdQueLen <= 0)  SiSIdle;\
901      SIS_MMIO_OUT32(pSiS->IOBase, LINE_X1, (y)<<16 | (x) );\
902      CmdQueLen--;
903
904#define SiSSetupLineCount(c) \
905      if (CmdQueLen <= 0)  SiSIdle;\
906      SIS_MMIO_OUT16(pSiS->IOBase, LINE_COUNT, c);\
907      CmdQueLen--;
908
909#define SiSSetupStylePeriod(p) \
910      if (CmdQueLen <= 0)  SiSIdle;\
911      SIS_MMIO_OUT16(pSiS->IOBase, LINE_STYLE_PERIOD, p);\
912      CmdQueLen--;
913
914#define SiSSetupStyleLow(ls) \
915      if (CmdQueLen <= 0)  SiSIdle;\
916      SIS_MMIO_OUT32(pSiS->IOBase, LINE_STYLE_0, ls);\
917      CmdQueLen--;
918
919#define SiSSetupStyleHigh(ls) \
920      if (CmdQueLen <= 0)  SiSIdle;\
921      SIS_MMIO_OUT32(pSiS->IOBase, LINE_STYLE_1, ls);\
922      CmdQueLen--;
923
924/* Trapezoid */
925
926#define SiSSetupYH(y,h) \
927      if (CmdQueLen <= 0)  SiSIdle;\
928      SIS_MMIO_OUT32(pSiS->IOBase, TRAP_YH, (y)<<16 | (h) );\
929      CmdQueLen--;
930
931#define SiSSetupLR(left,right) \
932      if (CmdQueLen <= 0)  SiSIdle;\
933      SIS_MMIO_OUT32(pSiS->IOBase, TRAP_LR, (right)<<16 | (left) );\
934      CmdQueLen--;
935
936#define SiSSetupdL(dxL,dyL) \
937      if (CmdQueLen <= 0)  SiSIdle;\
938      SIS_MMIO_OUT32(pSiS->IOBase, TRAP_DL, (dyL)<<16 | (dxL) );\
939      CmdQueLen--;
940
941#define SiSSetupdR(dxR,dyR) \
942      if (CmdQueLen <= 0)  SiSIdle;\
943      SIS_MMIO_OUT32(pSiS->IOBase, TRAP_DR, (dyR)<<16 | (dxR) );\
944      CmdQueLen--;
945
946#define SiSSetupEL(eL) \
947      if (CmdQueLen <= 0)  SiSIdle;\
948      SIS_MMIO_OUT32(pSiS->IOBase, TRAP_EL, eL);\
949      CmdQueLen--;
950
951#define SiSSetupER(eR) \
952      if (CmdQueLen <= 0)  SiSIdle;\
953      SIS_MMIO_OUT32(pSiS->IOBase, TRAP_ER, eR);\
954      CmdQueLen--;
955
956/* (Constant) alpha blended BitBlt (alpha = 8 bit) */
957
958#define SiSSetupAlpha(alpha) \
959      if (CmdQueLen <= 0)  SiSIdle;\
960      SIS_MMIO_OUT32(pSiS->IOBase, ALPHA_ALPHA, alpha);\
961      CmdQueLen--;
962
963/* Set Pattern register */
964
965#define SiSSetPattern(num, value) \
966      if (CmdQueLen <= 0)  SiSIdle; \
967      SIS_MMIO_OUT32(pSiS->IOBase, (PATTERN_REG + (num * 4)), value); \
968      CmdQueLen--;
969
970#endif  /* MMIO mode */
971
972