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