1 /*
2  * Copyright 1997 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 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <string.h>
28 #include <ctype.h>
29 #include <stdint.h>
30 
31 #include "ati.h"
32 #include "atichip.h"
33 #include "atidac.h"
34 #include "atimach64io.h"
35 #include "atiprint.h"
36 #include "atiwonderio.h"
37 
38 /*
39  * ATIPrintBIOS --
40  *
41  * Display various parts of the BIOS when the server is invoked with -verbose.
42  */
43 void
ATIPrintBIOS(const CARD8 * BIOS,const unsigned int Length)44 ATIPrintBIOS
45 (
46     const CARD8        *BIOS,
47     const unsigned int Length   /* A multiple of 512 */
48 )
49 {
50     unsigned char *Char = NULL;
51     unsigned int  Index;
52     unsigned char Printable[17];
53 
54     if (xf86GetVerbosity() <= 4)
55         return;
56 
57     (void)memset(Printable, 0, SizeOf(Printable));
58 
59     xf86ErrorFVerb(5, "\n BIOS image:");
60 
61     for (Index = 0;  Index < Length;  Index++)
62     {
63         if (!(Index & (4U - 1U)))
64         {
65             if (!(Index & (16U - 1U)))
66             {
67                 if (Printable[0])
68                     xf86ErrorFVerb(5, "  |%s|", Printable);
69                 Char = Printable;
70                 xf86ErrorFVerb(5, "\n 0x%08X: ", Index);
71             }
72             xf86ErrorFVerb(5, " ");
73         }
74         xf86ErrorFVerb(5, "%02X", BIOS[Index]);
75         if (isprint(BIOS[Index]))
76             *Char++ = BIOS[Index];
77         else
78             *Char++ = '.';
79     }
80 
81     xf86ErrorFVerb(5, "  |%s|\n", Printable);
82 }
83 
84 #ifndef AVOID_CPIO
85 
86 /*
87  * ATIPrintIndexedRegisters --
88  *
89  * Display a set of indexed byte-size registers when the server is invoked with
90  * -verbose.
91  */
92 static void
ATIPrintIndexedRegisters(const unsigned long Port,const CARD8 StartIndex,const CARD8 EndIndex,const char * Name,const unsigned long GenS1)93 ATIPrintIndexedRegisters
94 (
95     const unsigned long Port,
96     const CARD8     StartIndex,
97     const CARD8     EndIndex,
98     const char      *Name,
99     const unsigned long GenS1
100 )
101 {
102     int Index;
103 
104     xf86ErrorFVerb(4, "\n %s register values:", Name);
105     for (Index = StartIndex;  Index < EndIndex;  Index++)
106     {
107         if (!(Index & (4U - 1U)))
108         {
109             if (!(Index & (16U - 1U)))
110                 xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
111             xf86ErrorFVerb(4, " ");
112         }
113         if (Port == ATTRX)
114             (void)inb(GenS1);           /* Reset flip-flop */
115         xf86ErrorFVerb(4, "%02X", GetReg(Port, Index));
116     }
117 
118     if (Port == ATTRX)
119     {
120         (void)inb(GenS1);               /* Reset flip-flop */
121         outb(ATTRX, 0x20U);             /* Turn on PAS bit */
122     }
123 
124     xf86ErrorFVerb(4, "\n");
125 }
126 
127 #endif /* AVOID_CPIO */
128 
129 /*
130  * ATIMach64PrintRegisters --
131  *
132  * Display a Mach64's main register bank when the server is invoked with
133  * -verbose.
134  */
135 static void
ATIMach64PrintRegisters(ATIPtr pATI,CARD8 * crtc,const char * Description)136 ATIMach64PrintRegisters
137 (
138     ATIPtr     pATI,
139     CARD8      *crtc,
140     const char *Description
141 )
142 {
143     CARD32 IOValue;
144     CARD8 dac_read, dac_mask, dac_data, dac_write;
145     int Index, Limit;
146 
147 #ifndef AVOID_CPIO
148 
149     int Step;
150 
151 #endif /* AVOID_CPIO */
152 
153     xf86ErrorFVerb(4, "\n Mach64 %s register values:", Description);
154 
155 #ifdef AVOID_CPIO
156 
157     if (pATI->pBlock[1])
158         Limit = DWORD_SELECT;
159     else
160         Limit = MM_IO_SELECT;
161 
162     for (Index = 0;  Index <= Limit;  Index += UnitOf(MM_IO_SELECT))
163     {
164         if (!(Index & SetBits(3, MM_IO_SELECT)))
165             xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
166         if (Index == (DAC_REGS & DWORD_SELECT))
167         {
168             dac_read = in8(DAC_REGS + 3);
169             DACDelay;
170             dac_mask = in8(DAC_REGS + 2);
171             DACDelay;
172             dac_data = in8(DAC_REGS + 1);
173             DACDelay;
174             dac_write = in8(DAC_REGS + 0);
175             DACDelay;
176 
177             xf86ErrorFVerb(4, " %02X%02X%02X%02X",
178                 dac_read, dac_mask, dac_data, dac_write);
179 
180             out8(DAC_REGS + 2, dac_mask);
181             DACDelay;
182             out8(DAC_REGS + 3, dac_read);
183             DACDelay;
184         }
185         else
186         {
187             IOValue = inm(Index);
188 
189             if ((Index == (CRTC_GEN_CNTL & DWORD_SELECT)) &&
190                 (IOValue & CRTC_EXT_DISP_EN))
191                 *crtc = ATI_CRTC_MACH64;
192 
193             xf86ErrorFVerb(4, " %08lX", (unsigned long)IOValue);
194         }
195     }
196 
197 #else /* AVOID_CPIO */
198 
199     Limit = ATIIOPort(IOPortTag(0x1FU, 0x3FU));
200     Step = ATIIOPort(IOPortTag(0x01U, 0x01U)) - pATI->CPIOBase;
201     for (Index = pATI->CPIOBase;  Index <= Limit;  Index += Step)
202     {
203         if (!(((Index - pATI->CPIOBase) / Step) & 0x03U))
204             xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
205         if (Index == (int)ATIIOPort(DAC_REGS))
206         {
207             dac_read = in8(DAC_REGS + 3);
208             DACDelay;
209             dac_mask = in8(DAC_REGS + 2);
210             DACDelay;
211             dac_data = in8(DAC_REGS + 1);
212             DACDelay;
213             dac_write = in8(DAC_REGS + 0);
214             DACDelay;
215 
216             xf86ErrorFVerb(4, " %02X%02X%02X%02X",
217                 dac_read, dac_mask, dac_data, dac_write);
218 
219             out8(DAC_REGS + 2, dac_mask);
220             DACDelay;
221             out8(DAC_REGS + 3, dac_read);
222             DACDelay;
223         }
224         else
225         {
226             IOValue = inl(Index);
227 
228             if ((Index == (int)ATIIOPort(CRTC_GEN_CNTL)) &&
229                 (IOValue & CRTC_EXT_DISP_EN))
230                 *crtc = ATI_CRTC_MACH64;
231 
232             xf86ErrorFVerb(4, " %08lX", (unsigned long)IOValue);
233         }
234     }
235 
236 #endif /* AVOID_CPIO */
237 
238     xf86ErrorFVerb(4, "\n");
239 }
240 
241 /*
242  * ATIMach64PrintPLLRegisters --
243  *
244  * Display an integrated Mach64's PLL registers when the server is invoked with
245  * -verbose.
246  */
247 static void
ATIMach64PrintPLLRegisters(ATIPtr pATI)248 ATIMach64PrintPLLRegisters
249 (
250     ATIPtr pATI
251 )
252 {
253     int Index, Limit;
254     CARD8 PLLReg[MaxBits(PLL_ADDR) + 1];
255 
256     for (Limit = 0;  Limit < SizeOf(PLLReg);  Limit++)
257         PLLReg[Limit] = ATIMach64GetPLLReg(Limit);
258 
259     /* Determine how many PLL registers there really are */
260     while ((Limit = Limit >> 1))
261         for (Index = 0;  Index < Limit;  Index++)
262             if (PLLReg[Index] != PLLReg[Index + Limit])
263                 goto FoundLimit;
264 FoundLimit:
265     Limit <<= 1;
266 
267     xf86ErrorFVerb(4, "\n Mach64 PLL register values:");
268     for (Index = 0;  Index < Limit;  Index++)
269     {
270         if (!(Index & 3))
271         {
272             if (!(Index & 15))
273                 xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
274             xf86ErrorFVerb(4, " ");
275         }
276         xf86ErrorFVerb(4, "%02X", PLLReg[Index]);
277     }
278 
279     xf86ErrorFVerb(4, "\n");
280 }
281 
282 /*
283  * ATIRGB514PrintRegisters --
284  *
285  * Display IBM RGB 514 registers when the server is invoked with -verbose.
286  */
287 static void
ATIRGB514PrintRegisters(ATIPtr pATI)288 ATIRGB514PrintRegisters
289 (
290     ATIPtr pATI
291 )
292 {
293     CARD32 crtc_gen_cntl, dac_cntl;
294     CARD8  index_lo, index_hi, index_ctl;
295     int    Index;
296 
297     /* Temporarily switch to Mach64 CRTC */
298     crtc_gen_cntl = inr(CRTC_GEN_CNTL);
299     if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
300         outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN);
301 
302     /* Temporarily switch to IBM RGB 514 registers */
303     dac_cntl = inr(DAC_CNTL);
304     outr(DAC_CNTL, (dac_cntl & ~DAC_EXT_SEL_RS3) | DAC_EXT_SEL_RS2);
305 
306     index_lo = in8(M64_DAC_WRITE);
307     index_hi = in8(M64_DAC_DATA);
308     index_ctl = in8(M64_DAC_READ);
309 
310     out8(M64_DAC_WRITE, 0x00U);
311     out8(M64_DAC_DATA, 0x00U);
312     out8(M64_DAC_READ, 0x01U);  /* Auto-increment */
313 
314     xf86ErrorFVerb(4, "\n IBM RGB 514 registers:");
315     for (Index = 0;  Index < 0x0800;  Index++)
316     {
317         if (!(Index & 3))
318         {
319             if (!(Index & 15))
320             {
321                 xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
322 
323                 /* Need to rewrite index every so often... */
324                 if ((Index == 0x0100) || (Index == 0x0500))
325                 {
326                     out8(M64_DAC_WRITE, 0x00U);
327                     out8(M64_DAC_DATA, Index >> 8);
328                 }
329             }
330 
331             xf86ErrorFVerb(4, " ");
332         }
333 
334         xf86ErrorFVerb(4, "%02X", in8(M64_DAC_MASK));
335     }
336 
337     /* Restore registers */
338     out8(M64_DAC_WRITE, index_lo);
339     out8(M64_DAC_DATA, index_hi);
340     out8(M64_DAC_READ, index_ctl);
341     outr(DAC_CNTL, dac_cntl);
342     if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN))
343         outr(CRTC_GEN_CNTL, crtc_gen_cntl);
344 
345     xf86ErrorFVerb(4, "\n");
346 }
347 
348 /*
349  * ATIPrintRegisters --
350  *
351  * Display various registers when the server is invoked with -verbose.
352  */
353 void
ATIPrintRegisters(ATIPtr pATI)354 ATIPrintRegisters
355 (
356     ATIPtr pATI
357 )
358 {
359     int          Index;
360     CARD32       lcd_index, tv_out_index, lcd_gen_ctrl;
361     CARD8        dac_read, dac_mask, dac_write;
362     CARD8        crtc;
363 
364 #ifndef AVOID_CPIO
365 
366     CARD8 genmo;
367 
368     crtc = ATI_CRTC_VGA;
369 
370     if (pATI->VGAAdapter)
371     {
372         xf86ErrorFVerb(4, "\n Miscellaneous output register value:  0x%02X.\n",
373             genmo = inb(R_GENMO));
374 
375         if (genmo & 0x01U)
376         {
377             if (pATI->Chip == ATI_CHIP_264LT)
378             {
379                 lcd_gen_ctrl = inr(LCD_GEN_CTRL);
380 
381                 outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
382                 ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
383                     "Non-shadow colour CRT controller", 0);
384 
385                 outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
386                 ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
387                     "Shadow colour CRT controller", 0);
388 
389                 outr(LCD_GEN_CTRL, lcd_gen_ctrl);
390             }
391             else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
392                      (pATI->Chip == ATI_CHIP_264XL) ||
393                      (pATI->Chip == ATI_CHIP_MOBILITY))
394             {
395                 lcd_index = inr(LCD_INDEX);
396                 lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
397 
398                 ATIMach64PutLCDReg(LCD_GEN_CNTL,
399                     lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
400                 ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
401                     "Non-shadow colour CRT controller", 0);
402 
403                 ATIMach64PutLCDReg(LCD_GEN_CNTL,
404                     (lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
405                 ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
406                     "Shadow colour CRT controller", 0);
407 
408                 ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
409                 outr(LCD_INDEX, lcd_index);
410             }
411             else
412             {
413                 ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
414                     "Colour CRT controller", 0);
415             }
416 
417             ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
418                 GENS1(ColourIOBase));
419         }
420         else
421         {
422             if (pATI->Chip == ATI_CHIP_264LT)
423             {
424                 lcd_gen_ctrl = inr(LCD_GEN_CTRL);
425 
426                 outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
427                 ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
428                     "Non-shadow monochrome CRT controller", 0);
429 
430                 outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
431                 ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
432                     "Shadow monochrome CRT controller", 0);
433 
434                 outr(LCD_GEN_CTRL, lcd_gen_ctrl);
435             }
436             else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
437                      (pATI->Chip == ATI_CHIP_264XL) ||
438                      (pATI->Chip == ATI_CHIP_MOBILITY))
439             {
440                 lcd_index = inr(LCD_INDEX);
441                 lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
442 
443                 ATIMach64PutLCDReg(LCD_GEN_CNTL,
444                     lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
445                 ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
446                     "Non-shadow monochrome CRT controller", 0);
447 
448                 ATIMach64PutLCDReg(LCD_GEN_CNTL,
449                     (lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
450                 ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
451                     "Shadow monochrome CRT controller", 0);
452 
453                 ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
454                 outr(LCD_INDEX, lcd_index);
455             }
456             else
457             {
458                 ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
459                     "Monochrome CRT controller", 0);
460             }
461 
462             ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
463                 GENS1(MonochromeIOBase));
464         }
465 
466         ATIPrintIndexedRegisters(GRAX, 0, 16, "Graphics controller", 0);
467         ATIPrintIndexedRegisters(SEQX, 0, 8, "Sequencer", 0);
468 
469         if (pATI->CPIO_VGAWonder)
470             ATIPrintIndexedRegisters(pATI->CPIO_VGAWonder, 0x80U, 0xC0U,
471                 "ATI extended VGA", 0);
472     }
473 
474 #endif /* AVOID_CPIO */
475 
476     if (pATI->Chip == ATI_CHIP_264LT)
477     {
478         lcd_gen_ctrl = inr(LCD_GEN_CTRL);
479 
480         outr(LCD_GEN_CTRL, lcd_gen_ctrl & ~SHADOW_RW_EN);
481         ATIMach64PrintRegisters(pATI, &crtc, "non-shadow");
482 
483         outr(LCD_GEN_CTRL, lcd_gen_ctrl | SHADOW_RW_EN);
484         ATIMach64PrintRegisters(pATI, &crtc, "shadow");
485 
486         outr(LCD_GEN_CTRL, lcd_gen_ctrl);
487 
488         ATIMach64PrintPLLRegisters(pATI);
489     }
490     else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
491              (pATI->Chip == ATI_CHIP_264XL) ||
492              (pATI->Chip == ATI_CHIP_MOBILITY))
493     {
494         lcd_index = inr(LCD_INDEX);
495         lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
496 
497         ATIMach64PutLCDReg(LCD_GEN_CNTL,
498             lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_RW_EN));
499         ATIMach64PrintRegisters(pATI, &crtc, "non-shadow");
500 
501         ATIMach64PutLCDReg(LCD_GEN_CNTL,
502             (lcd_gen_ctrl & ~CRTC_RW_SELECT) | SHADOW_RW_EN);
503         ATIMach64PrintRegisters(pATI, &crtc, "shadow");
504 
505         if (pATI->Chip != ATI_CHIP_264XL)
506         {
507             ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl | CRTC_RW_SELECT);
508             ATIMach64PrintRegisters(pATI, &crtc, "secondary");
509         }
510 
511         ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
512 
513         ATIMach64PrintPLLRegisters(pATI);
514 
515         xf86ErrorFVerb(4, "\n LCD register values:");
516         for (Index = 0;  Index < 64;  Index++)
517         {
518             if (!(Index & 3))
519                 xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
520             xf86ErrorFVerb(4, " %08X", ATIMach64GetLCDReg(Index));
521         }
522 
523         outr(LCD_INDEX, lcd_index);
524 
525         tv_out_index = inr(TV_OUT_INDEX);
526 
527         xf86ErrorFVerb(4, "\n\n TV_OUT register values:");
528         for (Index = 0;  Index < 256;  Index++)
529         {
530             if (!(Index & 3))
531                 xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
532             xf86ErrorFVerb(4, " %08X", ATIMach64GetTVReg(Index));
533         }
534 
535         outr(TV_OUT_INDEX, tv_out_index);
536 
537         xf86ErrorFVerb(4, "\n");
538     }
539     else
540     {
541 
542 #ifdef AVOID_CPIO
543 
544         ATIMach64PrintRegisters(pATI, &crtc, "MMIO");
545 
546 #else /* AVOID_CPIO */
547 
548         ATIMach64PrintRegisters(pATI, &crtc,
549             (pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block");
550 
551 #endif /* AVOID_CPIO */
552 
553         if (pATI->Chip >= ATI_CHIP_264CT)
554             ATIMach64PrintPLLRegisters(pATI);
555 
556         if (pATI->DAC == ATI_DAC_IBMRGB514)
557             ATIRGB514PrintRegisters(pATI);
558     }
559 
560 #ifdef AVOID_CPIO
561 
562     dac_read = in8(M64_DAC_READ);
563     DACDelay;
564     dac_write = in8(M64_DAC_WRITE);
565     DACDelay;
566     dac_mask = in8(M64_DAC_MASK);
567     DACDelay;
568 
569     xf86ErrorFVerb(4, "\n"
570                " DAC read index:   0x%02X\n"
571                " DAC write index:  0x%02X\n"
572                " DAC mask:         0x%02X\n\n"
573                " DAC colour lookup table:",
574         dac_read, dac_write, dac_mask);
575 
576     out8(M64_DAC_MASK, 0xFFU);
577     DACDelay;
578     out8(M64_DAC_READ, 0x00U);
579     DACDelay;
580 
581     for (Index = 0;  Index < 256;  Index++)
582     {
583         if (!(Index & 3))
584             xf86ErrorFVerb(4, "\n 0x%02X:", Index);
585         xf86ErrorFVerb(4, "  %02X", in8(M64_DAC_DATA));
586         DACDelay;
587         xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
588         DACDelay;
589         xf86ErrorFVerb(4, " %02X", in8(M64_DAC_DATA));
590         DACDelay;
591     }
592 
593     out8(M64_DAC_MASK, dac_mask);
594     DACDelay;
595     out8(M64_DAC_READ, dac_read);
596     DACDelay;
597 
598 #else /* AVOID_CPIO */
599 
600     ATISetDACIOPorts(pATI, crtc);
601 
602     dac_read = inb(pATI->CPIO_DAC_READ);
603     DACDelay;
604     dac_write = inb(pATI->CPIO_DAC_WRITE);
605     DACDelay;
606     dac_mask = inb(pATI->CPIO_DAC_MASK);
607     DACDelay;
608 
609     xf86ErrorFVerb(4, "\n"
610                " DAC read index:   0x%02X\n"
611                " DAC write index:  0x%02X\n"
612                " DAC mask:         0x%02X\n\n"
613                " DAC colour lookup table:",
614         dac_read, dac_write, dac_mask);
615 
616     outb(pATI->CPIO_DAC_MASK, 0xFFU);
617     DACDelay;
618     outb(pATI->CPIO_DAC_READ, 0x00U);
619     DACDelay;
620 
621     for (Index = 0;  Index < 256;  Index++)
622     {
623         if (!(Index & 3))
624             xf86ErrorFVerb(4, "\n 0x%02X:", Index);
625         xf86ErrorFVerb(4, "  %02X", inb(pATI->CPIO_DAC_DATA));
626         DACDelay;
627         xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
628         DACDelay;
629         xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
630         DACDelay;
631     }
632 
633     outb(pATI->CPIO_DAC_MASK, dac_mask);
634     DACDelay;
635     outb(pATI->CPIO_DAC_READ, dac_read);
636     DACDelay;
637 
638 #endif /* AVOID_CPIO */
639 
640     {
641         xf86ErrorFVerb(4, "\n\n PCI configuration register values:");
642         for (Index = 0;  Index < 256;  Index+= 4)
643         {
644             pciVideoPtr pVideo = pATI->PCIInfo;
645             uint32_t    data;
646 
647             PCI_READ_LONG(pVideo, &data, Index);
648 
649             if (!(Index & 15))
650                 xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
651             xf86ErrorFVerb(4, " 0x%08X", data);
652         }
653     }
654 
655     xf86ErrorFVerb(4, "\n");
656 
657 #ifndef AVOID_CPIO
658 
659     if (pATI->pBank)
660         xf86ErrorFVerb(4, "\n Banked aperture at 0x%0lX.",
661             (unsigned long)pATI->pBank);
662     else
663         xf86ErrorFVerb(4, "\n No banked aperture.");
664 
665 #endif /* AVOID_CPIO */
666 
667     if (pATI->pMemory)
668     {
669         xf86ErrorFVerb(4, "\n Linear aperture at %p.\n", pATI->pMemory);
670     }
671 
672     if (pATI->pBlock[0])
673     {
674         xf86ErrorFVerb(4, " Block 0 aperture at %p.\n", pATI->pBlock[0]);
675         if (inr(CONFIG_CHIP_ID) == pATI->config_chip_id)
676             xf86ErrorFVerb(4, " MMIO registers are correctly mapped.\n");
677         else
678             xf86ErrorFVerb(4, " MMIO mapping is in error!\n");
679         if (pATI->pBlock[1])
680             xf86ErrorFVerb(4, " Block 1 aperture at %p.\n",
681                 pATI->pBlock[1]);
682     }
683     else
684     {
685         xf86ErrorFVerb(4, " No MMIO aperture.\n");
686     }
687 
688     if (pATI->pCursorImage)
689         xf86ErrorFVerb(4, " Hardware cursor image aperture at %p.\n",
690             pATI->pCursorImage);
691     else
692         xf86ErrorFVerb(4, " No hardware cursor image aperture.\n");
693 
694     xf86ErrorFVerb(4, "\n");
695 }
696 
697 /*
698  * A table to associate mode attributes with character strings.
699  */
700 static const SymTabRec ModeAttributeNames[] =
701 {
702     {V_PHSYNC,    "+hsync"},
703     {V_NHSYNC,    "-hsync"},
704     {V_PVSYNC,    "+vsync"},
705     {V_NVSYNC,    "-vsync"},
706     {V_PCSYNC,    "+csync"},
707     {V_NCSYNC,    "-csync"},
708     {V_INTERLACE, "interlace"},
709     {V_DBLSCAN,   "doublescan"},
710     {V_CSYNC,     "composite"},
711     {V_DBLCLK,    "dblclk"},
712     {V_CLKDIV2,   "clkdiv2"},
713     {0,           NULL}
714 };
715 
716 /*
717  * ATIPrintMode --
718  *
719  * This function displays a mode's timing information.
720  */
721 void
ATIPrintMode(DisplayModePtr pMode)722 ATIPrintMode
723 (
724     DisplayModePtr pMode
725 )
726 {
727     const SymTabRec *pSymbol  = ModeAttributeNames;
728     int             flags     = pMode->Flags;
729     double          mClock, hSync, vRefresh;
730 
731     mClock = (double)pMode->SynthClock;
732     if (pMode->HSync > 0.0)
733         hSync = pMode->HSync;
734     else
735         hSync = mClock / pMode->HTotal;
736     if (pMode->VRefresh > 0.0)
737     {
738         vRefresh = pMode->VRefresh;
739     }
740     else
741     {
742         vRefresh = (hSync * 1000.0) / pMode->VTotal;
743         if (flags & V_INTERLACE)
744             vRefresh *= 2.0;
745         if (flags & V_DBLSCAN)
746             vRefresh /= 2.0;
747         if (pMode->VScan > 1)
748             vRefresh /= pMode->VScan;
749     }
750 
751     xf86ErrorFVerb(4, " Dot clock:           %7.3f MHz\n", mClock / 1000.0);
752     xf86ErrorFVerb(4, " Horizontal sync:     %7.3f kHz\n", hSync);
753     xf86ErrorFVerb(4, " Vertical refresh:    %7.3f Hz (%s)\n", vRefresh,
754         (flags & V_INTERLACE) ? "I" : "NI");
755     if ((pMode->ClockIndex >= 0) && (pMode->ClockIndex < MAXCLOCKS))
756         xf86ErrorFVerb(4, " Clock index:         %d\n", pMode->ClockIndex);
757     xf86ErrorFVerb(4, " Horizontal timings:  %4d %4d %4d %4d\n"
758                       " Vertical timings:    %4d %4d %4d %4d\n",
759         pMode->HDisplay, pMode->HSyncStart, pMode->HSyncEnd, pMode->HTotal,
760         pMode->VDisplay, pMode->VSyncStart, pMode->VSyncEnd, pMode->VTotal);
761 
762     if (flags & V_HSKEW)
763     {
764         flags &= ~V_HSKEW;
765         xf86ErrorFVerb(4, " Horizontal skew:     %4d\n", pMode->HSkew);
766     }
767 
768     if (pMode->VScan >= 1)
769         xf86ErrorFVerb(4, " Vertical scan:       %4d\n", pMode->VScan);
770 
771     xf86ErrorFVerb(4, " Flags:              ");
772     for (;  pSymbol->token;  pSymbol++)
773     {
774         if (flags & pSymbol->token)
775         {
776             xf86ErrorFVerb(4, " %s", pSymbol->name);
777             flags &= ~pSymbol->token;
778             if (!flags)
779                 break;
780         }
781     }
782 
783     xf86ErrorFVerb(4, "\n");
784 }
785