1706f2543Smrg/* 2706f2543Smrg * Copyright 1998 by Alan Hourihane, Wigan, England. 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Alan Hourihane not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Alan Hourihane makes no representations 11706f2543Smrg * about the suitability of this software for any purpose. It is provided 12706f2543Smrg * "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg * 22706f2543Smrg * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23706f2543Smrg * 24706f2543Smrg * Modified from IBM.c to support TI RAMDAC routines 25706f2543Smrg * by Jens Owen, <jens@tungstengraphics.com>. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 29706f2543Smrg#include <xorg-config.h> 30706f2543Smrg#endif 31706f2543Smrg 32706f2543Smrg#include "xf86.h" 33706f2543Smrg#include "xf86_OSproc.h" 34706f2543Smrg 35706f2543Smrg#include "xf86Cursor.h" 36706f2543Smrg 37706f2543Smrg#define INIT_TI_RAMDAC_INFO 38706f2543Smrg#include "TIPriv.h" 39706f2543Smrg#include "xf86RamDacPriv.h" 40706f2543Smrg 41706f2543Smrg/* The following values are in kHz */ 42706f2543Smrg#define TI_MIN_VCO_FREQ 110000 43706f2543Smrg#define TI_MAX_VCO_FREQ 220000 44706f2543Smrg 45706f2543Smrgunsigned long 46706f2543SmrgTIramdacCalculateMNPForClock( 47706f2543Smrg unsigned long RefClock, /* In 100Hz units */ 48706f2543Smrg unsigned long ReqClock, /* In 100Hz units */ 49706f2543Smrg char IsPixClock, /* boolean, is this the pixel or the sys clock */ 50706f2543Smrg unsigned long MinClock, /* Min VCO rating */ 51706f2543Smrg unsigned long MaxClock, /* Max VCO rating */ 52706f2543Smrg unsigned long *rM, /* M Out */ 53706f2543Smrg unsigned long *rN, /* N Out */ 54706f2543Smrg unsigned long *rP /* Min P In, P Out */ 55706f2543Smrg) 56706f2543Smrg{ 57706f2543Smrg unsigned long n, p; 58706f2543Smrg unsigned long best_m = 0, best_n = 0; 59706f2543Smrg double VCO, IntRef = (double)RefClock; 60706f2543Smrg double m_err, inc_m, calc_m; 61706f2543Smrg unsigned long ActualClock; 62706f2543Smrg 63706f2543Smrg /* Make sure that MinClock <= ReqClock <= MaxClock */ 64706f2543Smrg if ( ReqClock < MinClock) 65706f2543Smrg ReqClock = MinClock; 66706f2543Smrg if ( ReqClock > MaxClock ) 67706f2543Smrg ReqClock = MaxClock; 68706f2543Smrg 69706f2543Smrg /* 70706f2543Smrg * ActualClock = VCO / 2 ^ p 71706f2543Smrg * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ 72706f2543Smrg * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ 73706f2543Smrg * we don't have to bother checking for this maximum limit. 74706f2543Smrg */ 75706f2543Smrg VCO = (double)ReqClock; 76706f2543Smrg for ( p = 0; p < 3 && VCO < TI_MIN_VCO_FREQ; ( p )++ ) 77706f2543Smrg VCO *= 2.0; 78706f2543Smrg 79706f2543Smrg /* 80706f2543Smrg * We avoid doing multiplications by ( 65 - n ), 81706f2543Smrg * and add an increment instead - this keeps any error small. 82706f2543Smrg */ 83706f2543Smrg inc_m = VCO / ( IntRef * 8.0 ); 84706f2543Smrg 85706f2543Smrg /* Initial value of calc_m for the loop */ 86706f2543Smrg calc_m = inc_m + inc_m + inc_m; 87706f2543Smrg 88706f2543Smrg /* Initial amount of error for an integer - impossibly large */ 89706f2543Smrg m_err = 2.0; 90706f2543Smrg 91706f2543Smrg /* Search for the closest INTEGER value of ( 65 - m ) */ 92706f2543Smrg for ( n = 3; n <= 25; ( n )++, calc_m += inc_m ) { 93706f2543Smrg 94706f2543Smrg /* Ignore values of ( 65 - m ) which we can't use */ 95706f2543Smrg if ( calc_m < 3.0 || calc_m > 64.0 ) 96706f2543Smrg continue; 97706f2543Smrg 98706f2543Smrg /* 99706f2543Smrg * Pick the closest INTEGER (has smallest fractional part). 100706f2543Smrg * The optimizer should clean this up for us. 101706f2543Smrg */ 102706f2543Smrg if (( calc_m - ( int ) calc_m ) < m_err ) { 103706f2543Smrg m_err = calc_m - ( int ) calc_m; 104706f2543Smrg best_m = ( int ) calc_m; 105706f2543Smrg best_n = n; 106706f2543Smrg } 107706f2543Smrg } 108706f2543Smrg 109706f2543Smrg /* 65 - ( 65 - x ) = x */ 110706f2543Smrg *rM = 65 - best_m; 111706f2543Smrg *rN = 65 - best_n; 112706f2543Smrg *rP = p; 113706f2543Smrg 114706f2543Smrg /* Now all the calculations can be completed */ 115706f2543Smrg VCO = 8.0 * IntRef * best_m / best_n; 116706f2543Smrg ActualClock = VCO / ( 1 << p ); 117706f2543Smrg 118706f2543Smrg DebugF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n", 119706f2543Smrg ActualClock, VCO, *rN, *rM, *rP); 120706f2543Smrg 121706f2543Smrg return ActualClock; 122706f2543Smrg} 123706f2543Smrg 124706f2543Smrgvoid 125706f2543SmrgTIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 126706f2543Smrg RamDacRegRecPtr ramdacReg) 127706f2543Smrg{ 128706f2543Smrg int i; 129706f2543Smrg unsigned long status; 130706f2543Smrg 131706f2543Smrg /* Here we pass a short, so that we can evaluate a mask too 132706f2543Smrg * So that the mask is the high byte and the data the low byte 133706f2543Smrg * Order is important 134706f2543Smrg */ 135706f2543Smrg TIRESTORE(TIDAC_latch_ctrl); 136706f2543Smrg TIRESTORE(TIDAC_true_color_ctrl); 137706f2543Smrg TIRESTORE(TIDAC_multiplex_ctrl); 138706f2543Smrg TIRESTORE(TIDAC_clock_select); 139706f2543Smrg TIRESTORE(TIDAC_palette_page); 140706f2543Smrg TIRESTORE(TIDAC_general_ctrl); 141706f2543Smrg TIRESTORE(TIDAC_misc_ctrl); 142706f2543Smrg /* 0x2A & 0x2B are reserved */ 143706f2543Smrg TIRESTORE(TIDAC_key_over_low); 144706f2543Smrg TIRESTORE(TIDAC_key_over_high); 145706f2543Smrg TIRESTORE(TIDAC_key_red_low); 146706f2543Smrg TIRESTORE(TIDAC_key_red_high); 147706f2543Smrg TIRESTORE(TIDAC_key_green_low); 148706f2543Smrg TIRESTORE(TIDAC_key_green_high); 149706f2543Smrg TIRESTORE(TIDAC_key_blue_low); 150706f2543Smrg TIRESTORE(TIDAC_key_blue_high); 151706f2543Smrg TIRESTORE(TIDAC_key_ctrl); 152706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x30); 153706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x38); 154706f2543Smrg TIRESTORE(TIDAC_clock_ctrl); 155706f2543Smrg TIRESTORE(TIDAC_sense_test); 156706f2543Smrg TIRESTORE(TIDAC_ind_curs_ctrl); 157706f2543Smrg 158706f2543Smrg /* only restore clocks if they were valid to begin with */ 159706f2543Smrg 160706f2543Smrg if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) { 161706f2543Smrg /* Reset pixel clock */ 162706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22); 163706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 0x3c); 164706f2543Smrg 165706f2543Smrg /* Restore N, M & P values for pixel clocks */ 166706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0); 167706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 168706f2543Smrg ramdacReg->DacRegs[TIDAC_PIXEL_N]); 169706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 170706f2543Smrg ramdacReg->DacRegs[TIDAC_PIXEL_M]); 171706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 172706f2543Smrg ramdacReg->DacRegs[TIDAC_PIXEL_P]); 173706f2543Smrg 174706f2543Smrg /* wait for pixel clock to lock */ 175706f2543Smrg i = 1000000; 176706f2543Smrg do { 177706f2543Smrg status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data); 178706f2543Smrg } while ((!(status & 0x40)) && (--i)); 179706f2543Smrg if (!(status & 0x40)) { 180706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 181706f2543Smrg "Pixel clock setup timed out\n"); 182706f2543Smrg return; 183706f2543Smrg } 184706f2543Smrg } 185706f2543Smrg 186706f2543Smrg if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) { 187706f2543Smrg /* Reset loop clock */ 188706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22); 189706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 0x70); 190706f2543Smrg 191706f2543Smrg /* Restore N, M & P values for pixel clocks */ 192706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0); 193706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 194706f2543Smrg ramdacReg->DacRegs[TIDAC_LOOP_N]); 195706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 196706f2543Smrg ramdacReg->DacRegs[TIDAC_LOOP_M]); 197706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 198706f2543Smrg ramdacReg->DacRegs[TIDAC_LOOP_P]); 199706f2543Smrg 200706f2543Smrg /* wait for loop clock to lock */ 201706f2543Smrg i = 1000000; 202706f2543Smrg do { 203706f2543Smrg status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data); 204706f2543Smrg } while ((!(status & 0x40)) && (--i)); 205706f2543Smrg if (!(status & 0x40)) { 206706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 207706f2543Smrg "Loop clock setup timed out\n"); 208706f2543Smrg return; 209706f2543Smrg } 210706f2543Smrg } 211706f2543Smrg 212706f2543Smrg /* restore palette */ 213706f2543Smrg (*ramdacPtr->WriteAddress)(pScrn, 0); 214706f2543Smrg#ifndef NOT_DONE 215706f2543Smrg for (i=0;i<768;i++) 216706f2543Smrg (*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]); 217706f2543Smrg#else 218706f2543Smrg (*ramdacPtr->WriteData)(pScrn, 0); 219706f2543Smrg (*ramdacPtr->WriteData)(pScrn, 0); 220706f2543Smrg (*ramdacPtr->WriteData)(pScrn, 0); 221706f2543Smrg for (i=0;i<765;i++) 222706f2543Smrg (*ramdacPtr->WriteData)(pScrn, 0xff); 223706f2543Smrg#endif 224706f2543Smrg} 225706f2543Smrg 226706f2543Smrgvoid 227706f2543SmrgTIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 228706f2543Smrg RamDacRegRecPtr ramdacReg) 229706f2543Smrg{ 230706f2543Smrg int i; 231706f2543Smrg 232706f2543Smrg (*ramdacPtr->ReadAddress)(pScrn, 0); 233706f2543Smrg for (i=0;i<768;i++) 234706f2543Smrg ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn); 235706f2543Smrg 236706f2543Smrg /* Read back N,M and P values for pixel clock */ 237706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0); 238706f2543Smrg ramdacReg->DacRegs[TIDAC_PIXEL_N] = 239706f2543Smrg (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data); 240706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11); 241706f2543Smrg ramdacReg->DacRegs[TIDAC_PIXEL_M] = 242706f2543Smrg (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data); 243706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22); 244706f2543Smrg ramdacReg->DacRegs[TIDAC_PIXEL_P] = 245706f2543Smrg (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data); 246706f2543Smrg 247706f2543Smrg /* Read back N,M and P values for loop clock */ 248706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0); 249706f2543Smrg ramdacReg->DacRegs[TIDAC_LOOP_N] = 250706f2543Smrg (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data); 251706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11); 252706f2543Smrg ramdacReg->DacRegs[TIDAC_LOOP_M] = 253706f2543Smrg (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data); 254706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22); 255706f2543Smrg ramdacReg->DacRegs[TIDAC_LOOP_P] = 256706f2543Smrg (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data); 257706f2543Smrg 258706f2543Smrg /* Order is important */ 259706f2543Smrg TISAVE(TIDAC_latch_ctrl); 260706f2543Smrg TISAVE(TIDAC_true_color_ctrl); 261706f2543Smrg TISAVE(TIDAC_multiplex_ctrl); 262706f2543Smrg TISAVE(TIDAC_clock_select); 263706f2543Smrg TISAVE(TIDAC_palette_page); 264706f2543Smrg TISAVE(TIDAC_general_ctrl); 265706f2543Smrg TISAVE(TIDAC_misc_ctrl); 266706f2543Smrg /* 0x2A & 0x2B are reserved */ 267706f2543Smrg TISAVE(TIDAC_key_over_low); 268706f2543Smrg TISAVE(TIDAC_key_over_high); 269706f2543Smrg TISAVE(TIDAC_key_red_low); 270706f2543Smrg TISAVE(TIDAC_key_red_high); 271706f2543Smrg TISAVE(TIDAC_key_green_low); 272706f2543Smrg TISAVE(TIDAC_key_green_high); 273706f2543Smrg TISAVE(TIDAC_key_blue_low); 274706f2543Smrg TISAVE(TIDAC_key_blue_high); 275706f2543Smrg TISAVE(TIDAC_key_ctrl); 276706f2543Smrg TISAVE(TIDAC_clock_ctrl); 277706f2543Smrg TISAVE(TIDAC_sense_test); 278706f2543Smrg TISAVE(TIDAC_ind_curs_ctrl); 279706f2543Smrg} 280706f2543Smrg 281706f2543SmrgRamDacHelperRecPtr 282706f2543SmrgTIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs) 283706f2543Smrg{ 284706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 285706f2543Smrg RamDacHelperRecPtr ramdacHelperPtr = NULL; 286706f2543Smrg Bool RamDacIsSupported = FALSE; 287706f2543Smrg int TIramdac_ID = -1; 288706f2543Smrg int i; 289706f2543Smrg unsigned char id, rev, rev2, id2; 290706f2543Smrg 291706f2543Smrg /* read ID and revision */ 292706f2543Smrg rev = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev); 293706f2543Smrg id = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id); 294706f2543Smrg 295706f2543Smrg /* check if ID and revision are read only */ 296706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, TIDAC_rev); 297706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, TIDAC_id); 298706f2543Smrg rev2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev); 299706f2543Smrg id2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id); 300706f2543Smrg 301706f2543Smrg switch (id) { 302706f2543Smrg case TIDAC_TVP_3030_ID: 303706f2543Smrg if (id == id2 && rev == rev2) /* check for READ ONLY */ 304706f2543Smrg TIramdac_ID = TI3030_RAMDAC; 305706f2543Smrg break; 306706f2543Smrg case TIDAC_TVP_3026_ID: 307706f2543Smrg if (id == id2 && rev == rev2) /* check for READ ONLY */ 308706f2543Smrg TIramdac_ID = TI3026_RAMDAC; 309706f2543Smrg break; 310706f2543Smrg } 311706f2543Smrg 312706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, rev, 0, TIDAC_rev); 313706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, id, 0, TIDAC_id); 314706f2543Smrg 315706f2543Smrg if (TIramdac_ID == -1) { 316706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 317706f2543Smrg "Cannot determine TI RAMDAC type, aborting\n"); 318706f2543Smrg return NULL; 319706f2543Smrg } else { 320706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 321706f2543Smrg "Attached RAMDAC is %s\n", TIramdacDeviceInfo[TIramdac_ID&0xFFFF].DeviceName); 322706f2543Smrg } 323706f2543Smrg 324706f2543Smrg for (i=0;ramdacs[i].token != -1;i++) { 325706f2543Smrg if (ramdacs[i].token == TIramdac_ID) 326706f2543Smrg RamDacIsSupported = TRUE; 327706f2543Smrg } 328706f2543Smrg 329706f2543Smrg if (!RamDacIsSupported) { 330706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 331706f2543Smrg "This TI RAMDAC is NOT supported by this driver, aborting\n"); 332706f2543Smrg return NULL; 333706f2543Smrg } 334706f2543Smrg 335706f2543Smrg ramdacHelperPtr = RamDacHelperCreateInfoRec(); 336706f2543Smrg switch (TIramdac_ID) { 337706f2543Smrg case TI3030_RAMDAC: 338706f2543Smrg ramdacHelperPtr->SetBpp = TIramdac3030SetBpp; 339706f2543Smrg ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit; 340706f2543Smrg break; 341706f2543Smrg case TI3026_RAMDAC: 342706f2543Smrg ramdacHelperPtr->SetBpp = TIramdac3026SetBpp; 343706f2543Smrg ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit; 344706f2543Smrg break; 345706f2543Smrg } 346706f2543Smrg ramdacPtr->RamDacType = TIramdac_ID; 347706f2543Smrg ramdacHelperPtr->RamDacType = TIramdac_ID; 348706f2543Smrg ramdacHelperPtr->Save = TIramdacSave; 349706f2543Smrg ramdacHelperPtr->Restore = TIramdacRestore; 350706f2543Smrg 351706f2543Smrg return ramdacHelperPtr; 352706f2543Smrg} 353706f2543Smrg 354706f2543Smrgvoid 355706f2543SmrgTIramdac3026SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg) 356706f2543Smrg{ 357706f2543Smrg switch (pScrn->bitsPerPixel) { 358706f2543Smrg case 32: 359706f2543Smrg /* order is important */ 360706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 361706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46; 362706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5c; 363706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x05; 364706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 365706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10; 366706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C; 367706f2543Smrg /* 0x2A & 0x2B are reserved */ 368706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 369706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 370706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 371706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 372706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 373706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 374706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF; 375706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 376706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10; 377706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 378706f2543Smrg if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 379706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06; 380706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C; 381706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01; 382706f2543Smrg } 383706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 384706f2543Smrg break; 385706f2543Smrg case 24: 386706f2543Smrg /* order is important */ 387706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 388706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56; 389706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58; 390706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x25; 391706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 392706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00; 393706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C; 394706f2543Smrg /* 0x2A & 0x2B are reserved */ 395706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 396706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 397706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 398706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 399706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 400706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 401706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF; 402706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 403706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10; 404706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 405706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 406706f2543Smrg break; 407706f2543Smrg case 16: 408706f2543Smrg /* order is important */ 409706f2543Smrg#if 0 410706f2543Smrg /* Matrox driver uses this */ 411706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07; 412706f2543Smrg#else 413706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 414706f2543Smrg#endif 415706f2543Smrg if (pScrn->depth == 16) { 416706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45; 417706f2543Smrg } else { 418706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44; 419706f2543Smrg } 420706f2543Smrg#if 0 421706f2543Smrg /* Matrox driver uses this */ 422706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50; 423706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x15; 424706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 425706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00; 426706f2543Smrg#else 427706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x54; 428706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x05; 429706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 430706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10; 431706f2543Smrg#endif 432706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C; 433706f2543Smrg /* 0x2A & 0x2B are reserved */ 434706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 435706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 436706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 437706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 438706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 439706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 440706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF; 441706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 442706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10; 443706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 444706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 445706f2543Smrg break; 446706f2543Smrg case 8: 447706f2543Smrg /* order is important */ 448706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 449706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80; 450706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4c; 451706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x05; 452706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 453706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10; 454706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C; 455706f2543Smrg /* 0x2A & 0x2B are reserved */ 456706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 457706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 458706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 459706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 460706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 461706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 462706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00; 463706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 464706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00; 465706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 466706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 467706f2543Smrg break; 468706f2543Smrg } 469706f2543Smrg} 470706f2543Smrg 471706f2543Smrgvoid 472706f2543SmrgTIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg) 473706f2543Smrg{ 474706f2543Smrg switch (pScrn->bitsPerPixel) { 475706f2543Smrg case 32: 476706f2543Smrg /* order is important */ 477706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 478706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46; 479706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5D; 480706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x05; 481706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 482706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10; 483706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C; 484706f2543Smrg /* 0x2A & 0x2B are reserved */ 485706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 486706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 487706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 488706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 489706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 490706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 491706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF; 492706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 493706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10; 494706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 495706f2543Smrg if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 496706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06; 497706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C; 498706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01; 499706f2543Smrg } 500706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 501706f2543Smrg break; 502706f2543Smrg case 24: 503706f2543Smrg /* order is important */ 504706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 505706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56; 506706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58; 507706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x25; 508706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 509706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00; 510706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C; 511706f2543Smrg /* 0x2A & 0x2B are reserved */ 512706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 513706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 514706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 515706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 516706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 517706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 518706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF; 519706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 520706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10; 521706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 522706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 523706f2543Smrg break; 524706f2543Smrg case 16: 525706f2543Smrg /* order is important */ 526706f2543Smrg#if 0 527706f2543Smrg /* Matrox driver uses this */ 528706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07; 529706f2543Smrg#else 530706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 531706f2543Smrg#endif 532706f2543Smrg if (pScrn->depth == 16) { 533706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45; 534706f2543Smrg } else { 535706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44; 536706f2543Smrg } 537706f2543Smrg#if 0 538706f2543Smrg /* Matrox driver uses this */ 539706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50; 540706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x15; 541706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 542706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00; 543706f2543Smrg#else 544706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x55; 545706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x85; 546706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 547706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10; 548706f2543Smrg#endif 549706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C; 550706f2543Smrg /* 0x2A & 0x2B are reserved */ 551706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 552706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 553706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 554706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 555706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 556706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 557706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF; 558706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 559706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10; 560706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 561706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 562706f2543Smrg break; 563706f2543Smrg case 8: 564706f2543Smrg /* order is important */ 565706f2543Smrg ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06; 566706f2543Smrg ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80; 567706f2543Smrg ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4d; 568706f2543Smrg ramdacReg->DacRegs[TIDAC_clock_select] = 0x05; 569706f2543Smrg ramdacReg->DacRegs[TIDAC_palette_page] = 0x00; 570706f2543Smrg ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10; 571706f2543Smrg ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C; 572706f2543Smrg /* 0x2A & 0x2B are reserved */ 573706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF; 574706f2543Smrg ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF; 575706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF; 576706f2543Smrg ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF; 577706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF; 578706f2543Smrg ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF; 579706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00; 580706f2543Smrg ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00; 581706f2543Smrg ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00; 582706f2543Smrg ramdacReg->DacRegs[TIDAC_sense_test] = 0x00; 583706f2543Smrg ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00; 584706f2543Smrg break; 585706f2543Smrg } 586706f2543Smrg} 587706f2543Smrg 588706f2543Smrgstatic void 589706f2543SmrgTIramdacShowCursor(ScrnInfoPtr pScrn) 590706f2543Smrg{ 591706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 592706f2543Smrg 593706f2543Smrg /* Enable cursor - X11 mode */ 594706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x03); 595706f2543Smrg} 596706f2543Smrg 597706f2543Smrgstatic void 598706f2543SmrgTIramdacHideCursor(ScrnInfoPtr pScrn) 599706f2543Smrg{ 600706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 601706f2543Smrg 602706f2543Smrg /* Disable cursor - X11 mode */ 603706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00); 604706f2543Smrg} 605706f2543Smrg 606706f2543Smrgstatic void 607706f2543SmrgTIramdacSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 608706f2543Smrg{ 609706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 610706f2543Smrg 611706f2543Smrg x += 64; 612706f2543Smrg y += 64; 613706f2543Smrg 614706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XLOW, 0, x & 0xff); 615706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XHIGH, 0, (x >> 8) & 0x0f); 616706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YLOW, 0, y & 0xff); 617706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YHIGH, 0, (y >> 8) & 0x0f); 618706f2543Smrg} 619706f2543Smrg 620706f2543Smrgstatic void 621706f2543SmrgTIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 622706f2543Smrg{ 623706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 624706f2543Smrg 625706f2543Smrg /* Background color */ 626706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 1); 627706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x00ff0000) >> 16)); 628706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x0000ff00) >> 8)); 629706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, (bg&0x000000ff) ); 630706f2543Smrg 631706f2543Smrg /* Foreground color */ 632706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 2); 633706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x00ff0000) >> 16)); 634706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x0000ff00) >> 8)); 635706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, (fg&0x000000ff) ); 636706f2543Smrg} 637706f2543Smrg 638706f2543Smrgstatic void 639706f2543SmrgTIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 640706f2543Smrg{ 641706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 642706f2543Smrg int i = 1024; 643706f2543Smrg 644706f2543Smrg /* reset A9,A8 */ 645706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00); 646706f2543Smrg /* reset cursor RAM load address A7..A0 */ 647706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_INDEX, 0x00, 0x00); 648706f2543Smrg 649706f2543Smrg while(i--) { 650706f2543Smrg /* NOT_DONE: might need a delay here */ 651706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++)); 652706f2543Smrg } 653706f2543Smrg} 654706f2543Smrg 655706f2543Smrgstatic Bool 656706f2543SmrgTIramdacUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 657706f2543Smrg{ 658706f2543Smrg return TRUE; 659706f2543Smrg} 660706f2543Smrg 661706f2543Smrgvoid 662706f2543SmrgTIramdacHWCursorInit(xf86CursorInfoPtr infoPtr) 663706f2543Smrg{ 664706f2543Smrg infoPtr->MaxWidth = 64; 665706f2543Smrg infoPtr->MaxHeight = 64; 666706f2543Smrg infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 667706f2543Smrg HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 668706f2543Smrg HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED; 669706f2543Smrg infoPtr->SetCursorColors = TIramdacSetCursorColors; 670706f2543Smrg infoPtr->SetCursorPosition = TIramdacSetCursorPosition; 671706f2543Smrg infoPtr->LoadCursorImage = TIramdacLoadCursorImage; 672706f2543Smrg infoPtr->HideCursor = TIramdacHideCursor; 673706f2543Smrg infoPtr->ShowCursor = TIramdacShowCursor; 674706f2543Smrg infoPtr->UseHWCursor = TIramdacUseHWCursor; 675706f2543Smrg} 676706f2543Smrg 677706f2543Smrgvoid TIramdacLoadPalette( 678706f2543Smrg ScrnInfoPtr pScrn, 679706f2543Smrg int numColors, 680706f2543Smrg int *indices, 681706f2543Smrg LOCO *colors, 682706f2543Smrg VisualPtr pVisual 683706f2543Smrg){ 684706f2543Smrg RamDacRecPtr hwp = RAMDACSCRPTR(pScrn); 685706f2543Smrg int i, index, shift; 686706f2543Smrg 687706f2543Smrg if (pScrn->depth == 16) { 688706f2543Smrg for(i = 0; i < numColors; i++) { 689706f2543Smrg index = indices[i]; 690706f2543Smrg (*hwp->WriteAddress)(pScrn, index << 2); 691706f2543Smrg (*hwp->WriteData)(pScrn, colors[index >> 1].red); 692706f2543Smrg (*hwp->WriteData)(pScrn, colors[index].green); 693706f2543Smrg (*hwp->WriteData)(pScrn, colors[index >> 1].blue); 694706f2543Smrg 695706f2543Smrg if(index <= 31) { 696706f2543Smrg (*hwp->WriteAddress)(pScrn, index << 3); 697706f2543Smrg (*hwp->WriteData)(pScrn, colors[index].red); 698706f2543Smrg (*hwp->WriteData)(pScrn, colors[(index << 1) + 1].green); 699706f2543Smrg (*hwp->WriteData)(pScrn, colors[index].blue); 700706f2543Smrg } 701706f2543Smrg } 702706f2543Smrg} else { 703706f2543Smrg shift = (pScrn->depth == 15) ? 3 : 0; 704706f2543Smrg 705706f2543Smrg for(i = 0; i < numColors; i++) { 706706f2543Smrg index = indices[i]; 707706f2543Smrg (*hwp->WriteAddress)(pScrn, index << shift); 708706f2543Smrg (*hwp->WriteData)(pScrn, colors[index].red); 709706f2543Smrg (*hwp->WriteData)(pScrn, colors[index].green); 710706f2543Smrg (*hwp->WriteData)(pScrn, colors[index].blue); 711706f2543Smrg } 712706f2543Smrg} 713706f2543Smrg} 714706f2543Smrg 715706f2543SmrgTIramdacLoadPaletteProc *TIramdacLoadPaletteWeak(void) { 716706f2543Smrg return TIramdacLoadPalette; 717706f2543Smrg} 718