1dfe64dd3Smacallan/* 2dfe64dd3Smacallan * Basic hardware and memory detection 3dfe64dd3Smacallan * 4dfe64dd3Smacallan * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria. 5dfe64dd3Smacallan * 6dfe64dd3Smacallan * Redistribution and use in source and binary forms, with or without 7dfe64dd3Smacallan * modification, are permitted provided that the following conditions 8dfe64dd3Smacallan * are met: 9dfe64dd3Smacallan * 1) Redistributions of source code must retain the above copyright 10dfe64dd3Smacallan * notice, this list of conditions and the following disclaimer. 11dfe64dd3Smacallan * 2) Redistributions in binary form must reproduce the above copyright 12dfe64dd3Smacallan * notice, this list of conditions and the following disclaimer in the 13dfe64dd3Smacallan * documentation and/or other materials provided with the distribution. 14dfe64dd3Smacallan * 3) The name of the author may not be used to endorse or promote products 15dfe64dd3Smacallan * derived from this software without specific prior written permission. 16dfe64dd3Smacallan * 17dfe64dd3Smacallan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR 18dfe64dd3Smacallan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19dfe64dd3Smacallan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20dfe64dd3Smacallan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21dfe64dd3Smacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22dfe64dd3Smacallan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23dfe64dd3Smacallan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24dfe64dd3Smacallan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25dfe64dd3Smacallan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26dfe64dd3Smacallan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27dfe64dd3Smacallan * 28dfe64dd3Smacallan * Author: Thomas Winischhofer <thomas@winischhofer.net> 29dfe64dd3Smacallan * 30dfe64dd3Smacallan * Ideas and methods for old series based on code by Can-Ru Yeou, XGI Inc. 31dfe64dd3Smacallan * 32dfe64dd3Smacallan */ 33dfe64dd3Smacallan 34dfe64dd3Smacallan#ifdef HAVE_CONFIG_H 35dfe64dd3Smacallan#include "config.h" 36dfe64dd3Smacallan#endif 37dfe64dd3Smacallan 38dfe64dd3Smacallan#include "xf86PciInfo.h" 39dfe64dd3Smacallan#include "xf86Pci.h" 40dfe64dd3Smacallan#include "xf86.h" 41dfe64dd3Smacallan#include "fb.h" 42dfe64dd3Smacallan#include "xf86_OSproc.h" 43dfe64dd3Smacallan#include "xorgVersion.h" 44dfe64dd3Smacallan 45dfe64dd3Smacallan#include "xf86cmap.h" 46dfe64dd3Smacallan 47dfe64dd3Smacallan#include "xgi.h" 48dfe64dd3Smacallan#include "xgi_regs.h" 49dfe64dd3Smacallan#include "xgi_dac.h" 50098ad5bdSmacallan#include "xgi_driver.h" 51dfe64dd3Smacallan/* #include "valid_mode.h" */ 52dfe64dd3Smacallan 53dfe64dd3Smacallan#define _XF86DGA_SERVER_ 54098ad5bdSmacallan#include <X11/extensions/xf86dgaproto.h> 55dfe64dd3Smacallan 56dfe64dd3Smacallan#include "globals.h" 57dfe64dd3Smacallan#ifdef HAVE_XEXTPROTO_71 58dfe64dd3Smacallan#include <X11/extensions/dpmsconst.h> 59dfe64dd3Smacallan#else 60dfe64dd3Smacallan#define DPMS_SERVER 61dfe64dd3Smacallan#include <X11/extensions/dpms.h> 62dfe64dd3Smacallan#endif 63dfe64dd3Smacallan 64dfe64dd3Smacallan 65dfe64dd3Smacallan#include "vb_def.h" 66dfe64dd3Smacallanextern int FbDevExist; 67dfe64dd3Smacallan 68dfe64dd3Smacallanstatic Bool bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset, 69098ad5bdSmacallan ULONG ulSet, CARD32 *pulValue); 70dfe64dd3Smacallanstatic Bool bAccessNBridgePCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, 71dfe64dd3Smacallan ULONG ulOffset, ULONG ulSet, ULONG *pulValue); 72dfe64dd3Smacallanstatic Bool XGI_IsXG21(ScrnInfoPtr pScrn); 73dfe64dd3Smacallan 74dfe64dd3Smacallanstatic void XGI_InitHwDevInfo(ScrnInfoPtr pScrn); 75dfe64dd3Smacallan 76dfe64dd3Smacallan/* Jong 10/16/2007; merge code */ 77dfe64dd3Smacallanstatic void 78dfe64dd3SmacallanxgiXG2X_Setup(ScrnInfoPtr pScrn) 79dfe64dd3Smacallan{ 80dfe64dd3Smacallan 81dfe64dd3Smacallan/********************************************************************* 82dfe64dd3Smacallan * Setup 83dfe64dd3Smacallan * Decide the following item of execution data: 84dfe64dd3Smacallan * 85dfe64dd3Smacallan * pXGI->BusWidth 86dfe64dd3Smacallan * pXGI->videoRam (with KB unit) 87dfe64dd3Smacallan * pXGI->CursorOffset (with Byte Unit) 88dfe64dd3Smacallan * pXGI->cmdQueueSize (with Byte Unit) 89dfe64dd3Smacallan * pXGI->cmdQueueSizeMask (with Byte Unit) 90dfe64dd3Smacallan * pXGI->cmdQueueOffset (with Byte Unit) 91dfe64dd3Smacallan * pXGI->cmdQueueLen = 0 ; // init value 92dfe64dd3Smacallan * pXGI->cmdQueueLenMin = 0x200 ; // init value 93dfe64dd3Smacallan * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ; 94dfe64dd3Smacallan *********************************************************************/ 95dfe64dd3Smacallan 96dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 97dfe64dd3Smacallan unsigned int ulMemConfig = 0; 98dfe64dd3Smacallan unsigned long ulMemSize = 0; 99dfe64dd3Smacallan unsigned long ulDramType = 0; 100dfe64dd3Smacallan char *dramTypeStr ; 101dfe64dd3Smacallan unsigned long ulTemp ; 102dfe64dd3Smacallan 103dfe64dd3Smacallan /* DumpDDIName("xgiXG2X_Setup()\n") ; */ 104dfe64dd3Smacallan 105dfe64dd3Smacallan inXGIIDXREG(XGICR, 0x48, ulTemp) ; 106dfe64dd3Smacallan if(ulTemp & (1<<0)) /* GPIOH, CR48 D[0] read */ 107dfe64dd3Smacallan { 108dfe64dd3Smacallan dramTypeStr = "DDRII DRAM" ; 109dfe64dd3Smacallan } 110dfe64dd3Smacallan else 111dfe64dd3Smacallan { 112dfe64dd3Smacallan dramTypeStr = "DDR DRAM" ; 113dfe64dd3Smacallan } 114dfe64dd3Smacallan 115dfe64dd3Smacallan 116dfe64dd3Smacallan pXGI->MemClock = XG40Mclk(pXGI); 117dfe64dd3Smacallan 118dfe64dd3Smacallan /********************************************************************************************************* 119dfe64dd3Smacallan * SR14 DRAM Size Register 120dfe64dd3Smacallan * Default value: XXh 121dfe64dd3Smacallan * D[7:4] Memory size per channel {BChMemSize} 122dfe64dd3Smacallan * 0011: 8 MB 123dfe64dd3Smacallan * 0100: 16 MB 124dfe64dd3Smacallan * 0101: 32 MB 125dfe64dd3Smacallan * 0110: 64 MB 126dfe64dd3Smacallan * 0111: 128 MB 127dfe64dd3Smacallan * 1000: 256MB 128dfe64dd3Smacallan * others: reserved 129dfe64dd3Smacallan * D[3:2] Number of dram channels [1:0] {BChNum} 130dfe64dd3Smacallan * 00: uni-channel 131dfe64dd3Smacallan * 01: reserved 132dfe64dd3Smacallan * 10: dual-channel. 133dfe64dd3Smacallan * 11: quad-channel 134dfe64dd3Smacallan * D1 Data width per channel selection {BDataWidth} 135dfe64dd3Smacallan * 0: 32-bits 136dfe64dd3Smacallan * 1: 64-bits 137dfe64dd3Smacallan * D0 Dram channel mapping {BReverseChMapping} 138dfe64dd3Smacallan * 0: Normal mapping 139dfe64dd3Smacallan * 1: Reversal mapping 140dfe64dd3Smacallan * Dual-channel: Logical channel A/B to physical channel B/A 141dfe64dd3Smacallan * Quad-channel: Logical channel A/B/C/D to physical channel C/D/A/B 142dfe64dd3Smacallan * 143dfe64dd3Smacallan *********************************************************************************************************/ 144dfe64dd3Smacallan 145dfe64dd3Smacallan outXGIIDXREG(XGISR, 0x5, 0x86) ; 146dfe64dd3Smacallan inXGIIDXREG(XGISR, 0x14, ulMemConfig) ; 147dfe64dd3Smacallan inXGIIDXREG(XGISR, 0x3A, ulDramType) ; 148dfe64dd3Smacallan 149dfe64dd3Smacallan PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ; 150dfe64dd3Smacallan PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ; 151dfe64dd3Smacallan 152dfe64dd3Smacallan pXGI->BusWidth = (ulMemConfig & (1<<1) )?64:32 ; 153dfe64dd3Smacallan 154dfe64dd3Smacallan switch(ulMemConfig>>4) 155dfe64dd3Smacallan { 156dfe64dd3Smacallan case 8: 157dfe64dd3Smacallan ulMemSize = 256*1024 ; 158dfe64dd3Smacallan break ; 159dfe64dd3Smacallan case 7: 160dfe64dd3Smacallan ulMemSize = 128*1024 ; 161dfe64dd3Smacallan break ; 162dfe64dd3Smacallan case 6: 163dfe64dd3Smacallan ulMemSize = 64*1024 ; 164dfe64dd3Smacallan break ; 165dfe64dd3Smacallan case 5: 166dfe64dd3Smacallan ulMemSize = 32*1024 ; 167dfe64dd3Smacallan break ; 168dfe64dd3Smacallan case 4: 169dfe64dd3Smacallan ulMemSize = 16*1024 ; 170dfe64dd3Smacallan break ; 171dfe64dd3Smacallan case 3: 172dfe64dd3Smacallan ulMemSize = 8*1024 ; 173dfe64dd3Smacallan break ; 174dfe64dd3Smacallan default: 175dfe64dd3Smacallan ulMemSize = 8*1024 ; 176dfe64dd3Smacallan } 177dfe64dd3Smacallan 178dfe64dd3Smacallan if (pXGI->Chipset == PCI_CHIP_XGIXG40) { 179dfe64dd3Smacallan const unsigned revision = 180dfe64dd3Smacallan#ifdef XSERVER_LIBPCIACCESS 181dfe64dd3Smacallan pXGI->PciInfo->revision 182dfe64dd3Smacallan#else 183dfe64dd3Smacallan pciReadLong(pXGI->PciTag, 0x08) & 0x0FF 184dfe64dd3Smacallan#endif 185dfe64dd3Smacallan ; 186dfe64dd3Smacallan 187dfe64dd3Smacallan /* Revision 2 cards encode the memory config bits slightly differently 188dfe64dd3Smacallan * from revision 1 cards. 189dfe64dd3Smacallan */ 190dfe64dd3Smacallan if (revision == 2) { 191dfe64dd3Smacallan switch((ulMemConfig>>2)&0x1) 192dfe64dd3Smacallan { 193dfe64dd3Smacallan case 0: 194dfe64dd3Smacallan /* Uni channel */ 195dfe64dd3Smacallan ulMemSize *= 1 ; 196dfe64dd3Smacallan break ; 197dfe64dd3Smacallan case 1: 198dfe64dd3Smacallan /* Dual channel */ 199dfe64dd3Smacallan ulMemSize *= 2 ; 200dfe64dd3Smacallan break ; 201dfe64dd3Smacallan } 202dfe64dd3Smacallan } 203dfe64dd3Smacallan else 204dfe64dd3Smacallan { 205dfe64dd3Smacallan switch((ulMemConfig>>2)&0x3) 206dfe64dd3Smacallan { 207dfe64dd3Smacallan case 2: 208dfe64dd3Smacallan /* Dual channel */ 209dfe64dd3Smacallan ulMemSize *= 2 ; 210dfe64dd3Smacallan break ; 211dfe64dd3Smacallan case 3: 212dfe64dd3Smacallan /* Quad channel */ 213dfe64dd3Smacallan ulMemSize *= 4 ; 214dfe64dd3Smacallan break ; 215dfe64dd3Smacallan } 216dfe64dd3Smacallan } 217dfe64dd3Smacallan } 218dfe64dd3Smacallan 219dfe64dd3Smacallan pScrn->videoRam = ulMemSize ; 220dfe64dd3Smacallan 221dfe64dd3Smacallan /********************************************************************************************************* 222dfe64dd3Smacallan * SR15 DRAM Address Mapping Register 223dfe64dd3Smacallan * Default value: XXh 224dfe64dd3Smacallan * D7 Channel interleaving configuration { BChConfig } 225dfe64dd3Smacallan * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel 226dfe64dd3Smacallan * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region 227dfe64dd3Smacallan * will be channel-interleaved as per BFineGranSize; the high-address region will be channel- 228dfe64dd3Smacallan * interleaved as per BCoarseGranSize[1:0] 229dfe64dd3Smacallan * D[6:5] Memory size of tile-mapped region {BTilingSize} 230dfe64dd3Smacallan * 00: 4 MB 231dfe64dd3Smacallan * 01: 8 MB 232dfe64dd3Smacallan * 10: 16 MB 233dfe64dd3Smacallan * 11: 32 MB 234dfe64dd3Smacallan * The following bits are effective only when D7=1 235dfe64dd3Smacallan * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize} 236dfe64dd3Smacallan * 0: 64 B 237dfe64dd3Smacallan * 1: 128 B 238dfe64dd3Smacallan * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize} 239dfe64dd3Smacallan * 00: 1KB 240dfe64dd3Smacallan * 01: 2KB 241dfe64dd3Smacallan * 10: 4KB 242dfe64dd3Smacallan * 11: 1MB 243dfe64dd3Smacallan * D[1:0] reserved 244dfe64dd3Smacallan *********************************************************************************************************/ 245dfe64dd3Smacallan 246dfe64dd3Smacallan /* Accelerator parameter Initialization */ 247dfe64dd3Smacallan if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) 248dfe64dd3Smacallan { 249dfe64dd3Smacallan pXGI->cmdQueueSize = VOLARI_CQSIZEXG20; 250dfe64dd3Smacallan /* XgiMode = XG20_Mode ; */ 251dfe64dd3Smacallan PDEBUG(ErrorF(" ---XG20_Mode \n")); 252dfe64dd3Smacallan } 253dfe64dd3Smacallan 254dfe64dd3Smacallan 255dfe64dd3Smacallan pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ; 256dfe64dd3Smacallan pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D); 257dfe64dd3Smacallan 258dfe64dd3Smacallan 259dfe64dd3Smacallan /* 260dfe64dd3Smacallan If FbDevExist, XFree86 driver use the 8MB only. The rest 261dfe64dd3Smacallan frame buffer is used by other AP. 262dfe64dd3Smacallan */ 263dfe64dd3Smacallan 264dfe64dd3Smacallan if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) ) 265dfe64dd3Smacallan { 266dfe64dd3Smacallan if( pScrn->videoRam < 8*1024 ) 267dfe64dd3Smacallan { 268dfe64dd3Smacallan pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ; 269dfe64dd3Smacallan } 270dfe64dd3Smacallan else if( pScrn->videoRam < 16*1024 ) 271dfe64dd3Smacallan { 272dfe64dd3Smacallan pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ; 273dfe64dd3Smacallan } 274dfe64dd3Smacallan else 275dfe64dd3Smacallan { 276dfe64dd3Smacallan pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ; 277dfe64dd3Smacallan } 278dfe64dd3Smacallan } 279dfe64dd3Smacallan else 280dfe64dd3Smacallan { 281dfe64dd3Smacallan pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ; 282dfe64dd3Smacallan } 283dfe64dd3Smacallan 284dfe64dd3Smacallan pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024 ; 285dfe64dd3Smacallan PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n", 286dfe64dd3Smacallan pScrn->videoRam, pXGI->cmdQueueSize)) ; 287dfe64dd3Smacallan PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n", 288dfe64dd3Smacallan pXGI->cmdQueueOffset, pXGI->CursorOffset)) ; 289dfe64dd3Smacallan 290dfe64dd3Smacallan pXGI->cmdQueueLen = 0 ; 291dfe64dd3Smacallan pXGI->cmdQueueLenMin = 0x200 ; 292dfe64dd3Smacallan pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ; 293dfe64dd3Smacallan 294dfe64dd3Smacallan /***************************************************************** 295dfe64dd3Smacallan * Dual Chip support put here * 296dfe64dd3Smacallan *****************************************************************/ 297dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 298dfe64dd3Smacallan "Detected DRAM type : %s\n", dramTypeStr); 299dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 300dfe64dd3Smacallan "Detected memory clock : %3.3fMHz\n", 301dfe64dd3Smacallan pXGI->MemClock/1000.0); 302dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 303dfe64dd3Smacallan "Detected VRAM bus width is %d\n", pXGI->BusWidth); 304dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 305dfe64dd3Smacallan "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024); 306dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 307dfe64dd3Smacallan "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ; 308dfe64dd3Smacallan XGI_InitHwDevInfo(pScrn); 309dfe64dd3Smacallan} 310dfe64dd3Smacallan 311dfe64dd3Smacallanstatic void 312dfe64dd3SmacallanxgiXG40_Setup(ScrnInfoPtr pScrn) 313dfe64dd3Smacallan{ 314dfe64dd3Smacallan static const char *const dramChannelStr[5] = { 315dfe64dd3Smacallan "<invalid>", "Single", "Dual", "<invalid>", "Quad" 316dfe64dd3Smacallan }; 317dfe64dd3Smacallan 318dfe64dd3Smacallan static const char *const dramTypeStr[4] = { 319dfe64dd3Smacallan "DDR SDRAM", 320dfe64dd3Smacallan "DDR2 SDRAM", 321dfe64dd3Smacallan "DDR2x SDRAM", 322dfe64dd3Smacallan "" 323dfe64dd3Smacallan }; 324dfe64dd3Smacallan 325dfe64dd3Smacallan/********************************************************************* 326dfe64dd3Smacallan * Setup 327dfe64dd3Smacallan * Decide the following item of execution data: 328dfe64dd3Smacallan * 329dfe64dd3Smacallan * pXGI->BusWidth 330dfe64dd3Smacallan * pXGI->videoRam (with KB unit) 331dfe64dd3Smacallan * pXGI->CursorOffset (with Byte Unit) 332dfe64dd3Smacallan * pXGI->cmdQueueSize (with Byte Unit) 333dfe64dd3Smacallan * pXGI->cmdQueueSizeMask (with Byte Unit) 334dfe64dd3Smacallan * pXGI->cmdQueueOffset (with Byte Unit) 335dfe64dd3Smacallan * pXGI->cmdQueueLen = 0 ; // init value 336dfe64dd3Smacallan * pXGI->cmdQueueLenMin = 0x200 ; // init value 337dfe64dd3Smacallan * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ; 338dfe64dd3Smacallan *********************************************************************/ 339dfe64dd3Smacallan 340dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 341dfe64dd3Smacallan unsigned int ulMemConfig = 0; 342dfe64dd3Smacallan unsigned mem_per_channel; 343dfe64dd3Smacallan unsigned mem_channels = 1; 344dfe64dd3Smacallan unsigned long ulDramType = 0; 345dfe64dd3Smacallan 346dfe64dd3Smacallan PDEBUG4(ErrorF("xgiXG40_Setup()\n")) ; 347dfe64dd3Smacallan 348dfe64dd3Smacallan pXGI->MemClock = XG40Mclk(pXGI); 349dfe64dd3Smacallan 350dfe64dd3Smacallan /* SR14 DRAM Size Register 351dfe64dd3Smacallan * Default value: XXh 352dfe64dd3Smacallan * D[7:4] Memory size per channel {BChMemSize} 353dfe64dd3Smacallan * 0011: 8 MB 354dfe64dd3Smacallan * 0100: 16 MB 355dfe64dd3Smacallan * 0101: 32 MB 356dfe64dd3Smacallan * 0110: 64 MB 357dfe64dd3Smacallan * 0111: 128 MB 358dfe64dd3Smacallan * 1000: 256MB 359dfe64dd3Smacallan * others: reserved 360dfe64dd3Smacallan * D[3:2] Number of dram channels [1:0] {BChNum} 361dfe64dd3Smacallan * 00: uni-channel 362dfe64dd3Smacallan * 01: reserved 363dfe64dd3Smacallan * 10: dual-channel 364dfe64dd3Smacallan * 11: quad-channel 365dfe64dd3Smacallan * D1 Data width per channel selection {BDataWidth} 366dfe64dd3Smacallan * 0: 32-bits 367dfe64dd3Smacallan * 1: 64-bits 368dfe64dd3Smacallan * D0 Dram channel mapping {BReverseChMapping} 369dfe64dd3Smacallan * 0: Normal mapping 370dfe64dd3Smacallan * 1: Reversal mapping 371dfe64dd3Smacallan * Dual-channel: Logical channel A/B to physical channel B/A 372dfe64dd3Smacallan * Quad-channel: Logical channel A/B/C/D to physical channel 373dfe64dd3Smacallan * C/D/A/B 374dfe64dd3Smacallan */ 375dfe64dd3Smacallan 376dfe64dd3Smacallan outXGIIDXREG(XGISR, 0x5, 0x86) ; 377dfe64dd3Smacallan inXGIIDXREG(XGISR, 0x14, ulMemConfig) ; 378dfe64dd3Smacallan 379dfe64dd3Smacallan /* FIXME: Is this correct? The SiS driver detects this differently 380dfe64dd3Smacallan * FIXME: for XG20. 381dfe64dd3Smacallan */ 382dfe64dd3Smacallan inXGIIDXREG(XGISR, 0x3A, ulDramType) ; 383dfe64dd3Smacallan 384dfe64dd3Smacallan PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ; 385dfe64dd3Smacallan PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ; 386dfe64dd3Smacallan 387dfe64dd3Smacallan /* FIXME: Is this correct? The SiS driver detects this differently 388dfe64dd3Smacallan * FIXME: for XG20. 389dfe64dd3Smacallan */ 390dfe64dd3Smacallan pXGI->BusWidth = (ulMemConfig & 0x02) ? 64 : 32; 391dfe64dd3Smacallan 392dfe64dd3Smacallan mem_per_channel = ((ulMemConfig >> 4) >= 3) 393dfe64dd3Smacallan ? (1 << (ulMemConfig >> 4)) * 1024 394dfe64dd3Smacallan : 8 * 1024; 395dfe64dd3Smacallan 396dfe64dd3Smacallan 397dfe64dd3Smacallan /* All XG20 family chips are single channel, so only test the channel 398dfe64dd3Smacallan * count field on XG40 family chips. 399dfe64dd3Smacallan */ 400dfe64dd3Smacallan if (pXGI->Chipset == PCI_CHIP_XGIXG40) { 401dfe64dd3Smacallan /* Check the PCI revision field. For whatever reason, rev. 2 XG40 402dfe64dd3Smacallan * chips encode the DRAM channel count differently than other 403dfe64dd3Smacallan * revisions. 404dfe64dd3Smacallan */ 405dfe64dd3Smacallan if (pXGI->ChipRev == 2) { 406dfe64dd3Smacallan switch ((ulMemConfig >> 2) & 0x1) { 407dfe64dd3Smacallan case 1: 408dfe64dd3Smacallan /* Dual channel */ 409dfe64dd3Smacallan mem_channels = 2; 410dfe64dd3Smacallan break ; 411dfe64dd3Smacallan } 412dfe64dd3Smacallan } 413dfe64dd3Smacallan else { 414dfe64dd3Smacallan switch ((ulMemConfig >> 2) & 0x3) { 415dfe64dd3Smacallan case 2: 416dfe64dd3Smacallan /* Dual channel */ 417dfe64dd3Smacallan mem_channels = 2; 418dfe64dd3Smacallan break ; 419dfe64dd3Smacallan case 3: 420dfe64dd3Smacallan /* Quad channel */ 421dfe64dd3Smacallan mem_channels = 4; 422dfe64dd3Smacallan break ; 423dfe64dd3Smacallan } 424dfe64dd3Smacallan } 425dfe64dd3Smacallan } 426dfe64dd3Smacallan 427dfe64dd3Smacallan pScrn->videoRam = mem_per_channel * mem_channels; 428dfe64dd3Smacallan 429dfe64dd3Smacallan /* SR15 DRAM Address Mapping Register 430dfe64dd3Smacallan * Default value: XXh 431dfe64dd3Smacallan * D7 Channel interleaving configuration { BChConfig } 432dfe64dd3Smacallan * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel 433dfe64dd3Smacallan * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region 434dfe64dd3Smacallan * will be channel-interleaved as per BFineGranSize; the high-address region will be channel- 435dfe64dd3Smacallan * interleaved as per BCoarseGranSize[1:0] 436dfe64dd3Smacallan * D[6:5] Memory size of tile-mapped region {BTilingSize} 437dfe64dd3Smacallan * 00: 4 MB 438dfe64dd3Smacallan * 01: 8 MB 439dfe64dd3Smacallan * 10: 16 MB 440dfe64dd3Smacallan * 11: 32 MB 441dfe64dd3Smacallan * The following bits are effective only when D7=1 442dfe64dd3Smacallan * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize} 443dfe64dd3Smacallan * 0: 64 B 444dfe64dd3Smacallan * 1: 128 B 445dfe64dd3Smacallan * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize} 446dfe64dd3Smacallan * 00: 1KB 447dfe64dd3Smacallan * 01: 2KB 448dfe64dd3Smacallan * 10: 4KB 449dfe64dd3Smacallan * 11: 1MB 450dfe64dd3Smacallan * D[1:0] reserved 451dfe64dd3Smacallan */ 452dfe64dd3Smacallan 453dfe64dd3Smacallan /* Accelerator parameter Initialization */ 454dfe64dd3Smacallan 455dfe64dd3Smacallan pXGI->cmdQueueSize = ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21||(pXGI->Chipset == PCI_CHIP_XGIXG27))) 456dfe64dd3Smacallan ? VOLARI_CQSIZEXG20 : VOLARI_CQSIZE; 457dfe64dd3Smacallan pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ; 458dfe64dd3Smacallan pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D); 459dfe64dd3Smacallan 460dfe64dd3Smacallan 461dfe64dd3Smacallan /* If FbDevExist, X.org driver uses 8MB only. The rest of the framebuffer 462dfe64dd3Smacallan * is used by the fbdev driver. 463dfe64dd3Smacallan */ 464dfe64dd3Smacallan if (FbDevExist) { 465dfe64dd3Smacallan /* FIXME: Is it even possible to have less than 8Mb of video memory? 466dfe64dd3Smacallan */ 467dfe64dd3Smacallan if (pScrn->videoRam < 8*1024) { 468dfe64dd3Smacallan pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize; 469dfe64dd3Smacallan } 470dfe64dd3Smacallan else if (pScrn->videoRam < 16*1024) { 471dfe64dd3Smacallan pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize; 472dfe64dd3Smacallan } 473dfe64dd3Smacallan else { 474dfe64dd3Smacallan pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize; 475dfe64dd3Smacallan } 476dfe64dd3Smacallan } 477dfe64dd3Smacallan else { 478dfe64dd3Smacallan pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize; 479dfe64dd3Smacallan } 480dfe64dd3Smacallan 481dfe64dd3Smacallan pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024; 482dfe64dd3Smacallan PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n", 483dfe64dd3Smacallan pScrn->videoRam, pXGI->cmdQueueSize)) ; 484dfe64dd3Smacallan PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n", 485dfe64dd3Smacallan pXGI->cmdQueueOffset, pXGI->CursorOffset)) ; 486dfe64dd3Smacallan 487dfe64dd3Smacallan pXGI->cmdQueueLen = 0 ; 488dfe64dd3Smacallan pXGI->cmdQueueLenMin = 0x200 ; 489dfe64dd3Smacallan pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ; 490dfe64dd3Smacallan 491dfe64dd3Smacallan /* Dual Chip support put here 492dfe64dd3Smacallan */ 493dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 494dfe64dd3Smacallan "Detected DRAM type : %s channel %s\n", 495dfe64dd3Smacallan dramChannelStr[mem_channels], 496dfe64dd3Smacallan dramTypeStr[(ulDramType & 0x02) >> 1]); 497dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 498dfe64dd3Smacallan "Detected memory clock : %3.3fMHz\n", 499dfe64dd3Smacallan pXGI->MemClock/1000.0); 500dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 501dfe64dd3Smacallan "Detected VRAM bus width is %d\n", pXGI->BusWidth); 502dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 503dfe64dd3Smacallan "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024); 504dfe64dd3Smacallan xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 505dfe64dd3Smacallan "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ; 506dfe64dd3Smacallan XGI_InitHwDevInfo(pScrn); 507dfe64dd3Smacallan} 508dfe64dd3Smacallan 509dfe64dd3Smacallanvoid 510dfe64dd3SmacallanXGISetup(ScrnInfoPtr pScrn) 511dfe64dd3Smacallan{ 512dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 513dfe64dd3Smacallan 514dfe64dd3Smacallan pXGI->Flags = 0; 515dfe64dd3Smacallan pXGI->VBFlags = 0; 516dfe64dd3Smacallan 517dfe64dd3Smacallan /* Jong 10/16/2007; merge code */ 518dfe64dd3Smacallan switch (pXGI->Chipset) { 519dfe64dd3Smacallan case PCI_CHIP_XGIXG20: 520dfe64dd3Smacallan case PCI_CHIP_XGIXG21: 521dfe64dd3Smacallan case PCI_CHIP_XGIXG27: 522dfe64dd3Smacallan xgiXG2X_Setup(pScrn); 523dfe64dd3Smacallan break; 524dfe64dd3Smacallan 525dfe64dd3Smacallan case PCI_CHIP_XGIXG40: 526dfe64dd3Smacallan default: 527dfe64dd3Smacallan xgiXG40_Setup(pScrn); 528dfe64dd3Smacallan break; 529dfe64dd3Smacallan } 530dfe64dd3Smacallan} 531dfe64dd3Smacallan 532dfe64dd3Smacallan/* Jong 01/07/2008; Force to disable 2D engine by SR3A[6]=1 */ 533dfe64dd3SmacallanBool ForceToDisable2DEngine(ScrnInfoPtr pScrn) 534dfe64dd3Smacallan{ 535dfe64dd3Smacallan XGIPtr pXGI ; 536dfe64dd3Smacallan Bool bReturn=FALSE; 537dfe64dd3Smacallan CARD8 bForce; 538dfe64dd3Smacallan 539dfe64dd3Smacallan pXGI = XGIPTR(pScrn); 540dfe64dd3Smacallan 541dfe64dd3Smacallan if(pXGI->Chipset == PCI_CHIP_XGIXG21) 542dfe64dd3Smacallan { 543dfe64dd3Smacallan inXGIIDXREG(XGISR, 0x3A, bForce) ; 544dfe64dd3Smacallan bForce &= 0x40; 545dfe64dd3Smacallan 546dfe64dd3Smacallan if(bForce == 0) 547dfe64dd3Smacallan bReturn=FALSE; 548dfe64dd3Smacallan else 549dfe64dd3Smacallan bReturn=TRUE; 550dfe64dd3Smacallan } 551dfe64dd3Smacallan else 552dfe64dd3Smacallan { 553dfe64dd3Smacallan bReturn=FALSE; 554dfe64dd3Smacallan } 555dfe64dd3Smacallan 556dfe64dd3Smacallan return(bReturn); 557dfe64dd3Smacallan} 558dfe64dd3Smacallan 559dfe64dd3SmacallanBool 560dfe64dd3SmacallanXGI_IsXG21(ScrnInfoPtr pScrn) 561dfe64dd3Smacallan{ 562dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 563dfe64dd3Smacallan Bool is_XG21 = FALSE; 564dfe64dd3Smacallan 565dfe64dd3Smacallan if (pXGI->Chipset == PCI_CHIP_XGIXG20) { 566dfe64dd3Smacallan int temp; 567dfe64dd3Smacallan 568dfe64dd3Smacallan orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN); 569dfe64dd3Smacallan inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, temp); 570dfe64dd3Smacallan 571dfe64dd3Smacallan is_XG21 = ((temp & GPIOG_READ) != 0); 572dfe64dd3Smacallan } 573dfe64dd3Smacallan 574dfe64dd3Smacallan return is_XG21; 575dfe64dd3Smacallan} 576dfe64dd3Smacallan 577dfe64dd3Smacallanvoid 578dfe64dd3SmacallanXGI_InitHwDevInfo(ScrnInfoPtr pScrn) 579dfe64dd3Smacallan{ 580dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 581dfe64dd3Smacallan PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt; 582dfe64dd3Smacallan int i; 583dfe64dd3Smacallan 584dfe64dd3Smacallan pHwDevInfo->pDevice = pXGI ; 585dfe64dd3Smacallan pHwDevInfo->pjVirtualRomBase = pXGI->BIOS ; 586dfe64dd3Smacallan pHwDevInfo->pjCustomizedROMImage = NULL ; 587dfe64dd3Smacallan pHwDevInfo->pjVideoMemoryAddress = (UCHAR*)(pXGI->FbBase) ; 588dfe64dd3Smacallan PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n",(ULONG)(pXGI->FbBase))) ; 589dfe64dd3Smacallan PDEBUG(ErrorF("pHwDevInfo->pjVideoMemoryAddress = 0x%08lx\n",(ULONG)(pHwDevInfo->pjVideoMemoryAddress))) ; 590dfe64dd3Smacallan pHwDevInfo->ulVideoMemorySize = pXGI->FbMapSize ; 591dfe64dd3Smacallan pHwDevInfo->pjIOAddress = pXGI->RelIO + 0x30 ; 592dfe64dd3Smacallan 593dfe64dd3Smacallan switch (pXGI->Chipset) { 594dfe64dd3Smacallan case PCI_CHIP_XGIXG40: 595dfe64dd3Smacallan pHwDevInfo->jChipType = XG40 ; 596dfe64dd3Smacallan break ; 597dfe64dd3Smacallan case PCI_CHIP_XGIXG20: 598dfe64dd3Smacallan pHwDevInfo->jChipType = XGI_IsXG21(pScrn)?XG21:XG20 ; 599dfe64dd3Smacallan break ; 600dfe64dd3Smacallan case PCI_CHIP_XGIXG27: 601dfe64dd3Smacallan pHwDevInfo->jChipType = XG27; 602dfe64dd3Smacallan break; 603dfe64dd3Smacallan case PCI_CHIP_XGIXG21: 604dfe64dd3Smacallan pHwDevInfo->jChipType = XG21; 605dfe64dd3Smacallan break; 606dfe64dd3Smacallan default: 607dfe64dd3Smacallan pHwDevInfo->jChipType = XG40 ; 608dfe64dd3Smacallan break ; 609dfe64dd3Smacallan } 610dfe64dd3Smacallan 611dfe64dd3Smacallan pHwDevInfo->jChipRevision = pXGI->ChipRev; 612dfe64dd3Smacallan pHwDevInfo->ujVBChipID = VB_CHIP_UNKNOWN ; 613dfe64dd3Smacallan pHwDevInfo->ulExternalChip = 0 ; 614dfe64dd3Smacallan 615dfe64dd3Smacallan pHwDevInfo->ulCRT2LCDType = LCD_1024x768 ; 616dfe64dd3Smacallan pHwDevInfo->bIntegratedMMEnabled = FALSE ; 617dfe64dd3Smacallan pHwDevInfo->bSkipDramSizing = TRUE ; 618dfe64dd3Smacallan 619dfe64dd3Smacallan pHwDevInfo->pSR = pXGI->SRList ; 620dfe64dd3Smacallan pHwDevInfo->pCR = pXGI->CRList ; 621dfe64dd3Smacallan pHwDevInfo->pQueryVGAConfigSpace = (PXGI_QUERYSPACE) bAccessVGAPCIInfo; 622dfe64dd3Smacallan 623dfe64dd3Smacallan for( i = 0 ; i < ExtRegSize ; i++ ){ 624dfe64dd3Smacallan pHwDevInfo->pSR[i].jIdx = 0xFF ; 625dfe64dd3Smacallan pHwDevInfo->pSR[i].jVal = 0xFF ; 626dfe64dd3Smacallan pHwDevInfo->pCR[i].jIdx = 0xFF ; 627dfe64dd3Smacallan pHwDevInfo->pCR[i].jVal = 0xFF ; 628dfe64dd3Smacallan } 629dfe64dd3Smacallan 630dfe64dd3Smacallan for( i = 0 ; i < VBIOS_VER_MAX_LENGTH ; i++ ){ 631dfe64dd3Smacallan pHwDevInfo -> szVBIOSVer[i] = '\0' ; 632dfe64dd3Smacallan } 633dfe64dd3Smacallan 634dfe64dd3Smacallan 635dfe64dd3Smacallan XGINew_InitVBIOSData(pHwDevInfo, pXGI->XGI_Pr); 636dfe64dd3Smacallan PDEBUG(ErrorF("XGINew_InitVBIOSData(pHwDevInfo) done\n")) ; 637dfe64dd3Smacallan 638dfe64dd3Smacallan ErrorF("XGI_InitVBIOSData VBType = %x\n", pXGI->XGI_Pr->VBType); 639dfe64dd3Smacallan XGI_New_GetVBType(pXGI->XGI_Pr, pHwDevInfo); //yilin 640dfe64dd3Smacallan ErrorF("XGI_New_GetVBType VBType = %x\n", pXGI->XGI_Pr->VBType); 641dfe64dd3Smacallan 642dfe64dd3Smacallan // pHwDevInfo->ujVBChipID = VB_CHIP_301 ; //yilin 643dfe64dd3Smacallan if( pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C)) 644dfe64dd3Smacallan { 645dfe64dd3Smacallan PDEBUG(ErrorF("VB chip = 301 \n")) ; 646dfe64dd3Smacallan pHwDevInfo->ujVBChipID = VB_CHIP_301 ; 647dfe64dd3Smacallan } 648dfe64dd3Smacallan else if( pXGI->VBFlags & ( VB_XGI302B| VB_XGI302LV )) 649dfe64dd3Smacallan { 650dfe64dd3Smacallan pHwDevInfo->ujVBChipID = VB_CHIP_302 ; 651dfe64dd3Smacallan } 652dfe64dd3Smacallan/* 653dfe64dd3Smacallan else if (pXGI->VBFlags & VB_LVDS) { 654dfe64dd3Smacallan pHwDevInfo->ulExternalChip |= 0x01 ; 655dfe64dd3Smacallan } 656dfe64dd3Smacallan*/ //yilin 657dfe64dd3Smacallan 658dfe64dd3Smacallan 659dfe64dd3Smacallan PDEBUG(ErrorF("pHwDevInfo->jChipType = %08lX done\n",pHwDevInfo->jChipType)) ; 660dfe64dd3Smacallan} 661dfe64dd3Smacallan 662dfe64dd3SmacallanBool 663098ad5bdSmacallanbAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset, ULONG ulSet, CARD32 *pulValue) 664dfe64dd3Smacallan{ 665dfe64dd3Smacallan XGIPtr pXGI ; 666dfe64dd3Smacallan#ifdef XSERVER_LIBPCIACCESS 667dfe64dd3Smacallan int err; 668dfe64dd3Smacallan#else 669dfe64dd3Smacallan PCITAG pciDev; 670dfe64dd3Smacallan#endif 671dfe64dd3Smacallan 672dfe64dd3Smacallan if (!pHwDevInfo || !pulValue) { 673dfe64dd3Smacallan return FALSE; 674dfe64dd3Smacallan } 675dfe64dd3Smacallan 676dfe64dd3Smacallan pXGI = (XGIPtr)pHwDevInfo->pDevice ; 677dfe64dd3Smacallan#ifdef XSERVER_LIBPCIACCESS 678dfe64dd3Smacallan if (ulSet) { 679dfe64dd3Smacallan err = pci_device_cfg_write_u32(pXGI->PciInfo, *pulValue, 680dfe64dd3Smacallan ulOffset & ~3); 681dfe64dd3Smacallan } else { 682cb1acafbSmacallan err = pci_device_cfg_read_u32(pXGI->PciInfo, (uint32_t *)pulValue, 683dfe64dd3Smacallan ulOffset & ~3); 684dfe64dd3Smacallan } 685dfe64dd3Smacallan 686dfe64dd3Smacallan return (err == 0); 687dfe64dd3Smacallan#else 688dfe64dd3Smacallan pciDev = pXGI->PciTag ; 689dfe64dd3Smacallan 690dfe64dd3Smacallan if (ulSet) { 691dfe64dd3Smacallan pciWriteLong(pciDev, ulOffset&0xFFFFFFFc, *pulValue); 692dfe64dd3Smacallan } else { 693dfe64dd3Smacallan *pulValue = pciReadLong(pciDev, ulOffset&0xFFFFFFFc); 694dfe64dd3Smacallan } 695dfe64dd3Smacallan 696dfe64dd3Smacallan return TRUE ; 697dfe64dd3Smacallan#endif 698dfe64dd3Smacallan} 699