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