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