ffb_rcache.h revision dbbd9e4b
1dbbd9e4bSmacallan/*
2dbbd9e4bSmacallan * Acceleration for the Creator and Creator3D framebuffer - register caching.
3dbbd9e4bSmacallan *
4dbbd9e4bSmacallan * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5dbbd9e4bSmacallan * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
6dbbd9e4bSmacallan *
7dbbd9e4bSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy
8dbbd9e4bSmacallan * of this software and associated documentation files (the "Software"), to deal
9dbbd9e4bSmacallan * in the Software without restriction, including without limitation the rights
10dbbd9e4bSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11dbbd9e4bSmacallan * copies of the Software, and to permit persons to whom the Software is
12dbbd9e4bSmacallan * furnished to do so, subject to the following conditions:
13dbbd9e4bSmacallan *
14dbbd9e4bSmacallan * The above copyright notice and this permission notice shall be included in
15dbbd9e4bSmacallan * all copies or substantial portions of the Software.
16dbbd9e4bSmacallan *
17dbbd9e4bSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18dbbd9e4bSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19dbbd9e4bSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20dbbd9e4bSmacallan * JAKUB JELINEK OR DAVID MILLER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21dbbd9e4bSmacallan * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22dbbd9e4bSmacallan * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23dbbd9e4bSmacallan * IN THE SOFTWARE.
24dbbd9e4bSmacallan *
25dbbd9e4bSmacallan */
26dbbd9e4bSmacallan/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_rcache.h,v 1.1 2000/05/18 23:21:37 dawes Exp $ */
27dbbd9e4bSmacallan
28dbbd9e4bSmacallan#ifndef FFBRCACHE_H
29dbbd9e4bSmacallan#define FFBRCACHE_H
30dbbd9e4bSmacallan
31dbbd9e4bSmacallan/* We only need to write the bits which actually change,
32dbbd9e4bSmacallan * writing unnessary bits causes the operation to go more
33dbbd9e4bSmacallan * slowly. -DaveM
34dbbd9e4bSmacallan *
35dbbd9e4bSmacallan * We used to have some hairy code here which tried to
36dbbd9e4bSmacallan * avoid writing attribute bits unnecessarily.  It has been
37dbbd9e4bSmacallan * removed because various two bit fields have different
38dbbd9e4bSmacallan * semantics.  For example, for some the higher bit is the
39dbbd9e4bSmacallan * edit bit, for others there are three state patterns
40dbbd9e4bSmacallan * and zero is a special "no edit" value.  Ho hum, it was
41dbbd9e4bSmacallan * a nice idea...
42dbbd9e4bSmacallan */
43dbbd9e4bSmacallan#define FFB_WRITE_PPC(__fpriv, __ffb, __val, __chg_mask) \
44dbbd9e4bSmacallando {	unsigned int __oldval = (__fpriv)->ppc_cache; \
45dbbd9e4bSmacallan	unsigned int __t; \
46dbbd9e4bSmacallan	__t = (__oldval & (__chg_mask)) ^ (__val); \
47dbbd9e4bSmacallan	if (__t) { \
48dbbd9e4bSmacallan		unsigned int __newval = __oldval & ~(__chg_mask); \
49dbbd9e4bSmacallan		__newval |= (__val); \
50dbbd9e4bSmacallan		(__fpriv)->ppc_cache = __newval; \
51dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
52dbbd9e4bSmacallan		(__ffb)->ppc = (__val); \
53dbbd9e4bSmacallan	} \
54dbbd9e4bSmacallan} while(0)
55dbbd9e4bSmacallan
56dbbd9e4bSmacallan#define FFB_WRITE_PMASK(__fpriv, __ffb, __val) \
57dbbd9e4bSmacallando {	if((__fpriv)->pmask_cache != (__val)) { \
58dbbd9e4bSmacallan		(__fpriv)->pmask_cache = (__val); \
59dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
60dbbd9e4bSmacallan		(__ffb)->pmask = (__val); \
61dbbd9e4bSmacallan	} \
62dbbd9e4bSmacallan} while(0)
63dbbd9e4bSmacallan
64dbbd9e4bSmacallan#define FFB_WRITE_ROP(__fpriv, __ffb, __val) \
65dbbd9e4bSmacallando {	if((__fpriv)->rop_cache != (__val)) { \
66dbbd9e4bSmacallan		(__fpriv)->rop_cache = (__val); \
67dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
68dbbd9e4bSmacallan		(__ffb)->rop = (__val); \
69dbbd9e4bSmacallan	} \
70dbbd9e4bSmacallan} while(0)
71dbbd9e4bSmacallan
72dbbd9e4bSmacallan#define FFB_WRITE_DRAWOP(__fpriv, __ffb, __val) \
73dbbd9e4bSmacallando {	if((__fpriv)->drawop_cache != (__val)) { \
74dbbd9e4bSmacallan		(__fpriv)->drawop_cache = (__val); \
75dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
76dbbd9e4bSmacallan		(__ffb)->drawop = (__val); \
77dbbd9e4bSmacallan	} \
78dbbd9e4bSmacallan} while(0)
79dbbd9e4bSmacallan
80dbbd9e4bSmacallan#define FFB_WRITE_FG(__fpriv, __ffb, __val) \
81dbbd9e4bSmacallando {	if((__fpriv)->fg_cache != (__val)) { \
82dbbd9e4bSmacallan		(__fpriv)->fg_cache = (__val); \
83dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
84dbbd9e4bSmacallan		(__ffb)->fg = (__val); \
85dbbd9e4bSmacallan	} \
86dbbd9e4bSmacallan} while(0)
87dbbd9e4bSmacallan
88dbbd9e4bSmacallan#define FFB_WRITE_BG(__fpriv, __ffb, __val) \
89dbbd9e4bSmacallando {	if((__fpriv)->bg_cache != (__val)) { \
90dbbd9e4bSmacallan		(__fpriv)->bg_cache = (__val); \
91dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
92dbbd9e4bSmacallan		(__ffb)->bg = (__val); \
93dbbd9e4bSmacallan	} \
94dbbd9e4bSmacallan} while(0)
95dbbd9e4bSmacallan
96dbbd9e4bSmacallan#define FFB_WRITE_FONTW(__fpriv, __ffb, __val) \
97dbbd9e4bSmacallando {	if((__fpriv)->fontw_cache != (__val)) { \
98dbbd9e4bSmacallan		(__fpriv)->fontw_cache = (__val); \
99dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
100dbbd9e4bSmacallan		(__ffb)->fontw = (__val); \
101dbbd9e4bSmacallan	} \
102dbbd9e4bSmacallan} while(0)
103dbbd9e4bSmacallan
104dbbd9e4bSmacallan#define FFB_WRITE_FONTINC(__fpriv, __ffb, __val) \
105dbbd9e4bSmacallando {	if((__fpriv)->fontinc_cache != (__val)) { \
106dbbd9e4bSmacallan		(__fpriv)->fontinc_cache = (__val); \
107dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
108dbbd9e4bSmacallan		(__ffb)->fontinc = (__val); \
109dbbd9e4bSmacallan	} \
110dbbd9e4bSmacallan} while(0)
111dbbd9e4bSmacallan
112dbbd9e4bSmacallan#define FFB_WRITE_FBC(__fpriv, __ffb, __val) \
113dbbd9e4bSmacallando {	if((__fpriv)->fbc_cache != (__val)) { \
114dbbd9e4bSmacallan		(__fpriv)->fbc_cache = (__val); \
115dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
116dbbd9e4bSmacallan		(__ffb)->fbc = (__val); \
117dbbd9e4bSmacallan	} \
118dbbd9e4bSmacallan} while(0)
119dbbd9e4bSmacallan
120dbbd9e4bSmacallan#define FFB_WRITE_WID(__fpriv, __ffb, __val) \
121dbbd9e4bSmacallando {	if((__fpriv)->wid_cache != (__val)) { \
122dbbd9e4bSmacallan		(__fpriv)->wid_cache = (__val); \
123dbbd9e4bSmacallan		FFBFifo((__fpriv), 1); \
124dbbd9e4bSmacallan		(__ffb)->wid = (__val); \
125dbbd9e4bSmacallan	} \
126dbbd9e4bSmacallan} while(0)
127dbbd9e4bSmacallan
128dbbd9e4bSmacallanextern void __FFB_Attr_Raw(FFBPtr pFfb,
129dbbd9e4bSmacallan			   unsigned int ppc,
130dbbd9e4bSmacallan			   unsigned int ppc_mask,
131dbbd9e4bSmacallan			   unsigned int pmask,
132dbbd9e4bSmacallan			   unsigned int rop,
133dbbd9e4bSmacallan			   int drawop, int fg,
134dbbd9e4bSmacallan			   unsigned int fbc,
135dbbd9e4bSmacallan			   unsigned int wid);
136dbbd9e4bSmacallan
137dbbd9e4bSmacallan#define FFB_ATTR_RAW(__fpriv, __ppc, __ppc_mask, __pmask, __rop, __drawop, __fg, __fbc, __wid) \
138dbbd9e4bSmacallan	if((((__fpriv)->ppc_cache & (__ppc_mask)) != (__ppc))			|| \
139dbbd9e4bSmacallan	   ((__fpriv)->pmask_cache != (__pmask))				|| \
140dbbd9e4bSmacallan	   ((__fpriv)->rop_cache != (__rop))					|| \
141dbbd9e4bSmacallan	   (((__drawop) != -1) && ((__fpriv)->drawop_cache != (__drawop)))	|| \
142dbbd9e4bSmacallan	   ((__fpriv)->fg_cache != (__fg))					|| \
143dbbd9e4bSmacallan	   ((__fpriv)->fbc_cache != (__fbc))					|| \
144dbbd9e4bSmacallan	   ((__fpriv)->wid_cache != (__wid))) \
145dbbd9e4bSmacallan		__FFB_Attr_Raw((__fpriv), (__ppc), (__ppc_mask), (__pmask), \
146dbbd9e4bSmacallan			       (__rop), (__drawop), (__fg), (__fbc), (__wid))
147dbbd9e4bSmacallan
148dbbd9e4bSmacallan#define FFB_PPC_GCMASK	(FFB_PPC_APE_MASK | FFB_PPC_CS_MASK)
149dbbd9e4bSmacallan
150dbbd9e4bSmacallan#define FFB_PPC_WINMASK	(FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK)
151dbbd9e4bSmacallan
152dbbd9e4bSmacallan/* We have to be careful when copying windows around.  For that
153dbbd9e4bSmacallan * case we will use either VIS copies or hw accelerated VSCROLL.
154dbbd9e4bSmacallan * All of the planes needs to be copied in the framebuffer from
155dbbd9e4bSmacallan * src to dst in order to handle child windows using different WIDs
156dbbd9e4bSmacallan * than the parent window being copied.
157dbbd9e4bSmacallan */
158dbbd9e4bSmacallan
159dbbd9e4bSmacallan/* Setup to access the smart frame buffer (SFB) directly where the
160dbbd9e4bSmacallan * pixel color comes from the cpu on writes.
161dbbd9e4bSmacallan */
162dbbd9e4bSmacallan#define FFB_PPC_WINCOPY		(FFB_PPC_APE_DISABLE | FFB_PPC_XS_VAR | FFB_PPC_CS_VAR)
163dbbd9e4bSmacallan#define FFB_PPC_WINCOPY_MASK	(FFB_PPC_APE_MASK | FFB_PPC_XS_MASK | FFB_PPC_CS_MASK)
164dbbd9e4bSmacallan#define FFB_FBC_WINCOPY		(FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_WE_FORCEON | \
165dbbd9e4bSmacallan				 FFB_FBC_RB_A | FFB_FBC_SB_BOTH | FFB_FBC_XE_ON | \
166dbbd9e4bSmacallan				 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_ON)
167dbbd9e4bSmacallan
168dbbd9e4bSmacallan#define FFB_ATTR_SFB_VAR_WINCOPY(__fpriv) \
169dbbd9e4bSmacallando {	unsigned int __ppc = FFB_PPC_WINCOPY; \
170dbbd9e4bSmacallan	unsigned int __ppc_mask = FFB_PPC_WINCOPY_MASK; \
171dbbd9e4bSmacallan	unsigned int __rop = FFB_ROP_NEW|(FFB_ROP_NEW<<8); \
172dbbd9e4bSmacallan	unsigned int __fbc = FFB_FBC_WINCOPY; \
173dbbd9e4bSmacallan	if((__fpriv)->has_double_buffer) { \
174dbbd9e4bSmacallan		__fbc &= ~FFB_FBC_WB_MASK; \
175dbbd9e4bSmacallan		__fbc |= FFB_FBC_WB_AB; \
176dbbd9e4bSmacallan	} \
177dbbd9e4bSmacallan	if (((__fpriv)->ppc_cache & __ppc_mask) != __ppc || \
178dbbd9e4bSmacallan	    (__fpriv)->fbc_cache != __fbc || \
179dbbd9e4bSmacallan	    (__fpriv)->rop_cache != __rop || \
180dbbd9e4bSmacallan	    (__fpriv)->pmask_cache != 0xffffffff) { \
181dbbd9e4bSmacallan		ffb_fbcPtr __ffb = (__fpriv)->regs; \
182dbbd9e4bSmacallan		(__fpriv)->ppc_cache &= ~__ppc_mask; \
183dbbd9e4bSmacallan		(__fpriv)->ppc_cache |= __ppc; \
184dbbd9e4bSmacallan		(__fpriv)->fbc_cache = __fbc; \
185dbbd9e4bSmacallan		(__fpriv)->rop_cache = __rop; \
186dbbd9e4bSmacallan		(__fpriv)->pmask_cache = 0xffffffff; \
187dbbd9e4bSmacallan		(__fpriv)->rp_active = 1; \
188dbbd9e4bSmacallan		FFBFifo(__fpriv, 4); \
189dbbd9e4bSmacallan		(__ffb)->ppc = __ppc; \
190dbbd9e4bSmacallan		(__ffb)->fbc = __fbc; \
191dbbd9e4bSmacallan		(__ffb)->rop = __rop; \
192dbbd9e4bSmacallan		(__ffb)->pmask = 0xffffffff; \
193dbbd9e4bSmacallan		(__fpriv)->rp_active = 1; \
194dbbd9e4bSmacallan	} \
195dbbd9e4bSmacallan} while(0)
196dbbd9e4bSmacallan
197dbbd9e4bSmacallanextern void __FFB_Attr_SFB_VAR(FFBPtr pFfb, unsigned int ppc, unsigned int ppc_mask, unsigned int fbc,
198dbbd9e4bSmacallan			       unsigned int wid, unsigned int rop, unsigned int pmask);
199dbbd9e4bSmacallan
200dbbd9e4bSmacallan#define FFB_ATTR_SFB_VAR_WIN(__fpriv, __pmask, __alu, __pwin) \
201dbbd9e4bSmacallando {	unsigned int __ppc = FFB_PPC_APE_DISABLE | FFB_PPC_CS_VAR | FFB_PPC_XS_WID; \
202dbbd9e4bSmacallan	unsigned int __ppc_mask = FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; \
203dbbd9e4bSmacallan	unsigned int __rop = (FFB_ROP_EDIT_BIT | (__alu))|(FFB_ROP_NEW<<8); \
204dbbd9e4bSmacallan	unsigned int __fbc = FFB_FBC_WIN(__pwin); \
205dbbd9e4bSmacallan	if((__fpriv)->has_double_buffer) { \
206dbbd9e4bSmacallan		__fbc &= ~FFB_FBC_WB_MASK; \
207dbbd9e4bSmacallan		__fbc |= FFB_FBC_WB_AB; \
208dbbd9e4bSmacallan	} \
209dbbd9e4bSmacallan	if(((__fpriv)->ppc_cache & __ppc_mask) != __ppc || \
210dbbd9e4bSmacallan	   (__fpriv)->fbc_cache != __fbc || \
211dbbd9e4bSmacallan	   (__fpriv)->wid_cache != FFB_WID_WIN(__pwin) || \
212dbbd9e4bSmacallan	   (__fpriv)->rop_cache != __rop || \
213dbbd9e4bSmacallan	   (__fpriv)->pmask_cache != (__pmask)) \
214dbbd9e4bSmacallan		__FFB_Attr_SFB_VAR(__fpriv, __ppc, __ppc_mask, __fbc, \
215dbbd9e4bSmacallan				   FFB_WID_WIN(__pwin), __rop, (__pmask)); \
216dbbd9e4bSmacallan} while(0)
217dbbd9e4bSmacallan
218dbbd9e4bSmacallan/* VSCROLL Attributes:
219dbbd9e4bSmacallan *
220dbbd9e4bSmacallan * PPC) VCE_DISABLE must be set, all other attributes are effectively
221dbbd9e4bSmacallan *      ignored since this drawop just copies pixels within the ram
222dbbd9e4bSmacallan *      chips and bypasses the pixel processor entirely.  So you
223dbbd9e4bSmacallan *	end up with a PPC color source behavior of {ZS,YS,XS,CS}_VAR.
224dbbd9e4bSmacallan * FBC) all options are allowed, but the SRC/DST buffers are determined
225dbbd9e4bSmacallan *      solely by the WB_* setting, that is, the RB_* setting is effectively
226dbbd9e4bSmacallan *      ignored since the pixels are copied directly through the write buffer
227dbbd9e4bSmacallan * ROP) must be FFB_ROP_OLD (even for the X plane!)
228dbbd9e4bSmacallan * PMASK) all options allowed
229dbbd9e4bSmacallan */
230dbbd9e4bSmacallan#define FFB_ATTR_VSCROLL_WINCOPY(__fpriv) \
231dbbd9e4bSmacallando {	unsigned int __rop = (FFB_ROP_OLD | (FFB_ROP_OLD << 8)); \
232dbbd9e4bSmacallan	unsigned int __fbc = FFB_FBC_WINCOPY; \
233dbbd9e4bSmacallan	if((__fpriv)->has_double_buffer) { \
234dbbd9e4bSmacallan		__fbc &= ~FFB_FBC_WB_MASK; \
235dbbd9e4bSmacallan		__fbc |= FFB_FBC_WB_AB; \
236dbbd9e4bSmacallan	} \
237dbbd9e4bSmacallan	if((__fpriv)->fbc_cache != __fbc || \
238dbbd9e4bSmacallan	   (__fpriv)->rop_cache != __rop || \
239dbbd9e4bSmacallan	   (__fpriv)->pmask_cache != 0xffffffff || \
240dbbd9e4bSmacallan	   (__fpriv)->drawop_cache != FFB_DRAWOP_VSCROLL) { \
241dbbd9e4bSmacallan		ffb_fbcPtr __ffb = (__fpriv)->regs; \
242dbbd9e4bSmacallan		(__fpriv)->fbc_cache = __fbc; \
243dbbd9e4bSmacallan		(__fpriv)->rop_cache = __rop; \
244dbbd9e4bSmacallan		(__fpriv)->pmask_cache = 0xffffffff; \
245dbbd9e4bSmacallan		(__fpriv)->drawop_cache = FFB_DRAWOP_VSCROLL; \
246dbbd9e4bSmacallan		(__fpriv)->rp_active = 1; \
247dbbd9e4bSmacallan		FFBFifo(__fpriv, 4); \
248dbbd9e4bSmacallan		(__ffb)->fbc = __fbc; \
249dbbd9e4bSmacallan		(__ffb)->rop = __rop; \
250dbbd9e4bSmacallan		(__ffb)->pmask = 0xffffffff; \
251dbbd9e4bSmacallan		(__ffb)->drawop = FFB_DRAWOP_VSCROLL; \
252dbbd9e4bSmacallan		(__fpriv)->rp_active = 1; \
253dbbd9e4bSmacallan	} \
254dbbd9e4bSmacallan} while(0)
255dbbd9e4bSmacallan
256dbbd9e4bSmacallan#define FFB_ATTR_VSCROLL_WIN(__fpriv, __pmask, __pwin) \
257dbbd9e4bSmacallando {	unsigned int __rop = (FFB_ROP_OLD | (FFB_ROP_OLD << 8)); \
258dbbd9e4bSmacallan	unsigned int __fbc = FFB_FBC_WIN(__pwin); \
259dbbd9e4bSmacallan	if((__fpriv)->has_double_buffer) { \
260dbbd9e4bSmacallan		__fbc &= ~FFB_FBC_WB_MASK; \
261dbbd9e4bSmacallan		__fbc |= FFB_FBC_WB_AB; \
262dbbd9e4bSmacallan	} \
263dbbd9e4bSmacallan	if((__fpriv)->fbc_cache != __fbc || \
264dbbd9e4bSmacallan	   (__fpriv)->rop_cache != __rop || \
265dbbd9e4bSmacallan	   (__fpriv)->pmask_cache != (__pmask) || \
266dbbd9e4bSmacallan	   (__fpriv)->drawop_cache != FFB_DRAWOP_VSCROLL) { \
267dbbd9e4bSmacallan		ffb_fbcPtr __ffb = (__fpriv)->regs; \
268dbbd9e4bSmacallan		(__fpriv)->fbc_cache = __fbc; \
269dbbd9e4bSmacallan		(__fpriv)->rop_cache = __rop; \
270dbbd9e4bSmacallan		(__fpriv)->pmask_cache = (__pmask); \
271dbbd9e4bSmacallan		(__fpriv)->drawop_cache = FFB_DRAWOP_VSCROLL; \
272dbbd9e4bSmacallan		(__fpriv)->rp_active = 1; \
273dbbd9e4bSmacallan		FFBFifo(__fpriv, 4); \
274dbbd9e4bSmacallan		(__ffb)->fbc = __fbc; \
275dbbd9e4bSmacallan		(__ffb)->rop = __rop; \
276dbbd9e4bSmacallan		(__ffb)->pmask = (__pmask); \
277dbbd9e4bSmacallan		(__ffb)->drawop = FFB_DRAWOP_VSCROLL; \
278dbbd9e4bSmacallan	} \
279dbbd9e4bSmacallan} while(0)
280dbbd9e4bSmacallan
281dbbd9e4bSmacallan#endif /* FFBRCACHE_H */
282