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