[PATCH] atyfb: Fix kconfig error
[safe/jmp/linux-2.6] / drivers / video / aty / atyfb_base.c
1 /*
2  *  ATI Frame Buffer Device Driver Core
3  *
4  *      Copyright (C) 2004  Alex Kern <alex.kern@gmx.de>
5  *      Copyright (C) 1997-2001  Geert Uytterhoeven
6  *      Copyright (C) 1998  Bernd Harries
7  *      Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
8  *
9  *  This driver supports the following ATI graphics chips:
10  *    - ATI Mach64
11  *
12  *  To do: add support for
13  *    - ATI Rage128 (from aty128fb.c)
14  *    - ATI Radeon (from radeonfb.c)
15  *
16  *  This driver is partly based on the PowerMac console driver:
17  *
18  *      Copyright (C) 1996 Paul Mackerras
19  *
20  *  and on the PowerMac ATI/mach64 display driver:
21  *
22  *      Copyright (C) 1997 Michael AK Tesch
23  *
24  *            with work by Jon Howell
25  *                         Harry AC Eaton
26  *                         Anthony Tong <atong@uiuc.edu>
27  *
28  *  Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
29  *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
30  *
31  *  This file is subject to the terms and conditions of the GNU General Public
32  *  License. See the file COPYING in the main directory of this archive for
33  *  more details.
34  *
35  *  Many thanks to Nitya from ATI devrel for support and patience !
36  */
37
38 /******************************************************************************
39
40   TODO:
41
42     - cursor support on all cards and all ramdacs.
43     - cursor parameters controlable via ioctl()s.
44     - guess PLL and MCLK based on the original PLL register values initialized
45       by Open Firmware (if they are initialized). BIOS is done
46
47     (Anyone with Mac to help with this?)
48
49 ******************************************************************************/
50
51
52 #include <linux/module.h>
53 #include <linux/moduleparam.h>
54 #include <linux/kernel.h>
55 #include <linux/errno.h>
56 #include <linux/string.h>
57 #include <linux/mm.h>
58 #include <linux/slab.h>
59 #include <linux/vmalloc.h>
60 #include <linux/delay.h>
61 #include <linux/console.h>
62 #include <linux/fb.h>
63 #include <linux/init.h>
64 #include <linux/pci.h>
65 #include <linux/interrupt.h>
66 #include <linux/spinlock.h>
67 #include <linux/wait.h>
68 #include <linux/backlight.h>
69
70 #include <asm/io.h>
71 #include <asm/uaccess.h>
72
73 #include <video/mach64.h>
74 #include "atyfb.h"
75 #include "ati_ids.h"
76
77 #ifdef __powerpc__
78 #include <asm/machdep.h>
79 #include <asm/prom.h>
80 #include "../macmodes.h"
81 #endif
82 #ifdef __sparc__
83 #include <asm/pbm.h>
84 #include <asm/fbio.h>
85 #endif
86
87 #ifdef CONFIG_ADB_PMU
88 #include <linux/adb.h>
89 #include <linux/pmu.h>
90 #endif
91 #ifdef CONFIG_BOOTX_TEXT
92 #include <asm/btext.h>
93 #endif
94 #ifdef CONFIG_PMAC_BACKLIGHT
95 #include <asm/backlight.h>
96 #endif
97 #ifdef CONFIG_MTRR
98 #include <asm/mtrr.h>
99 #endif
100
101 /*
102  * Debug flags.
103  */
104 #undef DEBUG
105 /*#define DEBUG*/
106
107 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
108 /*  - must be large enough to catch all GUI-Regs   */
109 /*  - must be aligned to a PAGE boundary           */
110 #define GUI_RESERVE     (1 * PAGE_SIZE)
111
112 /* FIXME: remove the FAIL definition */
113 #define FAIL(msg) do { \
114         if (!(var->activate & FB_ACTIVATE_TEST)) \
115                 printk(KERN_CRIT "atyfb: " msg "\n"); \
116         return -EINVAL; \
117 } while (0)
118 #define FAIL_MAX(msg, x, _max_) do { \
119         if (x > _max_) { \
120                 if (!(var->activate & FB_ACTIVATE_TEST)) \
121                         printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
122                 return -EINVAL; \
123         } \
124 } while (0)
125 #ifdef DEBUG
126 #define DPRINTK(fmt, args...)   printk(KERN_DEBUG "atyfb: " fmt, ## args)
127 #else
128 #define DPRINTK(fmt, args...)
129 #endif
130
131 #define PRINTKI(fmt, args...)   printk(KERN_INFO "atyfb: " fmt, ## args)
132 #define PRINTKE(fmt, args...)    printk(KERN_ERR "atyfb: " fmt, ## args)
133
134 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
135 defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
136 static const u32 lt_lcd_regs[] = {
137         CONFIG_PANEL_LG,
138         LCD_GEN_CNTL_LG,
139         DSTN_CONTROL_LG,
140         HFB_PITCH_ADDR_LG,
141         HORZ_STRETCHING_LG,
142         VERT_STRETCHING_LG,
143         0, /* EXT_VERT_STRETCH */
144         LT_GIO_LG,
145         POWER_MANAGEMENT_LG
146 };
147
148 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
149 {
150         if (M64_HAS(LT_LCD_REGS)) {
151                 aty_st_le32(lt_lcd_regs[index], val, par);
152         } else {
153                 unsigned long temp;
154
155                 /* write addr byte */
156                 temp = aty_ld_le32(LCD_INDEX, par);
157                 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
158                 /* write the register value */
159                 aty_st_le32(LCD_DATA, val, par);
160         }
161 }
162
163 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
164 {
165         if (M64_HAS(LT_LCD_REGS)) {
166                 return aty_ld_le32(lt_lcd_regs[index], par);
167         } else {
168                 unsigned long temp;
169
170                 /* write addr byte */
171                 temp = aty_ld_le32(LCD_INDEX, par);
172                 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
173                 /* read the register value */
174                 return aty_ld_le32(LCD_DATA, par);
175         }
176 }
177 #endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
178
179 #ifdef CONFIG_FB_ATY_GENERIC_LCD
180 /*
181  * ATIReduceRatio --
182  *
183  * Reduce a fraction by factoring out the largest common divider of the
184  * fraction's numerator and denominator.
185  */
186 static void ATIReduceRatio(int *Numerator, int *Denominator)
187 {
188     int Multiplier, Divider, Remainder;
189
190     Multiplier = *Numerator;
191     Divider = *Denominator;
192
193     while ((Remainder = Multiplier % Divider))
194     {
195         Multiplier = Divider;
196         Divider = Remainder;
197     }
198
199     *Numerator /= Divider;
200     *Denominator /= Divider;
201 }
202 #endif
203     /*
204      *  The Hardware parameters for each card
205      */
206
207 struct pci_mmap_map {
208         unsigned long voff;
209         unsigned long poff;
210         unsigned long size;
211         unsigned long prot_flag;
212         unsigned long prot_mask;
213 };
214
215 static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
216         .id             = "ATY Mach64",
217         .type           = FB_TYPE_PACKED_PIXELS,
218         .visual         = FB_VISUAL_PSEUDOCOLOR,
219         .xpanstep       = 8,
220         .ypanstep       = 1,
221 };
222
223     /*
224      *  Frame buffer device API
225      */
226
227 static int atyfb_open(struct fb_info *info, int user);
228 static int atyfb_release(struct fb_info *info, int user);
229 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
230 static int atyfb_set_par(struct fb_info *info);
231 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
232         u_int transp, struct fb_info *info);
233 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
234 static int atyfb_blank(int blank, struct fb_info *info);
235 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
236 #ifdef __sparc__
237 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
238 #endif
239 static int atyfb_sync(struct fb_info *info);
240
241     /*
242      *  Internal routines
243      */
244
245 static int aty_init(struct fb_info *info);
246 static void aty_resume_chip(struct fb_info *info);
247 #ifdef CONFIG_ATARI
248 static int store_video_par(char *videopar, unsigned char m64_num);
249 #endif
250
251 static struct crtc saved_crtc;
252 static union aty_pll saved_pll;
253 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
254
255 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
256 static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);
257 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);
258 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
259 #ifdef CONFIG_PPC
260 static int read_aty_sense(const struct atyfb_par *par);
261 #endif
262
263
264     /*
265      *  Interface used by the world
266      */
267
268 static struct fb_var_screeninfo default_var = {
269         /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
270         640, 480, 640, 480, 0, 0, 8, 0,
271         {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
272         0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
273         0, FB_VMODE_NONINTERLACED
274 };
275
276 static struct fb_videomode defmode = {
277         /* 640x480 @ 60 Hz, 31.5 kHz hsync */
278         NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
279         0, FB_VMODE_NONINTERLACED
280 };
281
282 static struct fb_ops atyfb_ops = {
283         .owner          = THIS_MODULE,
284         .fb_open        = atyfb_open,
285         .fb_release     = atyfb_release,
286         .fb_check_var   = atyfb_check_var,
287         .fb_set_par     = atyfb_set_par,
288         .fb_setcolreg   = atyfb_setcolreg,
289         .fb_pan_display = atyfb_pan_display,
290         .fb_blank       = atyfb_blank,
291         .fb_ioctl       = atyfb_ioctl,
292         .fb_fillrect    = atyfb_fillrect,
293         .fb_copyarea    = atyfb_copyarea,
294         .fb_imageblit   = atyfb_imageblit,
295 #ifdef __sparc__
296         .fb_mmap        = atyfb_mmap,
297 #endif
298         .fb_sync        = atyfb_sync,
299 };
300
301 static int noaccel;
302 #ifdef CONFIG_MTRR
303 static int nomtrr;
304 #endif
305 static int vram;
306 static int pll;
307 static int mclk;
308 static int xclk;
309 static int comp_sync __devinitdata = -1;
310 static char *mode;
311
312 #ifdef CONFIG_PPC
313 static int default_vmode __devinitdata = VMODE_CHOOSE;
314 static int default_cmode __devinitdata = CMODE_CHOOSE;
315
316 module_param_named(vmode, default_vmode, int, 0);
317 MODULE_PARM_DESC(vmode, "int: video mode for mac");
318 module_param_named(cmode, default_cmode, int, 0);
319 MODULE_PARM_DESC(cmode, "int: color mode for mac");
320 #endif
321
322 #ifdef CONFIG_ATARI
323 static unsigned int mach64_count __devinitdata = 0;
324 static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, };
325 static unsigned long phys_size[FB_MAX] __devinitdata = { 0, };
326 static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
327 #endif
328
329 /* top -> down is an evolution of mach64 chipset, any corrections? */
330 #define ATI_CHIP_88800GX   (M64F_GX)
331 #define ATI_CHIP_88800CX   (M64F_GX)
332
333 #define ATI_CHIP_264CT     (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
334 #define ATI_CHIP_264ET     (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
335
336 #define ATI_CHIP_264VT     (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
337 #define ATI_CHIP_264GT     (M64F_GT | M64F_INTEGRATED               | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
338
339 #define ATI_CHIP_264VTB    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
340 #define ATI_CHIP_264VT3    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
341 #define ATI_CHIP_264VT4    (M64F_VT | M64F_INTEGRATED               | M64F_GTB_DSP)
342
343 /* FIXME what is this chip? */
344 #define ATI_CHIP_264LT     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP)
345
346 /* make sets shorter */
347 #define ATI_MODERN_SET     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
348
349 #define ATI_CHIP_264GTB    (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
350 /*#define ATI_CHIP_264GTDVD  ?*/
351 #define ATI_CHIP_264LTG    (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
352
353 #define ATI_CHIP_264GT2C   (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
354 #define ATI_CHIP_264GTPRO  (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
355 #define ATI_CHIP_264LTPRO  (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
356
357 #define ATI_CHIP_264XL     (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
358 #define ATI_CHIP_MOBILITY  (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS)
359
360 static struct {
361         u16 pci_id;
362         const char *name;
363         int pll, mclk, xclk, ecp_max;
364         u32 features;
365 } aty_chips[] __devinitdata = {
366 #ifdef CONFIG_FB_ATY_GX
367         /* Mach64 GX */
368         { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
369         { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },
370 #endif /* CONFIG_FB_ATY_GX */
371
372 #ifdef CONFIG_FB_ATY_CT
373         { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },
374         { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },
375
376         /* FIXME what is this chip? */
377         { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },
378
379         { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },
380         { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },
381
382         { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },
383         { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },
384
385         { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
386
387         { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },
388
389         { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
390         { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
391         { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
392         { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
393
394         { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
395         { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
396         { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
397         { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
398         { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
399
400         { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
401         { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
402         { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
403         { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
404         { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
405
406         { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
407         { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
408         { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
409         { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
410         { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
411         { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },
412
413         { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
414         { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
415         { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
416         { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
417 #endif /* CONFIG_FB_ATY_CT */
418 };
419
420 /* can not fail */
421 static int __devinit correct_chipset(struct atyfb_par *par)
422 {
423         u8 rev;
424         u16 type;
425         u32 chip_id;
426         const char *name;
427         int i;
428
429         for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
430                 if (par->pci_id == aty_chips[i].pci_id)
431                         break;
432
433         name = aty_chips[i].name;
434         par->pll_limits.pll_max = aty_chips[i].pll;
435         par->pll_limits.mclk = aty_chips[i].mclk;
436         par->pll_limits.xclk = aty_chips[i].xclk;
437         par->pll_limits.ecp_max = aty_chips[i].ecp_max;
438         par->features = aty_chips[i].features;
439
440         chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
441         type = chip_id & CFG_CHIP_TYPE;
442         rev = (chip_id & CFG_CHIP_REV) >> 24;
443
444         switch(par->pci_id) {
445 #ifdef CONFIG_FB_ATY_GX
446         case PCI_CHIP_MACH64GX:
447                 if(type != 0x00d7)
448                         return -ENODEV;
449                 break;
450         case PCI_CHIP_MACH64CX:
451                 if(type != 0x0057)
452                         return -ENODEV;
453                 break;
454 #endif
455 #ifdef CONFIG_FB_ATY_CT
456         case PCI_CHIP_MACH64VT:
457                 switch (rev & 0x07) {
458                 case 0x00:
459                         switch (rev & 0xc0) {
460                         case 0x00:
461                                 name = "ATI264VT (A3) (Mach64 VT)";
462                                 par->pll_limits.pll_max = 170;
463                                 par->pll_limits.mclk = 67;
464                                 par->pll_limits.xclk = 67;
465                                 par->pll_limits.ecp_max = 80;
466                                 par->features = ATI_CHIP_264VT;
467                                 break;
468                         case 0x40:
469                                 name = "ATI264VT2 (A4) (Mach64 VT)";
470                                 par->pll_limits.pll_max = 200;
471                                 par->pll_limits.mclk = 67;
472                                 par->pll_limits.xclk = 67;
473                                 par->pll_limits.ecp_max = 80;
474                                 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
475                                 break;
476                         }
477                         break;
478                 case 0x01:
479                         name = "ATI264VT3 (B1) (Mach64 VT)";
480                         par->pll_limits.pll_max = 200;
481                         par->pll_limits.mclk = 67;
482                         par->pll_limits.xclk = 67;
483                         par->pll_limits.ecp_max = 80;
484                         par->features = ATI_CHIP_264VTB;
485                         break;
486                 case 0x02:
487                         name = "ATI264VT3 (B2) (Mach64 VT)";
488                         par->pll_limits.pll_max = 200;
489                         par->pll_limits.mclk = 67;
490                         par->pll_limits.xclk = 67;
491                         par->pll_limits.ecp_max = 80;
492                         par->features = ATI_CHIP_264VT3;
493                         break;
494                 }
495                 break;
496         case PCI_CHIP_MACH64GT:
497                 switch (rev & 0x07) {
498                 case 0x01:
499                         name = "3D RAGE II (Mach64 GT)";
500                         par->pll_limits.pll_max = 170;
501                         par->pll_limits.mclk = 67;
502                         par->pll_limits.xclk = 67;
503                         par->pll_limits.ecp_max = 80;
504                         par->features = ATI_CHIP_264GTB;
505                         break;
506                 case 0x02:
507                         name = "3D RAGE II+ (Mach64 GT)";
508                         par->pll_limits.pll_max = 200;
509                         par->pll_limits.mclk = 67;
510                         par->pll_limits.xclk = 67;
511                         par->pll_limits.ecp_max = 100;
512                         par->features = ATI_CHIP_264GTB;
513                         break;
514                 }
515                 break;
516 #endif
517         }
518
519         PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
520         return 0;
521 }
522
523 static char ram_dram[] __devinitdata = "DRAM";
524 static char ram_resv[] __devinitdata = "RESV";
525 #ifdef CONFIG_FB_ATY_GX
526 static char ram_vram[] __devinitdata = "VRAM";
527 #endif /* CONFIG_FB_ATY_GX */
528 #ifdef CONFIG_FB_ATY_CT
529 static char ram_edo[] __devinitdata = "EDO";
530 static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
531 static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
532 static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
533 static char ram_off[] __devinitdata = "OFF";
534 #endif /* CONFIG_FB_ATY_CT */
535
536
537 static u32 pseudo_palette[17];
538
539 #ifdef CONFIG_FB_ATY_GX
540 static char *aty_gx_ram[8] __devinitdata = {
541         ram_dram, ram_vram, ram_vram, ram_dram,
542         ram_dram, ram_vram, ram_vram, ram_resv
543 };
544 #endif /* CONFIG_FB_ATY_GX */
545
546 #ifdef CONFIG_FB_ATY_CT
547 static char *aty_ct_ram[8] __devinitdata = {
548         ram_off, ram_dram, ram_edo, ram_edo,
549         ram_sdram, ram_sgram, ram_sdram32, ram_resv
550 };
551 #endif /* CONFIG_FB_ATY_CT */
552
553 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par)
554 {
555         u32 pixclock = var->pixclock;
556 #ifdef CONFIG_FB_ATY_GENERIC_LCD
557         u32 lcd_on_off;
558         par->pll.ct.xres = 0;
559         if (par->lcd_table != 0) {
560                 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
561                 if(lcd_on_off & LCD_ON) {
562                         par->pll.ct.xres = var->xres;
563                         pixclock = par->lcd_pixclock;
564                 }
565         }
566 #endif
567         return pixclock;
568 }
569
570 #if defined(CONFIG_PPC)
571
572 /*
573  *  Apple monitor sense
574  */
575
576 static int __devinit read_aty_sense(const struct atyfb_par *par)
577 {
578         int sense, i;
579
580         aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */
581         __delay(200);
582         aty_st_le32(GP_IO, 0, par); /* turn off outputs */
583         __delay(2000);
584         i = aty_ld_le32(GP_IO, par); /* get primary sense value */
585         sense = ((i & 0x3000) >> 3) | (i & 0x100);
586
587         /* drive each sense line low in turn and collect the other 2 */
588         aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */
589         __delay(2000);
590         i = aty_ld_le32(GP_IO, par);
591         sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
592         aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */
593         __delay(200);
594
595         aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */
596         __delay(2000);
597         i = aty_ld_le32(GP_IO, par);
598         sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
599         aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */
600         __delay(200);
601
602         aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */
603         __delay(2000);
604         sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
605         aty_st_le32(GP_IO, 0, par); /* turn off outputs */
606         return sense;
607 }
608
609 #endif /* defined(CONFIG_PPC) */
610
611 /* ------------------------------------------------------------------------- */
612
613 /*
614  *  CRTC programming
615  */
616
617 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
618 {
619 #ifdef CONFIG_FB_ATY_GENERIC_LCD
620         if (par->lcd_table != 0) {
621                 if(!M64_HAS(LT_LCD_REGS)) {
622                     crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
623                     aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
624                 }
625                 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
626                 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
627
628
629                 /* switch to non shadow registers */
630                 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
631                     ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
632
633                 /* save stretching */
634                 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
635                 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
636                 if (!M64_HAS(LT_LCD_REGS))
637                         crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
638         }
639 #endif
640         crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
641         crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
642         crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
643         crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
644         crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
645         crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
646         crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
647
648 #ifdef CONFIG_FB_ATY_GENERIC_LCD
649         if (par->lcd_table != 0) {
650                 /* switch to shadow registers */
651                 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
652                         SHADOW_EN | SHADOW_RW_EN, par);
653
654                 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
655                 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
656                 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
657                 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
658
659                 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
660         }
661 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
662 }
663
664 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
665 {
666 #ifdef CONFIG_FB_ATY_GENERIC_LCD
667         if (par->lcd_table != 0) {
668                 /* stop CRTC */
669                 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
670
671                 /* update non-shadow registers first */
672                 aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
673                 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
674                         ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
675
676                 /* temporarily disable stretching */
677                 aty_st_lcd(HORZ_STRETCHING,
678                         crtc->horz_stretching &
679                         ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
680                 aty_st_lcd(VERT_STRETCHING,
681                         crtc->vert_stretching &
682                         ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
683                         VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
684         }
685 #endif
686         /* turn off CRT */
687         aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
688
689         DPRINTK("setting up CRTC\n");
690         DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
691             ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1),
692             (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P',
693             (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N');
694
695         DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
696         DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
697         DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
698         DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
699         DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
700         DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
701         DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
702
703         aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
704         aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
705         aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
706         aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
707         aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
708         aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
709
710         aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
711 #if 0
712         FIXME
713         if (par->accel_flags & FB_ACCELF_TEXT)
714                 aty_init_engine(par, info);
715 #endif
716 #ifdef CONFIG_FB_ATY_GENERIC_LCD
717         /* after setting the CRTC registers we should set the LCD registers. */
718         if (par->lcd_table != 0) {
719                 /* switch to shadow registers */
720                 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
721                         (SHADOW_EN | SHADOW_RW_EN), par);
722
723                 DPRINTK("set shadow CRT to %ix%i %c%c\n",
724                     ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
725                     (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
726
727                 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp);
728                 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid);
729                 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp);
730                 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid);
731
732                 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
733                 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
734                 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
735                 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
736
737                 /* restore CRTC selection & shadow state and enable stretching */
738                 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
739                 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
740                 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
741                 if(!M64_HAS(LT_LCD_REGS))
742                     DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
743
744                 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
745                 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
746                 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
747                 if(!M64_HAS(LT_LCD_REGS)) {
748                     aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
749                     aty_ld_le32(LCD_INDEX, par);
750                     aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
751                 }
752         }
753 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
754 }
755
756 static int aty_var_to_crtc(const struct fb_info *info,
757         const struct fb_var_screeninfo *var, struct crtc *crtc)
758 {
759         struct atyfb_par *par = (struct atyfb_par *) info->par;
760         u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
761         u32 sync, vmode, vdisplay;
762         u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
763         u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
764         u32 pix_width, dp_pix_width, dp_chain_mask;
765
766         /* input */
767         xres = var->xres;
768         yres = var->yres;
769         vxres = var->xres_virtual;
770         vyres = var->yres_virtual;
771         xoffset = var->xoffset;
772         yoffset = var->yoffset;
773         bpp = var->bits_per_pixel;
774         if (bpp == 16)
775                 bpp = (var->green.length == 5) ? 15 : 16;
776         sync = var->sync;
777         vmode = var->vmode;
778
779         /* convert (and round up) and validate */
780         if (vxres < xres + xoffset)
781                 vxres = xres + xoffset;
782         h_disp = xres;
783
784         if (vyres < yres + yoffset)
785                 vyres = yres + yoffset;
786         v_disp = yres;
787
788         if (bpp <= 8) {
789                 bpp = 8;
790                 pix_width = CRTC_PIX_WIDTH_8BPP;
791                 dp_pix_width =
792                     HOST_8BPP | SRC_8BPP | DST_8BPP |
793                     BYTE_ORDER_LSB_TO_MSB;
794                 dp_chain_mask = DP_CHAIN_8BPP;
795         } else if (bpp <= 15) {
796                 bpp = 16;
797                 pix_width = CRTC_PIX_WIDTH_15BPP;
798                 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
799                     BYTE_ORDER_LSB_TO_MSB;
800                 dp_chain_mask = DP_CHAIN_15BPP;
801         } else if (bpp <= 16) {
802                 bpp = 16;
803                 pix_width = CRTC_PIX_WIDTH_16BPP;
804                 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
805                     BYTE_ORDER_LSB_TO_MSB;
806                 dp_chain_mask = DP_CHAIN_16BPP;
807         } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
808                 bpp = 24;
809                 pix_width = CRTC_PIX_WIDTH_24BPP;
810                 dp_pix_width =
811                     HOST_8BPP | SRC_8BPP | DST_8BPP |
812                     BYTE_ORDER_LSB_TO_MSB;
813                 dp_chain_mask = DP_CHAIN_24BPP;
814         } else if (bpp <= 32) {
815                 bpp = 32;
816                 pix_width = CRTC_PIX_WIDTH_32BPP;
817                 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
818                     BYTE_ORDER_LSB_TO_MSB;
819                 dp_chain_mask = DP_CHAIN_32BPP;
820         } else
821                 FAIL("invalid bpp");
822
823         if (vxres * vyres * bpp / 8 > info->fix.smem_len)
824                 FAIL("not enough video RAM");
825
826         h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
827         v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
828
829         if((xres > 1600) || (yres > 1200)) {
830                 FAIL("MACH64 chips are designed for max 1600x1200\n"
831                 "select anoter resolution.");
832         }
833         h_sync_strt = h_disp + var->right_margin;
834         h_sync_end = h_sync_strt + var->hsync_len;
835         h_sync_dly  = var->right_margin & 7;
836         h_total = h_sync_end + h_sync_dly + var->left_margin;
837
838         v_sync_strt = v_disp + var->lower_margin;
839         v_sync_end = v_sync_strt + var->vsync_len;
840         v_total = v_sync_end + var->upper_margin;
841
842 #ifdef CONFIG_FB_ATY_GENERIC_LCD
843         if (par->lcd_table != 0) {
844                 if(!M64_HAS(LT_LCD_REGS)) {
845                     u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
846                     crtc->lcd_index = lcd_index &
847                         ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
848                     aty_st_le32(LCD_INDEX, lcd_index, par);
849                 }
850
851                 if (!M64_HAS(MOBIL_BUS))
852                         crtc->lcd_index |= CRTC2_DISPLAY_DIS;
853
854                 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
855                 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
856
857                 crtc->lcd_gen_cntl &=
858                         ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
859                         /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
860                         USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
861                 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
862
863                 if((crtc->lcd_gen_cntl & LCD_ON) &&
864                         ((xres > par->lcd_width) || (yres > par->lcd_height))) {
865                         /* We cannot display the mode on the LCD. If the CRT is enabled
866                            we can turn off the LCD.
867                            If the CRT is off, it isn't a good idea to switch it on; we don't
868                            know if one is connected. So it's better to fail then.
869                          */
870                         if (crtc->lcd_gen_cntl & CRT_ON) {
871                                 if (!(var->activate & FB_ACTIVATE_TEST))
872                                         PRINTKI("Disable LCD panel, because video mode does not fit.\n");
873                                 crtc->lcd_gen_cntl &= ~LCD_ON;
874                                 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
875                         } else {
876                                 if (!(var->activate & FB_ACTIVATE_TEST))
877                                         PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
878                                 return -EINVAL;
879                         }
880                 }
881         }
882
883         if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
884                 int VScan = 1;
885                 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
886                 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
887                 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 };  */
888
889                 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
890
891                 /* This is horror! When we simulate, say 640x480 on an 800x600
892                    LCD monitor, the CRTC should be programmed 800x600 values for
893                    the non visible part, but 640x480 for the visible part.
894                    This code has been tested on a laptop with it's 1400x1050 LCD
895                    monitor and a conventional monitor both switched on.
896                    Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
897                     works with little glitches also with DOUBLESCAN modes
898                  */
899                 if (yres < par->lcd_height) {
900                         VScan = par->lcd_height / yres;
901                         if(VScan > 1) {
902                                 VScan = 2;
903                                 vmode |= FB_VMODE_DOUBLE;
904                         }
905                 }
906
907                 h_sync_strt = h_disp + par->lcd_right_margin;
908                 h_sync_end = h_sync_strt + par->lcd_hsync_len;
909                 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly;
910                 h_total = h_disp + par->lcd_hblank_len;
911
912                 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
913                 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
914                 v_total = v_disp + par->lcd_vblank_len / VScan;
915         }
916 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
917
918         h_disp = (h_disp >> 3) - 1;
919         h_sync_strt = (h_sync_strt >> 3) - 1;
920         h_sync_end = (h_sync_end >> 3) - 1;
921         h_total = (h_total >> 3) - 1;
922         h_sync_wid = h_sync_end - h_sync_strt;
923
924         FAIL_MAX("h_disp too large", h_disp, 0xff);
925         FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
926         /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
927         if(h_sync_wid > 0x1f)
928                 h_sync_wid = 0x1f;
929         FAIL_MAX("h_total too large", h_total, 0x1ff);
930
931         if (vmode & FB_VMODE_DOUBLE) {
932                 v_disp <<= 1;
933                 v_sync_strt <<= 1;
934                 v_sync_end <<= 1;
935                 v_total <<= 1;
936         }
937
938         vdisplay = yres;
939 #ifdef CONFIG_FB_ATY_GENERIC_LCD
940         if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON))
941                 vdisplay  = par->lcd_height;
942 #endif
943
944         v_disp--;
945         v_sync_strt--;
946         v_sync_end--;
947         v_total--;
948         v_sync_wid = v_sync_end - v_sync_strt;
949
950         FAIL_MAX("v_disp too large", v_disp, 0x7ff);
951         FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
952         /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
953         if(v_sync_wid > 0x1f)
954                 v_sync_wid = 0x1f;
955         FAIL_MAX("v_total too large", v_total, 0x7ff);
956
957         c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
958
959         /* output */
960         crtc->vxres = vxres;
961         crtc->vyres = vyres;
962         crtc->xoffset = xoffset;
963         crtc->yoffset = yoffset;
964         crtc->bpp = bpp;
965         crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
966         crtc->vline_crnt_vline = 0;
967
968         crtc->h_tot_disp = h_total | (h_disp<<16);
969         crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
970                 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21);
971         crtc->v_tot_disp = v_total | (v_disp<<16);
972         crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
973
974         /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
975         crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
976         crtc->gen_cntl |= CRTC_VGA_LINEAR;
977
978         /* Enable doublescan mode if requested */
979         if (vmode & FB_VMODE_DOUBLE)
980                 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
981         /* Enable interlaced mode if requested */
982         if (vmode & FB_VMODE_INTERLACED)
983                 crtc->gen_cntl |= CRTC_INTERLACE_EN;
984 #ifdef CONFIG_FB_ATY_GENERIC_LCD
985         if (par->lcd_table != 0) {
986                 vdisplay = yres;
987                 if(vmode & FB_VMODE_DOUBLE)
988                         vdisplay <<= 1;
989                 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
990                 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
991                         /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
992                         USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
993                 crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/);
994
995                 /* MOBILITY M1 tested, FIXME: LT */
996                 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
997                 if (!M64_HAS(LT_LCD_REGS))
998                         crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
999                                 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
1000
1001                 crtc->horz_stretching &=
1002                         ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
1003                         HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
1004                 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) {
1005                         do {
1006                                 /*
1007                                 * The horizontal blender misbehaves when HDisplay is less than a
1008                                 * a certain threshold (440 for a 1024-wide panel).  It doesn't
1009                                 * stretch such modes enough.  Use pixel replication instead of
1010                                 * blending to stretch modes that can be made to exactly fit the
1011                                 * panel width.  The undocumented "NoLCDBlend" option allows the
1012                                 * pixel-replicated mode to be slightly wider or narrower than the
1013                                 * panel width.  It also causes a mode that is exactly half as wide
1014                                 * as the panel to be pixel-replicated, rather than blended.
1015                                 */
1016                                 int HDisplay  = xres & ~7;
1017                                 int nStretch  = par->lcd_width / HDisplay;
1018                                 int Remainder = par->lcd_width % HDisplay;
1019
1020                                 if ((!Remainder && ((nStretch > 2))) ||
1021                                         (((HDisplay * 16) / par->lcd_width) < 7)) {
1022                                         static const char StretchLoops[] = {10, 12, 13, 15, 16};
1023                                         int horz_stretch_loop = -1, BestRemainder;
1024                                         int Numerator = HDisplay, Denominator = par->lcd_width;
1025                                         int Index = 5;
1026                                         ATIReduceRatio(&Numerator, &Denominator);
1027
1028                                         BestRemainder = (Numerator * 16) / Denominator;
1029                                         while (--Index >= 0) {
1030                                                 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1031                                                         Denominator;
1032                                                 if (Remainder < BestRemainder) {
1033                                                         horz_stretch_loop = Index;
1034                                                         if (!(BestRemainder = Remainder))
1035                                                                 break;
1036                                                 }
1037                                         }
1038
1039                                         if ((horz_stretch_loop >= 0) && !BestRemainder) {
1040                                                 int horz_stretch_ratio = 0, Accumulator = 0;
1041                                                 int reuse_previous = 1;
1042
1043                                                 Index = StretchLoops[horz_stretch_loop];
1044
1045                                                 while (--Index >= 0) {
1046                                                         if (Accumulator > 0)
1047                                                                 horz_stretch_ratio |= reuse_previous;
1048                                                         else
1049                                                                 Accumulator += Denominator;
1050                                                         Accumulator -= Numerator;
1051                                                         reuse_previous <<= 1;
1052                                                 }
1053
1054                                                 crtc->horz_stretching |= (HORZ_STRETCH_EN |
1055                                                         ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) |
1056                                                         (horz_stretch_ratio & HORZ_STRETCH_RATIO));
1057                                                 break;      /* Out of the do { ... } while (0) */
1058                                         }
1059                                 }
1060
1061                                 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1062                                         (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
1063                         } while (0);
1064                 }
1065
1066                 if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) {
1067                         crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
1068                                 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1069
1070                         if (!M64_HAS(LT_LCD_REGS) &&
1071                             xres <= (M64_HAS(MOBIL_BUS)?1024:800))
1072                                 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1073                 } else {
1074                         /*
1075                          * Don't use vertical blending if the mode is too wide or not
1076                          * vertically stretched.
1077                          */
1078                         crtc->vert_stretching = 0;
1079                 }
1080                 /* copy to shadow crtc */
1081                 crtc->shadow_h_tot_disp = crtc->h_tot_disp;
1082                 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
1083                 crtc->shadow_v_tot_disp = crtc->v_tot_disp;
1084                 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
1085         }
1086 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1087
1088         if (M64_HAS(MAGIC_FIFO)) {
1089                 /* FIXME: display FIFO low watermark values */
1090                 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM);
1091         }
1092         crtc->dp_pix_width = dp_pix_width;
1093         crtc->dp_chain_mask = dp_chain_mask;
1094
1095         return 0;
1096 }
1097
1098 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var)
1099 {
1100         u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1101         u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
1102             h_sync_pol;
1103         u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1104         u32 pix_width;
1105         u32 double_scan, interlace;
1106
1107         /* input */
1108         h_total = crtc->h_tot_disp & 0x1ff;
1109         h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1110         h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1111         h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1112         h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1113         h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1114         v_total = crtc->v_tot_disp & 0x7ff;
1115         v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1116         v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1117         v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1118         v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1119         c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1120         pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1121         double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1122         interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1123
1124         /* convert */
1125         xres = (h_disp + 1) * 8;
1126         yres = v_disp + 1;
1127         left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1128         right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1129         hslen = h_sync_wid * 8;
1130         upper = v_total - v_sync_strt - v_sync_wid;
1131         lower = v_sync_strt - v_disp;
1132         vslen = v_sync_wid;
1133         sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1134             (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1135             (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1136
1137         switch (pix_width) {
1138 #if 0
1139         case CRTC_PIX_WIDTH_4BPP:
1140                 bpp = 4;
1141                 var->red.offset = 0;
1142                 var->red.length = 8;
1143                 var->green.offset = 0;
1144                 var->green.length = 8;
1145                 var->blue.offset = 0;
1146                 var->blue.length = 8;
1147                 var->transp.offset = 0;
1148                 var->transp.length = 0;
1149                 break;
1150 #endif
1151         case CRTC_PIX_WIDTH_8BPP:
1152                 bpp = 8;
1153                 var->red.offset = 0;
1154                 var->red.length = 8;
1155                 var->green.offset = 0;
1156                 var->green.length = 8;
1157                 var->blue.offset = 0;
1158                 var->blue.length = 8;
1159                 var->transp.offset = 0;
1160                 var->transp.length = 0;
1161                 break;
1162         case CRTC_PIX_WIDTH_15BPP:      /* RGB 555 */
1163                 bpp = 16;
1164                 var->red.offset = 10;
1165                 var->red.length = 5;
1166                 var->green.offset = 5;
1167                 var->green.length = 5;
1168                 var->blue.offset = 0;
1169                 var->blue.length = 5;
1170                 var->transp.offset = 0;
1171                 var->transp.length = 0;
1172                 break;
1173         case CRTC_PIX_WIDTH_16BPP:      /* RGB 565 */
1174                 bpp = 16;
1175                 var->red.offset = 11;
1176                 var->red.length = 5;
1177                 var->green.offset = 5;
1178                 var->green.length = 6;
1179                 var->blue.offset = 0;
1180                 var->blue.length = 5;
1181                 var->transp.offset = 0;
1182                 var->transp.length = 0;
1183                 break;
1184         case CRTC_PIX_WIDTH_24BPP:      /* RGB 888 */
1185                 bpp = 24;
1186                 var->red.offset = 16;
1187                 var->red.length = 8;
1188                 var->green.offset = 8;
1189                 var->green.length = 8;
1190                 var->blue.offset = 0;
1191                 var->blue.length = 8;
1192                 var->transp.offset = 0;
1193                 var->transp.length = 0;
1194                 break;
1195         case CRTC_PIX_WIDTH_32BPP:      /* ARGB 8888 */
1196                 bpp = 32;
1197                 var->red.offset = 16;
1198                 var->red.length = 8;
1199                 var->green.offset = 8;
1200                 var->green.length = 8;
1201                 var->blue.offset = 0;
1202                 var->blue.length = 8;
1203                 var->transp.offset = 24;
1204                 var->transp.length = 8;
1205                 break;
1206         default:
1207                 PRINTKE("Invalid pixel width\n");
1208                 return -EINVAL;
1209         }
1210
1211         /* output */
1212         var->xres = xres;
1213         var->yres = yres;
1214         var->xres_virtual = crtc->vxres;
1215         var->yres_virtual = crtc->vyres;
1216         var->bits_per_pixel = bpp;
1217         var->left_margin = left;
1218         var->right_margin = right;
1219         var->upper_margin = upper;
1220         var->lower_margin = lower;
1221         var->hsync_len = hslen;
1222         var->vsync_len = vslen;
1223         var->sync = sync;
1224         var->vmode = FB_VMODE_NONINTERLACED;
1225         /* In double scan mode, the vertical parameters are doubled, so we need to
1226            half them to get the right values.
1227            In interlaced mode the values are already correct, so no correction is
1228            necessary.
1229          */
1230         if (interlace)
1231                 var->vmode = FB_VMODE_INTERLACED;
1232
1233         if (double_scan) {
1234                 var->vmode = FB_VMODE_DOUBLE;
1235                 var->yres>>=1;
1236                 var->upper_margin>>=1;
1237                 var->lower_margin>>=1;
1238                 var->vsync_len>>=1;
1239         }
1240
1241         return 0;
1242 }
1243
1244 /* ------------------------------------------------------------------------- */
1245
1246 static int atyfb_set_par(struct fb_info *info)
1247 {
1248         struct atyfb_par *par = (struct atyfb_par *) info->par;
1249         struct fb_var_screeninfo *var = &info->var;
1250         u32 tmp, pixclock;
1251         int err;
1252 #ifdef DEBUG
1253         struct fb_var_screeninfo debug;
1254         u32 pixclock_in_ps;
1255 #endif
1256         if (par->asleep)
1257                 return 0;
1258
1259         if ((err = aty_var_to_crtc(info, var, &par->crtc)))
1260                 return err;
1261
1262         pixclock = atyfb_get_pixclock(var, par);
1263
1264         if (pixclock == 0) {
1265                 PRINTKE("Invalid pixclock\n");
1266                 return -EINVAL;
1267         } else {
1268                 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll)))
1269                         return err;
1270         }
1271
1272         par->accel_flags = var->accel_flags; /* hack */
1273
1274         if (var->accel_flags) {
1275                 info->fbops->fb_sync = atyfb_sync;
1276                 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1277         } else {
1278                 info->fbops->fb_sync = NULL;
1279                 info->flags |= FBINFO_HWACCEL_DISABLED;
1280         }
1281
1282         if (par->blitter_may_be_busy)
1283                 wait_for_idle(par);
1284
1285         aty_set_crtc(par, &par->crtc);
1286         par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags);
1287         par->pll_ops->set_pll(info, &par->pll);
1288
1289 #ifdef DEBUG
1290         if(par->pll_ops && par->pll_ops->pll_to_var)
1291                 pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll));
1292         else
1293                 pixclock_in_ps = 0;
1294
1295         if(0 == pixclock_in_ps) {
1296                 PRINTKE("ALERT ops->pll_to_var get 0\n");
1297                 pixclock_in_ps = pixclock;
1298         }
1299
1300         memset(&debug, 0, sizeof(debug));
1301         if(!aty_crtc_to_var(&(par->crtc), &debug)) {
1302                 u32 hSync, vRefresh;
1303                 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1304                 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1305
1306                 h_disp = debug.xres;
1307                 h_sync_strt = h_disp + debug.right_margin;
1308                 h_sync_end = h_sync_strt + debug.hsync_len;
1309                 h_total = h_sync_end + debug.left_margin;
1310                 v_disp = debug.yres;
1311                 v_sync_strt = v_disp + debug.lower_margin;
1312                 v_sync_end = v_sync_strt + debug.vsync_len;
1313                 v_total = v_sync_end + debug.upper_margin;
1314
1315                 hSync = 1000000000 / (pixclock_in_ps * h_total);
1316                 vRefresh = (hSync * 1000) / v_total;
1317                 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1318                 vRefresh *= 2;
1319                 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1320                 vRefresh /= 2;
1321
1322                 DPRINTK("atyfb_set_par\n");
1323                 DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
1324                 DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
1325                         var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps);
1326                 DPRINTK(" Dot clock:           %i MHz\n", 1000000 / pixclock_in_ps);
1327                 DPRINTK(" Horizontal sync:     %i kHz\n", hSync);
1328                 DPRINTK(" Vertical refresh:    %i Hz\n", vRefresh);
1329                 DPRINTK(" x  style: %i.%03i %i %i %i %i   %i %i %i %i\n",
1330                         1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1331                         h_disp, h_sync_strt, h_sync_end, h_total,
1332                         v_disp, v_sync_strt, v_sync_end, v_total);
1333                 DPRINTK(" fb style: %i  %i %i %i %i %i %i %i %i\n",
1334                         pixclock_in_ps,
1335                         debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1336                         debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1337         }
1338 #endif /* DEBUG */
1339
1340         if (!M64_HAS(INTEGRATED)) {
1341                 /* Don't forget MEM_CNTL */
1342                 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1343                 switch (var->bits_per_pixel) {
1344                 case 8:
1345                         tmp |= 0x02000000;
1346                         break;
1347                 case 16:
1348                         tmp |= 0x03000000;
1349                         break;
1350                 case 32:
1351                         tmp |= 0x06000000;
1352                         break;
1353                 }
1354                 aty_st_le32(MEM_CNTL, tmp, par);
1355         } else {
1356                 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1357                 if (!M64_HAS(MAGIC_POSTDIV))
1358                         tmp |= par->mem_refresh_rate << 20;
1359                 switch (var->bits_per_pixel) {
1360                 case 8:
1361                 case 24:
1362                         tmp |= 0x00000000;
1363                         break;
1364                 case 16:
1365                         tmp |= 0x04000000;
1366                         break;
1367                 case 32:
1368                         tmp |= 0x08000000;
1369                         break;
1370                 }
1371                 if (M64_HAS(CT_BUS)) {
1372                         aty_st_le32(DAC_CNTL, 0x87010184, par);
1373                         aty_st_le32(BUS_CNTL, 0x680000f9, par);
1374                 } else if (M64_HAS(VT_BUS)) {
1375                         aty_st_le32(DAC_CNTL, 0x87010184, par);
1376                         aty_st_le32(BUS_CNTL, 0x680000f9, par);
1377                 } else if (M64_HAS(MOBIL_BUS)) {
1378                         aty_st_le32(DAC_CNTL, 0x80010102, par);
1379                         aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1380                 } else {
1381                         /* GT */
1382                         aty_st_le32(DAC_CNTL, 0x86010102, par);
1383                         aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1384                         aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1385                 }
1386                 aty_st_le32(MEM_CNTL, tmp, par);
1387         }
1388         aty_st_8(DAC_MASK, 0xff, par);
1389
1390         info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
1391         info->fix.visual = var->bits_per_pixel <= 8 ?
1392                 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1393
1394         /* Initialize the graphics engine */
1395         if (par->accel_flags & FB_ACCELF_TEXT)
1396                 aty_init_engine(par, info);
1397
1398 #ifdef CONFIG_BOOTX_TEXT
1399         btext_update_display(info->fix.smem_start,
1400                 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1401                 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1402                 var->bits_per_pixel,
1403                 par->crtc.vxres * var->bits_per_pixel / 8);
1404 #endif /* CONFIG_BOOTX_TEXT */
1405 #if 0
1406         /* switch to accelerator mode */
1407         if (!(par->crtc.gen_cntl & CRTC_EXT_DISP_EN))
1408                 aty_st_le32(CRTC_GEN_CNTL, par->crtc.gen_cntl | CRTC_EXT_DISP_EN, par);
1409 #endif
1410 #ifdef DEBUG
1411 {
1412         /* dump non shadow CRTC, pll, LCD registers */
1413         int i; u32 base;
1414
1415         /* CRTC registers */
1416         base = 0x2000;
1417         printk("debug atyfb: Mach64 non-shadow register values:");
1418         for (i = 0; i < 256; i = i+4) {
1419                 if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i);
1420                 printk(" %08X", aty_ld_le32(i, par));
1421         }
1422         printk("\n\n");
1423
1424 #ifdef CONFIG_FB_ATY_CT
1425         /* PLL registers */
1426         base = 0x00;
1427         printk("debug atyfb: Mach64 PLL register values:");
1428         for (i = 0; i < 64; i++) {
1429                 if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1430                 if(i%4 == 0)  printk(" ");
1431                 printk("%02X", aty_ld_pll_ct(i, par));
1432         }
1433         printk("\n\n");
1434 #endif  /* CONFIG_FB_ATY_CT */
1435
1436 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1437         if (par->lcd_table != 0) {
1438                 /* LCD registers */
1439                 base = 0x00;
1440                 printk("debug atyfb: LCD register values:");
1441                 if(M64_HAS(LT_LCD_REGS)) {
1442                     for(i = 0; i <= POWER_MANAGEMENT; i++) {
1443                         if(i == EXT_VERT_STRETCH)
1444                             continue;
1445                         printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]);
1446                         printk(" %08X", aty_ld_lcd(i, par));
1447                     }
1448
1449                 } else {
1450                     for (i = 0; i < 64; i++) {
1451                         if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1452                         printk(" %08X", aty_ld_lcd(i, par));
1453                     }
1454                 }
1455                 printk("\n\n");
1456         }
1457 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1458 }
1459 #endif /* DEBUG */
1460         return 0;
1461 }
1462
1463 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1464 {
1465         struct atyfb_par *par = (struct atyfb_par *) info->par;
1466         int err;
1467         struct crtc crtc;
1468         union aty_pll pll;
1469         u32 pixclock;
1470
1471         memcpy(&pll, &(par->pll), sizeof(pll));
1472
1473         if((err = aty_var_to_crtc(info, var, &crtc)))
1474                 return err;
1475
1476         pixclock = atyfb_get_pixclock(var, par);
1477
1478         if (pixclock == 0) {
1479                 if (!(var->activate & FB_ACTIVATE_TEST))
1480                         PRINTKE("Invalid pixclock\n");
1481                 return -EINVAL;
1482         } else {
1483                 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll)))
1484                         return err;
1485         }
1486
1487         if (var->accel_flags & FB_ACCELF_TEXT)
1488                 info->var.accel_flags = FB_ACCELF_TEXT;
1489         else
1490                 info->var.accel_flags = 0;
1491
1492         aty_crtc_to_var(&crtc, var);
1493         var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1494         return 0;
1495 }
1496
1497 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1498 {
1499         u32 xoffset = info->var.xoffset;
1500         u32 yoffset = info->var.yoffset;
1501         u32 vxres = par->crtc.vxres;
1502         u32 bpp = info->var.bits_per_pixel;
1503
1504         par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
1505 }
1506
1507
1508     /*
1509      *  Open/Release the frame buffer device
1510      */
1511
1512 static int atyfb_open(struct fb_info *info, int user)
1513 {
1514         struct atyfb_par *par = (struct atyfb_par *) info->par;
1515
1516         if (user) {
1517                 par->open++;
1518 #ifdef __sparc__
1519                 par->mmaped = 0;
1520 #endif
1521         }
1522         return (0);
1523 }
1524
1525 static irqreturn_t aty_irq(int irq, void *dev_id)
1526 {
1527         struct atyfb_par *par = dev_id;
1528         int handled = 0;
1529         u32 int_cntl;
1530
1531         spin_lock(&par->int_lock);
1532
1533         int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1534
1535         if (int_cntl & CRTC_VBLANK_INT) {
1536                 /* clear interrupt */
1537                 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par);
1538                 par->vblank.count++;
1539                 if (par->vblank.pan_display) {
1540                         par->vblank.pan_display = 0;
1541                         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1542                 }
1543                 wake_up_interruptible(&par->vblank.wait);
1544                 handled = 1;
1545         }
1546
1547         spin_unlock(&par->int_lock);
1548
1549         return IRQ_RETVAL(handled);
1550 }
1551
1552 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1553 {
1554         u32 int_cntl;
1555
1556         if (!test_and_set_bit(0, &par->irq_flags)) {
1557                 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) {
1558                         clear_bit(0, &par->irq_flags);
1559                         return -EINVAL;
1560                 }
1561                 spin_lock_irq(&par->int_lock);
1562                 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1563                 /* clear interrupt */
1564                 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1565                 /* enable interrupt */
1566                 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1567                 spin_unlock_irq(&par->int_lock);
1568         } else if (reenable) {
1569                 spin_lock_irq(&par->int_lock);
1570                 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1571                 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1572                         printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl);
1573                         /* re-enable interrupt */
1574                         aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par );
1575                 }
1576                 spin_unlock_irq(&par->int_lock);
1577         }
1578
1579         return 0;
1580 }
1581
1582 static int aty_disable_irq(struct atyfb_par *par)
1583 {
1584         u32 int_cntl;
1585
1586         if (test_and_clear_bit(0, &par->irq_flags)) {
1587                 if (par->vblank.pan_display) {
1588                         par->vblank.pan_display = 0;
1589                         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1590                 }
1591                 spin_lock_irq(&par->int_lock);
1592                 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1593                 /* disable interrupt */
1594                 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par );
1595                 spin_unlock_irq(&par->int_lock);
1596                 free_irq(par->irq, par);
1597         }
1598
1599         return 0;
1600 }
1601
1602 static int atyfb_release(struct fb_info *info, int user)
1603 {
1604         struct atyfb_par *par = (struct atyfb_par *) info->par;
1605         if (user) {
1606                 par->open--;
1607                 mdelay(1);
1608                 wait_for_idle(par);
1609                 if (!par->open) {
1610 #ifdef __sparc__
1611                         int was_mmaped = par->mmaped;
1612
1613                         par->mmaped = 0;
1614
1615                         if (was_mmaped) {
1616                                 struct fb_var_screeninfo var;
1617
1618                                 /* Now reset the default display config, we have no
1619                                  * idea what the program(s) which mmap'd the chip did
1620                                  * to the configuration, nor whether it restored it
1621                                  * correctly.
1622                                  */
1623                                 var = default_var;
1624                                 if (noaccel)
1625                                         var.accel_flags &= ~FB_ACCELF_TEXT;
1626                                 else
1627                                         var.accel_flags |= FB_ACCELF_TEXT;
1628                                 if (var.yres == var.yres_virtual) {
1629                                         u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1630                                         var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
1631                                         if (var.yres_virtual < var.yres)
1632                                                 var.yres_virtual = var.yres;
1633                                 }
1634                         }
1635 #endif
1636                         aty_disable_irq(par);
1637                 }
1638         }
1639         return (0);
1640 }
1641
1642     /*
1643      *  Pan or Wrap the Display
1644      *
1645      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1646      */
1647
1648 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1649 {
1650         struct atyfb_par *par = (struct atyfb_par *) info->par;
1651         u32 xres, yres, xoffset, yoffset;
1652
1653         xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1654         yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1655         if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1656                 yres >>= 1;
1657         xoffset = (var->xoffset + 7) & ~7;
1658         yoffset = var->yoffset;
1659         if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres)
1660                 return -EINVAL;
1661         info->var.xoffset = xoffset;
1662         info->var.yoffset = yoffset;
1663         if (par->asleep)
1664                 return 0;
1665
1666         set_off_pitch(par, info);
1667         if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1668                 par->vblank.pan_display = 1;
1669         } else {
1670                 par->vblank.pan_display = 0;
1671                 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1672         }
1673
1674         return 0;
1675 }
1676
1677 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1678 {
1679         struct aty_interrupt *vbl;
1680         unsigned int count;
1681         int ret;
1682
1683         switch (crtc) {
1684         case 0:
1685                 vbl = &par->vblank;
1686                 break;
1687         default:
1688                 return -ENODEV;
1689         }
1690
1691         ret = aty_enable_irq(par, 0);
1692         if (ret)
1693                 return ret;
1694
1695         count = vbl->count;
1696         ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10);
1697         if (ret < 0) {
1698                 return ret;
1699         }
1700         if (ret == 0) {
1701                 aty_enable_irq(par, 1);
1702                 return -ETIMEDOUT;
1703         }
1704
1705         return 0;
1706 }
1707
1708
1709 #ifdef DEBUG
1710 #define ATYIO_CLKR              0x41545900      /* ATY\00 */
1711 #define ATYIO_CLKW              0x41545901      /* ATY\01 */
1712
1713 struct atyclk {
1714         u32 ref_clk_per;
1715         u8 pll_ref_div;
1716         u8 mclk_fb_div;
1717         u8 mclk_post_div;       /* 1,2,3,4,8 */
1718         u8 mclk_fb_mult;        /* 2 or 4 */
1719         u8 xclk_post_div;       /* 1,2,3,4,8 */
1720         u8 vclk_fb_div;
1721         u8 vclk_post_div;       /* 1,2,3,4,6,8,12 */
1722         u32 dsp_xclks_per_row;  /* 0-16383 */
1723         u32 dsp_loop_latency;   /* 0-15 */
1724         u32 dsp_precision;      /* 0-7 */
1725         u32 dsp_on;             /* 0-2047 */
1726         u32 dsp_off;            /* 0-2047 */
1727 };
1728
1729 #define ATYIO_FEATR             0x41545902      /* ATY\02 */
1730 #define ATYIO_FEATW             0x41545903      /* ATY\03 */
1731 #endif
1732
1733 #ifndef FBIO_WAITFORVSYNC
1734 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
1735 #endif
1736
1737 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1738 {
1739         struct atyfb_par *par = (struct atyfb_par *) info->par;
1740 #ifdef __sparc__
1741         struct fbtype fbtyp;
1742 #endif
1743
1744         switch (cmd) {
1745 #ifdef __sparc__
1746         case FBIOGTYPE:
1747                 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1748                 fbtyp.fb_width = par->crtc.vxres;
1749                 fbtyp.fb_height = par->crtc.vyres;
1750                 fbtyp.fb_depth = info->var.bits_per_pixel;
1751                 fbtyp.fb_cmsize = info->cmap.len;
1752                 fbtyp.fb_size = info->fix.smem_len;
1753                 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp)))
1754                         return -EFAULT;
1755                 break;
1756 #endif /* __sparc__ */
1757
1758         case FBIO_WAITFORVSYNC:
1759                 {
1760                         u32 crtc;
1761
1762                         if (get_user(crtc, (__u32 __user *) arg))
1763                                 return -EFAULT;
1764
1765                         return aty_waitforvblank(par, crtc);
1766                 }
1767                 break;
1768
1769 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1770         case ATYIO_CLKR:
1771                 if (M64_HAS(INTEGRATED)) {
1772                         struct atyclk clk;
1773                         union aty_pll *pll = &(par->pll);
1774                         u32 dsp_config = pll->ct.dsp_config;
1775                         u32 dsp_on_off = pll->ct.dsp_on_off;
1776                         clk.ref_clk_per = par->ref_clk_per;
1777                         clk.pll_ref_div = pll->ct.pll_ref_div;
1778                         clk.mclk_fb_div = pll->ct.mclk_fb_div;
1779                         clk.mclk_post_div = pll->ct.mclk_post_div_real;
1780                         clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1781                         clk.xclk_post_div = pll->ct.xclk_post_div_real;
1782                         clk.vclk_fb_div = pll->ct.vclk_fb_div;
1783                         clk.vclk_post_div = pll->ct.vclk_post_div_real;
1784                         clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1785                         clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1786                         clk.dsp_precision = (dsp_config >> 20) & 7;
1787                         clk.dsp_off = dsp_on_off & 0x7ff;
1788                         clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1789                         if (copy_to_user((struct atyclk __user *) arg, &clk,
1790                                          sizeof(clk)))
1791                                 return -EFAULT;
1792                 } else
1793                         return -EINVAL;
1794                 break;
1795         case ATYIO_CLKW:
1796                 if (M64_HAS(INTEGRATED)) {
1797                         struct atyclk clk;
1798                         union aty_pll *pll = &(par->pll);
1799                         if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk)))
1800                                 return -EFAULT;
1801                         par->ref_clk_per = clk.ref_clk_per;
1802                         pll->ct.pll_ref_div = clk.pll_ref_div;
1803                         pll->ct.mclk_fb_div = clk.mclk_fb_div;
1804                         pll->ct.mclk_post_div_real = clk.mclk_post_div;
1805                         pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1806                         pll->ct.xclk_post_div_real = clk.xclk_post_div;
1807                         pll->ct.vclk_fb_div = clk.vclk_fb_div;
1808                         pll->ct.vclk_post_div_real = clk.vclk_post_div;
1809                         pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1810                                 ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20);
1811                         pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16);
1812                         /*aty_calc_pll_ct(info, &pll->ct);*/
1813                         aty_set_pll_ct(info, pll);
1814                 } else
1815                         return -EINVAL;
1816                 break;
1817         case ATYIO_FEATR:
1818                 if (get_user(par->features, (u32 __user *) arg))
1819                         return -EFAULT;
1820                 break;
1821         case ATYIO_FEATW:
1822                 if (put_user(par->features, (u32 __user *) arg))
1823                         return -EFAULT;
1824                 break;
1825 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1826         default:
1827                 return -EINVAL;
1828         }
1829         return 0;
1830 }
1831
1832 static int atyfb_sync(struct fb_info *info)
1833 {
1834         struct atyfb_par *par = (struct atyfb_par *) info->par;
1835
1836         if (par->blitter_may_be_busy)
1837                 wait_for_idle(par);
1838         return 0;
1839 }
1840
1841 #ifdef __sparc__
1842 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1843 {
1844         struct atyfb_par *par = (struct atyfb_par *) info->par;
1845         unsigned int size, page, map_size = 0;
1846         unsigned long map_offset = 0;
1847         unsigned long off;
1848         int i;
1849
1850         if (!par->mmap_map)
1851                 return -ENXIO;
1852
1853         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1854                 return -EINVAL;
1855
1856         off = vma->vm_pgoff << PAGE_SHIFT;
1857         size = vma->vm_end - vma->vm_start;
1858
1859         /* To stop the swapper from even considering these pages. */
1860         vma->vm_flags |= (VM_IO | VM_RESERVED);
1861
1862         if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1863             ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1864                 off += 0x8000000000000000UL;
1865
1866         vma->vm_pgoff = off >> PAGE_SHIFT;      /* propagate off changes */
1867
1868         /* Each page, see which map applies */
1869         for (page = 0; page < size;) {
1870                 map_size = 0;
1871                 for (i = 0; par->mmap_map[i].size; i++) {
1872                         unsigned long start = par->mmap_map[i].voff;
1873                         unsigned long end = start + par->mmap_map[i].size;
1874                         unsigned long offset = off + page;
1875
1876                         if (start > offset)
1877                                 continue;
1878                         if (offset >= end)
1879                                 continue;
1880
1881                         map_size = par->mmap_map[i].size - (offset - start);
1882                         map_offset =
1883                             par->mmap_map[i].poff + (offset - start);
1884                         break;
1885                 }
1886                 if (!map_size) {
1887                         page += PAGE_SIZE;
1888                         continue;
1889                 }
1890                 if (page + map_size > size)
1891                         map_size = size - page;
1892
1893                 pgprot_val(vma->vm_page_prot) &=
1894                     ~(par->mmap_map[i].prot_mask);
1895                 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1896
1897                 if (remap_pfn_range(vma, vma->vm_start + page,
1898                         map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1899                         return -EAGAIN;
1900
1901                 page += map_size;
1902         }
1903
1904         if (!map_size)
1905                 return -EINVAL;
1906
1907         if (!par->mmaped)
1908                 par->mmaped = 1;
1909         return 0;
1910 }
1911
1912 static struct {
1913         u32 yoffset;
1914         u8 r[2][256];
1915         u8 g[2][256];
1916         u8 b[2][256];
1917 } atyfb_save;
1918
1919 static void atyfb_save_palette(struct atyfb_par *par, int enter)
1920 {
1921         int i, tmp;
1922
1923         for (i = 0; i < 256; i++) {
1924                 tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
1925                 if (M64_HAS(EXTRA_BRIGHT))
1926                         tmp |= 0x2;
1927                 aty_st_8(DAC_CNTL, tmp, par);
1928                 aty_st_8(DAC_MASK, 0xff, par);
1929
1930                 aty_st_8(DAC_R_INDEX, i, par);
1931                 atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
1932                 atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
1933                 atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
1934                 aty_st_8(DAC_W_INDEX, i, par);
1935                 aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
1936                 aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
1937                 aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
1938         }
1939 }
1940
1941 static void atyfb_palette(int enter)
1942 {
1943         struct atyfb_par *par;
1944         struct fb_info *info;
1945         int i;
1946
1947         for (i = 0; i < FB_MAX; i++) {
1948                 info = registered_fb[i];
1949                 if (info && info->fbops == &atyfb_ops) {
1950                         par = (struct atyfb_par *) info->par;
1951                         
1952                         atyfb_save_palette(par, enter);
1953                         if (enter) {
1954                                 atyfb_save.yoffset = info->var.yoffset;
1955                                 info->var.yoffset = 0;
1956                                 set_off_pitch(par, info);
1957                         } else {
1958                                 info->var.yoffset = atyfb_save.yoffset;
1959                                 set_off_pitch(par, info);
1960                         }
1961                         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1962                         break;
1963                 }
1964         }
1965 }
1966 #endif /* __sparc__ */
1967
1968
1969
1970 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
1971
1972 #ifdef CONFIG_PPC_PMAC
1973 /* Power management routines. Those are used for PowerBook sleep.
1974  */
1975 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1976 {
1977         u32 pm;
1978         int timeout;
1979
1980         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1981         pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1982         aty_st_lcd(POWER_MANAGEMENT, pm, par);
1983         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1984
1985         timeout = 2000;
1986         if (sleep) {
1987                 /* Sleep */
1988                 pm &= ~PWR_MGT_ON;
1989                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1990                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1991                 udelay(10);
1992                 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1993                 pm |= SUSPEND_NOW;
1994                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1995                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1996                 udelay(10);
1997                 pm |= PWR_MGT_ON;
1998                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1999                 do {
2000                         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2001                         mdelay(1);
2002                         if ((--timeout) == 0)
2003                                 break;
2004                 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
2005         } else {
2006                 /* Wakeup */
2007                 pm &= ~PWR_MGT_ON;
2008                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2009                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2010                 udelay(10);
2011                 pm &= ~SUSPEND_NOW;
2012                 pm |= (PWR_BLON | AUTO_PWR_UP);
2013                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2014                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2015                 udelay(10);
2016                 pm |= PWR_MGT_ON;
2017                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2018                 do {
2019                         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2020                         mdelay(1);
2021                         if ((--timeout) == 0)
2022                                 break;
2023                 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2024         }
2025         mdelay(500);
2026
2027         return timeout ? 0 : -EIO;
2028 }
2029 #endif
2030
2031 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2032 {
2033         struct fb_info *info = pci_get_drvdata(pdev);
2034         struct atyfb_par *par = (struct atyfb_par *) info->par;
2035
2036         if (state.event == pdev->dev.power.power_state.event)
2037                 return 0;
2038
2039         acquire_console_sem();
2040
2041         fb_set_suspend(info, 1);
2042
2043         /* Idle & reset engine */
2044         wait_for_idle(par);
2045         aty_reset_engine(par);
2046
2047         /* Blank display and LCD */
2048         atyfb_blank(FB_BLANK_POWERDOWN, info);
2049
2050         par->asleep = 1;
2051         par->lock_blank = 1;
2052
2053 #ifdef CONFIG_PPC_PMAC
2054         /* Set chip to "suspend" mode */
2055         if (aty_power_mgmt(1, par)) {
2056                 par->asleep = 0;
2057                 par->lock_blank = 0;
2058                 atyfb_blank(FB_BLANK_UNBLANK, info);
2059                 fb_set_suspend(info, 0);
2060                 release_console_sem();
2061                 return -EIO;
2062         }
2063 #else
2064         pci_set_power_state(pdev, pci_choose_state(pdev, state));
2065 #endif
2066
2067         release_console_sem();
2068
2069         pdev->dev.power.power_state = state;
2070
2071         return 0;
2072 }
2073
2074 static int atyfb_pci_resume(struct pci_dev *pdev)
2075 {
2076         struct fb_info *info = pci_get_drvdata(pdev);
2077         struct atyfb_par *par = (struct atyfb_par *) info->par;
2078
2079         if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2080                 return 0;
2081
2082         acquire_console_sem();
2083
2084 #ifdef CONFIG_PPC_PMAC
2085         if (pdev->dev.power.power_state.event == 2)
2086                 aty_power_mgmt(0, par);
2087 #else
2088         pci_set_power_state(pdev, PCI_D0);
2089 #endif
2090
2091         aty_resume_chip(info);
2092
2093         par->asleep = 0;
2094
2095         /* Restore display */
2096         atyfb_set_par(info);
2097
2098         /* Refresh */
2099         fb_set_suspend(info, 0);
2100
2101         /* Unblank */
2102         par->lock_blank = 0;
2103         atyfb_blank(FB_BLANK_UNBLANK, info);
2104
2105         release_console_sem();
2106
2107         pdev->dev.power.power_state = PMSG_ON;
2108
2109         return 0;
2110 }
2111
2112 #endif /*  defined(CONFIG_PM) && defined(CONFIG_PCI) */
2113
2114 /* Backlight */
2115 #ifdef CONFIG_FB_ATY_BACKLIGHT
2116 #define MAX_LEVEL 0xFF
2117
2118 static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2119 {
2120         struct fb_info *info = pci_get_drvdata(par->pdev);
2121         int atylevel;
2122
2123         /* Get and convert the value */
2124         /* No locking of bl_curve since we read a single value */
2125         atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2126
2127         if (atylevel < 0)
2128                 atylevel = 0;
2129         else if (atylevel > MAX_LEVEL)
2130                 atylevel = MAX_LEVEL;
2131
2132         return atylevel;
2133 }
2134
2135 static int aty_bl_update_status(struct backlight_device *bd)
2136 {
2137         struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2138         unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2139         int level;
2140
2141         if (bd->props.power != FB_BLANK_UNBLANK ||
2142             bd->props.fb_blank != FB_BLANK_UNBLANK)
2143                 level = 0;
2144         else
2145                 level = bd->props.brightness;
2146
2147         reg |= (BLMOD_EN | BIASMOD_EN);
2148         if (level > 0) {
2149                 reg &= ~BIAS_MOD_LEVEL_MASK;
2150                 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT);
2151         } else {
2152                 reg &= ~BIAS_MOD_LEVEL_MASK;
2153                 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT);
2154         }
2155         aty_st_lcd(LCD_MISC_CNTL, reg, par);
2156
2157         return 0;
2158 }
2159
2160 static int aty_bl_get_brightness(struct backlight_device *bd)
2161 {
2162         return bd->props.brightness;
2163 }
2164
2165 static struct backlight_ops aty_bl_data = {
2166         .get_brightness = aty_bl_get_brightness,
2167         .update_status  = aty_bl_update_status,
2168 };
2169
2170 static void aty_bl_init(struct atyfb_par *par)
2171 {
2172         struct fb_info *info = pci_get_drvdata(par->pdev);
2173         struct backlight_device *bd;
2174         char name[12];
2175
2176 #ifdef CONFIG_PMAC_BACKLIGHT
2177         if (!pmac_has_backlight_type("ati"))
2178                 return;
2179 #endif
2180
2181         snprintf(name, sizeof(name), "atybl%d", info->node);
2182
2183         bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
2184         if (IS_ERR(bd)) {
2185                 info->bl_dev = NULL;
2186                 printk(KERN_WARNING "aty: Backlight registration failed\n");
2187                 goto error;
2188         }
2189
2190         info->bl_dev = bd;
2191         fb_bl_default_curve(info, 0,
2192                 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2193                 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2194
2195         bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2196         bd->props.brightness = bd->props.max_brightness;
2197         bd->props.power = FB_BLANK_UNBLANK;
2198         backlight_update_status(bd);
2199
2200         printk("aty: Backlight initialized (%s)\n", name);
2201
2202         return;
2203
2204 error:
2205         return;
2206 }
2207
2208 static void aty_bl_exit(struct backlight_device *bd)
2209 {
2210         backlight_device_unregister(bd);
2211         printk("aty: Backlight unloaded\n");
2212 }
2213
2214 #endif /* CONFIG_FB_ATY_BACKLIGHT */
2215
2216 static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2217 {
2218         const int ragepro_tbl[] = {
2219                 44, 50, 55, 66, 75, 80, 100
2220         };
2221         const int ragexl_tbl[] = {
2222                 50, 66, 75, 83, 90, 95, 100, 105,
2223                 110, 115, 120, 125, 133, 143, 166
2224         };
2225         const int *refresh_tbl;
2226         int i, size;
2227
2228         if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
2229                 refresh_tbl = ragexl_tbl;
2230                 size = ARRAY_SIZE(ragexl_tbl);
2231         } else {
2232                 refresh_tbl = ragepro_tbl;
2233                 size = ARRAY_SIZE(ragepro_tbl);
2234         }
2235
2236         for (i=0; i < size; i++) {
2237                 if (xclk < refresh_tbl[i])
2238                 break;
2239         }
2240         par->mem_refresh_rate = i;
2241 }
2242
2243     /*
2244      *  Initialisation
2245      */
2246
2247 static struct fb_info *fb_list = NULL;
2248
2249 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2250 static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2251                                                 struct fb_var_screeninfo *var)
2252 {
2253         int ret = -EINVAL;
2254
2255         if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2256                 *var = default_var;
2257                 var->xres = var->xres_virtual = par->lcd_hdisp;
2258                 var->right_margin = par->lcd_right_margin;
2259                 var->left_margin = par->lcd_hblank_len -
2260                         (par->lcd_right_margin + par->lcd_hsync_dly +
2261                          par->lcd_hsync_len);
2262                 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2263                 var->yres = var->yres_virtual = par->lcd_vdisp;
2264                 var->lower_margin = par->lcd_lower_margin;
2265                 var->upper_margin = par->lcd_vblank_len -
2266                         (par->lcd_lower_margin + par->lcd_vsync_len);
2267                 var->vsync_len = par->lcd_vsync_len;
2268                 var->pixclock = par->lcd_pixclock;
2269                 ret = 0;
2270         }
2271
2272         return ret;
2273 }
2274 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2275
2276 static int __devinit aty_init(struct fb_info *info)
2277 {
2278         struct atyfb_par *par = (struct atyfb_par *) info->par;
2279         const char *ramname = NULL, *xtal;
2280         int gtb_memsize, has_var = 0;
2281         struct fb_var_screeninfo var;
2282
2283         init_waitqueue_head(&par->vblank.wait);
2284         spin_lock_init(&par->int_lock);
2285
2286 #ifdef CONFIG_PPC_PMAC
2287         /* The Apple iBook1 uses non-standard memory frequencies. We detect it
2288          * and set the frequency manually. */
2289         if (machine_is_compatible("PowerBook2,1")) {
2290                 par->pll_limits.mclk = 70;
2291                 par->pll_limits.xclk = 53;
2292         }
2293 #endif
2294         if (pll)
2295                 par->pll_limits.pll_max = pll;
2296         if (mclk)
2297                 par->pll_limits.mclk = mclk;
2298         if (xclk)
2299                 par->pll_limits.xclk = xclk;
2300
2301         aty_calc_mem_refresh(par, par->pll_limits.xclk);
2302         par->pll_per = 1000000/par->pll_limits.pll_max;
2303         par->mclk_per = 1000000/par->pll_limits.mclk;
2304         par->xclk_per = 1000000/par->pll_limits.xclk;
2305
2306         par->ref_clk_per = 1000000000000ULL / 14318180;
2307         xtal = "14.31818";
2308
2309 #ifdef CONFIG_FB_ATY_GX
2310         if (!M64_HAS(INTEGRATED)) {
2311                 u32 stat0;
2312                 u8 dac_type, dac_subtype, clk_type;
2313                 stat0 = aty_ld_le32(CONFIG_STAT0, par);
2314                 par->bus_type = (stat0 >> 0) & 0x07;
2315                 par->ram_type = (stat0 >> 3) & 0x07;
2316                 ramname = aty_gx_ram[par->ram_type];
2317                 /* FIXME: clockchip/RAMDAC probing? */
2318                 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
2319 #ifdef CONFIG_ATARI
2320                 clk_type = CLK_ATI18818_1;
2321                 dac_type = (stat0 >> 9) & 0x07;
2322                 if (dac_type == 0x07)
2323                         dac_subtype = DAC_ATT20C408;
2324                 else
2325                         dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2326 #else
2327                 dac_type = DAC_IBMRGB514;
2328                 dac_subtype = DAC_IBMRGB514;
2329                 clk_type = CLK_IBMRGB514;
2330 #endif
2331                 switch (dac_subtype) {
2332                 case DAC_IBMRGB514:
2333                         par->dac_ops = &aty_dac_ibm514;
2334                         break;
2335                 case DAC_ATI68860_B:
2336                 case DAC_ATI68860_C:
2337                         par->dac_ops = &aty_dac_ati68860b;
2338                         break;
2339                 case DAC_ATT20C408:
2340                 case DAC_ATT21C498:
2341                         par->dac_ops = &aty_dac_att21c498;
2342                         break;
2343                 default:
2344                         PRINTKI("aty_init: DAC type not implemented yet!\n");
2345                         par->dac_ops = &aty_dac_unsupported;
2346                         break;
2347                 }
2348                 switch (clk_type) {
2349 #ifdef CONFIG_ATARI
2350                 case CLK_ATI18818_1:
2351                         par->pll_ops = &aty_pll_ati18818_1;
2352                         break;
2353 #else
2354                 case CLK_IBMRGB514:
2355                         par->pll_ops = &aty_pll_ibm514;
2356                         break;
2357 #endif
2358 #if 0 /* dead code */
2359                 case CLK_STG1703:
2360                         par->pll_ops = &aty_pll_stg1703;
2361                         break;
2362                 case CLK_CH8398:
2363                         par->pll_ops = &aty_pll_ch8398;
2364                         break;
2365                 case CLK_ATT20C408:
2366                         par->pll_ops = &aty_pll_att20c408;
2367                         break;
2368 #endif
2369                 default:
2370                         PRINTKI("aty_init: CLK type not implemented yet!");
2371                         par->pll_ops = &aty_pll_unsupported;
2372                         break;
2373                 }
2374         }
2375 #endif /* CONFIG_FB_ATY_GX */
2376 #ifdef CONFIG_FB_ATY_CT
2377         if (M64_HAS(INTEGRATED)) {
2378                 par->dac_ops = &aty_dac_ct;
2379                 par->pll_ops = &aty_pll_ct;
2380                 par->bus_type = PCI;
2381                 par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
2382                 ramname = aty_ct_ram[par->ram_type];
2383                 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2384                 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2385                         par->pll_limits.mclk = 63;
2386         }
2387
2388         if (M64_HAS(GTB_DSP)) {
2389                 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2390
2391                 if (pll_ref_div) {
2392                         int diff1, diff2;
2393                         diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2394                         diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2395                         if (diff1 < 0)
2396                                 diff1 = -diff1;
2397                         if (diff2 < 0)
2398                                 diff2 = -diff2;
2399                         if (diff2 < diff1) {
2400                                 par->ref_clk_per = 1000000000000ULL / 29498928;
2401                                 xtal = "29.498928";
2402                         }
2403                 }
2404         }
2405 #endif /* CONFIG_FB_ATY_CT */
2406
2407         /* save previous video mode */
2408         aty_get_crtc(par, &saved_crtc);
2409         if(par->pll_ops->get_pll)
2410                 par->pll_ops->get_pll(info, &saved_pll);
2411
2412         par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
2413         gtb_memsize = M64_HAS(GTB_DSP);
2414         if (gtb_memsize)
2415                 switch (par->mem_cntl & 0xF) {  /* 0xF used instead of MEM_SIZE_ALIAS */
2416                 case MEM_SIZE_512K:
2417                         info->fix.smem_len = 0x80000;
2418                         break;
2419                 case MEM_SIZE_1M:
2420                         info->fix.smem_len = 0x100000;
2421                         break;
2422                 case MEM_SIZE_2M_GTB:
2423                         info->fix.smem_len = 0x200000;
2424                         break;
2425                 case MEM_SIZE_4M_GTB:
2426                         info->fix.smem_len = 0x400000;
2427                         break;
2428                 case MEM_SIZE_6M_GTB:
2429                         info->fix.smem_len = 0x600000;
2430                         break;
2431                 case MEM_SIZE_8M_GTB:
2432                         info->fix.smem_len = 0x800000;
2433                         break;
2434                 default:
2435                         info->fix.smem_len = 0x80000;
2436         } else
2437                 switch (par->mem_cntl & MEM_SIZE_ALIAS) {
2438                 case MEM_SIZE_512K:
2439                         info->fix.smem_len = 0x80000;
2440                         break;
2441                 case MEM_SIZE_1M:
2442                         info->fix.smem_len = 0x100000;
2443                         break;
2444                 case MEM_SIZE_2M:
2445                         info->fix.smem_len = 0x200000;
2446                         break;
2447                 case MEM_SIZE_4M:
2448                         info->fix.smem_len = 0x400000;
2449                         break;
2450                 case MEM_SIZE_6M:
2451                         info->fix.smem_len = 0x600000;
2452                         break;
2453                 case MEM_SIZE_8M:
2454                         info->fix.smem_len = 0x800000;
2455                         break;
2456                 default:
2457                         info->fix.smem_len = 0x80000;
2458                 }
2459
2460         if (M64_HAS(MAGIC_VRAM_SIZE)) {
2461                 if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
2462                         info->fix.smem_len += 0x400000;
2463         }
2464
2465         if (vram) {
2466                 info->fix.smem_len = vram * 1024;
2467                 par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2468                 if (info->fix.smem_len <= 0x80000)
2469                         par->mem_cntl |= MEM_SIZE_512K;
2470                 else if (info->fix.smem_len <= 0x100000)
2471                         par->mem_cntl |= MEM_SIZE_1M;
2472                 else if (info->fix.smem_len <= 0x200000)
2473                         par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2474                 else if (info->fix.smem_len <= 0x400000)
2475                         par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2476                 else if (info->fix.smem_len <= 0x600000)
2477                         par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2478                 else
2479                         par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2480                 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2481         }
2482
2483         /*
2484          *  Reg Block 0 (CT-compatible block) is at mmio_start
2485          *  Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2486          */
2487         if (M64_HAS(GX)) {
2488                 info->fix.mmio_len = 0x400;
2489                 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2490         } else if (M64_HAS(CT)) {
2491                 info->fix.mmio_len = 0x400;
2492                 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2493         } else if (M64_HAS(VT)) {
2494                 info->fix.mmio_start -= 0x400;
2495                 info->fix.mmio_len = 0x800;
2496                 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2497         } else {/* GT */
2498                 info->fix.mmio_start -= 0x400;
2499                 info->fix.mmio_len = 0x800;
2500                 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2501         }
2502
2503         PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2504                info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
2505                info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
2506                par->pll_limits.mclk, par->pll_limits.xclk);
2507
2508 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
2509         if (M64_HAS(INTEGRATED)) {
2510                 int i;
2511                 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
2512                        "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n"
2513                        "debug atyfb: %08x %08x %08x %08x     %08x      %08x   %08x   %08x\n"
2514                        "debug atyfb: PLL",
2515                         aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par),
2516                         aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par),
2517                         aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par),
2518                         aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par));
2519                 for (i = 0; i < 40; i++)
2520                         printk(" %02x", aty_ld_pll_ct(i, par));
2521                 printk("\n");
2522         }
2523 #endif
2524         if(par->pll_ops->init_pll)
2525                 par->pll_ops->init_pll(info, &par->pll);
2526         if (par->pll_ops->resume_pll)
2527                 par->pll_ops->resume_pll(info, &par->pll);
2528
2529         /*
2530          *  Last page of 8 MB (4 MB on ISA) aperture is MMIO,
2531          *  unless the auxiliary register aperture is used.
2532          */
2533
2534         if (!par->aux_start &&
2535                 (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
2536                 info->fix.smem_len -= GUI_RESERVE;
2537
2538         /*
2539          *  Disable register access through the linear aperture
2540          *  if the auxiliary aperture is used so we can access
2541          *  the full 8 MB of video RAM on 8 MB boards.
2542          */
2543         if (par->aux_start)
2544                 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2545
2546 #ifdef CONFIG_MTRR
2547         par->mtrr_aper = -1;
2548         par->mtrr_reg = -1;
2549         if (!nomtrr) {
2550                 /* Cover the whole resource. */
2551                  par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1);
2552                  if (par->mtrr_aper >= 0 && !par->aux_start) {
2553                         /* Make a hole for mmio. */
2554                         par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE,
2555                                 GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1);
2556                         if (par->mtrr_reg < 0) {
2557                                 mtrr_del(par->mtrr_aper, 0, 0);
2558                                 par->mtrr_aper = -1;
2559                         }
2560                  }
2561         }
2562 #endif
2563
2564         info->fbops = &atyfb_ops;
2565         info->pseudo_palette = pseudo_palette;
2566         info->flags = FBINFO_DEFAULT           |
2567                       FBINFO_HWACCEL_IMAGEBLIT |
2568                       FBINFO_HWACCEL_FILLRECT  |
2569                       FBINFO_HWACCEL_COPYAREA  |
2570                       FBINFO_HWACCEL_YPAN;
2571
2572 #ifdef CONFIG_PMAC_BACKLIGHT
2573         if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2574                 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2575                 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par)
2576                            | (USE_F32KHZ | TRISTATE_MEM_EN), par);
2577         } else
2578 #endif
2579         if (M64_HAS(MOBIL_BUS)) {
2580 #ifdef CONFIG_FB_ATY_BACKLIGHT
2581                 aty_bl_init (par);
2582 #endif
2583         }
2584
2585         memset(&var, 0, sizeof(var));
2586 #ifdef CONFIG_PPC
2587         if (machine_is(powermac)) {
2588                 /*
2589                  *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2590                  *         applies to all Mac video cards
2591                  */
2592                 if (mode) {
2593                         if (mac_find_mode(&var, info, mode, 8))
2594                                 has_var = 1;
2595                 } else {
2596                         if (default_vmode == VMODE_CHOOSE) {
2597                                 int sense;
2598                                 if (M64_HAS(G3_PB_1024x768))
2599                                         /* G3 PowerBook with 1024x768 LCD */
2600                                         default_vmode = VMODE_1024_768_60;
2601                                 else if (machine_is_compatible("iMac"))
2602                                         default_vmode = VMODE_1024_768_75;
2603                                 else if (machine_is_compatible
2604                                          ("PowerBook2,1"))
2605                                         /* iBook with 800x600 LCD */
2606                                         default_vmode = VMODE_800_600_60;
2607                                 else
2608                                         default_vmode = VMODE_640_480_67;
2609                                 sense = read_aty_sense(par);
2610                                 PRINTKI("monitor sense=%x, mode %d\n",
2611                                         sense,  mac_map_monitor_sense(sense));
2612                         }
2613                         if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2614                                 default_vmode = VMODE_640_480_60;
2615                         if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2616                                 default_cmode = CMODE_8;
2617                         if (!mac_vmode_to_var(default_vmode, default_cmode,
2618                                                &var))
2619                                 has_var = 1;
2620                 }
2621         }
2622
2623 #endif /* !CONFIG_PPC */
2624
2625 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2626         if (!atyfb_get_timings_from_lcd(par, &var))
2627                 has_var = 1;
2628 #endif
2629
2630         if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2631                 has_var = 1;
2632
2633         if (!has_var)
2634                 var = default_var;
2635
2636         if (noaccel)
2637                 var.accel_flags &= ~FB_ACCELF_TEXT;
2638         else
2639                 var.accel_flags |= FB_ACCELF_TEXT;
2640
2641         if (comp_sync != -1) {
2642                 if (!comp_sync)
2643                         var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2644                 else
2645                         var.sync |= FB_SYNC_COMP_HIGH_ACT;
2646         }
2647
2648         if (var.yres == var.yres_virtual) {
2649                 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2650                 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2651                 if (var.yres_virtual < var.yres)
2652                         var.yres_virtual = var.yres;
2653         }
2654
2655         if (atyfb_check_var(&var, info)) {
2656                 PRINTKE("can't set default video mode\n");
2657                 goto aty_init_exit;
2658         }
2659
2660 #ifdef __sparc__
2661         atyfb_save_palette(par, 0);
2662 #endif
2663
2664 #ifdef CONFIG_FB_ATY_CT
2665         if (!noaccel && M64_HAS(INTEGRATED))
2666                 aty_init_cursor(info);
2667 #endif /* CONFIG_FB_ATY_CT */
2668         info->var = var;
2669
2670         fb_alloc_cmap(&info->cmap, 256, 0);
2671
2672         if (register_framebuffer(info) < 0)
2673                 goto aty_init_exit;
2674
2675         fb_list = info;
2676
2677         PRINTKI("fb%d: %s frame buffer device on %s\n",
2678                 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
2679         return 0;
2680
2681 aty_init_exit:
2682         /* restore video mode */
2683         aty_set_crtc(par, &saved_crtc);
2684         par->pll_ops->set_pll(info, &saved_pll);
2685
2686 #ifdef CONFIG_MTRR
2687         if (par->mtrr_reg >= 0) {
2688             mtrr_del(par->mtrr_reg, 0, 0);
2689             par->mtrr_reg = -1;
2690         }
2691         if (par->mtrr_aper >= 0) {
2692             mtrr_del(par->mtrr_aper, 0, 0);
2693             par->mtrr_aper = -1;
2694         }
2695 #endif
2696         return -1;
2697 }
2698
2699 static void aty_resume_chip(struct fb_info *info)
2700 {
2701         struct atyfb_par *par = info->par;
2702
2703         aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2704
2705         if (par->pll_ops->resume_pll)
2706                 par->pll_ops->resume_pll(info, &par->pll);
2707
2708         if (par->aux_start)
2709                 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2710 }
2711
2712 #ifdef CONFIG_ATARI
2713 static int __devinit store_video_par(char *video_str, unsigned char m64_num)
2714 {
2715         char *p;
2716         unsigned long vmembase, size, guiregbase;
2717
2718         PRINTKI("store_video_par() '%s' \n", video_str);
2719
2720         if (!(p = strsep(&video_str, ";")) || !*p)
2721                 goto mach64_invalid;
2722         vmembase = simple_strtoul(p, NULL, 0);
2723         if (!(p = strsep(&video_str, ";")) || !*p)
2724                 goto mach64_invalid;
2725         size = simple_strtoul(p, NULL, 0);
2726         if (!(p = strsep(&video_str, ";")) || !*p)
2727                 goto mach64_invalid;
2728         guiregbase = simple_strtoul(p, NULL, 0);
2729
2730         phys_vmembase[m64_num] = vmembase;
2731         phys_size[m64_num] = size;
2732         phys_guiregbase[m64_num] = guiregbase;
2733         PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2734                guiregbase);
2735         return 0;
2736
2737       mach64_invalid:
2738         phys_vmembase[m64_num] = 0;
2739         return -1;
2740 }
2741 #endif /* CONFIG_ATARI */
2742
2743     /*
2744      *  Blank the display.
2745      */
2746
2747 static int atyfb_blank(int blank, struct fb_info *info)
2748 {
2749         struct atyfb_par *par = (struct atyfb_par *) info->par;
2750         u32 gen_cntl;
2751
2752         if (par->lock_blank || par->asleep)
2753                 return 0;
2754
2755 #ifdef CONFIG_FB_ATY_BACKLIGHT
2756 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2757         if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2758             (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2759                 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2760                 pm &= ~PWR_BLON;
2761                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2762         }
2763 #endif
2764
2765         gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2766         gen_cntl &= ~0x400004c;
2767         switch (blank) {
2768                 case FB_BLANK_UNBLANK:
2769                         break;
2770                 case FB_BLANK_NORMAL:
2771                         gen_cntl |= 0x4000040;
2772                         break;
2773                 case FB_BLANK_VSYNC_SUSPEND:
2774                         gen_cntl |= 0x4000048;
2775                         break;
2776                 case FB_BLANK_HSYNC_SUSPEND:
2777                         gen_cntl |= 0x4000044;
2778                         break;
2779                 case FB_BLANK_POWERDOWN:
2780                         gen_cntl |= 0x400004c;
2781                         break;
2782         }
2783         aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2784
2785 #ifdef CONFIG_FB_ATY_BACKLIGHT
2786 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2787         if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2788             (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2789                 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2790                 pm |= PWR_BLON;
2791                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2792         }
2793 #endif
2794
2795         return 0;
2796 }
2797
2798 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2799                        const struct atyfb_par *par)
2800 {
2801         aty_st_8(DAC_W_INDEX, regno, par);
2802         aty_st_8(DAC_DATA, red, par);
2803         aty_st_8(DAC_DATA, green, par);
2804         aty_st_8(DAC_DATA, blue, par);
2805 }
2806
2807     /*
2808      *  Set a single color register. The values supplied are already
2809      *  rounded down to the hardware's capabilities (according to the
2810      *  entries in the var structure). Return != 0 for invalid regno.
2811      *  !! 4 & 8 =  PSEUDO, > 8 = DIRECTCOLOR
2812      */
2813
2814 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2815         u_int transp, struct fb_info *info)
2816 {
2817         struct atyfb_par *par = (struct atyfb_par *) info->par;
2818         int i, depth;
2819         u32 *pal = info->pseudo_palette;
2820
2821         depth = info->var.bits_per_pixel;
2822         if (depth == 16)
2823                 depth = (info->var.green.length == 5) ? 15 : 16;
2824
2825         if (par->asleep)
2826                 return 0;
2827
2828         if (regno > 255 ||
2829             (depth == 16 && regno > 63) ||
2830             (depth == 15 && regno > 31))
2831                 return 1;
2832
2833         red >>= 8;
2834         green >>= 8;
2835         blue >>= 8;
2836
2837         par->palette[regno].red = red;
2838         par->palette[regno].green = green;
2839         par->palette[regno].blue = blue;
2840
2841         if (regno < 16) {
2842                 switch (depth) {
2843                 case 15:
2844                         pal[regno] = (regno << 10) | (regno << 5) | regno;
2845                         break;
2846                 case 16:
2847                         pal[regno] = (regno << 11) | (regno << 5) | regno;
2848                         break;
2849                 case 24:
2850                         pal[regno] = (regno << 16) | (regno << 8) | regno;
2851                         break;
2852                 case 32:
2853                         i = (regno << 8) | regno;
2854                         pal[regno] = (i << 16) | i;
2855                         break;
2856                 }
2857         }
2858
2859         i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2860         if (M64_HAS(EXTRA_BRIGHT))
2861                 i |= 0x2; /* DAC_CNTL | 0x2 turns off the extra brightness for gt */
2862         aty_st_8(DAC_CNTL, i, par);
2863         aty_st_8(DAC_MASK, 0xff, par);
2864
2865         if (M64_HAS(INTEGRATED)) {
2866                 if (depth == 16) {
2867                         if (regno < 32)
2868                                 aty_st_pal(regno << 3, red,
2869                                            par->palette[regno<<1].green,
2870                                            blue, par);
2871                         red = par->palette[regno>>1].red;
2872                         blue = par->palette[regno>>1].blue;
2873                         regno <<= 2;
2874                 } else if (depth == 15) {
2875                         regno <<= 3;
2876                         for(i = 0; i < 8; i++) {
2877                             aty_st_pal(regno + i, red, green, blue, par);
2878                         }
2879                 }
2880         }
2881         aty_st_pal(regno, red, green, blue, par);
2882
2883         return 0;
2884 }
2885
2886 #ifdef CONFIG_PCI
2887
2888 #ifdef __sparc__
2889
2890 extern void (*prom_palette) (int);
2891
2892 static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2893                         struct fb_info *info, unsigned long addr)
2894 {
2895         struct atyfb_par *par = info->par;
2896         struct pcidev_cookie *pcp;
2897         char prop[128];
2898         int node, len, i, j, ret;
2899         u32 mem, chip_id;
2900
2901         /* Do not attach when we have a serial console. */
2902         if (!con_is_present())
2903                 return -ENXIO;
2904
2905         /*
2906          * Map memory-mapped registers.
2907          */
2908         par->ati_regbase = (void *)addr + 0x7ffc00UL;
2909         info->fix.mmio_start = addr + 0x7ffc00UL;
2910
2911         /*
2912          * Map in big-endian aperture.
2913          */
2914         info->screen_base = (char *) (addr + 0x800000UL);
2915         info->fix.smem_start = addr + 0x800000UL;
2916
2917         /*
2918          * Figure mmap addresses from PCI config space.
2919          * Split Framebuffer in big- and little-endian halfs.
2920          */
2921         for (i = 0; i < 6 && pdev->resource[i].start; i++)
2922                 /* nothing */ ;
2923         j = i + 4;
2924
2925         par->mmap_map = kmalloc(j * sizeof(*par->mmap_map), GFP_ATOMIC);
2926         if (!par->mmap_map) {
2927                 PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n");
2928                 return -ENOMEM;
2929         }
2930         memset(par->mmap_map, 0, j * sizeof(*par->mmap_map));
2931
2932         for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
2933                 struct resource *rp = &pdev->resource[i];
2934                 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
2935                 unsigned long base;
2936                 u32 size, pbase;
2937
2938                 base = rp->start;
2939
2940                 io = (rp->flags & IORESOURCE_IO);
2941
2942                 size = rp->end - base + 1;
2943
2944                 pci_read_config_dword(pdev, breg, &pbase);
2945
2946                 if (io)
2947                         size &= ~1;
2948
2949                 /*
2950                  * Map the framebuffer a second time, this time without
2951                  * the braindead _PAGE_IE setting. This is used by the
2952                  * fixed Xserver, but we need to maintain the old mapping
2953                  * to stay compatible with older ones...
2954                  */
2955                 if (base == addr) {
2956                         par->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
2957                         par->mmap_map[j].poff = base & PAGE_MASK;
2958                         par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2959                         par->mmap_map[j].prot_mask = _PAGE_CACHE;
2960                         par->mmap_map[j].prot_flag = _PAGE_E;
2961                         j++;
2962                 }
2963
2964                 /*
2965                  * Here comes the old framebuffer mapping with _PAGE_IE
2966                  * set for the big endian half of the framebuffer...
2967                  */
2968                 if (base == addr) {
2969                         par->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
2970                         par->mmap_map[j].poff = (base + 0x800000) & PAGE_MASK;
2971                         par->mmap_map[j].size = 0x800000;
2972                         par->mmap_map[j].prot_mask = _PAGE_CACHE;
2973                         par->mmap_map[j].prot_flag = _PAGE_E | _PAGE_IE;
2974                         size -= 0x800000;
2975                         j++;
2976                 }
2977
2978                 par->mmap_map[j].voff = pbase & PAGE_MASK;
2979                 par->mmap_map[j].poff = base & PAGE_MASK;
2980                 par->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
2981                 par->mmap_map[j].prot_mask = _PAGE_CACHE;
2982                 par->mmap_map[j].prot_flag = _PAGE_E;
2983                 j++;
2984         }
2985
2986         if((ret = correct_chipset(par)))
2987                 return ret;
2988
2989         if (IS_XL(pdev->device)) {
2990                 /*
2991                  * Fix PROMs idea of MEM_CNTL settings...
2992                  */
2993                 mem = aty_ld_le32(MEM_CNTL, par);
2994                 chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
2995                 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
2996                         switch (mem & 0x0f) {
2997                         case 3:
2998                                 mem = (mem & ~(0x0f)) | 2;
2999                                 break;
3000                         case 7:
3001                                 mem = (mem & ~(0x0f)) | 3;
3002                                 break;
3003                         case 9:
3004                                 mem = (mem & ~(0x0f)) | 4;
3005                                 break;
3006                         case 11:
3007                                 mem = (mem & ~(0x0f)) | 5;
3008                                 break;
3009                         default:
3010                                 break;
3011                         }
3012                         if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
3013                                 mem &= ~(0x00700000);
3014                 }
3015                 mem &= ~(0xcf80e000);   /* Turn off all undocumented bits. */
3016                 aty_st_le32(MEM_CNTL, mem, par);
3017         }
3018
3019         /*
3020          * If this is the console device, we will set default video
3021          * settings to what the PROM left us with.
3022          */
3023         node = prom_getchild(prom_root_node);
3024         node = prom_searchsiblings(node, "aliases");
3025         if (node) {
3026                 len = prom_getproperty(node, "screen", prop, sizeof(prop));
3027                 if (len > 0) {
3028                         prop[len] = '\0';
3029                         node = prom_finddevice(prop);
3030                 } else
3031                         node = 0;
3032         }
3033
3034         pcp = pdev->sysdata;
3035         if (node == pcp->prom_node->node) {
3036                 struct fb_var_screeninfo *var = &default_var;
3037                 unsigned int N, P, Q, M, T, R;
3038                 u32 v_total, h_total;
3039                 struct crtc crtc;
3040                 u8 pll_regs[16];
3041                 u8 clock_cntl;
3042
3043                 crtc.vxres = prom_getintdefault(node, "width", 1024);
3044                 crtc.vyres = prom_getintdefault(node, "height", 768);
3045                 var->bits_per_pixel = prom_getintdefault(node, "depth", 8);
3046                 var->xoffset = var->yoffset = 0;
3047                 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
3048                 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
3049                 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
3050                 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
3051                 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
3052                 aty_crtc_to_var(&crtc, var);
3053
3054                 h_total = var->xres + var->right_margin + var->hsync_len + var->left_margin;
3055                 v_total = var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
3056
3057                 /*
3058                  * Read the PLL to figure actual Refresh Rate.
3059                  */
3060                 clock_cntl = aty_ld_8(CLOCK_CNTL, par);
3061                 /* DPRINTK("CLOCK_CNTL %02x\n", clock_cntl); */
3062                 for (i = 0; i < 16; i++)
3063                         pll_regs[i] = aty_ld_pll_ct(i, par);
3064
3065                 /*
3066                  * PLL Reference Divider M:
3067                  */
3068                 M = pll_regs[2];
3069
3070                 /*
3071                  * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
3072                  */
3073                 N = pll_regs[7 + (clock_cntl & 3)];
3074
3075                 /*
3076                  * PLL Post Divider P (Dependant on CLOCK_CNTL):
3077                  */
3078                 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3079
3080                 /*
3081                  * PLL Divider Q:
3082                  */
3083                 Q = N / P;
3084
3085                 /*
3086                  * Target Frequency:
3087                  *
3088                  *      T * M
3089                  * Q = -------
3090                  *      2 * R
3091                  *
3092                  * where R is XTALIN (= 14318 or 29498 kHz).
3093                  */
3094                 if (IS_XL(pdev->device))
3095                         R = 29498;
3096                 else
3097                         R = 14318;
3098
3099                 T = 2 * Q * R / M;
3100
3101                 default_var.pixclock = 1000000000 / T;
3102         }
3103
3104         return 0;
3105 }
3106
3107 #else /* __sparc__ */
3108
3109 #ifdef __i386__
3110 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3111 static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3112 {
3113         u32 driv_inf_tab, sig;
3114         u16 lcd_ofs;
3115
3116         /* To support an LCD panel, we should know it's dimensions and
3117          *  it's desired pixel clock.
3118          * There are two ways to do it:
3119          *  - Check the startup video mode and calculate the panel
3120          *    size from it. This is unreliable.
3121          *  - Read it from the driver information table in the video BIOS.
3122         */
3123         /* Address of driver information table is at offset 0x78. */
3124         driv_inf_tab = bios_base + *((u16 *)(bios_base+0x78));
3125
3126         /* Check for the driver information table signature. */
3127         sig = (*(u32 *)driv_inf_tab);
3128         if ((sig == 0x54504c24) || /* Rage LT pro */
3129                 (sig == 0x544d5224) || /* Rage mobility */
3130                 (sig == 0x54435824) || /* Rage XC */
3131                 (sig == 0x544c5824)) { /* Rage XL */
3132                 PRINTKI("BIOS contains driver information table.\n");
3133                 lcd_ofs = (*(u16 *)(driv_inf_tab + 10));
3134                 par->lcd_table = 0;
3135                 if (lcd_ofs != 0) {
3136                         par->lcd_table = bios_base + lcd_ofs;
3137                 }
3138         }
3139
3140         if (par->lcd_table != 0) {
3141                 char model[24];
3142                 char strbuf[16];
3143                 char refresh_rates_buf[100];
3144                 int id, tech, f, i, m, default_refresh_rate;
3145                 char *txtcolour;
3146                 char *txtmonitor;
3147                 char *txtdual;
3148                 char *txtformat;
3149                 u16 width, height, panel_type, refresh_rates;
3150                 u16 *lcdmodeptr;
3151                 u32 format;
3152                 u8 lcd_refresh_rates[16] = {50,56,60,67,70,72,75,76,85,90,100,120,140,150,160,200};
3153                 /* The most important information is the panel size at
3154                  * offset 25 and 27, but there's some other nice information
3155                  * which we print to the screen.
3156                  */
3157                 id = *(u8 *)par->lcd_table;
3158                 strncpy(model,(char *)par->lcd_table+1,24);
3159                 model[23]=0;
3160
3161                 width = par->lcd_width = *(u16 *)(par->lcd_table+25);
3162                 height = par->lcd_height = *(u16 *)(par->lcd_table+27);
3163                 panel_type = *(u16 *)(par->lcd_table+29);
3164                 if (panel_type & 1)
3165                         txtcolour = "colour";
3166                 else
3167                         txtcolour = "monochrome";
3168                 if (panel_type & 2)
3169                         txtdual = "dual (split) ";
3170                 else
3171                         txtdual = "";
3172                 tech = (panel_type>>2) & 63;
3173                 switch (tech) {
3174                 case 0:
3175                         txtmonitor = "passive matrix";
3176                         break;
3177                 case 1:
3178                         txtmonitor = "active matrix";
3179                         break;
3180                 case 2:
3181                         txtmonitor = "active addressed STN";
3182                         break;
3183                 case 3:
3184                         txtmonitor = "EL";
3185                         break;
3186                 case 4:
3187                         txtmonitor = "plasma";
3188                         break;
3189                 default:
3190                         txtmonitor = "unknown";
3191                 }
3192                 format = *(u32 *)(par->lcd_table+57);
3193                 if (tech == 0 || tech == 2) {
3194                         switch (format & 7) {
3195                         case 0:
3196                                 txtformat = "12 bit interface";
3197                                 break;
3198                         case 1:
3199                                 txtformat = "16 bit interface";
3200                                 break;
3201                         case 2:
3202                                 txtformat = "24 bit interface";
3203                                 break;
3204                         default:
3205                                 txtformat = "unkown format";
3206                         }
3207                 } else {
3208                         switch (format & 7) {
3209                         case 0:
3210                                 txtformat = "8 colours";
3211                                 break;
3212                         case 1:
3213                                 txtformat = "512 colours";
3214                                 break;
3215                         case 2:
3216                                 txtformat = "4096 colours";
3217                                 break;
3218                         case 4:
3219                                 txtformat = "262144 colours (LT mode)";
3220                                 break;
3221                         case 5:
3222                                 txtformat = "16777216 colours";
3223                                 break;
3224                         case 6:
3225                                 txtformat = "262144 colours (FDPI-2 mode)";
3226                                 break;
3227                         default:
3228                                 txtformat = "unkown format";
3229                         }
3230                 }
3231                 PRINTKI("%s%s %s monitor detected: %s\n",
3232                         txtdual ,txtcolour, txtmonitor, model);
3233                 PRINTKI("       id=%d, %dx%d pixels, %s\n",
3234                         id, width, height, txtformat);
3235                 refresh_rates_buf[0] = 0;
3236                 refresh_rates = *(u16 *)(par->lcd_table+62);
3237                 m = 1;
3238                 f = 0;
3239                 for (i=0;i<16;i++) {
3240                         if (refresh_rates & m) {
3241                                 if (f == 0) {
3242                                         sprintf(strbuf, "%d", lcd_refresh_rates[i]);
3243                                         f++;
3244                                 } else {
3245                                         sprintf(strbuf, ",%d", lcd_refresh_rates[i]);
3246                                 }
3247                                 strcat(refresh_rates_buf,strbuf);
3248                         }
3249                         m = m << 1;
3250                 }
3251                 default_refresh_rate = (*(u8 *)(par->lcd_table+61) & 0xf0) >> 4;
3252                 PRINTKI("       supports refresh rates [%s], default %d Hz\n",
3253                         refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
3254                 par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
3255                 /* We now need to determine the crtc parameters for the
3256                  * LCD monitor. This is tricky, because they are not stored
3257                  * individually in the BIOS. Instead, the BIOS contains a
3258                  * table of display modes that work for this monitor.
3259                  *
3260                  * The idea is that we search for a mode of the same dimensions
3261                  * as the dimensions of the LCD monitor. Say our LCD monitor
3262                  * is 800x600 pixels, we search for a 800x600 monitor.
3263                  * The CRTC parameters we find here are the ones that we need
3264                  * to use to simulate other resolutions on the LCD screen.
3265                  */
3266                 lcdmodeptr = (u16 *)(par->lcd_table + 64);
3267                 while (*lcdmodeptr != 0) {
3268                         u32 modeptr;
3269                         u16 mwidth, mheight, lcd_hsync_start, lcd_vsync_start;
3270                         modeptr = bios_base + *lcdmodeptr;
3271
3272                         mwidth = *((u16 *)(modeptr+0));
3273                         mheight = *((u16 *)(modeptr+2));
3274
3275                         if (mwidth == width && mheight == height) {
3276                                 par->lcd_pixclock = 100000000 / *((u16 *)(modeptr+9));
3277                                 par->lcd_htotal = *((u16 *)(modeptr+17)) & 511;
3278                                 par->lcd_hdisp = *((u16 *)(modeptr+19)) & 511;
3279                                 lcd_hsync_start = *((u16 *)(modeptr+21)) & 511;
3280                                 par->lcd_hsync_dly = (*((u16 *)(modeptr+21)) >> 9) & 7;
3281                                 par->lcd_hsync_len = *((u8 *)(modeptr+23)) & 63;
3282
3283                                 par->lcd_vtotal = *((u16 *)(modeptr+24)) & 2047;
3284                                 par->lcd_vdisp = *((u16 *)(modeptr+26)) & 2047;
3285                                 lcd_vsync_start = *((u16 *)(modeptr+28)) & 2047;
3286                                 par->lcd_vsync_len = (*((u16 *)(modeptr+28)) >> 11) & 31;
3287
3288                                 par->lcd_htotal = (par->lcd_htotal + 1) * 8;
3289                                 par->lcd_hdisp = (par->lcd_hdisp + 1) * 8;
3290                                 lcd_hsync_start = (lcd_hsync_start + 1) * 8;
3291                                 par->lcd_hsync_len = par->lcd_hsync_len * 8;
3292
3293                                 par->lcd_vtotal++;
3294                                 par->lcd_vdisp++;
3295                                 lcd_vsync_start++;
3296
3297                                 par->lcd_right_margin = lcd_hsync_start - par->lcd_hdisp;
3298                                 par->lcd_lower_margin = lcd_vsync_start - par->lcd_vdisp;
3299                                 par->lcd_hblank_len = par->lcd_htotal - par->lcd_hdisp;
3300                                 par->lcd_vblank_len = par->lcd_vtotal - par->lcd_vdisp;
3301                                 break;
3302                         }
3303
3304                         lcdmodeptr++;
3305                 }
3306                 if (*lcdmodeptr == 0) {
3307                         PRINTKE("LCD monitor CRTC parameters not found!!!\n");
3308                         /* To do: Switch to CRT if possible. */
3309                 } else {
3310                         PRINTKI("       LCD CRTC parameters: %d.%d  %d %d %d %d  %d %d %d %d\n",
3311                                 1000000 / par->lcd_pixclock, 1000000 % par->lcd_pixclock,
3312                                 par->lcd_hdisp,
3313                                 par->lcd_hdisp + par->lcd_right_margin,
3314                                 par->lcd_hdisp + par->lcd_right_margin
3315                                         + par->lcd_hsync_dly + par->lcd_hsync_len,
3316                                 par->lcd_htotal,
3317                                 par->lcd_vdisp,
3318                                 par->lcd_vdisp + par->lcd_lower_margin,
3319                                 par->lcd_vdisp + par->lcd_lower_margin + par->lcd_vsync_len,
3320                                 par->lcd_vtotal);
3321                         PRINTKI("                          : %d %d %d %d %d %d %d %d %d\n",
3322                                 par->lcd_pixclock,
3323                                 par->lcd_hblank_len - (par->lcd_right_margin +
3324                                         par->lcd_hsync_dly + par->lcd_hsync_len),
3325                                 par->lcd_hdisp,
3326                                 par->lcd_right_margin,
3327                                 par->lcd_hsync_len,
3328                                 par->lcd_vblank_len - (par->lcd_lower_margin + par->lcd_vsync_len),
3329                                 par->lcd_vdisp,
3330                                 par->lcd_lower_margin,
3331                                 par->lcd_vsync_len);
3332                 }
3333         }
3334 }
3335 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
3336
3337 static int __devinit init_from_bios(struct atyfb_par *par)
3338 {
3339         u32 bios_base, rom_addr;
3340         int ret;
3341
3342         rom_addr = 0xc0000 + ((aty_ld_le32(SCRATCH_REG1, par) & 0x7f) << 11);
3343         bios_base = (unsigned long)ioremap(rom_addr, 0x10000);
3344
3345         /* The BIOS starts with 0xaa55. */
3346         if (*((u16 *)bios_base) == 0xaa55) {
3347
3348                 u8 *bios_ptr;
3349                 u16 rom_table_offset, freq_table_offset;
3350                 PLL_BLOCK_MACH64 pll_block;
3351
3352                 PRINTKI("Mach64 BIOS is located at %x, mapped at %x.\n", rom_addr, bios_base);
3353
3354                 /* check for frequncy table */
3355                 bios_ptr = (u8*)bios_base;
3356                 rom_table_offset = (u16)(bios_ptr[0x48] | (bios_ptr[0x49] << 8));
3357                 freq_table_offset = bios_ptr[rom_table_offset + 16] | (bios_ptr[rom_table_offset + 17] << 8);
3358                 memcpy(&pll_block, bios_ptr + freq_table_offset, sizeof(PLL_BLOCK_MACH64));
3359
3360                 PRINTKI("BIOS frequency table:\n");
3361                 PRINTKI("PCLK_min_freq %d, PCLK_max_freq %d, ref_freq %d, ref_divider %d\n",
3362                         pll_block.PCLK_min_freq, pll_block.PCLK_max_freq,
3363                         pll_block.ref_freq, pll_block.ref_divider);
3364                 PRINTKI("MCLK_pwd %d, MCLK_max_freq %d, XCLK_max_freq %d, SCLK_freq %d\n",
3365                         pll_block.MCLK_pwd, pll_block.MCLK_max_freq,
3366                         pll_block.XCLK_max_freq, pll_block.SCLK_freq);
3367
3368                 par->pll_limits.pll_min = pll_block.PCLK_min_freq/100;
3369                 par->pll_limits.pll_max = pll_block.PCLK_max_freq/100;
3370                 par->pll_limits.ref_clk = pll_block.ref_freq/100;
3371                 par->pll_limits.ref_div = pll_block.ref_divider;
3372                 par->pll_limits.sclk = pll_block.SCLK_freq/100;
3373                 par->pll_limits.mclk = pll_block.MCLK_max_freq/100;
3374                 par->pll_limits.mclk_pm = pll_block.MCLK_pwd/100;
3375                 par->pll_limits.xclk = pll_block.XCLK_max_freq/100;
3376 #ifdef CONFIG_FB_ATY_GENERIC_LCD
3377                 aty_init_lcd(par, bios_base);
3378 #endif
3379                 ret = 0;
3380         } else {
3381                 PRINTKE("no BIOS frequency table found, use parameters\n");
3382                 ret = -ENXIO;
3383         }
3384         iounmap((void* __iomem )bios_base);
3385
3386         return ret;
3387 }
3388 #endif /* __i386__ */
3389
3390 static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *info, unsigned long addr)
3391 {
3392         struct atyfb_par *par = info->par;
3393         u16 tmp;
3394         unsigned long raddr;
3395         struct resource *rrp;
3396         int ret = 0;
3397
3398         raddr = addr + 0x7ff000UL;
3399         rrp = &pdev->resource[2];
3400         if ((rrp->flags & IORESOURCE_MEM) && request_mem_region(rrp->start, rrp->end - rrp->start + 1, "atyfb")) {
3401                 par->aux_start = rrp->start;
3402                 par->aux_size = rrp->end - rrp->start + 1;
3403                 raddr = rrp->start;
3404                 PRINTKI("using auxiliary register aperture\n");
3405         }
3406
3407         info->fix.mmio_start = raddr;
3408         par->ati_regbase = ioremap(info->fix.mmio_start, 0x1000);
3409         if (par->ati_regbase == 0)
3410                 return -ENOMEM;
3411
3412         info->fix.mmio_start += par->aux_start ? 0x400 : 0xc00;
3413         par->ati_regbase += par->aux_start ? 0x400 : 0xc00;
3414
3415         /*
3416          * Enable memory-space accesses using config-space
3417          * command register.
3418          */
3419         pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3420         if (!(tmp & PCI_COMMAND_MEMORY)) {
3421                 tmp |= PCI_COMMAND_MEMORY;
3422                 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3423         }
3424 #ifdef __BIG_ENDIAN
3425         /* Use the big-endian aperture */
3426         addr += 0x800000;
3427 #endif
3428
3429         /* Map in frame buffer */
3430         info->fix.smem_start = addr;
3431         info->screen_base = ioremap(addr, 0x800000);
3432         if (info->screen_base == NULL) {
3433                 ret = -ENOMEM;
3434                 goto atyfb_setup_generic_fail;
3435         }
3436
3437         if((ret = correct_chipset(par)))
3438                 goto atyfb_setup_generic_fail;
3439 #ifdef __i386__
3440         if((ret = init_from_bios(par)))
3441                 goto atyfb_setup_generic_fail;
3442 #endif
3443         if (!(aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_EXT_DISP_EN))
3444                 par->clk_wr_offset = (inb(R_GENMO) & 0x0CU) >> 2;
3445         else
3446                 par->clk_wr_offset = aty_ld_8(CLOCK_CNTL, par) & 0x03U;
3447
3448         /* according to ATI, we should use clock 3 for acelerated mode */
3449         par->clk_wr_offset = 3;
3450
3451         return 0;
3452
3453 atyfb_setup_generic_fail:
3454         iounmap(par->ati_regbase);
3455         par->ati_regbase = NULL;
3456         if (info->screen_base) {
3457                 iounmap(info->screen_base);
3458                 info->screen_base = NULL;
3459         }
3460         return ret;
3461 }
3462
3463 #endif /* !__sparc__ */
3464
3465 static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3466 {
3467         unsigned long addr, res_start, res_size;
3468         struct fb_info *info;
3469         struct resource *rp;
3470         struct atyfb_par *par;
3471         int i, rc = -ENOMEM;
3472
3473         for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
3474                 if (pdev->device == aty_chips[i].pci_id)
3475                         break;
3476
3477         if (i < 0)
3478                 return -ENODEV;
3479
3480         /* Enable device in PCI config */
3481         if (pci_enable_device(pdev)) {
3482                 PRINTKE("Cannot enable PCI device\n");
3483                 return -ENXIO;
3484         }
3485
3486         /* Find which resource to use */
3487         rp = &pdev->resource[0];
3488         if (rp->flags & IORESOURCE_IO)
3489                 rp = &pdev->resource[1];
3490         addr = rp->start;
3491         if (!addr)
3492                 return -ENXIO;
3493
3494         /* Reserve space */
3495         res_start = rp->start;
3496         res_size = rp->end - rp->start + 1;
3497         if (!request_mem_region (res_start, res_size, "atyfb"))
3498                 return -EBUSY;
3499
3500         /* Allocate framebuffer */
3501         info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3502         if (!info) {
3503                 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
3504                 return -ENOMEM;
3505         }
3506         par = info->par;
3507         info->fix = atyfb_fix;
3508         info->device = &pdev->dev;
3509         par->pci_id = aty_chips[i].pci_id;
3510         par->res_start = res_start;
3511         par->res_size = res_size;
3512         par->irq = pdev->irq;
3513         par->pdev = pdev;
3514
3515         /* Setup "info" structure */
3516 #ifdef __sparc__
3517         rc = atyfb_setup_sparc(pdev, info, addr);
3518 #else
3519         rc = atyfb_setup_generic(pdev, info, addr);
3520 #endif
3521         if (rc)
3522                 goto err_release_mem;
3523
3524         pci_set_drvdata(pdev, info);
3525
3526         /* Init chip & register framebuffer */
3527         if (aty_init(info))
3528                 goto err_release_io;
3529
3530 #ifdef __sparc__
3531         if (!prom_palette)
3532                 prom_palette = atyfb_palette;
3533
3534         /*
3535          * Add /dev/fb mmap values.
3536          */
3537         par->mmap_map[0].voff = 0x8000000000000000UL;
3538         par->mmap_map[0].poff = (unsigned long) info->screen_base & PAGE_MASK;
3539         par->mmap_map[0].size = info->fix.smem_len;
3540         par->mmap_map[0].prot_mask = _PAGE_CACHE;
3541         par->mmap_map[0].prot_flag = _PAGE_E;
3542         par->mmap_map[1].voff = par->mmap_map[0].voff + info->fix.smem_len;
3543         par->mmap_map[1].poff = (long)par->ati_regbase & PAGE_MASK;
3544         par->mmap_map[1].size = PAGE_SIZE;
3545         par->mmap_map[1].prot_mask = _PAGE_CACHE;
3546         par->mmap_map[1].prot_flag = _PAGE_E;
3547 #endif /* __sparc__ */
3548
3549         return 0;
3550
3551 err_release_io:
3552 #ifdef __sparc__
3553         kfree(par->mmap_map);
3554 #else
3555         if (par->ati_regbase)
3556                 iounmap(par->ati_regbase);
3557         if (info->screen_base)
3558                 iounmap(info->screen_base);
3559 #endif
3560 err_release_mem:
3561         if (par->aux_start)
3562                 release_mem_region(par->aux_start, par->aux_size);
3563
3564         release_mem_region(par->res_start, par->res_size);
3565         framebuffer_release(info);
3566
3567         return rc;
3568 }
3569
3570 #endif /* CONFIG_PCI */
3571
3572 #ifdef CONFIG_ATARI
3573
3574 static int __init atyfb_atari_probe(void)
3575 {
3576         struct atyfb_par *par;
3577         struct fb_info *info;
3578         int m64_num;
3579         u32 clock_r;
3580         int num_found = 0;
3581
3582         for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3583                 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
3584                     !phys_guiregbase[m64_num]) {
3585                     PRINTKI("phys_*[%d] parameters not set => returning early. \n", m64_num);
3586                         continue;
3587                 }
3588
3589                 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3590                 if (!info) {
3591                         PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
3592                         return -ENOMEM;
3593                 }
3594                 par = info->par;
3595
3596                 info->fix = atyfb_fix;
3597
3598                 par->irq = (unsigned int) -1; /* something invalid */
3599
3600                 /*
3601                  *  Map the video memory (physical address given) to somewhere in the
3602                  *  kernel address space.
3603                  */
3604                 info->screen_base = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
3605                 info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
3606                 par->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000) +
3607                                                 0xFC00ul;
3608                 info->fix.mmio_start = (unsigned long)par->ati_regbase; /* Fake! */
3609
3610                 aty_st_le32(CLOCK_CNTL, 0x12345678, par);
3611                 clock_r = aty_ld_le32(CLOCK_CNTL, par);
3612
3613                 switch (clock_r & 0x003F) {
3614                 case 0x12:
3615                         par->clk_wr_offset = 3; /*  */
3616                         break;
3617                 case 0x34:
3618                         par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
3619                         break;
3620                 case 0x16:
3621                         par->clk_wr_offset = 1; /*  */
3622                         break;
3623                 case 0x38:
3624                         par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
3625                         break;
3626                 }
3627
3628                 /* Fake pci_id for correct_chipset() */
3629                 switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
3630                 case 0x00d7:
3631                         par->pci_id = PCI_CHIP_MACH64GX;
3632                         break;
3633                 case 0x0057:
3634                         par->pci_id = PCI_CHIP_MACH64CX;
3635                         break;
3636                 default:
3637                         break;
3638                 }
3639
3640                 if (correct_chipset(par) || aty_init(info)) {
3641                         iounmap(info->screen_base);
3642                         iounmap(par->ati_regbase);
3643                         framebuffer_release(info);
3644                 } else {
3645                         num_found++;
3646                 }
3647         }
3648
3649         return num_found ? 0 : -ENXIO;
3650 }
3651
3652 #endif /* CONFIG_ATARI */
3653
3654 #ifdef CONFIG_PCI
3655
3656 static void __devexit atyfb_remove(struct fb_info *info)
3657 {
3658         struct atyfb_par *par = (struct atyfb_par *) info->par;
3659
3660         /* restore video mode */
3661         aty_set_crtc(par, &saved_crtc);
3662         par->pll_ops->set_pll(info, &saved_pll);
3663
3664         unregister_framebuffer(info);
3665
3666 #ifdef CONFIG_FB_ATY_BACKLIGHT
3667         if (M64_HAS(MOBIL_BUS))
3668                 aty_bl_exit(info->bl_dev);
3669 #endif
3670
3671 #ifdef CONFIG_MTRR
3672         if (par->mtrr_reg >= 0) {
3673             mtrr_del(par->mtrr_reg, 0, 0);
3674             par->mtrr_reg = -1;
3675         }
3676         if (par->mtrr_aper >= 0) {
3677             mtrr_del(par->mtrr_aper, 0, 0);
3678             par->mtrr_aper = -1;
3679         }
3680 #endif
3681 #ifndef __sparc__
3682         if (par->ati_regbase)
3683                 iounmap(par->ati_regbase);
3684         if (info->screen_base)
3685                 iounmap(info->screen_base);
3686 #ifdef __BIG_ENDIAN
3687         if (info->sprite.addr)
3688                 iounmap(info->sprite.addr);
3689 #endif
3690 #endif
3691 #ifdef __sparc__
3692         kfree(par->mmap_map);
3693 #endif
3694         if (par->aux_start)
3695                 release_mem_region(par->aux_start, par->aux_size);
3696
3697         if (par->res_start)
3698                 release_mem_region(par->res_start, par->res_size);
3699
3700         framebuffer_release(info);
3701 }
3702
3703
3704 static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
3705 {
3706         struct fb_info *info = pci_get_drvdata(pdev);
3707
3708         atyfb_remove(info);
3709 }
3710
3711 /*
3712  * This driver uses its own matching table. That will be more difficult
3713  * to fix, so for now, we just match against any ATI ID and let the
3714  * probe() function find out what's up. That also mean we don't have
3715  * a module ID table though.
3716  */
3717 static struct pci_device_id atyfb_pci_tbl[] = {
3718         { PCI_VENDOR_ID_ATI, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
3719           PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0 },
3720         { 0, }
3721 };
3722
3723 static struct pci_driver atyfb_driver = {
3724         .name           = "atyfb",
3725         .id_table       = atyfb_pci_tbl,
3726         .probe          = atyfb_pci_probe,
3727         .remove         = __devexit_p(atyfb_pci_remove),
3728 #ifdef CONFIG_PM
3729         .suspend        = atyfb_pci_suspend,
3730         .resume         = atyfb_pci_resume,
3731 #endif /* CONFIG_PM */
3732 };
3733
3734 #endif /* CONFIG_PCI */
3735
3736 #ifndef MODULE
3737 static int __init atyfb_setup(char *options)
3738 {
3739         char *this_opt;
3740
3741         if (!options || !*options)
3742                 return 0;
3743
3744         while ((this_opt = strsep(&options, ",")) != NULL) {
3745                 if (!strncmp(this_opt, "noaccel", 7)) {
3746                         noaccel = 1;
3747 #ifdef CONFIG_MTRR
3748                 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3749                         nomtrr = 1;
3750 #endif
3751                 } else if (!strncmp(this_opt, "vram:", 5))
3752                         vram = simple_strtoul(this_opt + 5, NULL, 0);
3753                 else if (!strncmp(this_opt, "pll:", 4))
3754                         pll = simple_strtoul(this_opt + 4, NULL, 0);
3755                 else if (!strncmp(this_opt, "mclk:", 5))
3756                         mclk = simple_strtoul(this_opt + 5, NULL, 0);
3757                 else if (!strncmp(this_opt, "xclk:", 5))
3758                         xclk = simple_strtoul(this_opt+5, NULL, 0);
3759                 else if (!strncmp(this_opt, "comp_sync:", 10))
3760                         comp_sync = simple_strtoul(this_opt+10, NULL, 0);
3761 #ifdef CONFIG_PPC
3762                 else if (!strncmp(this_opt, "vmode:", 6)) {
3763                         unsigned int vmode =
3764                             simple_strtoul(this_opt + 6, NULL, 0);
3765                         if (vmode > 0 && vmode <= VMODE_MAX)
3766                                 default_vmode = vmode;
3767                 } else if (!strncmp(this_opt, "cmode:", 6)) {
3768                         unsigned int cmode =
3769                             simple_strtoul(this_opt + 6, NULL, 0);
3770                         switch (cmode) {
3771                         case 0:
3772                         case 8:
3773                                 default_cmode = CMODE_8;
3774                                 break;
3775                         case 15:
3776                         case 16:
3777                                 default_cmode = CMODE_16;
3778                                 break;
3779                         case 24:
3780                         case 32:
3781                                 default_cmode = CMODE_32;
3782                                 break;
3783                         }
3784                 }
3785 #endif
3786 #ifdef CONFIG_ATARI
3787                 /*
3788                  * Why do we need this silly Mach64 argument?
3789                  * We are already here because of mach64= so its redundant.
3790                  */
3791                 else if (MACH_IS_ATARI
3792                          && (!strncmp(this_opt, "Mach64:", 7))) {
3793                         static unsigned char m64_num;
3794                         static char mach64_str[80];
3795                         strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
3796                         if (!store_video_par(mach64_str, m64_num)) {
3797                                 m64_num++;
3798                                 mach64_count = m64_num;
3799                         }
3800                 }
3801 #endif
3802                 else
3803                         mode = this_opt;
3804         }
3805         return 0;
3806 }
3807 #endif  /*  MODULE  */
3808
3809 static int __init atyfb_init(void)
3810 {
3811     int err1 = 1, err2 = 1;
3812 #ifndef MODULE
3813     char *option = NULL;
3814
3815     if (fb_get_options("atyfb", &option))
3816         return -ENODEV;
3817     atyfb_setup(option);
3818 #endif
3819
3820 #ifdef CONFIG_PCI
3821     err1 = pci_register_driver(&atyfb_driver);
3822 #endif
3823 #ifdef CONFIG_ATARI
3824     err2 = atyfb_atari_probe();
3825 #endif
3826
3827     return (err1 && err2) ? -ENODEV : 0;
3828 }
3829
3830 static void __exit atyfb_exit(void)
3831 {
3832 #ifdef CONFIG_PCI
3833         pci_unregister_driver(&atyfb_driver);
3834 #endif
3835 }
3836
3837 module_init(atyfb_init);
3838 module_exit(atyfb_exit);
3839
3840 MODULE_DESCRIPTION("FBDev driver for ATI Mach64 cards");
3841 MODULE_LICENSE("GPL");
3842 module_param(noaccel, bool, 0);
3843 MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
3844 module_param(vram, int, 0);
3845 MODULE_PARM_DESC(vram, "int: override size of video ram");
3846 module_param(pll, int, 0);
3847 MODULE_PARM_DESC(pll, "int: override video clock");
3848 module_param(mclk, int, 0);
3849 MODULE_PARM_DESC(mclk, "int: override memory clock");
3850 module_param(xclk, int, 0);
3851 MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
3852 module_param(comp_sync, int, 0);
3853 MODULE_PARM_DESC(comp_sync,
3854                  "Set composite sync signal to low (0) or high (1)");
3855 module_param(mode, charp, 0);
3856 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
3857 #ifdef CONFIG_MTRR
3858 module_param(nomtrr, bool, 0);
3859 MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
3860 #endif