1 /*
2  * Copyright 2000 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of Marc Aurele La France not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  Marc Aurele La France makes no representations
11  * about the suitability of this software for any purpose.  It is provided
12  * "as-is" without express or implied warranty.
13  *
14  * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
16  * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  * DRI support by:
23  *    Leif Delgass <ldelgass@retinalburn.net>
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <string.h>
31 
32 #include "ati.h"
33 #include "atichip.h"
34 #include "aticursor.h"
35 #include "atioption.h"
36 #include "atistruct.h"
37 
38 #include "mach64_common.h"
39 
40 #ifdef TV_OUT
41 
42 /*
43  * List of supported TV standard names
44  */
45 const char *ATITVStandardNames[ATI_TV_STDS_MAX_VALID+1] = {
46     "NTSC",
47     "PAL",
48     "PAL-M",
49     "PAL-60",
50     "NTSC-J",
51     "PAL-CN",
52     "PAL-N",
53     "Reserved1",
54     "Reserved2",
55     "SCART-PAL",
56     "None",
57     "Invalid"
58 };
59 
60 #endif /* TV_OUT */
61 
62 /*
63  * Recognised XF86Config options.
64  */
65 static const OptionInfoRec ATIPublicOptions[] =
66 {
67     {
68         ATI_OPTION_PROBE_SPARSE,
69         "probe_sparse",
70         OPTV_BOOLEAN,
71         {0, },
72         FALSE
73     },
74     {
75         ATI_OPTION_ACCEL,
76         "accel",
77         OPTV_BOOLEAN,
78         {0, },
79         FALSE
80     },
81     {
82         ATI_OPTION_CRT_DISPLAY,
83         "crt_display",
84         OPTV_BOOLEAN,
85         {0, },
86         FALSE
87     },
88     {
89         ATI_OPTION_CSYNC,
90         "composite_sync",
91         OPTV_BOOLEAN,
92         {0, },
93         FALSE
94     },
95     {
96         ATI_OPTION_HWCURSOR,
97         "hw_cursor",
98         OPTV_BOOLEAN,
99         {0, },
100         FALSE,
101     },
102 
103 #ifdef XF86DRI_DEVEL
104 
105     {
106         ATI_OPTION_IS_PCI,
107         "force_pci_mode",
108         OPTV_BOOLEAN,
109         {0, },
110         FALSE,
111     },
112     {
113         ATI_OPTION_DMA_MODE,
114         "dma_mode",
115         OPTV_STRING,
116         {0, },
117         FALSE,
118     },
119     {
120         ATI_OPTION_AGP_MODE,
121         "agp_mode",
122         OPTV_INTEGER,
123         {0, },
124         FALSE,
125     },
126     {
127         ATI_OPTION_AGP_SIZE,
128         "agp_size",
129         OPTV_INTEGER,
130         {0, },
131         FALSE,
132     },
133     {
134         ATI_OPTION_LOCAL_TEXTURES,
135         "local_textures",
136         OPTV_BOOLEAN,
137         {0, },
138         FALSE,
139     },
140     {
141         ATI_OPTION_BUFFER_SIZE,
142         "buffer_size",
143         OPTV_INTEGER,
144         {0, },
145         FALSE,
146     },
147 
148 #endif /* XF86DRI_DEVEL */
149 
150 #ifdef TV_OUT
151     {
152         ATI_OPTION_TV_OUT,
153         "tv_out",
154         OPTV_BOOLEAN,
155         {0, },
156         FALSE
157     },
158     {
159         ATI_OPTION_TV_STD,
160         "tv_standard",
161         OPTV_STRING,
162         {0, },
163         FALSE
164     },
165 
166 #endif /* TV_OUT */
167 
168     {
169         ATI_OPTION_MMIO_CACHE,
170         "mmio_cache",
171         OPTV_BOOLEAN,
172         {0, },
173         FALSE
174     },
175 
176 
177     {
178         ATI_OPTION_TEST_MMIO_CACHE,
179         "test_mmio_cache",
180         OPTV_BOOLEAN,
181         {0, },
182         FALSE
183     },
184     {
185         ATI_OPTION_PANEL_DISPLAY,
186         "panel_display",
187         OPTV_BOOLEAN,
188         {0, },
189         FALSE
190     },
191     {
192         ATI_OPTION_REFERENCE_CLOCK,
193         "reference_clock",
194         OPTV_FREQ,
195         {0, },
196         FALSE
197     },
198     {
199         ATI_OPTION_SHADOW_FB,
200         "shadow_fb",
201         OPTV_BOOLEAN,
202         {0, },
203         FALSE
204     },
205     {
206         ATI_OPTION_SWCURSOR,
207         "sw_cursor",
208         OPTV_BOOLEAN,
209         {0, },
210         FALSE,
211     },
212     {
213         ATI_OPTION_ACCELMETHOD,
214         "AccelMethod",
215         OPTV_STRING,
216         {0, },
217         FALSE
218     },
219     {
220         ATI_OPTION_RENDER_ACCEL,
221         "RenderAccel",
222         OPTV_BOOLEAN,
223         {0, },
224         FALSE
225     },
226     {
227         -1,
228         NULL,
229         OPTV_NONE,
230         {0, },
231         FALSE
232     }
233 };
234 
235 static const unsigned long ATIPublicOptionSize = SizeOf(ATIPublicOptions);
236 
237 const OptionInfoRec *
ATIOptionsWeak(void)238 ATIOptionsWeak(void) { return ATIPublicOptions; }
239 
240 /*
241  * Non-publicised XF86Config options.
242  */
243 typedef enum
244 {
245     ATI_OPTION_BIOS_DISPLAY,    /* Allow BIOS interference */
246     ATI_OPTION_CRT_SCREEN,      /* Legacy negation of "PanelDisplay" */
247     ATI_OPTION_DEVEL,           /* Intentionally undocumented */
248     ATI_OPTION_BLEND,           /* Force horizontal blending of small modes */
249     ATI_OPTION_LCDSYNC          /* Use XF86Config panel mode porches */
250 } ATIPrivateOptionType;
251 
252 /*
253  * ATIProcessOptions --
254  *
255  * This function extracts options from what was parsed out of the XF86Config
256  * file.
257  */
258 void
ATIProcessOptions(ScrnInfoPtr pScreenInfo,ATIPtr pATI)259 ATIProcessOptions
260 (
261     ScrnInfoPtr pScreenInfo,
262     ATIPtr      pATI
263 )
264 {
265     OptionInfoPtr PublicOption = xnfalloc(ATIPublicOptionSize);
266     OptionInfoRec PrivateOption[] =
267     {
268         {                       /* ON:  Let BIOS change display(s) */
269             ATI_OPTION_BIOS_DISPLAY,    /* OFF:  Don't */
270             "biosdisplay",
271             OPTV_BOOLEAN,
272             {0, },
273             FALSE
274         },
275         {                       /* Negation of "PanelDisplay" public option */
276             ATI_OPTION_CRT_SCREEN,
277             "crtscreen",
278             OPTV_BOOLEAN,
279             {0, },
280             FALSE
281         },
282         {                       /* ON:   Ease exploration of loose ends */
283             ATI_OPTION_DEVEL,   /* OFF:  Fit for public consumption */
284             "tsi",
285             OPTV_BOOLEAN,
286             {0, },
287             FALSE
288         },
289         {                       /* ON:   Horizontally blend most modes */
290             ATI_OPTION_BLEND,   /* OFF:  Use pixel replication more often */
291             "lcdblend",
292             OPTV_BOOLEAN,
293             {0, },
294             FALSE
295         },
296         {                       /* ON:   Use XF86Config porch timings */
297             ATI_OPTION_LCDSYNC, /* OFF:  Use porches from mode on entry */
298             "lcdsync",
299             OPTV_BOOLEAN,
300             {0, },
301             FALSE
302         },
303         {
304             -1,
305             NULL,
306             OPTV_NONE,
307             {0, },
308             FALSE
309         }
310     };
311 
312     (void)memcpy(PublicOption, ATIPublicOptions, ATIPublicOptionSize);
313 
314 #   define ProbeSparse   PublicOption[ATI_OPTION_PROBE_SPARSE].value.bool
315 #   define Accel         PublicOption[ATI_OPTION_ACCEL].value.bool
316 #   define BIOSDisplay   PrivateOption[ATI_OPTION_BIOS_DISPLAY].value.bool
317 #   define Blend         PrivateOption[ATI_OPTION_BLEND].value.bool
318 #   define CRTDisplay    PublicOption[ATI_OPTION_CRT_DISPLAY].value.bool
319 #   define CRTScreen     PrivateOption[ATI_OPTION_CRT_SCREEN].value.bool
320 #   define CSync         PublicOption[ATI_OPTION_CSYNC].value.bool
321 #   define Devel         PrivateOption[ATI_OPTION_DEVEL].value.bool
322 #   define HWCursor      PublicOption[ATI_OPTION_HWCURSOR].value.bool
323 
324 #ifdef XF86DRI_DEVEL
325 
326 #   define IsPCI       PublicOption[ATI_OPTION_IS_PCI].value.bool
327 #   define DMAMode     PublicOption[ATI_OPTION_DMA_MODE].value.str
328 #   define AGPMode     PublicOption[ATI_OPTION_AGP_MODE].value.num
329 #   define AGPSize     PublicOption[ATI_OPTION_AGP_SIZE].value.num
330 #   define LocalTex    PublicOption[ATI_OPTION_LOCAL_TEXTURES].value.bool
331 #   define BufferSize  PublicOption[ATI_OPTION_BUFFER_SIZE].value.num
332 
333 #endif /* XF86DRI_DEVEL */
334 
335 #ifdef TV_OUT
336 
337 #   define TvOut        PublicOption[ATI_OPTION_TV_OUT].value.bool
338 #   define TvStd        PublicOption[ATI_OPTION_TV_STD].value.str
339 
340 #endif /* TV_OUT */
341 
342 #   define CacheMMIO     PublicOption[ATI_OPTION_MMIO_CACHE].value.bool
343 #   define TestCacheMMIO PublicOption[ATI_OPTION_TEST_MMIO_CACHE].value.bool
344 #   define PanelDisplay  PublicOption[ATI_OPTION_PANEL_DISPLAY].value.bool
345 #   define ShadowFB      PublicOption[ATI_OPTION_SHADOW_FB].value.bool
346 #   define SWCursor      PublicOption[ATI_OPTION_SWCURSOR].value.bool
347 #   define AccelMethod   PublicOption[ATI_OPTION_ACCELMETHOD].value.str
348 #   define RenderAccel   PublicOption[ATI_OPTION_RENDER_ACCEL].value.bool
349 #   define LCDSync       PrivateOption[ATI_OPTION_LCDSYNC].value.bool
350 
351 #   define ReferenceClock \
352         PublicOption[ATI_OPTION_REFERENCE_CLOCK].value.freq.freq
353 
354     /* Pick up XF86Config options */
355     xf86CollectOptions(pScreenInfo, NULL);
356 
357     /* Set non-zero defaults */
358     Accel = CacheMMIO = HWCursor = TRUE;
359 
360     ReferenceClock = ((double)157500000.0) / ((double)11.0);
361 
362     ShadowFB = TRUE;
363 
364     Blend = PanelDisplay = TRUE;
365 
366 #ifdef USE_EXA
367     RenderAccel = TRUE;
368 #endif
369 
370 #ifdef XF86DRI_DEVEL
371     DMAMode = "async";
372 #endif
373 
374 #ifdef TV_OUT
375     TvStd = "None";  /* No tv standard change requested */
376 #endif
377 
378     xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
379         PublicOption);
380     xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
381         PrivateOption);
382 
383     /* Move option values into driver private structure */
384     pATI->OptionProbeSparse = ProbeSparse;
385     pATI->OptionAccel = Accel;
386     pATI->OptionBIOSDisplay = BIOSDisplay;
387     pATI->OptionBlend = Blend;
388     pATI->OptionCRTDisplay = CRTDisplay;
389     pATI->OptionCSync = CSync;
390     pATI->OptionDevel = Devel;
391 
392 #ifdef TV_OUT
393 
394     if (TvOut && pATI->Chip < ATI_CHIP_264GT) {
395        /* Only allow this for 3D Rage (I) or greater chip ID
396 	* AFAIK, no chips before this supported TV-Out
397 	* mach64VT has support for TV tuner, but no TV-Out
398 	*/
399 	xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
400                 "TV Out not supported for this chip.\n");
401     } else {
402 	ATITVStandard std;
403 	pATI->OptionTvOut = TvOut;
404 	pATI->OptionTvStd = ATI_TV_STD_INVALID;
405 	for (std = 0; std < ATI_TV_STDS_MAX_VALID; std++) {
406 	    if (std != ATI_TV_STD_RESERVED1 && std != ATI_TV_STD_RESERVED2) {
407 		if (strncasecmp(TvStd, ATITVStandardNames[std], ATI_TV_STDS_NAME_MAXLEN)==0) {
408 		    pATI->OptionTvStd = std;
409 		    break;
410 		}
411 	    }
412 	}
413     }
414 
415 #endif /* TV_OUT */
416 
417     pATI->OptionMMIOCache = CacheMMIO;
418     pATI->OptionTestMMIOCache = TestCacheMMIO;
419     pATI->OptionShadowFB = ShadowFB;
420     pATI->OptionLCDSync = LCDSync;
421 
422     /* "CRTScreen" is now "NoPanelDisplay" */
423     if ((PanelDisplay != CRTScreen) ||
424         PublicOption[ATI_OPTION_PANEL_DISPLAY].found)
425         pATI->OptionPanelDisplay = PanelDisplay;
426     else
427         pATI->OptionPanelDisplay = !CRTScreen;
428 
429 #ifdef XF86DRI_DEVEL
430 
431     pATI->OptionIsPCI = IsPCI;
432     pATI->OptionAGPMode = AGPMode;
433     pATI->OptionAGPSize = AGPSize;
434     pATI->OptionLocalTextures = LocalTex;
435     pATI->OptionBufferSize = BufferSize;
436 
437     if (strcasecmp(DMAMode, "async")==0)
438         pATI->OptionDMAMode = MACH64_MODE_DMA_ASYNC;
439     else if (strcasecmp(DMAMode, "sync")==0)
440         pATI->OptionDMAMode = MACH64_MODE_DMA_SYNC;
441     else if (strcasecmp(DMAMode, "mmio")==0 )
442         pATI->OptionDMAMode = MACH64_MODE_MMIO;
443     else {
444         xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
445 		   "Unkown dma_mode: '%s'\n", DMAMode);
446 	xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
447 		   "Valid dma_mode options are: 'async','sync','mmio'\n");
448         xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
449 		   "Defaulting to async DMA mode\n");
450 	pATI->OptionDMAMode = MACH64_MODE_DMA_ASYNC;
451     }
452 
453 #endif /* XF86DRI_DEVEL */
454 
455     /* Validate and set cursor options */
456     pATI->Cursor = ATI_CURSOR_SOFTWARE;
457     if (SWCursor || !HWCursor)
458     {
459         if (HWCursor && PublicOption[ATI_OPTION_HWCURSOR].found)
460             xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
461                 "Option \"sw_cursor\" overrides Option \"hw_cursor\".\n");
462     }
463     else if (pATI->Chip < ATI_CHIP_264CT)
464     {
465         if (HWCursor && PublicOption[ATI_OPTION_HWCURSOR].found)
466             xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
467                 "Option \"hw_cursor\" not supported in this configuration.\n");
468     }
469     else
470     {
471         pATI->Cursor = ATI_CURSOR_HARDWARE;
472     }
473 
474     pATI->refclk = (int)ReferenceClock;
475 
476     pATI->useEXA = FALSE;
477     if (pATI->OptionAccel)
478     {
479         MessageType from = X_DEFAULT;
480 #if defined(USE_EXA)
481 #if defined(USE_XAA)
482         if (AccelMethod != NULL)
483         {
484             from = X_CONFIG;
485             if (xf86NameCmp(AccelMethod, "EXA") == 0)
486                 pATI->useEXA = TRUE;
487         }
488 #else /* USE_XAA */
489         pATI->useEXA = TRUE;
490 #endif /* !USE_XAA */
491 #endif /* USE_EXA */
492         xf86DrvMsg(pScreenInfo->scrnIndex, from,
493             "Using %s acceleration architecture\n",
494             pATI->useEXA ? "EXA" : "XAA");
495 
496 #if defined(USE_EXA)
497         if (pATI->useEXA && pATI->Chip >= ATI_CHIP_264GTPRO)
498             pATI->RenderAccelEnabled = TRUE;
499 
500         if (pATI->useEXA && !RenderAccel)
501             pATI->RenderAccelEnabled = FALSE;
502 #endif
503     }
504 
505     free(PublicOption);
506 }
507