ffb_wid.c revision dbbd9e4b
1dbbd9e4bSmacallan/* 2dbbd9e4bSmacallan * Acceleration for the Creator and Creator3D framebuffer - WID pool management. 3dbbd9e4bSmacallan * 4dbbd9e4bSmacallan * Copyright (C) 2000 David S. Miller (davem@redhat.com) 5dbbd9e4bSmacallan * 6dbbd9e4bSmacallan * Permission is hereby granted, free of charge, to any person obtaining a copy 7dbbd9e4bSmacallan * of this software and associated documentation files (the "Software"), to deal 8dbbd9e4bSmacallan * in the Software without restriction, including without limitation the rights 9dbbd9e4bSmacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10dbbd9e4bSmacallan * copies of the Software, and to permit persons to whom the Software is 11dbbd9e4bSmacallan * furnished to do so, subject to the following conditions: 12dbbd9e4bSmacallan * 13dbbd9e4bSmacallan * The above copyright notice and this permission notice shall be included in 14dbbd9e4bSmacallan * all copies or substantial portions of the Software. 15dbbd9e4bSmacallan * 16dbbd9e4bSmacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17dbbd9e4bSmacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18dbbd9e4bSmacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19dbbd9e4bSmacallan * DAVID MILLER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20dbbd9e4bSmacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21dbbd9e4bSmacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22dbbd9e4bSmacallan * 23dbbd9e4bSmacallan */ 24dbbd9e4bSmacallan/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_wid.c,v 1.2 2000/06/20 05:08:48 dawes Exp $ */ 25dbbd9e4bSmacallan 26dbbd9e4bSmacallan#ifdef HAVE_CONFIG_H 27dbbd9e4bSmacallan#include "config.h" 28dbbd9e4bSmacallan#endif 29dbbd9e4bSmacallan 30dbbd9e4bSmacallan#include "ffb.h" 31dbbd9e4bSmacallan 32dbbd9e4bSmacallanstatic void 33dbbd9e4bSmacallandetermine_numwids(FFBPtr pFfb) 34dbbd9e4bSmacallan{ 35dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 36dbbd9e4bSmacallan 37dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) 38dbbd9e4bSmacallan p->wid_table.num_wids = 32; 39dbbd9e4bSmacallan else 40dbbd9e4bSmacallan p->wid_table.num_wids = 64; 41dbbd9e4bSmacallan} 42dbbd9e4bSmacallan 43dbbd9e4bSmacallanstatic void 44dbbd9e4bSmacallanmake_wlut_regval(ffb_dac_info_t *p, ffb_wid_info_t *wid) 45dbbd9e4bSmacallan{ 46dbbd9e4bSmacallan wid->wlut_regval = 0; 47dbbd9e4bSmacallan 48dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) { 49dbbd9e4bSmacallan unsigned int color_model_bits; 50dbbd9e4bSmacallan 51dbbd9e4bSmacallan /* Pacifica1 format */ 52dbbd9e4bSmacallan if (wid->buffer != 0) 53dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC1_WLUT_DB; 54dbbd9e4bSmacallan 55dbbd9e4bSmacallan if (wid->depth == 8) { 56dbbd9e4bSmacallan if (wid->greyscale) { 57dbbd9e4bSmacallan if (wid->linear) 58dbbd9e4bSmacallan color_model_bits = FFBDAC_PAC1_WLUT_C_8LG; 59dbbd9e4bSmacallan else 60dbbd9e4bSmacallan color_model_bits = FFBDAC_PAC1_WLUT_C_8NG; 61dbbd9e4bSmacallan } else { 62dbbd9e4bSmacallan color_model_bits = FFBDAC_PAC1_WLUT_C_8P; 63dbbd9e4bSmacallan } 64dbbd9e4bSmacallan } else { 65dbbd9e4bSmacallan if (wid->direct) { 66dbbd9e4bSmacallan color_model_bits = FFBDAC_PAC1_WLUT_C_24D; 67dbbd9e4bSmacallan } else { 68dbbd9e4bSmacallan if (wid->linear) 69dbbd9e4bSmacallan color_model_bits = FFBDAC_PAC1_WLUT_C_24LT; 70dbbd9e4bSmacallan else 71dbbd9e4bSmacallan color_model_bits = FFBDAC_PAC1_WLUT_C_24NT; 72dbbd9e4bSmacallan } 73dbbd9e4bSmacallan } 74dbbd9e4bSmacallan 75dbbd9e4bSmacallan wid->wlut_regval |= color_model_bits; 76dbbd9e4bSmacallan 77dbbd9e4bSmacallan switch (wid->channel) { 78dbbd9e4bSmacallan default: 79dbbd9e4bSmacallan case 0: 80dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC1_WLUT_P_XO; 81dbbd9e4bSmacallan break; 82dbbd9e4bSmacallan case 1: 83dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC1_WLUT_P_R; 84dbbd9e4bSmacallan break; 85dbbd9e4bSmacallan case 2: 86dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC1_WLUT_P_G; 87dbbd9e4bSmacallan break; 88dbbd9e4bSmacallan case 3: 89dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC1_WLUT_P_B; 90dbbd9e4bSmacallan break; 91dbbd9e4bSmacallan }; 92dbbd9e4bSmacallan } else { 93dbbd9e4bSmacallan /* Pacifica2 format */ 94dbbd9e4bSmacallan if (wid->buffer != 0) 95dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_DB; 96dbbd9e4bSmacallan 97dbbd9e4bSmacallan if (wid->depth == 24) 98dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_DEPTH; 99dbbd9e4bSmacallan 100dbbd9e4bSmacallan switch (wid->channel) { 101dbbd9e4bSmacallan default: 102dbbd9e4bSmacallan case 0: 103dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_P_XO; 104dbbd9e4bSmacallan break; 105dbbd9e4bSmacallan case 1: 106dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_P_R; 107dbbd9e4bSmacallan break; 108dbbd9e4bSmacallan case 2: 109dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_P_G; 110dbbd9e4bSmacallan break; 111dbbd9e4bSmacallan case 3: 112dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_P_B; 113dbbd9e4bSmacallan break; 114dbbd9e4bSmacallan }; 115dbbd9e4bSmacallan 116dbbd9e4bSmacallan if ((wid->depth == 8 && wid->greyscale == 0) || 117dbbd9e4bSmacallan (wid->depth == 24 && wid->direct != 0)) 118dbbd9e4bSmacallan wid->wlut_regval |= FFBDAC_PAC2_WLUT_LKUP; 119dbbd9e4bSmacallan 120dbbd9e4bSmacallan if (wid->palette != -1) 121dbbd9e4bSmacallan wid->wlut_regval |= 122dbbd9e4bSmacallan ((wid->palette << 4) & FFBDAC_PAC2_WLUT_PTBL); 123dbbd9e4bSmacallan } 124dbbd9e4bSmacallan} 125dbbd9e4bSmacallan 126dbbd9e4bSmacallanstatic void 127dbbd9e4bSmacallaninit_wid_table(FFBPtr pFfb) 128dbbd9e4bSmacallan{ 129dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 130dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 131dbbd9e4bSmacallan int i; 132dbbd9e4bSmacallan 133dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) { 134dbbd9e4bSmacallan table->wid_pool[i].InUse = FALSE; 135dbbd9e4bSmacallan table->wid_pool[i].buffer = 0; 136dbbd9e4bSmacallan table->wid_pool[i].depth = 24; 137dbbd9e4bSmacallan table->wid_pool[i].greyscale = 0; 138dbbd9e4bSmacallan table->wid_pool[i].linear = 0; 139dbbd9e4bSmacallan table->wid_pool[i].direct = 0; 140dbbd9e4bSmacallan table->wid_pool[i].channel = 0; 141dbbd9e4bSmacallan table->wid_pool[i].palette = -1; 142dbbd9e4bSmacallan make_wlut_regval(p, &table->wid_pool[i]); 143dbbd9e4bSmacallan } 144dbbd9e4bSmacallan 145dbbd9e4bSmacallan table->wid_pool[table->num_wids - 1].InUse = TRUE; 146dbbd9e4bSmacallan table->wid_pool[table->num_wids - 1].canshare = FALSE; 147dbbd9e4bSmacallan} 148dbbd9e4bSmacallan 149dbbd9e4bSmacallanstatic void 150dbbd9e4bSmacallaninit_hw_wids(FFBPtr pFfb) 151dbbd9e4bSmacallan{ 152dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 153dbbd9e4bSmacallan ffb_dacPtr dac = pFfb->dac; 154dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 155dbbd9e4bSmacallan int i; 156dbbd9e4bSmacallan 157dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) 158dbbd9e4bSmacallan dac->cfg = FFBDAC_PAC1_APWLUT_BASE; 159dbbd9e4bSmacallan else 160dbbd9e4bSmacallan dac->cfg = FFBDAC_PAC2_APWLUT_BASE; 161dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) 162dbbd9e4bSmacallan dac->cfgdata = table->wid_pool[i].wlut_regval; 163dbbd9e4bSmacallan 164dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) 165dbbd9e4bSmacallan dac->cfg = FFBDAC_PAC1_SPWLUT_BASE; 166dbbd9e4bSmacallan else 167dbbd9e4bSmacallan dac->cfg = FFBDAC_PAC2_SPWLUT_BASE; 168dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) 169dbbd9e4bSmacallan dac->cfgdata = table->wid_pool[i].wlut_regval; 170dbbd9e4bSmacallan} 171dbbd9e4bSmacallan 172dbbd9e4bSmacallanstatic void 173dbbd9e4bSmacallaninit_hw_widmode(FFBPtr pFfb) 174dbbd9e4bSmacallan{ 175dbbd9e4bSmacallan ffb_dacPtr dac = pFfb->dac; 176dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 177dbbd9e4bSmacallan unsigned int uctrl; 178dbbd9e4bSmacallan 179dbbd9e4bSmacallan /* For now we use the Combined WID mode until I figure 180dbbd9e4bSmacallan * out exactly how Seperate4 and Seperate8 work. We 181dbbd9e4bSmacallan * also disable overlays for the time being. 182dbbd9e4bSmacallan */ 183dbbd9e4bSmacallan p->wid_table.wid_shift = 0; 184dbbd9e4bSmacallan 185dbbd9e4bSmacallan dac->cfg = FFBDAC_CFG_UCTRL; 186dbbd9e4bSmacallan uctrl = dac->cfgdata; 187dbbd9e4bSmacallan uctrl &= ~FFBDAC_UCTRL_WMODE; 188dbbd9e4bSmacallan uctrl |= FFBDAC_UCTRL_WM_COMB; 189dbbd9e4bSmacallan uctrl &= ~FFBDAC_UCTRL_OVENAB; 190dbbd9e4bSmacallan dac->cfg = FFBDAC_CFG_UCTRL; 191dbbd9e4bSmacallan dac->cfgdata = uctrl; 192dbbd9e4bSmacallan} 193dbbd9e4bSmacallan 194dbbd9e4bSmacallanvoid 195dbbd9e4bSmacallanFFBWidPoolInit(FFBPtr pFfb) 196dbbd9e4bSmacallan{ 197dbbd9e4bSmacallan determine_numwids(pFfb); 198dbbd9e4bSmacallan init_wid_table(pFfb); 199dbbd9e4bSmacallan init_hw_wids(pFfb); 200dbbd9e4bSmacallan init_hw_widmode(pFfb); 201dbbd9e4bSmacallan} 202dbbd9e4bSmacallan 203dbbd9e4bSmacallanstatic void 204dbbd9e4bSmacallanupdate_wids(FFBPtr pFfb, int index) 205dbbd9e4bSmacallan{ 206dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 207dbbd9e4bSmacallan ffb_dacPtr dac = pFfb->dac; 208dbbd9e4bSmacallan unsigned int base; 209dbbd9e4bSmacallan int limit; 210dbbd9e4bSmacallan 211dbbd9e4bSmacallan if (pFfb->vtSema) 212dbbd9e4bSmacallan return; 213dbbd9e4bSmacallan 214dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) 215dbbd9e4bSmacallan base = FFBDAC_PAC1_SPWLUT(index); 216dbbd9e4bSmacallan else 217dbbd9e4bSmacallan base = FFBDAC_PAC2_SPWLUT(index); 218dbbd9e4bSmacallan DACCFG_WRITE(dac, base, p->wid_table.wid_pool[index].wlut_regval); 219dbbd9e4bSmacallan 220dbbd9e4bSmacallan /* Schedule the window transfer. */ 221dbbd9e4bSmacallan DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL, 222dbbd9e4bSmacallan (FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE)); 223dbbd9e4bSmacallan 224dbbd9e4bSmacallan limit = 1000000; 225dbbd9e4bSmacallan while (limit--) { 226dbbd9e4bSmacallan unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL); 227dbbd9e4bSmacallan 228dbbd9e4bSmacallan if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0) 229dbbd9e4bSmacallan break; 230dbbd9e4bSmacallan } 231dbbd9e4bSmacallan} 232dbbd9e4bSmacallan 233dbbd9e4bSmacallanunsigned int 234dbbd9e4bSmacallanFFBWidAlloc(FFBPtr pFfb, int visclass, int cmap, Bool canshare) 235dbbd9e4bSmacallan{ 236dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 237dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 238dbbd9e4bSmacallan int i, depth, direct, static_greyscale, palette, channel; 239dbbd9e4bSmacallan 240dbbd9e4bSmacallan direct = 0; 241dbbd9e4bSmacallan static_greyscale = 0; 242dbbd9e4bSmacallan switch (visclass) { 243dbbd9e4bSmacallan case StaticGray: 244dbbd9e4bSmacallan static_greyscale = 1; 245dbbd9e4bSmacallan /* Fallthrough... */ 246dbbd9e4bSmacallan case StaticColor: 247dbbd9e4bSmacallan case GrayScale: 248dbbd9e4bSmacallan case PseudoColor: 249dbbd9e4bSmacallan depth = 8; 250dbbd9e4bSmacallan channel = 1; 251dbbd9e4bSmacallan break; 252dbbd9e4bSmacallan 253dbbd9e4bSmacallan case DirectColor: 254dbbd9e4bSmacallan direct = 1; 255dbbd9e4bSmacallan /* Fallthrough... */ 256dbbd9e4bSmacallan case TrueColor: 257dbbd9e4bSmacallan depth = 24; 258dbbd9e4bSmacallan channel = 0; 259dbbd9e4bSmacallan break; 260dbbd9e4bSmacallan 261dbbd9e4bSmacallan default: 262dbbd9e4bSmacallan return (unsigned int) -1; 263dbbd9e4bSmacallan }; 264dbbd9e4bSmacallan 265dbbd9e4bSmacallan palette = -1; 266dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) { 267dbbd9e4bSmacallan if (visclass == PseudoColor || 268dbbd9e4bSmacallan visclass == GrayScale || 269dbbd9e4bSmacallan visclass == DirectColor) 270dbbd9e4bSmacallan palette = 0; 271dbbd9e4bSmacallan } else { 272dbbd9e4bSmacallan if (visclass == PseudoColor) 273dbbd9e4bSmacallan palette = 0; 274dbbd9e4bSmacallan if (visclass == GrayScale) 275dbbd9e4bSmacallan palette = 1; 276dbbd9e4bSmacallan if (visclass == DirectColor) 277dbbd9e4bSmacallan palette = 2; 278dbbd9e4bSmacallan } 279dbbd9e4bSmacallan 280dbbd9e4bSmacallan if (canshare) { 281dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) { 282dbbd9e4bSmacallan if (table->wid_pool[i].InUse == TRUE && 283dbbd9e4bSmacallan table->wid_pool[i].canshare == TRUE && 284dbbd9e4bSmacallan table->wid_pool[i].palette == palette && 285dbbd9e4bSmacallan table->wid_pool[i].direct == direct && 286dbbd9e4bSmacallan table->wid_pool[i].greyscale == static_greyscale && 287dbbd9e4bSmacallan table->wid_pool[i].channel == channel && 288dbbd9e4bSmacallan table->wid_pool[i].depth == depth) { 289dbbd9e4bSmacallan table->wid_pool[i].refcount++; 290dbbd9e4bSmacallan return i << table->wid_shift; 291dbbd9e4bSmacallan } 292dbbd9e4bSmacallan } 293dbbd9e4bSmacallan } 294dbbd9e4bSmacallan 295dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) { 296dbbd9e4bSmacallan if (table->wid_pool[i].InUse == FALSE) 297dbbd9e4bSmacallan break; 298dbbd9e4bSmacallan } 299dbbd9e4bSmacallan 300dbbd9e4bSmacallan if (i != table->num_wids) { 301dbbd9e4bSmacallan table->wid_pool[i].InUse = TRUE; 302dbbd9e4bSmacallan table->wid_pool[i].buffer = 0; 303dbbd9e4bSmacallan table->wid_pool[i].depth = depth; 304dbbd9e4bSmacallan table->wid_pool[i].palette = palette; 305dbbd9e4bSmacallan table->wid_pool[i].direct = direct; 306dbbd9e4bSmacallan table->wid_pool[i].greyscale = static_greyscale; 307dbbd9e4bSmacallan if (depth == 8) 308dbbd9e4bSmacallan table->wid_pool[i].channel = 1; 309dbbd9e4bSmacallan else 310dbbd9e4bSmacallan table->wid_pool[i].channel = 0; 311dbbd9e4bSmacallan table->wid_pool[i].refcount = 1; 312dbbd9e4bSmacallan table->wid_pool[i].canshare = canshare; 313dbbd9e4bSmacallan make_wlut_regval(p, &table->wid_pool[i]); 314dbbd9e4bSmacallan update_wids(pFfb, i); 315dbbd9e4bSmacallan return i << table->wid_shift; 316dbbd9e4bSmacallan } 317dbbd9e4bSmacallan 318dbbd9e4bSmacallan return (unsigned int) -1; 319dbbd9e4bSmacallan} 320dbbd9e4bSmacallan 321dbbd9e4bSmacallanvoid 322dbbd9e4bSmacallanFFBWidFree(FFBPtr pFfb, unsigned int wid) 323dbbd9e4bSmacallan{ 324dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 325dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 326dbbd9e4bSmacallan int index = wid >> table->wid_shift; 327dbbd9e4bSmacallan 328dbbd9e4bSmacallan if (index < 0 || index >= table->num_wids) { 329dbbd9e4bSmacallan return; 330dbbd9e4bSmacallan } 331dbbd9e4bSmacallan 332dbbd9e4bSmacallan if (--table->wid_pool[index].refcount == 0) { 333dbbd9e4bSmacallan table->wid_pool[index].InUse = FALSE; 334dbbd9e4bSmacallan } 335dbbd9e4bSmacallan} 336dbbd9e4bSmacallan 337dbbd9e4bSmacallan/* Double Buffering support. */ 338dbbd9e4bSmacallan 339dbbd9e4bSmacallanunsigned int 340dbbd9e4bSmacallanFFBWidUnshare(FFBPtr pFfb, unsigned int wid) 341dbbd9e4bSmacallan{ 342dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 343dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 344dbbd9e4bSmacallan int index = wid >> table->wid_shift; 345dbbd9e4bSmacallan int i; 346dbbd9e4bSmacallan 347dbbd9e4bSmacallan if (index < 0 || index >= table->num_wids) { 348dbbd9e4bSmacallan return (unsigned int) -1; 349dbbd9e4bSmacallan } 350dbbd9e4bSmacallan 351dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) { 352dbbd9e4bSmacallan if (table->wid_pool[i].InUse == FALSE) 353dbbd9e4bSmacallan break; 354dbbd9e4bSmacallan } 355dbbd9e4bSmacallan 356dbbd9e4bSmacallan if (i == table->num_wids) { 357dbbd9e4bSmacallan return (unsigned int) -1; 358dbbd9e4bSmacallan } 359dbbd9e4bSmacallan 360dbbd9e4bSmacallan table->wid_pool[i].InUse = TRUE; 361dbbd9e4bSmacallan table->wid_pool[i].buffer = 0; 362dbbd9e4bSmacallan table->wid_pool[i].depth = table->wid_pool[index].depth; 363dbbd9e4bSmacallan table->wid_pool[i].palette = table->wid_pool[index].palette; 364dbbd9e4bSmacallan table->wid_pool[i].direct = table->wid_pool[index].direct; 365dbbd9e4bSmacallan table->wid_pool[i].greyscale = table->wid_pool[index].greyscale; 366dbbd9e4bSmacallan table->wid_pool[i].channel = table->wid_pool[index].channel; 367dbbd9e4bSmacallan table->wid_pool[i].refcount = 1; 368dbbd9e4bSmacallan table->wid_pool[i].canshare = FALSE; 369dbbd9e4bSmacallan make_wlut_regval(p, &table->wid_pool[i]); 370dbbd9e4bSmacallan update_wids(pFfb, i); 371dbbd9e4bSmacallan 372dbbd9e4bSmacallan /* Now free the original WID. */ 373dbbd9e4bSmacallan if (--table->wid_pool[index].refcount == 0) { 374dbbd9e4bSmacallan table->wid_pool[index].InUse = FALSE; 375dbbd9e4bSmacallan } 376dbbd9e4bSmacallan 377dbbd9e4bSmacallan return i << table->wid_shift; 378dbbd9e4bSmacallan} 379dbbd9e4bSmacallan 380dbbd9e4bSmacallanunsigned int 381dbbd9e4bSmacallanFFBWidReshare(FFBPtr pFfb, unsigned int wid) 382dbbd9e4bSmacallan{ 383dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 384dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 385dbbd9e4bSmacallan int index = wid >> table->wid_shift; 386dbbd9e4bSmacallan int i; 387dbbd9e4bSmacallan 388dbbd9e4bSmacallan if (index < 0 || index >= table->num_wids) { 389dbbd9e4bSmacallan return wid; 390dbbd9e4bSmacallan } 391dbbd9e4bSmacallan 392dbbd9e4bSmacallan for (i = 0; i < table->num_wids; i++) { 393dbbd9e4bSmacallan if (table->wid_pool[i].InUse == TRUE && 394dbbd9e4bSmacallan table->wid_pool[i].canshare == TRUE && 395dbbd9e4bSmacallan table->wid_pool[i].depth == table->wid_pool[index].depth && 396dbbd9e4bSmacallan table->wid_pool[i].palette == table->wid_pool[index].palette && 397dbbd9e4bSmacallan table->wid_pool[i].direct == table->wid_pool[index].direct && 398dbbd9e4bSmacallan table->wid_pool[i].greyscale == table->wid_pool[index].greyscale && 399dbbd9e4bSmacallan table->wid_pool[i].channel == table->wid_pool[index].channel) 400dbbd9e4bSmacallan break; 401dbbd9e4bSmacallan } 402dbbd9e4bSmacallan 403dbbd9e4bSmacallan if (i == table->num_wids) { 404dbbd9e4bSmacallan /* OK, very simple, just make the old one shared. */ 405dbbd9e4bSmacallan table->wid_pool[index].canshare = TRUE; 406dbbd9e4bSmacallan table->wid_pool[index].buffer = 0; 407dbbd9e4bSmacallan make_wlut_regval(p, &table->wid_pool[index]); 408dbbd9e4bSmacallan update_wids(pFfb, index); 409dbbd9e4bSmacallan return wid; 410dbbd9e4bSmacallan } 411dbbd9e4bSmacallan 412dbbd9e4bSmacallan /* Ok, free the original WID. */ 413dbbd9e4bSmacallan if (--table->wid_pool[index].refcount == 0) { 414dbbd9e4bSmacallan table->wid_pool[index].InUse = FALSE; 415dbbd9e4bSmacallan } 416dbbd9e4bSmacallan 417dbbd9e4bSmacallan /* And grab a reference to the new one. */ 418dbbd9e4bSmacallan table->wid_pool[i].refcount++; 419dbbd9e4bSmacallan 420dbbd9e4bSmacallan /* And return the shared one. */ 421dbbd9e4bSmacallan return i << table->wid_shift; 422dbbd9e4bSmacallan} 423dbbd9e4bSmacallan 424dbbd9e4bSmacallanvoid 425dbbd9e4bSmacallanFFBWidChangeBuffer(FFBPtr pFfb, unsigned int wid, int visible) 426dbbd9e4bSmacallan{ 427dbbd9e4bSmacallan ffb_dac_info_t *p = &pFfb->dac_info; 428dbbd9e4bSmacallan ffb_wid_pool_t *table = &p->wid_table; 429dbbd9e4bSmacallan int index = wid >> table->wid_shift; 430dbbd9e4bSmacallan int buffer; 431dbbd9e4bSmacallan 432dbbd9e4bSmacallan if (index < 0 || index >= table->num_wids) 433dbbd9e4bSmacallan return; 434dbbd9e4bSmacallan 435dbbd9e4bSmacallan buffer = (table->wid_pool[index].buffer ^= 1); 436dbbd9e4bSmacallan if (visible) { 437dbbd9e4bSmacallan unsigned int bit; 438dbbd9e4bSmacallan 439dbbd9e4bSmacallan if (p->flags & FFB_DAC_PAC1) 440dbbd9e4bSmacallan bit = FFBDAC_PAC1_WLUT_DB; 441dbbd9e4bSmacallan else 442dbbd9e4bSmacallan bit = FFBDAC_PAC2_WLUT_DB; 443dbbd9e4bSmacallan 444dbbd9e4bSmacallan if (buffer) 445dbbd9e4bSmacallan table->wid_pool[index].wlut_regval |= bit; 446dbbd9e4bSmacallan else 447dbbd9e4bSmacallan table->wid_pool[index].wlut_regval &= ~bit; 448dbbd9e4bSmacallan 449dbbd9e4bSmacallan update_wids(pFfb, index); 450dbbd9e4bSmacallan } 451dbbd9e4bSmacallan} 452