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 27dbbd9e4bSmacallan#ifndef FFBRCACHE_H 28dbbd9e4bSmacallan#define FFBRCACHE_H 29dbbd9e4bSmacallan 30dbbd9e4bSmacallan/* We only need to write the bits which actually change, 31dbbd9e4bSmacallan * writing unnessary bits causes the operation to go more 32dbbd9e4bSmacallan * slowly. -DaveM 33dbbd9e4bSmacallan * 34dbbd9e4bSmacallan * We used to have some hairy code here which tried to 35dbbd9e4bSmacallan * avoid writing attribute bits unnecessarily. It has been 36dbbd9e4bSmacallan * removed because various two bit fields have different 37dbbd9e4bSmacallan * semantics. For example, for some the higher bit is the 38dbbd9e4bSmacallan * edit bit, for others there are three state patterns 39dbbd9e4bSmacallan * and zero is a special "no edit" value. Ho hum, it was 40dbbd9e4bSmacallan * a nice idea... 41dbbd9e4bSmacallan */ 42dbbd9e4bSmacallan#define FFB_WRITE_PPC(__fpriv, __ffb, __val, __chg_mask) \ 43dbbd9e4bSmacallando { unsigned int __oldval = (__fpriv)->ppc_cache; \ 44dbbd9e4bSmacallan unsigned int __t; \ 45dbbd9e4bSmacallan __t = (__oldval & (__chg_mask)) ^ (__val); \ 46dbbd9e4bSmacallan if (__t) { \ 47dbbd9e4bSmacallan unsigned int __newval = __oldval & ~(__chg_mask); \ 48dbbd9e4bSmacallan __newval |= (__val); \ 49dbbd9e4bSmacallan (__fpriv)->ppc_cache = __newval; \ 50dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 51dbbd9e4bSmacallan (__ffb)->ppc = (__val); \ 52dbbd9e4bSmacallan } \ 53dbbd9e4bSmacallan} while(0) 54dbbd9e4bSmacallan 55dbbd9e4bSmacallan#define FFB_WRITE_PMASK(__fpriv, __ffb, __val) \ 56dbbd9e4bSmacallando { if((__fpriv)->pmask_cache != (__val)) { \ 57dbbd9e4bSmacallan (__fpriv)->pmask_cache = (__val); \ 58dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 59dbbd9e4bSmacallan (__ffb)->pmask = (__val); \ 60dbbd9e4bSmacallan } \ 61dbbd9e4bSmacallan} while(0) 62dbbd9e4bSmacallan 63dbbd9e4bSmacallan#define FFB_WRITE_ROP(__fpriv, __ffb, __val) \ 64dbbd9e4bSmacallando { if((__fpriv)->rop_cache != (__val)) { \ 65dbbd9e4bSmacallan (__fpriv)->rop_cache = (__val); \ 66dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 67dbbd9e4bSmacallan (__ffb)->rop = (__val); \ 68dbbd9e4bSmacallan } \ 69dbbd9e4bSmacallan} while(0) 70dbbd9e4bSmacallan 71dbbd9e4bSmacallan#define FFB_WRITE_DRAWOP(__fpriv, __ffb, __val) \ 72dbbd9e4bSmacallando { if((__fpriv)->drawop_cache != (__val)) { \ 73dbbd9e4bSmacallan (__fpriv)->drawop_cache = (__val); \ 74dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 75dbbd9e4bSmacallan (__ffb)->drawop = (__val); \ 76dbbd9e4bSmacallan } \ 77dbbd9e4bSmacallan} while(0) 78dbbd9e4bSmacallan 79dbbd9e4bSmacallan#define FFB_WRITE_FG(__fpriv, __ffb, __val) \ 80dbbd9e4bSmacallando { if((__fpriv)->fg_cache != (__val)) { \ 81dbbd9e4bSmacallan (__fpriv)->fg_cache = (__val); \ 82dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 83dbbd9e4bSmacallan (__ffb)->fg = (__val); \ 84dbbd9e4bSmacallan } \ 85dbbd9e4bSmacallan} while(0) 86dbbd9e4bSmacallan 87dbbd9e4bSmacallan#define FFB_WRITE_BG(__fpriv, __ffb, __val) \ 88dbbd9e4bSmacallando { if((__fpriv)->bg_cache != (__val)) { \ 89dbbd9e4bSmacallan (__fpriv)->bg_cache = (__val); \ 90dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 91dbbd9e4bSmacallan (__ffb)->bg = (__val); \ 92dbbd9e4bSmacallan } \ 93dbbd9e4bSmacallan} while(0) 94dbbd9e4bSmacallan 95dbbd9e4bSmacallan#define FFB_WRITE_FONTW(__fpriv, __ffb, __val) \ 96dbbd9e4bSmacallando { if((__fpriv)->fontw_cache != (__val)) { \ 97dbbd9e4bSmacallan (__fpriv)->fontw_cache = (__val); \ 98dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 99dbbd9e4bSmacallan (__ffb)->fontw = (__val); \ 100dbbd9e4bSmacallan } \ 101dbbd9e4bSmacallan} while(0) 102dbbd9e4bSmacallan 103dbbd9e4bSmacallan#define FFB_WRITE_FONTINC(__fpriv, __ffb, __val) \ 104dbbd9e4bSmacallando { if((__fpriv)->fontinc_cache != (__val)) { \ 105dbbd9e4bSmacallan (__fpriv)->fontinc_cache = (__val); \ 106dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 107dbbd9e4bSmacallan (__ffb)->fontinc = (__val); \ 108dbbd9e4bSmacallan } \ 109dbbd9e4bSmacallan} while(0) 110dbbd9e4bSmacallan 111dbbd9e4bSmacallan#define FFB_WRITE_FBC(__fpriv, __ffb, __val) \ 112dbbd9e4bSmacallando { if((__fpriv)->fbc_cache != (__val)) { \ 113dbbd9e4bSmacallan (__fpriv)->fbc_cache = (__val); \ 114dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 115dbbd9e4bSmacallan (__ffb)->fbc = (__val); \ 116dbbd9e4bSmacallan } \ 117dbbd9e4bSmacallan} while(0) 118dbbd9e4bSmacallan 119dbbd9e4bSmacallan#define FFB_WRITE_WID(__fpriv, __ffb, __val) \ 120dbbd9e4bSmacallando { if((__fpriv)->wid_cache != (__val)) { \ 121dbbd9e4bSmacallan (__fpriv)->wid_cache = (__val); \ 122dbbd9e4bSmacallan FFBFifo((__fpriv), 1); \ 123dbbd9e4bSmacallan (__ffb)->wid = (__val); \ 124dbbd9e4bSmacallan } \ 125dbbd9e4bSmacallan} while(0) 126dbbd9e4bSmacallan 127dbbd9e4bSmacallanextern void __FFB_Attr_Raw(FFBPtr pFfb, 128dbbd9e4bSmacallan unsigned int ppc, 129dbbd9e4bSmacallan unsigned int ppc_mask, 130dbbd9e4bSmacallan unsigned int pmask, 131dbbd9e4bSmacallan unsigned int rop, 132dbbd9e4bSmacallan int drawop, int fg, 133dbbd9e4bSmacallan unsigned int fbc, 134dbbd9e4bSmacallan unsigned int wid); 135dbbd9e4bSmacallan 136dbbd9e4bSmacallan#define FFB_ATTR_RAW(__fpriv, __ppc, __ppc_mask, __pmask, __rop, __drawop, __fg, __fbc, __wid) \ 137dbbd9e4bSmacallan if((((__fpriv)->ppc_cache & (__ppc_mask)) != (__ppc)) || \ 138dbbd9e4bSmacallan ((__fpriv)->pmask_cache != (__pmask)) || \ 139dbbd9e4bSmacallan ((__fpriv)->rop_cache != (__rop)) || \ 140dbbd9e4bSmacallan (((__drawop) != -1) && ((__fpriv)->drawop_cache != (__drawop))) || \ 141dbbd9e4bSmacallan ((__fpriv)->fg_cache != (__fg)) || \ 142dbbd9e4bSmacallan ((__fpriv)->fbc_cache != (__fbc)) || \ 143dbbd9e4bSmacallan ((__fpriv)->wid_cache != (__wid))) \ 144dbbd9e4bSmacallan __FFB_Attr_Raw((__fpriv), (__ppc), (__ppc_mask), (__pmask), \ 145dbbd9e4bSmacallan (__rop), (__drawop), (__fg), (__fbc), (__wid)) 146dbbd9e4bSmacallan 147dbbd9e4bSmacallan#define FFB_PPC_GCMASK (FFB_PPC_APE_MASK | FFB_PPC_CS_MASK) 148dbbd9e4bSmacallan 149dbbd9e4bSmacallan#define FFB_PPC_WINMASK (FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK) 150dbbd9e4bSmacallan 151dbbd9e4bSmacallan/* We have to be careful when copying windows around. For that 152dbbd9e4bSmacallan * case we will use either VIS copies or hw accelerated VSCROLL. 153dbbd9e4bSmacallan * All of the planes needs to be copied in the framebuffer from 154dbbd9e4bSmacallan * src to dst in order to handle child windows using different WIDs 155dbbd9e4bSmacallan * than the parent window being copied. 156dbbd9e4bSmacallan */ 157dbbd9e4bSmacallan 158dbbd9e4bSmacallan/* Setup to access the smart frame buffer (SFB) directly where the 159dbbd9e4bSmacallan * pixel color comes from the cpu on writes. 160dbbd9e4bSmacallan */ 161dbbd9e4bSmacallan#define FFB_PPC_WINCOPY (FFB_PPC_APE_DISABLE | FFB_PPC_XS_VAR | FFB_PPC_CS_VAR) 162dbbd9e4bSmacallan#define FFB_PPC_WINCOPY_MASK (FFB_PPC_APE_MASK | FFB_PPC_XS_MASK | FFB_PPC_CS_MASK) 163dbbd9e4bSmacallan#define FFB_FBC_WINCOPY (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_WE_FORCEON | \ 164dbbd9e4bSmacallan FFB_FBC_RB_A | FFB_FBC_SB_BOTH | FFB_FBC_XE_ON | \ 165dbbd9e4bSmacallan FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_ON) 166dbbd9e4bSmacallan 167dbbd9e4bSmacallan#define FFB_ATTR_SFB_VAR_WINCOPY(__fpriv) \ 168dbbd9e4bSmacallando { unsigned int __ppc = FFB_PPC_WINCOPY; \ 169dbbd9e4bSmacallan unsigned int __ppc_mask = FFB_PPC_WINCOPY_MASK; \ 170dbbd9e4bSmacallan unsigned int __rop = FFB_ROP_NEW|(FFB_ROP_NEW<<8); \ 171dbbd9e4bSmacallan unsigned int __fbc = FFB_FBC_WINCOPY; \ 172dbbd9e4bSmacallan if((__fpriv)->has_double_buffer) { \ 173dbbd9e4bSmacallan __fbc &= ~FFB_FBC_WB_MASK; \ 174dbbd9e4bSmacallan __fbc |= FFB_FBC_WB_AB; \ 175dbbd9e4bSmacallan } \ 176dbbd9e4bSmacallan if (((__fpriv)->ppc_cache & __ppc_mask) != __ppc || \ 177dbbd9e4bSmacallan (__fpriv)->fbc_cache != __fbc || \ 178dbbd9e4bSmacallan (__fpriv)->rop_cache != __rop || \ 179dbbd9e4bSmacallan (__fpriv)->pmask_cache != 0xffffffff) { \ 180dbbd9e4bSmacallan ffb_fbcPtr __ffb = (__fpriv)->regs; \ 181dbbd9e4bSmacallan (__fpriv)->ppc_cache &= ~__ppc_mask; \ 182dbbd9e4bSmacallan (__fpriv)->ppc_cache |= __ppc; \ 183dbbd9e4bSmacallan (__fpriv)->fbc_cache = __fbc; \ 184dbbd9e4bSmacallan (__fpriv)->rop_cache = __rop; \ 185dbbd9e4bSmacallan (__fpriv)->pmask_cache = 0xffffffff; \ 186dbbd9e4bSmacallan (__fpriv)->rp_active = 1; \ 187dbbd9e4bSmacallan FFBFifo(__fpriv, 4); \ 188dbbd9e4bSmacallan (__ffb)->ppc = __ppc; \ 189dbbd9e4bSmacallan (__ffb)->fbc = __fbc; \ 190dbbd9e4bSmacallan (__ffb)->rop = __rop; \ 191dbbd9e4bSmacallan (__ffb)->pmask = 0xffffffff; \ 192dbbd9e4bSmacallan (__fpriv)->rp_active = 1; \ 193dbbd9e4bSmacallan } \ 194dbbd9e4bSmacallan} while(0) 195dbbd9e4bSmacallan 196dbbd9e4bSmacallanextern void __FFB_Attr_SFB_VAR(FFBPtr pFfb, unsigned int ppc, unsigned int ppc_mask, unsigned int fbc, 197dbbd9e4bSmacallan unsigned int wid, unsigned int rop, unsigned int pmask); 198dbbd9e4bSmacallan 199dbbd9e4bSmacallan#define FFB_ATTR_SFB_VAR_WIN(__fpriv, __pmask, __alu, __pwin) \ 200dbbd9e4bSmacallando { unsigned int __ppc = FFB_PPC_APE_DISABLE | FFB_PPC_CS_VAR | FFB_PPC_XS_WID; \ 201dbbd9e4bSmacallan unsigned int __ppc_mask = FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; \ 202dbbd9e4bSmacallan unsigned int __rop = (FFB_ROP_EDIT_BIT | (__alu))|(FFB_ROP_NEW<<8); \ 203dbbd9e4bSmacallan unsigned int __fbc = FFB_FBC_WIN(__pwin); \ 204dbbd9e4bSmacallan if((__fpriv)->has_double_buffer) { \ 205dbbd9e4bSmacallan __fbc &= ~FFB_FBC_WB_MASK; \ 206dbbd9e4bSmacallan __fbc |= FFB_FBC_WB_AB; \ 207dbbd9e4bSmacallan } \ 208dbbd9e4bSmacallan if(((__fpriv)->ppc_cache & __ppc_mask) != __ppc || \ 209dbbd9e4bSmacallan (__fpriv)->fbc_cache != __fbc || \ 210dbbd9e4bSmacallan (__fpriv)->wid_cache != FFB_WID_WIN(__pwin) || \ 211dbbd9e4bSmacallan (__fpriv)->rop_cache != __rop || \ 212dbbd9e4bSmacallan (__fpriv)->pmask_cache != (__pmask)) \ 213dbbd9e4bSmacallan __FFB_Attr_SFB_VAR(__fpriv, __ppc, __ppc_mask, __fbc, \ 214dbbd9e4bSmacallan FFB_WID_WIN(__pwin), __rop, (__pmask)); \ 215dbbd9e4bSmacallan} while(0) 216dbbd9e4bSmacallan 217dbbd9e4bSmacallan/* VSCROLL Attributes: 218dbbd9e4bSmacallan * 219dbbd9e4bSmacallan * PPC) VCE_DISABLE must be set, all other attributes are effectively 220dbbd9e4bSmacallan * ignored since this drawop just copies pixels within the ram 221dbbd9e4bSmacallan * chips and bypasses the pixel processor entirely. So you 222dbbd9e4bSmacallan * end up with a PPC color source behavior of {ZS,YS,XS,CS}_VAR. 223dbbd9e4bSmacallan * FBC) all options are allowed, but the SRC/DST buffers are determined 224dbbd9e4bSmacallan * solely by the WB_* setting, that is, the RB_* setting is effectively 225dbbd9e4bSmacallan * ignored since the pixels are copied directly through the write buffer 226dbbd9e4bSmacallan * ROP) must be FFB_ROP_OLD (even for the X plane!) 227dbbd9e4bSmacallan * PMASK) all options allowed 228dbbd9e4bSmacallan */ 229dbbd9e4bSmacallan#define FFB_ATTR_VSCROLL_WINCOPY(__fpriv) \ 230dbbd9e4bSmacallando { unsigned int __rop = (FFB_ROP_OLD | (FFB_ROP_OLD << 8)); \ 231dbbd9e4bSmacallan unsigned int __fbc = FFB_FBC_WINCOPY; \ 232dbbd9e4bSmacallan if((__fpriv)->has_double_buffer) { \ 233dbbd9e4bSmacallan __fbc &= ~FFB_FBC_WB_MASK; \ 234dbbd9e4bSmacallan __fbc |= FFB_FBC_WB_AB; \ 235dbbd9e4bSmacallan } \ 236dbbd9e4bSmacallan if((__fpriv)->fbc_cache != __fbc || \ 237dbbd9e4bSmacallan (__fpriv)->rop_cache != __rop || \ 238dbbd9e4bSmacallan (__fpriv)->pmask_cache != 0xffffffff || \ 239dbbd9e4bSmacallan (__fpriv)->drawop_cache != FFB_DRAWOP_VSCROLL) { \ 240dbbd9e4bSmacallan ffb_fbcPtr __ffb = (__fpriv)->regs; \ 241dbbd9e4bSmacallan (__fpriv)->fbc_cache = __fbc; \ 242dbbd9e4bSmacallan (__fpriv)->rop_cache = __rop; \ 243dbbd9e4bSmacallan (__fpriv)->pmask_cache = 0xffffffff; \ 244dbbd9e4bSmacallan (__fpriv)->drawop_cache = FFB_DRAWOP_VSCROLL; \ 245dbbd9e4bSmacallan (__fpriv)->rp_active = 1; \ 246dbbd9e4bSmacallan FFBFifo(__fpriv, 4); \ 247dbbd9e4bSmacallan (__ffb)->fbc = __fbc; \ 248dbbd9e4bSmacallan (__ffb)->rop = __rop; \ 249dbbd9e4bSmacallan (__ffb)->pmask = 0xffffffff; \ 250dbbd9e4bSmacallan (__ffb)->drawop = FFB_DRAWOP_VSCROLL; \ 251dbbd9e4bSmacallan (__fpriv)->rp_active = 1; \ 252dbbd9e4bSmacallan } \ 253dbbd9e4bSmacallan} while(0) 254dbbd9e4bSmacallan 255dbbd9e4bSmacallan#define FFB_ATTR_VSCROLL_WIN(__fpriv, __pmask, __pwin) \ 256dbbd9e4bSmacallando { unsigned int __rop = (FFB_ROP_OLD | (FFB_ROP_OLD << 8)); \ 257dbbd9e4bSmacallan unsigned int __fbc = FFB_FBC_WIN(__pwin); \ 258dbbd9e4bSmacallan if((__fpriv)->has_double_buffer) { \ 259dbbd9e4bSmacallan __fbc &= ~FFB_FBC_WB_MASK; \ 260dbbd9e4bSmacallan __fbc |= FFB_FBC_WB_AB; \ 261dbbd9e4bSmacallan } \ 262dbbd9e4bSmacallan if((__fpriv)->fbc_cache != __fbc || \ 263dbbd9e4bSmacallan (__fpriv)->rop_cache != __rop || \ 264dbbd9e4bSmacallan (__fpriv)->pmask_cache != (__pmask) || \ 265dbbd9e4bSmacallan (__fpriv)->drawop_cache != FFB_DRAWOP_VSCROLL) { \ 266dbbd9e4bSmacallan ffb_fbcPtr __ffb = (__fpriv)->regs; \ 267dbbd9e4bSmacallan (__fpriv)->fbc_cache = __fbc; \ 268dbbd9e4bSmacallan (__fpriv)->rop_cache = __rop; \ 269dbbd9e4bSmacallan (__fpriv)->pmask_cache = (__pmask); \ 270dbbd9e4bSmacallan (__fpriv)->drawop_cache = FFB_DRAWOP_VSCROLL; \ 271dbbd9e4bSmacallan (__fpriv)->rp_active = 1; \ 272dbbd9e4bSmacallan FFBFifo(__fpriv, 4); \ 273dbbd9e4bSmacallan (__ffb)->fbc = __fbc; \ 274dbbd9e4bSmacallan (__ffb)->rop = __rop; \ 275dbbd9e4bSmacallan (__ffb)->pmask = (__pmask); \ 276dbbd9e4bSmacallan (__ffb)->drawop = FFB_DRAWOP_VSCROLL; \ 277dbbd9e4bSmacallan } \ 278dbbd9e4bSmacallan} while(0) 279dbbd9e4bSmacallan 280dbbd9e4bSmacallan#endif /* FFBRCACHE_H */ 281