/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** File name: h3cinit.c ** ** Description: HW-specific initialization routines for Banshee/Avenger. ** ** $Revision: 1.1.1.1 $ ** $Date: 1999/11/24 21:44:53 $ ** ** $History: h3cinit.c $ ** ** ***************** Version 1 ***************** ** User: Sapphire Date: 3/16/99 Time: 7:28p ** Created in $/Releases/Voodoo3/V3_OEM_100/3dfx/devel/H3/cinit ** ** ***************** Version 60 ***************** ** User: Stb_srogers Date: 2/16/99 Time: 4:17p ** Updated in $/devel/h3/win95/dx/minivdd ** ** ***************** Version 59 ***************** ** User: Cwilcox Date: 2/10/99 Time: 6:23p ** Updated in $/devel/h3/Win95/dx/minivdd ** Fixed video initialization to handle tiled mode for low resolutions. ** ** ***************** Version 58 ***************** ** User: Cwilcox Date: 2/10/99 Time: 3:44p ** Updated in $/devel/h3/Win95/dx/minivdd ** Linear versus tiled promotion removal. ** ** ***************** Version 57 ***************** ** User: Andrew Date: 2/07/99 Time: 4:44p ** Updated in $/devel/h3/Win95/dx/minivdd ** Added a check for 2048 and then I make it 2046 so that the mode will ** come up. ** ** ***************** Version 56 ***************** ** User: Jeske Date: 1/15/99 Time: 11:41a ** Updated in $/devel/h3/cinit ** allow setting of only one clock for h3 ** ** ***************** Version 55 ***************** ** User: Michael Date: 1/05/99 Time: 8:44a ** Updated in $/devel/h3/Win95/dx/minivdd ** Implement the 3Dfx/STB unified header. ** ** ***************** Version 54 ***************** ** User: Jeske Date: 12/22/98 Time: 3:25p ** Updated in $/devel/h3/cinit ** added h3InitGetMemSize(), it calculates the memory size and does NOT ** write any registers... ** ** ***************** Version 53 ***************** ** User: Lab Date: 11/13/98 Time: 6:58p ** Updated in $/devel/h4/cinit ** Changed draminit1 for Avenger ** ** ***************** Version 52 ***************** ** User: Pault Date: 11/12/98 Time: 3:46p ** Updated in $/devel/h4/cinit ** Removed Banshee A series silicon support. No more ifdef H3_B0. ** ** ***************** Version 50 ***************** ** User: Pault Date: 11/05/98 Time: 2:04p ** Updated in $/devel/h4/cinit ** Added h4InitPlls function. ** ** ***************** Version 49 ***************** ** User: Jeske Date: 8/18/98 Time: 5:33p ** Updated in $/devel/h3/cinit ** don't change dramInit1 for diags either... this probably should be the ** case for everyone ** ** ***************** Version 48 ***************** ** User: Psmith Date: 7/29/98 Time: 8:22a ** Updated in $/devel/h3/cinit ** prevent memory type from being undefined, default to SGRAM ** ** ***************** Version 47 ***************** ** User: Psmith Date: 7/29/98 Time: 7:42a ** Updated in $/devel/h3/cinit ** added h3InitResetAll() routine to perform a full reset of the chip ** ** ***************** Version 46 ***************** ** User: Andrew Date: 7/27/98 Time: 1:29p ** Updated in $/devel/h3/Win95/dx/minivdd ** Added Scan Line Double Modes ** ** ***************** Version 45 ***************** ** User: Psmith Date: 7/23/98 Time: 5:14p ** Updated in $/devel/h3/cinit ** added initialization of dramInit1_strap for A-series silicon ** ** ***************** Version 44 ***************** ** User: Psmith Date: 7/23/98 Time: 6:14a ** Updated in $/devel/h3/cinit ** updated SDRAM init code to only disable 2d block writes ** ** ***************** Version 43 ***************** ** User: Psmith Date: 7/22/98 Time: 9:11a ** Updated in $/devel/h3/cinit ** added sdram support ** ** ***************** Version 42 ***************** ** User: Mikec Date: 7/20/98 Time: 11:14a ** Updated in $/devel/h3/cinit ** Made H3_A2 default instead of H3_B0. Also added #if H3VDD around ** vidOverlayDudxOffsetSrcWidth. ** ** ***************** Version 41 ***************** ** User: Psmith Date: 7/17/98 Time: 12:32p ** Updated in $/devel/h3/cinit ** updated dramInit1 timing parameters for Gateway ** made sgram vendor lookup case insensitive ** ** ***************** Version 40 ***************** ** User: Ken Date: 7/11/98 Time: 5:51p ** Updated in $/devel/h3/win95/dx/minivdd ** more b0 fixups for gateway ** ** ***************** Version 39 ***************** ** User: Ken Date: 7/10/98 Time: 9:00p ** Updated in $/devel/h3/win95/dx/minivdd ** memory / clock timing default changes. default grxclock and memclock ** timings are now settable at compile time. temporarily, set HR=B0 to ** compile for A2/A3 for minivdd only. dramInit0 is now not touched in ** the win95 init sequence, unless there's an override in the registry ** ** ***************** Version 38 ***************** ** User: Psmith Date: 7/10/98 Time: 5:18p ** Updated in $/devel/h3/cinit ** *** changed default compilation mode to H3_B0 *** ** new sgram config for b0 ** allow env variables to override sgram config values ** ** ***************** Version 37 ***************** ** User: Ken Date: 7/02/98 Time: 6:23p ** Updated in $/devel/h3/win95/dx/minivdd ** added magic parameter values to h3InitSGRAM so that windows boot can ** skip the writing of the SGRAM registers ** ** ***************** Version 36 ***************** ** User: Ken Date: 7/01/98 Time: 6:36p ** Updated in $/devel/h3/win95/dx/minivdd ** added 16bpp low res modes using video overlay stretching ** ** ***************** Version 35 ***************** ** User: Jeske Date: 6/03/98 Time: 1:51p ** Updated in $/devel/h3/cinit ** put h3InitSetVideoMode() back to taking refresh in Hz, documented the ** argument requirements. ** ** ***************** Version 34 ***************** ** User: Ken Date: 6/02/98 Time: 12:27p ** Updated in $/devel/h3/win95/dx/minivdd ** fixed off by one error in LUT initialization ** ** ***************** Version 33 ***************** ** User: Jeske Date: 6/01/98 Time: 5:48p ** Updated in $/devel/h3/cinit ** 1) convert the ordinal refresh mode to a numerical refresh in HZ, 2) ** support failing the video mode set so we can shutdown gracefully.. ** ** ***************** Version 32 ***************** ** User: Psmith Date: 5/09/98 Time: 11:20a ** Updated in $/devel/h3/cinit ** fixed #if's to compile correctly for H3_A2 ** ** ***************** Version 31 ***************** ** User: Psmith Date: 5/08/98 Time: 2:50p ** Updated in $/devel/h3/cinit ** added routine to set BlockWrite threshhold ** ** ***************** Version 30 ***************** ** User: Andrew Date: 5/07/98 Time: 2:42p ** Updated in $/devel/h3/Win95/dx/minivdd ** Added a hack to get 1800x1440 to work in Win '9X. Unknown why display ** pitch needs to be crunched. ** ** ***************** Version 29 ***************** ** User: Peter Date: 4/17/98 Time: 1:24p ** Updated in $/devel/h3/cinit ** 8.3 fun ** ** ***************** Version 28 ***************** ** User: Ken Date: 4/16/98 Time: 5:32p ** Updated in $/devel/h3/win95/dx/minivdd ** properly set the vidProcCfg 1x/2x bit ** ** ***************** Version 27 ***************** ** User: Dow Date: 4/16/98 Time: 12:00p ** Updated in $/devel/h3/cinit ** fixed warnings in h3cinit made warnings=errors for Glide ** ** ***************** Version 26 ***************** ** User: Ken Date: 4/15/98 Time: 6:41p ** Updated in $/devel/h3/win95/dx/minivdd ** added unified header to all files, with revision, etc. info in it ** ** ***************** Version 25 ***************** ** User: Psmith Date: 4/09/98 Time: 8:00p ** Updated in $/devel/h3/cinit ** added support for multiple SGRAM vendors ** added support for programming PLLs a wider range of clock frequencies ** ** ***************** Version 24 ***************** ** User: Psmith Date: 3/30/98 Time: 5:37p ** Updated in $/devel/h3/cinit ** fix for VGA blank with screen off ** ** ***************** Version 23 ***************** ** User: Ken Date: 3/20/98 Time: 11:30a ** Updated in $/devel/h3/win95/dx/minivdd ** removed non-vdd friendly stuff (ifdefed out proces monitor function, ** until its fixed up) ** ** ***************** Version 22 ***************** ** User: Psmith Date: 3/19/98 Time: 8:47p ** Updated in $/devel/h3/cinit ** added code to read/display silicon performance values ** ** ***************** Version 21 ***************** ** User: Ken Date: 3/17/98 Time: 3:55p ** Updated in $/devel/h3/win95/dx/minivdd ** added -DH3_A1 when compiling on A1. changed h3cinit.c so that until ** the non-MS folks add an H3_A0 flag, when not compiling the H3 VDD, the ** absence of H3_A1 automatically defines H3_A0 ** ** ***************** Version 20 ***************** ** User: Ken Date: 3/17/98 Time: 12:07p ** Updated in $/devel/h3/win95/dx/minivdd ** fixed incorrect #ifdef'ing for H3_A0 ** ** ***************** Version 19 ***************** ** User: Ken Date: 3/17/98 Time: 11:21a ** Updated in $/devel/h3/win95/dx/minivdd ** placed A0 workarounds in #ifdef H3_A0. updated makefiles to use ** environment variable HR for hardware rev. if hardware rev is not ** HR=A1, then we build an A0 revision. use #ifdef H3_A0 for A0 ** workarounds ** ** ***************** Version 18 ***************** ** User: Ken Date: 2/15/98 Time: 11:47a ** Updated in $/devel/h3/win95/dx/minivdd ** added parameter to setvideomode to conditionally initialize clut ** ** ***************** Version 17 ***************** ** User: Psmith Date: 2/13/98 Time: 7:38p ** Updated in $/devel/h3/cinit ** added 16Mbit SGRAM support ** ** ***************** Version 16 ***************** ** User: Ken Date: 2/13/98 Time: 4:55p ** Updated in $/devel/h3/win95/dx/minivdd ** added init of tmuGbeInit to turn off texture caching ** ** ***************** Version 15 ***************** ** User: Miriam Date: 2/13/98 Time: 1:17p ** Updated in $/devel/h3/Win95/dx/minivdd ** Can't use texture cache yet. ** ** ***************** Version 14 ***************** ** User: Ken Date: 2/11/98 Time: 8:13p ** Updated in $/devel/h3/win95/dx/minivdd ** updated to latest h3init.pm, fixes 1280 modes ** ** ***************** Version 13 ***************** ** User: Psmith Date: 2/10/98 Time: 7:34p ** Updated in $/devel/h3/cinit ** got rid of monitor click !!! ** ** ***************** Version 12 ***************** ** User: Bangell Date: 2/10/98 Time: 3:50p ** Updated in $/devel/h3/cinit ** allow MEM and GRX clocks to be set to different frequencies ** ** ***************** Version 11 ***************** ** User: Ken Date: 2/09/98 Time: 8:31a ** Updated in $/devel/h3/win95/dx/minivdd ** updated to andy's latest perl code, now has full mode table ** ** ***************** Version 10 ***************** ** User: Ken Date: 2/04/98 Time: 1:29p ** Updated in $/devel/h3/win95/dx/minivdd ** turn off VGA screen refresh in h3initSetVideoMode ** ** ***************** Version 9 ***************** ** User: Ken Date: 1/25/98 Time: 3:08p ** Updated in $/Users/ken/banshee-bringup/directdiags/xor ** added desktop/overlay surface functions ** ** ***************** Version 8 ***************** ** User: Ken Date: 1/25/98 Time: 1:13p ** Updated in $/Users/ken/banshee-bringup/directdiags/xor ** changed h3InitVideo to h3InitVideoProc, now takes a single ** parameter which is simply passed into the vidProcCfg register ** ** ***************** Version 7 ***************** ** User: Ken Date: 1/25/98 Time: 12:27p ** Updated in $/users/ken/banshee-bringup/directdiags/xor ** rollback, new version ** ** ***************** Version 5 ***************** ** User: Ken Date: 1/24/98 Time: 4:41p ** Updated in $/devel/h3/cinit ** works now ** ** ***************** Version 4 ***************** ** User: Dow Date: 1/24/98 Time: 9:11a ** Updated in $/devel/h3/cinit ** WIP ** ** ***************** Version 3 ***************** ** User: Dow Date: 1/23/98 Time: 3:28p ** Updated in $/devel/h3/cinit ** Keywords ** */ #include #include /* 8.3 fun */ #ifdef __DOS32__ #include "h3cini~1.h" #else #include "h3cinitdd.h" #endif // Fixing support for H4 pll tables. #ifdef H4 #include "h4oempll.h" #include "h4pll.h" #else #include "plltable.h" #endif #include "memtable.h" #ifndef H3VDD #include "stdlib.h" #endif // #ifndef H3VDD // LISTEN UP // // The macros used in this file need a varible called regBase. // Because the init registers are aliased both in the io and memory // map, it's up to the caller and the implementor of h3cinitdd.h to // agree on whether you're using the i/o or the memory mapping // /*---------------------------------------------------------------------- Function name: h3InitGetMemSize Description: Return the size of memory in MBs. Information: Return: FxU32 The size of memory in MBs. ----------------------------------------------------------------------*/ FxU32 h3InitGetMemSize(FxU32 regBase) // init io-register base { FxU32 memType, // SGRAM or SDRAM partSize, // size of SGRAM chips in Mbits memSize, // total size of memory in MBytes nChips, // # of chips of SDRAM/SGRAM dramInit1_strap, dramInit0_strap; // determine memory type: SDRAM or SGRAM memType = MEM_TYPE_SGRAM; dramInit1_strap = IGET32(dramInit1); dramInit1_strap &= SST_MCTL_TYPE_SDRAM; if ( dramInit1_strap & SST_MCTL_TYPE_SDRAM ) memType = MEM_TYPE_SDRAM; // determine memory size from strapping pins (dramInit0 and dramInit1) dramInit0_strap = IGET32(dramInit0); dramInit0_strap &= SST_SGRAM_TYPE | SST_SGRAM_NUM_CHIPSETS; if ( memType == MEM_TYPE_SDRAM ) { nChips = 8; partSize = 16; memSize = 16; // avoid minor performance hit when using SDRAM dramInit0_strap &= ~SST_SGRAM_NUM_CHIPSETS; } else { nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8; if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_8MBIT ) { partSize = 8; } else if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_16MBIT) { partSize = 16; } else { MESSAGE("h3InitGetMemSize: invalid sgram type = 0x%x", (dramInit0_strap & SST_SGRAM_TYPE) << SST_SGRAM_TYPE_SHIFT ); return 0; } } memSize = (nChips * partSize) / 8; // in MBytes return (memSize); } /*---------------------------------------------------------------------- Function name: h3InitSgram Description: Initialize the dram registers. Information: Return: FxU32 The size of memory in MBs. ----------------------------------------------------------------------*/ FxU32 // return # of MB of memory h3InitSgram(FxU32 regBase, // init io-register base FxU32 sgramMode, FxU32 sgramMask, FxU32 sgramColor, char *vendorName // NULL or name of sgram vendor ) { FxU32 memType, // SGRAM or SDRAM partSize, // size of SGRAM chips in Mbits memSize, // total size of memory in MBytes nChips, // # chips of SDRAM/SGRAM dramInit0_strap, dramInit1_strap, dramInit0, dramInit1, miscInit1; FxU32 vendorID; // determine memory type: SDRAM or SGRAM memType = MEM_TYPE_SGRAM; dramInit1_strap = IGET32(dramInit1); dramInit1_strap &= SST_MCTL_TYPE_SDRAM; if ( dramInit1_strap & SST_MCTL_TYPE_SDRAM ) memType = MEM_TYPE_SDRAM; // set memory interface delay values and enable refresh // these apply to all RAM vendors dramInit1 = 0x0; dramInit1 |= SST_DRAM_REFRESH_EN; dramInit1 |= (0x18 << SST_DRAM_REFRESH_VALUE_SHIFT) & SST_DRAM_REFRESH_VALUE; dramInit1 |= SST_SGRAM_USE_INV_SAMPLE; dramInit1 |= SST_SGRAM_DEL_CLK_INVERT; dramInit1 |= (8<='a'&&(c)<='z') ? ((c)-'a'+'A') : (c) ) /* only works for alphabetic characters */ int i; char *v, *t; int found; // search table for a vendor/size match for (i=0; i= MEM_TABLE_SIZE ) GDBG_ERROR("h3InitSgram","vendor %s not found, defaulting to %s\n", vendorName, memTable[vendorID].vendor); } GDBG_INFO(80, "h3InitSgram: %d x %d Mbit %s %s parts = %d MBytes\n", nChips, partSize, memTable[vendorID].vendor, memType == MEM_TYPE_SDRAM ? "SDRAM" : "SGRAM", memSize); dramInit0 = memTable[vendorID].dramInit0; // write vendor specific SGRAM timings, preserving the SGRAM chipset/size // information #if !defined(H3VDD) && !defined(DIAG_BUILD) if ( GETENV("SSTH3_DRAMINIT0") ) dramInit0 = strtoul(GETENV("SSTH3_DRAMINIT0"),NULL,0); #endif // #ifndef H3VDD dramInit0 &= ~(SST_SGRAM_TYPE | SST_SGRAM_NUM_CHIPSETS); dramInit0 |= dramInit0_strap; #if !defined(H3VDD) && !defined(DIAG_BUILD) // don't write dramInit0 in the windows driver by default -- we're using // the BIOS's value instead. It can be overridden in the registry // if the user wants to change it or experiment // GDBG_INFO(80, "h3InitSgram: dramInit0 = 0x%x\n",dramInit0); ISET32(dramInit0, dramInit0); #endif // #ifndef H3VDD // Only set the SGRAM registers if the "magic code" isn't sent in. // The windows driver will send in the magic code for the main device // initialization on pre-B0 silicon, because writing to the SGRAM // registers on a soft reboot in certain conditions in pre-B silicon // causes the chip to go nuts, so in those cases we just have to live // with the BIOS defaults for the SGRAM registers. // if (!((sgramMode == 0xDEADBEEF) && (sgramMask == 0xF00DCAFE))) { #ifndef H3VDD sgramMode = memTable[vendorID].sgramMode; if ( GETENV("SSTH3_SGRAMMODE") ) sgramMode = strtoul(GETENV("SSTH3_SGRAMMODE"),NULL,0); #else sgramMode = memTable[vendorID].sgramMode; #endif // #ifndef H3VDD GDBG_INFO(80, "h3InitSgram: sgramMode = 0x%x\n", sgramMode); ISET32(dramData, sgramMode); ISET32(dramCommand, 0x10d); if ( memType == MEM_TYPE_SGRAM ) { // only for SGRAM ISET32(dramData, sgramMask); ISET32(dramCommand, 0x10e); ISET32(dramData, sgramColor); ISET32(dramCommand, 0x10f); } } // // disable block writes for SDRAM // if ( memType == MEM_TYPE_SDRAM ) { miscInit1 = IGET32(miscInit1); miscInit1 |= SST_DISABLE_2D_BLOCK_WRITE; ISET32(miscInit1, miscInit1); } // return # of MBytes of board memory return memSize; } // h3initSgram /*---------------------------------------------------------------------- Function name: h4InitPlls Description: Initialize the Avenger Plls. Information: Return: VOID ----------------------------------------------------------------------*/ #ifdef H4 void h4InitPlls(FxU32 regBase, // init register base FxU32 deviceID, // H4 or H4_OEM FxU32 grxSpeedInMHz) // desired clock frequency (MHz) { FxU32 maxGrxSpeedInMHz; if (deviceID == SST_DEVICE_ID_H4_OEM) { maxGrxSpeedInMHz = MAX_H4_OEM_PLL_FREQ; } else { maxGrxSpeedInMHz = MAX_H4_PLL_FREQ; } // set the graphics clock // if ( grxSpeedInMHz < MIN_PLL_FREQ || grxSpeedInMHz > maxGrxSpeedInMHz ) { MESSAGE("YO! GRX clock speed of %d MHz is out of range MIN_PLL_FREQ to maxGrxSpeedInMHz\n", grxSpeedInMHz); } else { GDBG_INFO(80, "Setting Graphics Clock (%d MHz)\n",grxSpeedInMHz); if (deviceID == SST_DEVICE_ID_H4_OEM) { ISET32(pllCtrl1, h4oempllTable[grxSpeedInMHz]); } else { ISET32(pllCtrl1, h4pllTable[grxSpeedInMHz]); } } } // h4InitPlls #else /*---------------------------------------------------------------------- Function name: h3InitPlls Description: Initialize the Banshee Plls. If you pass in a zero for one of the clock paramater, then that clock is ignored. Thus, you can set only the memory clock by calling h3InitPlls(regbase,0,memClock); Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitPlls(FxU32 regBase, // init iegister base FxU32 grxSpeedInMHz, // desired clock frequency (MHz) FxU32 memSpeedInMHz) // desired clock frequency (MHz) { // set the graphics clock // if ( grxSpeedInMHz < MIN_PLL_FREQ || grxSpeedInMHz > MAX_PLL_FREQ ) { if (grxSpeedInMHz != 0) { MESSAGE("YO! Figure out how to set GRX clock to %d MHz\n", grxSpeedInMHz); } } else { GDBG_INFO(80, "Setting Graphics Clock (%d MHz)\n",grxSpeedInMHz); ISET32(pllCtrl1, pllTable[grxSpeedInMHz]); } // set the memory clock // if ( memSpeedInMHz < MIN_PLL_FREQ || memSpeedInMHz > MAX_PLL_FREQ ) { if (memSpeedInMHz != 0) { MESSAGE("YO! Figure out how to set MEM clock to %d MHz\n", memSpeedInMHz); } } else { GDBG_INFO(80, "Setting Memory Clock (%d MHz)\n",memSpeedInMHz); ISET32(pllCtrl2, pllTable[memSpeedInMHz]); } } // h3InitPlls #endif /*---------------------------------------------------------------------- Function name: h3InitVga Description: Initialize the VGA. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVga( FxU32 regBase, // init iegister base FxU32 legacyDecode) // 1=enable VGA decode, 0=disable { FxU32 vgaInit0 = 0, miscInit1; vgaInit0 |= SST_VGA0_EXTENSIONS; vgaInit0 |= SST_WAKEUP_3C3 << SST_VGA0_WAKEUP_SELECT_SHIFT; if (legacyDecode) vgaInit0 |= SST_VGA0_ENABLE_DECODE << SST_VGA0_LEGACY_DECODE_SHIFT; else vgaInit0 |= SST_VGA0_DISABLE_DECODE << SST_VGA0_LEGACY_DECODE_SHIFT; vgaInit0 |= SST_ENABLE_ALT_READBACK << SST_VGA0_CONFIG_READBACK_SHIFT; CHECKFORROOM; ISET32(vgaInit0, vgaInit0); GDBG_INFO(80, "disable VESA mode and VGA VIDEO lock bits\n"); CHECKFORROOM; ISET32(vgaInit1, 0); CHECKFORROOM; ISET8PHYS(0xc3, 0x1); GDBG_INFO(80, "Cleared CLUT Invert Address\n"); miscInit1 = IGET32(miscInit1); miscInit1 |= BIT(0); CHECKFORROOM; ISET32(miscInit1, miscInit1); } // h3InitVga /*---------------------------------------------------------------------- Function name: h3InitVideoProc Description: Initialize the Video portion of the HW. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVideoProc(FxU32 regBase, FxU32 vidProcCfg) // control bits for video processor { ISET32(vidProcCfg, vidProcCfg); } // h3InitVideo FxU16 mode_table[][24] = { #include "modetabl.h" {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; FxU8 vgaattr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x00}; /*---------------------------------------------------------------------- Function name: h3InitFindVideoMode Description: Find the video mode in the mode table based on the xRes, yRes, and refresh rate. Information: Return: (FxU16 *) Ptr to the entry in the mode table, NULL if failure. ----------------------------------------------------------------------*/ FxU16 * h3InitFindVideoMode(FxU32 xRes, FxU32 yRes, FxU32 refresh) { int i = 0; while (mode_table[i][0] != 0) { if ((mode_table[i][0] == xRes) && (mode_table[i][1] == yRes) && (mode_table[i][2] == refresh)) { return &mode_table[i][3]; } i += 1; } return NULL; } /*---------------------------------------------------------------------- Function name: h3InitSetVideoMode Description: Set the video mode. Information: Return: FxBool FXTRUE if success or, FXFALSE if failure. ----------------------------------------------------------------------*/ FxBool h3InitSetVideoMode( FxU32 regBase, // regBase of this card FxU32 xRes, // xResolution in pixels FxU32 yRes, // yResolution in pixels FxU32 refresh, // refresh rate in Hz #if defined(H3VDD) FxU32 loadClut, // really a bool, should we load the lookup table FxU32 scanlinedouble) // set scanline double bit and double y? #else FxU32 loadClut) // really a bool, should we load the lookup table #endif { FxU16 i, j; FxU8 garbage; FxU16 *rs = h3InitFindVideoMode(xRes, yRes, refresh); FxU32 vidProcCfg; if (rs == NULL) { GDBG_ERROR("h3InitSetVideoMode", "mode %d x %d @ %dHz is not supported\n", xRes, yRes, refresh); return FXFALSE; } GDBG_INFO(1, "h3InitSetVideoMode(%d, %d, %d)\n", xRes, yRes, refresh); // // MISC REGISTERS // This register gets programmed first since the Mono/ Color // selection needs to be made. // // Sync polarities // Also force the programmable clock to be used with bits 3&2 // ISET8PHYS(0xc2, rs[16] | BIT(0)); // // CRTC REGISTERS // First Unlock CRTC, then program them // // Mystical VGA Magic ISET16PHYS(0x0d4, 0x11); ISET16PHYS(0x0d4, (rs[0] << 8) | 0x00); ISET16PHYS(0x0d4, (rs[1] << 8) | 0x01); ISET16PHYS(0x0d4, (rs[2] << 8) | 0x02); ISET16PHYS(0x0d4, (rs[3] << 8) | 0x03); ISET16PHYS(0x0d4, (rs[4] << 8) | 0x04); #ifdef H3_A0 // // The problem with 800x600 is due to a // synthesis bug (which A1 does not have) // if (rs[14] & 0x80) { ISET16PHYS(0xd4, ((rs[5] & 0xe0) << 8) | 0x05); } else { ISET16PHYS(0x0d4, (rs[5] << 8) | 0x05); } #else // #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[5] << 8) | 0x05); #endif // #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[6] << 8) | 0x06); ISET16PHYS(0x0d4, (rs[7] << 8) | 0x07); ISET16PHYS(0x0d4, (rs[8] << 8) | 0x09); ISET16PHYS(0x0d4, (rs[9] << 8) | 0x10); ISET16PHYS(0x0d4, (rs[10] << 8) | 0x11); ISET16PHYS(0x0d4, (rs[11] << 8) | 0x12); ISET16PHYS(0x0d4, (rs[12] << 8) | 0x15); ISET16PHYS(0x0d4, (rs[13] << 8) | 0x16); #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[14] << 8) | 0x101a); ISET16PHYS(0x0d4, (rs[15] << 8) | 0x101b); #else // #ifdef H3_A0 ISET16PHYS(0x0d4, (rs[14] << 8) | 0x1a); ISET16PHYS(0x0d4, (rs[15] << 8) | 0x1b); #endif // #ifdef H3_A0 // // Enable Sync Outputs // ISET16PHYS(0x0d4, (0x80 << 8) | 0x17); // // VIDCLK (32 bit access only!) // Set the Video Clock to the correct frequency // ISET32(pllCtrl0, (rs[19] << 8) | rs[18]); // // dacMode (32 bit access only!) // (sets up 1x mode or 2x mode) // ISET32(dacMode, rs[20]); // // the 1x / 2x bit must also be set in vidProcConfig to properly // enable 1x / 2x mode // vidProcCfg = IGET32(vidProcCfg); vidProcCfg &= ~(SST_VIDEO_2X_MODE_EN | SST_HALF_MODE); if (rs[20]) vidProcCfg |= SST_VIDEO_2X_MODE_EN; #if defined(H3VDD) if (scanlinedouble) vidProcCfg |= SST_HALF_MODE; #endif ISET32(vidProcCfg, vidProcCfg); // // SEQ REGISTERS // set run mode in the sequencer (not reset) // // make sure bit 5 == 0 (i.e., screen on) // ISET16PHYS(0x0c4, ((rs[17] & ((FxU16) ~BIT(5))) << 8) | 0x1 ); ISET16PHYS(0x0c4, ( 0x3 << 8) | 0x0 ); // // turn off VGA's screen refresh, as this function only sets extended // video modes, and the VGA screen refresh eats up performance // (10% difference in screen to screen blits!). This code is not in // the perl, but should stay here unless specifically decided otherwise // ISET32(vgaInit0, IGET32(vgaInit0)|BIT(12) ); // // Make sure attribute index register is initialized // garbage = IGET8PHYS(0x0da); // return value not used for (i = 0; i <= 19; i++) { ISET8PHYS(0xc0, i); ISET8PHYS(0xc0, vgaattr[i]); } ISET8PHYS(0xc0, 0x34); ISET8PHYS(0xda, 0); // // Initialize VIDEO res & proc mode info... // #if defined(H3VDD) if (scanlinedouble) ISET32( vidScreenSize, (yRes << 13) | (xRes & 0xfff)); else { if (2048 == xRes) ISET32( vidScreenSize, (yRes << 12) | ((xRes - 2) & 0xfff)); else ISET32( vidScreenSize, (yRes << 12) | (xRes & 0xfff)); } #else ISET32( vidScreenSize, (yRes << 12) | (xRes & 0xfff)); #endif ISET32(vidOverlayStartCoords, 0); // I think "xFixRes" is obsolete since we're not supporting 1800 // modes (only 1792 or 1808), so I won't use it here. -KMW // ISET32(vidOverlayEndScreenCoord, (((yRes - 1) << 12) | ((xRes - 1) & 0xfff))); // // Load CLUTs with an inverted ramp (undo inversion with new hardware!) // // Put in another routines. // if (loadClut) { for( i=0; i <= 0x1ff; i++) { ISET32( dacAddr, i); // assumes CLUT Invert Address, // miscInit1[0], is set IGET32(dacAddr); j = i & 0xff; #ifdef H3_A0 ISET32(dacData, ~((j<<16) | (j<<8) | j)); #else // #ifdef H3_A0 ISET32(dacData, (j<<16) | (j<<8) | j); #endif // #ifdef H3_A0 IGET32(dacData); } } return FXTRUE; /* success! */ } // h3InitSetVideoMode /*---------------------------------------------------------------------- Function name: h3InitVideoDesktopSurface Description: Set the width/height/start address/stride (position, stretch, filter, etc. for overlay) parameters of these surfaces. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVideoDesktopSurface( FxU32 regBase, FxU32 enable, // 1=enable desktop surface (DS), 1=disable FxU32 tiled, // 0=DS linear, 1=tiled FxU32 pixFmt, // pixel format of DS FxU32 clutBypass, // bypass clut for DS? FxU32 clutSelect, // 0=lower 256 CLUT entries, 1=upper 256 FxU32 startAddress, // board address of beginning of DS FxU32 stride) // distance between scanlines of the DS, in // units of bytes for linear DS's and tiles for // tiled DS's { FxU32 doStride; FxU32 vidProcCfg = IGET32(vidProcCfg); vidProcCfg &= ~ (SST_DESKTOP_EN | SST_DESKTOP_TILED_EN | SST_DESKTOP_PIXEL_FORMAT | SST_DESKTOP_CLUT_BYPASS | SST_DESKTOP_CLUT_SELECT ); if (enable) vidProcCfg |= SST_DESKTOP_EN; if (tiled) vidProcCfg |= SST_DESKTOP_TILED_EN; vidProcCfg |= pixFmt; if (clutBypass) vidProcCfg |= SST_DESKTOP_CLUT_BYPASS; if (clutSelect) vidProcCfg |= SST_DESKTOP_CLUT_SELECT; ISET32(vidProcCfg, vidProcCfg); ISET32(vidDesktopStartAddr, (startAddress & SST_VIDEO_START_ADDR) << SST_VIDEO_START_ADDR_SHIFT); // change only the desktop portion of the vidDesktopOverlayStride register // doStride = IGET32(vidDesktopOverlayStride); doStride &= ~(SST_DESKTOP_LINEAR_STRIDE | SST_DESKTOP_TILE_STRIDE); stride <<= SST_DESKTOP_STRIDE_SHIFT; if (tiled) stride &= SST_DESKTOP_TILE_STRIDE; else stride &= SST_DESKTOP_LINEAR_STRIDE; doStride |= stride; ISET32(vidDesktopOverlayStride, doStride); } /*---------------------------------------------------------------------- Function name: h3InitVideoOverlaySurface Description: Initialize the video overlay surface. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitVideoOverlaySurface( FxU32 regBase, FxU32 enable, // 1=enable Overlay surface (OS), 1=disable FxU32 stereo, // 1=enable OS stereo, 0=disable FxU32 horizScaling, // 1=enable horizontal scaling, 0=disable FxU32 dudx, // horizontal scale factor (ignored if not // scaling) FxU32 verticalScaling, // 1=enable vertical scaling, 0=disable FxU32 dvdy, // vertical scale factor (ignored if not // scaling) FxU32 filterMode, // duh FxU32 tiled, // 0=OS linear, 1=tiled FxU32 pixFmt, // pixel format of OS FxU32 clutBypass, // bypass clut for OS? FxU32 clutSelect, // 0=lower 256 CLUT entries, 1=upper 256 FxU32 startAddress, // board address of beginning of OS FxU32 stride) // distance between scanlines of the OS, in // units of bytes for linear OS's and tiles for // tiled OS's { FxU32 doStride; FxU32 vidProcCfg = IGET32(vidProcCfg); vidProcCfg &= ~(SST_OVERLAY_TILED_EN | SST_OVERLAY_STEREO_EN | SST_OVERLAY_HORIZ_SCALE_EN | SST_OVERLAY_VERT_SCALE_EN | SST_OVERLAY_TILED_EN | SST_OVERLAY_PIXEL_FORMAT | SST_OVERLAY_CLUT_BYPASS | SST_OVERLAY_CLUT_SELECT); if (enable) vidProcCfg |= SST_OVERLAY_EN; if (stereo) vidProcCfg |= SST_OVERLAY_STEREO_EN; if (horizScaling) vidProcCfg |= SST_OVERLAY_HORIZ_SCALE_EN; if (verticalScaling) vidProcCfg |= SST_OVERLAY_VERT_SCALE_EN; if (tiled) vidProcCfg |= SST_OVERLAY_TILED_EN; vidProcCfg |= pixFmt; if (clutBypass) vidProcCfg |= SST_OVERLAY_CLUT_BYPASS; if (clutSelect) vidProcCfg |= SST_OVERLAY_CLUT_SELECT; if (horizScaling) { vidProcCfg |= SST_OVERLAY_HORIZ_SCALE_EN; ISET32(vidOverlayDudx, dudx); } #ifdef H3VDD if (tiled) { ISET32(vidOverlayDudxOffsetSrcWidth, (0 | ((stride << 7) << SST_OVERLAY_FETCH_SIZE_SHIFT))); } else { ISET32(vidOverlayDudxOffsetSrcWidth, (0 | (stride << SST_OVERLAY_FETCH_SIZE_SHIFT))); } #endif if (verticalScaling) { vidProcCfg |= SST_OVERLAY_VERT_SCALE_EN; ISET32(vidOverlayDvdy, dvdy); ISET32(vidOverlayDvdyOffset, 0); } ISET32(vidProcCfg, vidProcCfg); // change only the overlay portion of the vidDesktopOverlayStride register // doStride = IGET32(vidDesktopOverlayStride); doStride &= ~(SST_OVERLAY_LINEAR_STRIDE | SST_OVERLAY_TILE_STRIDE); stride <<= SST_OVERLAY_STRIDE_SHIFT; if (tiled) stride &= SST_OVERLAY_TILE_STRIDE; else stride &= SST_OVERLAY_LINEAR_STRIDE; doStride |= stride; ISET32(vidDesktopOverlayStride, doStride); // must set the overlay start address! } /*---------------------------------------------------------------------- Function name: h3InitMeasureSiProcess Description: Read and display to the debug output device the performance monitor values. Information: Return: VOID ----------------------------------------------------------------------*/ #ifndef H3VDD // // read and display performance monitor values // void h3InitMeasureSiProcess(FxU32 regBase) // init register base { FxU32 siProcess, nandOsc, norOsc; FxU32 pciCntrLoad = 0xfff; if(GETENV("SSTH3_SIPROCESS_CNTR")) { pciCntrLoad = strtoul(GETENV("SSTH3_SIPROCESS_CNTR"),NULL,0); GDBG_INFO(1,"h3InitMeasureSiProcess(): Using PCI Counter preload value of 0x%x...\n", pciCntrLoad); } //////////////////////////////// // Test NAND oscillator tree... //////////////////////////////// ISET32(sipMonitor, (pciCntrLoad<>SST_BLOCK_WRITE_THRESH_SHIFT); } /*---------------------------------------------------------------------- Function name: h3InitResetAll Description: Perform a full HW reset. Information: Return: VOID ----------------------------------------------------------------------*/ void h3InitResetAll( FxU32 regBase) // init register base address { FxU32 miscInit0 = IGET32(miscInit0); FxU32 miscInit1 = IGET32(miscInit1); GDBG_INFO(80, "h3InitResetAll: initiating reset\n"); ISET32(miscInit1, miscInit1 | SST_CMDSTREAM_RESET); ISET32(miscInit0, miscInit0 | (SST_GRX_RESET | SST_FBI_FIFO_RESET | SST_VIDEO_RESET | SST_2D_RESET | SST_MEMORY_TIMING_RESET | SST_VGA_TIMING_RESET) ); ISET32(miscInit0, miscInit0 & ~(SST_GRX_RESET | SST_FBI_FIFO_RESET | SST_VIDEO_RESET | SST_2D_RESET | SST_MEMORY_TIMING_RESET | SST_VGA_TIMING_RESET) ); ISET32(miscInit1, miscInit1 & ~SST_CMDSTREAM_RESET); GDBG_INFO(80, "h3InitResetAll: reset completed\n"); }