[PATCH] atyfb: Improve atyfb_atari_probe()
[sfrench/cifs-2.6.git] / drivers / video / aty / atyfb_base.c
1 /*
2  *  ATI Frame Buffer Device Driver Core
3  *
4  *      Copyright (C) 2004  Alex Kern <alex.kern@gmx.de>
5  *      Copyright (C) 1997-2001  Geert Uytterhoeven
6  *      Copyright (C) 1998  Bernd Harries
7  *      Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
8  *
9  *  This driver supports the following ATI graphics chips:
10  *    - ATI Mach64
11  *
12  *  To do: add support for
13  *    - ATI Rage128 (from aty128fb.c)
14  *    - ATI Radeon (from radeonfb.c)
15  *
16  *  This driver is partly based on the PowerMac console driver:
17  *
18  *      Copyright (C) 1996 Paul Mackerras
19  *
20  *  and on the PowerMac ATI/mach64 display driver:
21  *
22  *      Copyright (C) 1997 Michael AK Tesch
23  *
24  *            with work by Jon Howell
25  *                         Harry AC Eaton
26  *                         Anthony Tong <atong@uiuc.edu>
27  *
28  *  Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
29  *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
30  *
31  *  This file is subject to the terms and conditions of the GNU General Public
32  *  License. See the file COPYING in the main directory of this archive for
33  *  more details.
34  *
35  *  Many thanks to Nitya from ATI devrel for support and patience !
36  */
37
38 /******************************************************************************
39
40   TODO:
41
42     - cursor support on all cards and all ramdacs.
43     - cursor parameters controlable via ioctl()s.
44     - guess PLL and MCLK based on the original PLL register values initialized
45       by Open Firmware (if they are initialized). BIOS is done
46
47     (Anyone with Mac to help with this?)
48
49 ******************************************************************************/
50
51
52 #include <linux/module.h>
53 #include <linux/moduleparam.h>
54 #include <linux/kernel.h>
55 #include <linux/errno.h>
56 #include <linux/string.h>
57 #include <linux/mm.h>
58 #include <linux/slab.h>
59 #include <linux/vmalloc.h>
60 #include <linux/delay.h>
61 #include <linux/console.h>
62 #include <linux/fb.h>
63 #include <linux/init.h>
64 #include <linux/pci.h>
65 #include <linux/interrupt.h>
66 #include <linux/spinlock.h>
67 #include <linux/wait.h>
68 #include <linux/backlight.h>
69
70 #include <asm/io.h>
71 #include <asm/uaccess.h>
72
73 #include <video/mach64.h>
74 #include "atyfb.h"
75 #include "ati_ids.h"
76
77 #ifdef __powerpc__
78 #include <asm/machdep.h>
79 #include <asm/prom.h>
80 #include "../macmodes.h"
81 #endif
82 #ifdef __sparc__
83 #include <asm/pbm.h>
84 #include <asm/fbio.h>
85 #endif
86
87 #ifdef CONFIG_ADB_PMU
88 #include <linux/adb.h>
89 #include <linux/pmu.h>
90 #endif
91 #ifdef CONFIG_BOOTX_TEXT
92 #include <asm/btext.h>
93 #endif
94 #ifdef CONFIG_PMAC_BACKLIGHT
95 #include <asm/backlight.h>
96 #endif
97 #ifdef CONFIG_MTRR
98 #include <asm/mtrr.h>
99 #endif
100
101 /*
102  * Debug flags.
103  */
104 #undef DEBUG
105 /*#define DEBUG*/
106
107 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
108 /*  - must be large enough to catch all GUI-Regs   */
109 /*  - must be aligned to a PAGE boundary           */
110 #define GUI_RESERVE     (1 * PAGE_SIZE)
111
112 /* FIXME: remove the FAIL definition */
113 #define FAIL(msg) do { \
114         if (!(var->activate & FB_ACTIVATE_TEST)) \
115                 printk(KERN_CRIT "atyfb: " msg "\n"); \
116         return -EINVAL; \
117 } while (0)
118 #define FAIL_MAX(msg, x, _max_) do { \
119         if (x > _max_) { \
120                 if (!(var->activate & FB_ACTIVATE_TEST)) \
121                         printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
122                 return -EINVAL; \
123         } \
124 } while (0)
125 #ifdef DEBUG
126 #define DPRINTK(fmt, args...)   printk(KERN_DEBUG "atyfb: " fmt, ## args)
127 #else
128 #define DPRINTK(fmt, args...)
129 #endif
130
131 #define PRINTKI(fmt, args...)   printk(KERN_INFO "atyfb: " fmt, ## args)
132 #define PRINTKE(fmt, args...)    printk(KERN_ERR "atyfb: " fmt, ## args)
133
134 #if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD)
135 static const u32 lt_lcd_regs[] = {
136         CONFIG_PANEL_LG,
137         LCD_GEN_CNTL_LG,
138         DSTN_CONTROL_LG,
139         HFB_PITCH_ADDR_LG,
140         HORZ_STRETCHING_LG,
141         VERT_STRETCHING_LG,
142         0, /* EXT_VERT_STRETCH */
143         LT_GIO_LG,
144         POWER_MANAGEMENT_LG
145 };
146
147 void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
148 {
149         if (M64_HAS(LT_LCD_REGS)) {
150                 aty_st_le32(lt_lcd_regs[index], val, par);
151         } else {
152                 unsigned long temp;
153
154                 /* write addr byte */
155                 temp = aty_ld_le32(LCD_INDEX, par);
156                 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
157                 /* write the register value */
158                 aty_st_le32(LCD_DATA, val, par);
159         }
160 }
161
162 u32 aty_ld_lcd(int index, const struct atyfb_par *par)
163 {
164         if (M64_HAS(LT_LCD_REGS)) {
165                 return aty_ld_le32(lt_lcd_regs[index], par);
166         } else {
167                 unsigned long temp;
168
169                 /* write addr byte */
170                 temp = aty_ld_le32(LCD_INDEX, par);
171                 aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
172                 /* read the register value */
173                 return aty_ld_le32(LCD_DATA, par);
174         }
175 }
176 #endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */
177
178 #ifdef CONFIG_FB_ATY_GENERIC_LCD
179 /*
180  * ATIReduceRatio --
181  *
182  * Reduce a fraction by factoring out the largest common divider of the
183  * fraction's numerator and denominator.
184  */
185 static void ATIReduceRatio(int *Numerator, int *Denominator)
186 {
187     int Multiplier, Divider, Remainder;
188
189     Multiplier = *Numerator;
190     Divider = *Denominator;
191
192     while ((Remainder = Multiplier % Divider))
193     {
194         Multiplier = Divider;
195         Divider = Remainder;
196     }
197
198     *Numerator /= Divider;
199     *Denominator /= Divider;
200 }
201 #endif
202     /*
203      *  The Hardware parameters for each card
204      */
205
206 struct pci_mmap_map {
207         unsigned long voff;
208         unsigned long poff;
209         unsigned long size;
210         unsigned long prot_flag;
211         unsigned long prot_mask;
212 };
213
214 static struct fb_fix_screeninfo atyfb_fix __devinitdata = {
215         .id             = "ATY Mach64",
216         .type           = FB_TYPE_PACKED_PIXELS,
217         .visual         = FB_VISUAL_PSEUDOCOLOR,
218         .xpanstep       = 8,
219         .ypanstep       = 1,
220 };
221
222     /*
223      *  Frame buffer device API
224      */
225
226 static int atyfb_open(struct fb_info *info, int user);
227 static int atyfb_release(struct fb_info *info, int user);
228 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
229 static int atyfb_set_par(struct fb_info *info);
230 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
231         u_int transp, struct fb_info *info);
232 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
233 static int atyfb_blank(int blank, struct fb_info *info);
234 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
235 #ifdef __sparc__
236 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);
237 #endif
238 static int atyfb_sync(struct fb_info *info);
239
240     /*
241      *  Internal routines
242      */
243
244 static int aty_init(struct fb_info *info);
245 #ifdef CONFIG_ATARI
246 static int store_video_par(char *videopar, unsigned char m64_num);
247 #endif
248
249 static struct crtc saved_crtc;
250 static union aty_pll saved_pll;
251 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
252
253 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
254 static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);
255 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);
256 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
257 #ifdef CONFIG_PPC
258 static int read_aty_sense(const struct atyfb_par *par);
259 #endif
260
261
262     /*
263      *  Interface used by the world
264      */
265
266 static struct fb_var_screeninfo default_var = {
267         /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
268         640, 480, 640, 480, 0, 0, 8, 0,
269         {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
270         0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
271         0, FB_VMODE_NONINTERLACED
272 };
273
274 static struct fb_videomode defmode = {
275         /* 640x480 @ 60 Hz, 31.5 kHz hsync */
276         NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
277         0, FB_VMODE_NONINTERLACED
278 };
279
280 static struct fb_ops atyfb_ops = {
281         .owner          = THIS_MODULE,
282         .fb_open        = atyfb_open,
283         .fb_release     = atyfb_release,
284         .fb_check_var   = atyfb_check_var,
285         .fb_set_par     = atyfb_set_par,
286         .fb_setcolreg   = atyfb_setcolreg,
287         .fb_pan_display = atyfb_pan_display,
288         .fb_blank       = atyfb_blank,
289         .fb_ioctl       = atyfb_ioctl,
290         .fb_fillrect    = atyfb_fillrect,
291         .fb_copyarea    = atyfb_copyarea,
292         .fb_imageblit   = atyfb_imageblit,
293 #ifdef __sparc__
294         .fb_mmap        = atyfb_mmap,
295 #endif
296         .fb_sync        = atyfb_sync,
297 };
298
299 static int noaccel;
300 #ifdef CONFIG_MTRR
301 static int nomtrr;
302 #endif
303 static int vram;
304 static int pll;
305 static int mclk;
306 static int xclk;
307 static int comp_sync __devinitdata = -1;
308 static char *mode;
309
310 #ifdef CONFIG_PPC
311 static int default_vmode __devinitdata = VMODE_CHOOSE;
312 static int default_cmode __devinitdata = CMODE_CHOOSE;
313
314 module_param_named(vmode, default_vmode, int, 0);
315 MODULE_PARM_DESC(vmode, "int: video mode for mac");
316 module_param_named(cmode, default_cmode, int, 0);
317 MODULE_PARM_DESC(cmode, "int: color mode for mac");
318 #endif
319
320 #ifdef CONFIG_ATARI
321 static unsigned int mach64_count __devinitdata = 0;
322 static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, };
323 static unsigned long phys_size[FB_MAX] __devinitdata = { 0, };
324 static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
325 #endif
326
327 /* top -> down is an evolution of mach64 chipset, any corrections? */
328 #define ATI_CHIP_88800GX   (M64F_GX)
329 #define ATI_CHIP_88800CX   (M64F_GX)
330
331 #define ATI_CHIP_264CT     (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
332 #define ATI_CHIP_264ET     (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)
333
334 #define ATI_CHIP_264VT     (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)
335 #define ATI_CHIP_264GT     (M64F_GT | M64F_INTEGRATED               | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)
336
337 #define ATI_CHIP_264VTB    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)
338 #define ATI_CHIP_264VT3    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
339 #define ATI_CHIP_264VT4    (M64F_VT | M64F_INTEGRATED               | M64F_GTB_DSP)
340
341 /* FIXME what is this chip? */
342 #define ATI_CHIP_264LT     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP)
343
344 /* make sets shorter */
345 #define ATI_MODERN_SET     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)
346
347 #define ATI_CHIP_264GTB    (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
348 /*#define ATI_CHIP_264GTDVD  ?*/
349 #define ATI_CHIP_264LTG    (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)
350
351 #define ATI_CHIP_264GT2C   (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)
352 #define ATI_CHIP_264GTPRO  (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
353 #define ATI_CHIP_264LTPRO  (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
354
355 #define ATI_CHIP_264XL     (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
356 #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)
357
358 static struct {
359         u16 pci_id;
360         const char *name;
361         int pll, mclk, xclk, ecp_max;
362         u32 features;
363 } aty_chips[] __devinitdata = {
364 #ifdef CONFIG_FB_ATY_GX
365         /* Mach64 GX */
366         { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
367         { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },
368 #endif /* CONFIG_FB_ATY_GX */
369
370 #ifdef CONFIG_FB_ATY_CT
371         { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },
372         { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },
373
374         /* FIXME what is this chip? */
375         { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },
376
377         { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },
378         { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },
379
380         { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },
381         { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },
382
383         { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
384
385         { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },
386
387         { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
388         { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
389         { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
390         { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
391
392         { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
393         { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
394         { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
395         { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
396         { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
397
398         { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
399         { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
400         { 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 },
401         { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
402         { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
403
404         { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
405         { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
406         { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
407         { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
408         { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
409         { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },
410
411         { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
412         { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
413         { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
414         { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
415 #endif /* CONFIG_FB_ATY_CT */
416 };
417
418 /* can not fail */
419 static int __devinit correct_chipset(struct atyfb_par *par)
420 {
421         u8 rev;
422         u16 type;
423         u32 chip_id;
424         const char *name;
425         int i;
426
427         for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
428                 if (par->pci_id == aty_chips[i].pci_id)
429                         break;
430
431         name = aty_chips[i].name;
432         par->pll_limits.pll_max = aty_chips[i].pll;
433         par->pll_limits.mclk = aty_chips[i].mclk;
434         par->pll_limits.xclk = aty_chips[i].xclk;
435         par->pll_limits.ecp_max = aty_chips[i].ecp_max;
436         par->features = aty_chips[i].features;
437
438         chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
439         type = chip_id & CFG_CHIP_TYPE;
440         rev = (chip_id & CFG_CHIP_REV) >> 24;
441
442         switch(par->pci_id) {
443 #ifdef CONFIG_FB_ATY_GX
444         case PCI_CHIP_MACH64GX:
445                 if(type != 0x00d7)
446                         return -ENODEV;
447                 break;
448         case PCI_CHIP_MACH64CX:
449                 if(type != 0x0057)
450                         return -ENODEV;
451                 break;
452 #endif
453 #ifdef CONFIG_FB_ATY_CT
454         case PCI_CHIP_MACH64VT:
455                 switch (rev & 0x07) {
456                 case 0x00:
457                         switch (rev & 0xc0) {
458                         case 0x00:
459                                 name = "ATI264VT (A3) (Mach64 VT)";
460                                 par->pll_limits.pll_max = 170;
461                                 par->pll_limits.mclk = 67;
462                                 par->pll_limits.xclk = 67;
463                                 par->pll_limits.ecp_max = 80;
464                                 par->features = ATI_CHIP_264VT;
465                                 break;
466                         case 0x40:
467                                 name = "ATI264VT2 (A4) (Mach64 VT)";
468                                 par->pll_limits.pll_max = 200;
469                                 par->pll_limits.mclk = 67;
470                                 par->pll_limits.xclk = 67;
471                                 par->pll_limits.ecp_max = 80;
472                                 par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
473                                 break;
474                         }
475                         break;
476                 case 0x01:
477                         name = "ATI264VT3 (B1) (Mach64 VT)";
478                         par->pll_limits.pll_max = 200;
479                         par->pll_limits.mclk = 67;
480                         par->pll_limits.xclk = 67;
481                         par->pll_limits.ecp_max = 80;
482                         par->features = ATI_CHIP_264VTB;
483                         break;
484                 case 0x02:
485                         name = "ATI264VT3 (B2) (Mach64 VT)";
486                         par->pll_limits.pll_max = 200;
487                         par->pll_limits.mclk = 67;
488                         par->pll_limits.xclk = 67;
489                         par->pll_limits.ecp_max = 80;
490                         par->features = ATI_CHIP_264VT3;
491                         break;
492                 }
493                 break;
494         case PCI_CHIP_MACH64GT:
495                 switch (rev & 0x07) {
496                 case 0x01:
497                         name = "3D RAGE II (Mach64 GT)";
498                         par->pll_limits.pll_max = 170;
499                         par->pll_limits.mclk = 67;
500                         par->pll_limits.xclk = 67;
501                         par->pll_limits.ecp_max = 80;
502                         par->features = ATI_CHIP_264GTB;
503                         break;
504                 case 0x02:
505                         name = "3D RAGE II+ (Mach64 GT)";
506                         par->pll_limits.pll_max = 200;
507                         par->pll_limits.mclk = 67;
508                         par->pll_limits.xclk = 67;
509                         par->pll_limits.ecp_max = 100;
510                         par->features = ATI_CHIP_264GTB;
511                         break;
512                 }
513                 break;
514 #endif
515         }
516
517         PRINTKI("%s [0x%04x rev 0x%02x]\n", name, type, rev);
518         return 0;
519 }
520
521 static char ram_dram[] __devinitdata = "DRAM";
522 static char ram_resv[] __devinitdata = "RESV";
523 #ifdef CONFIG_FB_ATY_GX
524 static char ram_vram[] __devinitdata = "VRAM";
525 #endif /* CONFIG_FB_ATY_GX */
526 #ifdef CONFIG_FB_ATY_CT
527 static char ram_edo[] __devinitdata = "EDO";
528 static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
529 static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
530 static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
531 static char ram_off[] __devinitdata = "OFF";
532 #endif /* CONFIG_FB_ATY_CT */
533
534
535 static u32 pseudo_palette[17];
536
537 #ifdef CONFIG_FB_ATY_GX
538 static char *aty_gx_ram[8] __devinitdata = {
539         ram_dram, ram_vram, ram_vram, ram_dram,
540         ram_dram, ram_vram, ram_vram, ram_resv
541 };
542 #endif /* CONFIG_FB_ATY_GX */
543
544 #ifdef CONFIG_FB_ATY_CT
545 static char *aty_ct_ram[8] __devinitdata = {
546         ram_off, ram_dram, ram_edo, ram_edo,
547         ram_sdram, ram_sgram, ram_sdram32, ram_resv
548 };
549 #endif /* CONFIG_FB_ATY_CT */
550
551 static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *par)
552 {
553         u32 pixclock = var->pixclock;
554 #ifdef CONFIG_FB_ATY_GENERIC_LCD
555         u32 lcd_on_off;
556         par->pll.ct.xres = 0;
557         if (par->lcd_table != 0) {
558                 lcd_on_off = aty_ld_lcd(LCD_GEN_CNTL, par);
559                 if(lcd_on_off & LCD_ON) {
560                         par->pll.ct.xres = var->xres;
561                         pixclock = par->lcd_pixclock;
562                 }
563         }
564 #endif
565         return pixclock;
566 }
567
568 #if defined(CONFIG_PPC)
569
570 /*
571  *  Apple monitor sense
572  */
573
574 static int __devinit read_aty_sense(const struct atyfb_par *par)
575 {
576         int sense, i;
577
578         aty_st_le32(GP_IO, 0x31003100, par); /* drive outputs high */
579         __delay(200);
580         aty_st_le32(GP_IO, 0, par); /* turn off outputs */
581         __delay(2000);
582         i = aty_ld_le32(GP_IO, par); /* get primary sense value */
583         sense = ((i & 0x3000) >> 3) | (i & 0x100);
584
585         /* drive each sense line low in turn and collect the other 2 */
586         aty_st_le32(GP_IO, 0x20000000, par); /* drive A low */
587         __delay(2000);
588         i = aty_ld_le32(GP_IO, par);
589         sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
590         aty_st_le32(GP_IO, 0x20002000, par); /* drive A high again */
591         __delay(200);
592
593         aty_st_le32(GP_IO, 0x10000000, par); /* drive B low */
594         __delay(2000);
595         i = aty_ld_le32(GP_IO, par);
596         sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
597         aty_st_le32(GP_IO, 0x10001000, par); /* drive B high again */
598         __delay(200);
599
600         aty_st_le32(GP_IO, 0x01000000, par); /* drive C low */
601         __delay(2000);
602         sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
603         aty_st_le32(GP_IO, 0, par); /* turn off outputs */
604         return sense;
605 }
606
607 #endif /* defined(CONFIG_PPC) */
608
609 /* ------------------------------------------------------------------------- */
610
611 /*
612  *  CRTC programming
613  */
614
615 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
616 {
617 #ifdef CONFIG_FB_ATY_GENERIC_LCD
618         if (par->lcd_table != 0) {
619                 if(!M64_HAS(LT_LCD_REGS)) {
620                     crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
621                     aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
622                 }
623                 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
624                 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
625
626
627                 /* switch to non shadow registers */
628                 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
629                     ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
630
631                 /* save stretching */
632                 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
633                 crtc->vert_stretching = aty_ld_lcd(VERT_STRETCHING, par);
634                 if (!M64_HAS(LT_LCD_REGS))
635                         crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par);
636         }
637 #endif
638         crtc->h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
639         crtc->h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
640         crtc->v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
641         crtc->v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
642         crtc->vline_crnt_vline = aty_ld_le32(CRTC_VLINE_CRNT_VLINE, par);
643         crtc->off_pitch = aty_ld_le32(CRTC_OFF_PITCH, par);
644         crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
645
646 #ifdef CONFIG_FB_ATY_GENERIC_LCD
647         if (par->lcd_table != 0) {
648                 /* switch to shadow registers */
649                 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
650                         SHADOW_EN | SHADOW_RW_EN, par);
651
652                 crtc->shadow_h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
653                 crtc->shadow_h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
654                 crtc->shadow_v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, par);
655                 crtc->shadow_v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, par);
656
657                 aty_st_le32(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
658         }
659 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
660 }
661
662 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
663 {
664 #ifdef CONFIG_FB_ATY_GENERIC_LCD
665         if (par->lcd_table != 0) {
666                 /* stop CRTC */
667                 aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
668
669                 /* update non-shadow registers first */
670                 aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
671                 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
672                         ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
673
674                 /* temporarily disable stretching */
675                 aty_st_lcd(HORZ_STRETCHING,
676                         crtc->horz_stretching &
677                         ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN), par);
678                 aty_st_lcd(VERT_STRETCHING,
679                         crtc->vert_stretching &
680                         ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
681                         VERT_STRETCH_USE0 | VERT_STRETCH_EN), par);
682         }
683 #endif
684         /* turn off CRT */
685         aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~CRTC_EN, par);
686
687         DPRINTK("setting up CRTC\n");
688         DPRINTK("set primary CRT to %ix%i %c%c composite %c\n",
689             ((((crtc->h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->v_tot_disp>>16) & 0x7ff) + 1),
690             (crtc->h_sync_strt_wid & 0x200000)?'N':'P', (crtc->v_sync_strt_wid & 0x200000)?'N':'P',
691             (crtc->gen_cntl & CRTC_CSYNC_EN)?'P':'N');
692
693         DPRINTK("CRTC_H_TOTAL_DISP: %x\n",crtc->h_tot_disp);
694         DPRINTK("CRTC_H_SYNC_STRT_WID: %x\n",crtc->h_sync_strt_wid);
695         DPRINTK("CRTC_V_TOTAL_DISP: %x\n",crtc->v_tot_disp);
696         DPRINTK("CRTC_V_SYNC_STRT_WID: %x\n",crtc->v_sync_strt_wid);
697         DPRINTK("CRTC_OFF_PITCH: %x\n", crtc->off_pitch);
698         DPRINTK("CRTC_VLINE_CRNT_VLINE: %x\n", crtc->vline_crnt_vline);
699         DPRINTK("CRTC_GEN_CNTL: %x\n",crtc->gen_cntl);
700
701         aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
702         aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
703         aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
704         aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
705         aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
706         aty_st_le32(CRTC_VLINE_CRNT_VLINE, crtc->vline_crnt_vline, par);
707
708         aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
709 #if 0
710         FIXME
711         if (par->accel_flags & FB_ACCELF_TEXT)
712                 aty_init_engine(par, info);
713 #endif
714 #ifdef CONFIG_FB_ATY_GENERIC_LCD
715         /* after setting the CRTC registers we should set the LCD registers. */
716         if (par->lcd_table != 0) {
717                 /* switch to shadow registers */
718                 aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
719                         (SHADOW_EN | SHADOW_RW_EN), par);
720
721                 DPRINTK("set shadow CRT to %ix%i %c%c\n",
722                     ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
723                     (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
724
725                 DPRINTK("SHADOW CRTC_H_TOTAL_DISP: %x\n", crtc->shadow_h_tot_disp);
726                 DPRINTK("SHADOW CRTC_H_SYNC_STRT_WID: %x\n", crtc->shadow_h_sync_strt_wid);
727                 DPRINTK("SHADOW CRTC_V_TOTAL_DISP: %x\n", crtc->shadow_v_tot_disp);
728                 DPRINTK("SHADOW CRTC_V_SYNC_STRT_WID: %x\n", crtc->shadow_v_sync_strt_wid);
729
730                 aty_st_le32(CRTC_H_TOTAL_DISP, crtc->shadow_h_tot_disp, par);
731                 aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->shadow_h_sync_strt_wid, par);
732                 aty_st_le32(CRTC_V_TOTAL_DISP, crtc->shadow_v_tot_disp, par);
733                 aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->shadow_v_sync_strt_wid, par);
734
735                 /* restore CRTC selection & shadow state and enable stretching */
736                 DPRINTK("LCD_GEN_CNTL: %x\n", crtc->lcd_gen_cntl);
737                 DPRINTK("HORZ_STRETCHING: %x\n", crtc->horz_stretching);
738                 DPRINTK("VERT_STRETCHING: %x\n", crtc->vert_stretching);
739                 if(!M64_HAS(LT_LCD_REGS))
740                     DPRINTK("EXT_VERT_STRETCH: %x\n", crtc->ext_vert_stretch);
741
742                 aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);
743                 aty_st_lcd(HORZ_STRETCHING, crtc->horz_stretching, par);
744                 aty_st_lcd(VERT_STRETCHING, crtc->vert_stretching, par);
745                 if(!M64_HAS(LT_LCD_REGS)) {
746                     aty_st_lcd(EXT_VERT_STRETCH, crtc->ext_vert_stretch, par);
747                     aty_ld_le32(LCD_INDEX, par);
748                     aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
749                 }
750         }
751 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
752 }
753
754 static int aty_var_to_crtc(const struct fb_info *info,
755         const struct fb_var_screeninfo *var, struct crtc *crtc)
756 {
757         struct atyfb_par *par = (struct atyfb_par *) info->par;
758         u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
759         u32 sync, vmode, vdisplay;
760         u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
761         u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
762         u32 pix_width, dp_pix_width, dp_chain_mask;
763
764         /* input */
765         xres = var->xres;
766         yres = var->yres;
767         vxres = var->xres_virtual;
768         vyres = var->yres_virtual;
769         xoffset = var->xoffset;
770         yoffset = var->yoffset;
771         bpp = var->bits_per_pixel;
772         if (bpp == 16)
773                 bpp = (var->green.length == 5) ? 15 : 16;
774         sync = var->sync;
775         vmode = var->vmode;
776
777         /* convert (and round up) and validate */
778         if (vxres < xres + xoffset)
779                 vxres = xres + xoffset;
780         h_disp = xres;
781
782         if (vyres < yres + yoffset)
783                 vyres = yres + yoffset;
784         v_disp = yres;
785
786         if (bpp <= 8) {
787                 bpp = 8;
788                 pix_width = CRTC_PIX_WIDTH_8BPP;
789                 dp_pix_width =
790                     HOST_8BPP | SRC_8BPP | DST_8BPP |
791                     BYTE_ORDER_LSB_TO_MSB;
792                 dp_chain_mask = DP_CHAIN_8BPP;
793         } else if (bpp <= 15) {
794                 bpp = 16;
795                 pix_width = CRTC_PIX_WIDTH_15BPP;
796                 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
797                     BYTE_ORDER_LSB_TO_MSB;
798                 dp_chain_mask = DP_CHAIN_15BPP;
799         } else if (bpp <= 16) {
800                 bpp = 16;
801                 pix_width = CRTC_PIX_WIDTH_16BPP;
802                 dp_pix_width = HOST_16BPP | SRC_16BPP | DST_16BPP |
803                     BYTE_ORDER_LSB_TO_MSB;
804                 dp_chain_mask = DP_CHAIN_16BPP;
805         } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
806                 bpp = 24;
807                 pix_width = CRTC_PIX_WIDTH_24BPP;
808                 dp_pix_width =
809                     HOST_8BPP | SRC_8BPP | DST_8BPP |
810                     BYTE_ORDER_LSB_TO_MSB;
811                 dp_chain_mask = DP_CHAIN_24BPP;
812         } else if (bpp <= 32) {
813                 bpp = 32;
814                 pix_width = CRTC_PIX_WIDTH_32BPP;
815                 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
816                     BYTE_ORDER_LSB_TO_MSB;
817                 dp_chain_mask = DP_CHAIN_32BPP;
818         } else
819                 FAIL("invalid bpp");
820
821         if (vxres * vyres * bpp / 8 > info->fix.smem_len)
822                 FAIL("not enough video RAM");
823
824         h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
825         v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
826
827         if((xres > 1600) || (yres > 1200)) {
828                 FAIL("MACH64 chips are designed for max 1600x1200\n"
829                 "select anoter resolution.");
830         }
831         h_sync_strt = h_disp + var->right_margin;
832         h_sync_end = h_sync_strt + var->hsync_len;
833         h_sync_dly  = var->right_margin & 7;
834         h_total = h_sync_end + h_sync_dly + var->left_margin;
835
836         v_sync_strt = v_disp + var->lower_margin;
837         v_sync_end = v_sync_strt + var->vsync_len;
838         v_total = v_sync_end + var->upper_margin;
839
840 #ifdef CONFIG_FB_ATY_GENERIC_LCD
841         if (par->lcd_table != 0) {
842                 if(!M64_HAS(LT_LCD_REGS)) {
843                     u32 lcd_index = aty_ld_le32(LCD_INDEX, par);
844                     crtc->lcd_index = lcd_index &
845                         ~(LCD_INDEX_MASK | LCD_DISPLAY_DIS | LCD_SRC_SEL | CRTC2_DISPLAY_DIS);
846                     aty_st_le32(LCD_INDEX, lcd_index, par);
847                 }
848
849                 if (!M64_HAS(MOBIL_BUS))
850                         crtc->lcd_index |= CRTC2_DISPLAY_DIS;
851
852                 crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
853                 crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
854
855                 crtc->lcd_gen_cntl &=
856                         ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | TVCLK_PM_EN |
857                         /*VCLK_DAC_PM_EN | USE_SHADOWED_VEND |*/
858                         USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
859                 crtc->lcd_gen_cntl |= DONT_SHADOW_VPAR | LOCK_8DOT;
860
861                 if((crtc->lcd_gen_cntl & LCD_ON) &&
862                         ((xres > par->lcd_width) || (yres > par->lcd_height))) {
863                         /* We cannot display the mode on the LCD. If the CRT is enabled
864                            we can turn off the LCD.
865                            If the CRT is off, it isn't a good idea to switch it on; we don't
866                            know if one is connected. So it's better to fail then.
867                          */
868                         if (crtc->lcd_gen_cntl & CRT_ON) {
869                                 if (!(var->activate & FB_ACTIVATE_TEST))
870                                         PRINTKI("Disable LCD panel, because video mode does not fit.\n");
871                                 crtc->lcd_gen_cntl &= ~LCD_ON;
872                                 /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
873                         } else {
874                                 if (!(var->activate & FB_ACTIVATE_TEST))
875                                         PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
876                                 return -EINVAL;
877                         }
878                 }
879         }
880
881         if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON)) {
882                 int VScan = 1;
883                 /* bpp -> bytespp, 1,4 -> 0; 8 -> 2; 15,16 -> 1; 24 -> 6; 32 -> 5
884                 const u8 DFP_h_sync_dly_LT[] = { 0, 2, 1, 6, 5 };
885                 const u8 ADD_to_strt_wid_and_dly_LT_DAC[] = { 0, 5, 6, 9, 9, 12, 12 };  */
886
887                 vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
888
889                 /* This is horror! When we simulate, say 640x480 on an 800x600
890                    LCD monitor, the CRTC should be programmed 800x600 values for
891                    the non visible part, but 640x480 for the visible part.
892                    This code has been tested on a laptop with it's 1400x1050 LCD
893                    monitor and a conventional monitor both switched on.
894                    Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
895                     works with little glitches also with DOUBLESCAN modes
896                  */
897                 if (yres < par->lcd_height) {
898                         VScan = par->lcd_height / yres;
899                         if(VScan > 1) {
900                                 VScan = 2;
901                                 vmode |= FB_VMODE_DOUBLE;
902                         }
903                 }
904
905                 h_sync_strt = h_disp + par->lcd_right_margin;
906                 h_sync_end = h_sync_strt + par->lcd_hsync_len;
907                 h_sync_dly = /*DFP_h_sync_dly[ ( bpp + 1 ) / 3 ]; */par->lcd_hsync_dly;
908                 h_total = h_disp + par->lcd_hblank_len;
909
910                 v_sync_strt = v_disp + par->lcd_lower_margin / VScan;
911                 v_sync_end = v_sync_strt + par->lcd_vsync_len / VScan;
912                 v_total = v_disp + par->lcd_vblank_len / VScan;
913         }
914 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
915
916         h_disp = (h_disp >> 3) - 1;
917         h_sync_strt = (h_sync_strt >> 3) - 1;
918         h_sync_end = (h_sync_end >> 3) - 1;
919         h_total = (h_total >> 3) - 1;
920         h_sync_wid = h_sync_end - h_sync_strt;
921
922         FAIL_MAX("h_disp too large", h_disp, 0xff);
923         FAIL_MAX("h_sync_strt too large", h_sync_strt, 0x1ff);
924         /*FAIL_MAX("h_sync_wid too large", h_sync_wid, 0x1f);*/
925         if(h_sync_wid > 0x1f)
926                 h_sync_wid = 0x1f;
927         FAIL_MAX("h_total too large", h_total, 0x1ff);
928
929         if (vmode & FB_VMODE_DOUBLE) {
930                 v_disp <<= 1;
931                 v_sync_strt <<= 1;
932                 v_sync_end <<= 1;
933                 v_total <<= 1;
934         }
935
936         vdisplay = yres;
937 #ifdef CONFIG_FB_ATY_GENERIC_LCD
938         if ((par->lcd_table != 0) && (crtc->lcd_gen_cntl & LCD_ON))
939                 vdisplay  = par->lcd_height;
940 #endif
941
942         v_disp--;
943         v_sync_strt--;
944         v_sync_end--;
945         v_total--;
946         v_sync_wid = v_sync_end - v_sync_strt;
947
948         FAIL_MAX("v_disp too large", v_disp, 0x7ff);
949         FAIL_MAX("v_sync_stsrt too large", v_sync_strt, 0x7ff);
950         /*FAIL_MAX("v_sync_wid too large", v_sync_wid, 0x1f);*/
951         if(v_sync_wid > 0x1f)
952                 v_sync_wid = 0x1f;
953         FAIL_MAX("v_total too large", v_total, 0x7ff);
954
955         c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
956
957         /* output */
958         crtc->vxres = vxres;
959         crtc->vyres = vyres;
960         crtc->xoffset = xoffset;
961         crtc->yoffset = yoffset;
962         crtc->bpp = bpp;
963         crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
964         crtc->vline_crnt_vline = 0;
965
966         crtc->h_tot_disp = h_total | (h_disp<<16);
967         crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
968                 ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) | (h_sync_pol<<21);
969         crtc->v_tot_disp = v_total | (v_disp<<16);
970         crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
971
972         /* crtc->gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_PRESERVED_MASK; */
973         crtc->gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN | pix_width | c_sync;
974         crtc->gen_cntl |= CRTC_VGA_LINEAR;
975
976         /* Enable doublescan mode if requested */
977         if (vmode & FB_VMODE_DOUBLE)
978                 crtc->gen_cntl |= CRTC_DBL_SCAN_EN;
979         /* Enable interlaced mode if requested */
980         if (vmode & FB_VMODE_INTERLACED)
981                 crtc->gen_cntl |= CRTC_INTERLACE_EN;
982 #ifdef CONFIG_FB_ATY_GENERIC_LCD
983         if (par->lcd_table != 0) {
984                 vdisplay = yres;
985                 if(vmode & FB_VMODE_DOUBLE)
986                         vdisplay <<= 1;
987                 crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
988                 crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
989                         /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
990                         USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN | SHADOW_RW_EN);
991                 crtc->lcd_gen_cntl |= (DONT_SHADOW_VPAR/* | LOCK_8DOT*/);
992
993                 /* MOBILITY M1 tested, FIXME: LT */
994                 crtc->horz_stretching = aty_ld_lcd(HORZ_STRETCHING, par);
995                 if (!M64_HAS(LT_LCD_REGS))
996                         crtc->ext_vert_stretch = aty_ld_lcd(EXT_VERT_STRETCH, par) &
997                                 ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE | VERT_STRETCH_RATIO3);
998
999                 crtc->horz_stretching &=
1000                         ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
1001                         HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
1002                 if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) {
1003                         do {
1004                                 /*
1005                                 * The horizontal blender misbehaves when HDisplay is less than a
1006                                 * a certain threshold (440 for a 1024-wide panel).  It doesn't
1007                                 * stretch such modes enough.  Use pixel replication instead of
1008                                 * blending to stretch modes that can be made to exactly fit the
1009                                 * panel width.  The undocumented "NoLCDBlend" option allows the
1010                                 * pixel-replicated mode to be slightly wider or narrower than the
1011                                 * panel width.  It also causes a mode that is exactly half as wide
1012                                 * as the panel to be pixel-replicated, rather than blended.
1013                                 */
1014                                 int HDisplay  = xres & ~7;
1015                                 int nStretch  = par->lcd_width / HDisplay;
1016                                 int Remainder = par->lcd_width % HDisplay;
1017
1018                                 if ((!Remainder && ((nStretch > 2))) ||
1019                                         (((HDisplay * 16) / par->lcd_width) < 7)) {
1020                                         static const char StretchLoops[] = {10, 12, 13, 15, 16};
1021                                         int horz_stretch_loop = -1, BestRemainder;
1022                                         int Numerator = HDisplay, Denominator = par->lcd_width;
1023                                         int Index = 5;
1024                                         ATIReduceRatio(&Numerator, &Denominator);
1025
1026                                         BestRemainder = (Numerator * 16) / Denominator;
1027                                         while (--Index >= 0) {
1028                                                 Remainder = ((Denominator - Numerator) * StretchLoops[Index]) %
1029                                                         Denominator;
1030                                                 if (Remainder < BestRemainder) {
1031                                                         horz_stretch_loop = Index;
1032                                                         if (!(BestRemainder = Remainder))
1033                                                                 break;
1034                                                 }
1035                                         }
1036
1037                                         if ((horz_stretch_loop >= 0) && !BestRemainder) {
1038                                                 int horz_stretch_ratio = 0, Accumulator = 0;
1039                                                 int reuse_previous = 1;
1040
1041                                                 Index = StretchLoops[horz_stretch_loop];
1042
1043                                                 while (--Index >= 0) {
1044                                                         if (Accumulator > 0)
1045                                                                 horz_stretch_ratio |= reuse_previous;
1046                                                         else
1047                                                                 Accumulator += Denominator;
1048                                                         Accumulator -= Numerator;
1049                                                         reuse_previous <<= 1;
1050                                                 }
1051
1052                                                 crtc->horz_stretching |= (HORZ_STRETCH_EN |
1053                                                         ((horz_stretch_loop & HORZ_STRETCH_LOOP) << 16) |
1054                                                         (horz_stretch_ratio & HORZ_STRETCH_RATIO));
1055                                                 break;      /* Out of the do { ... } while (0) */
1056                                         }
1057                                 }
1058
1059                                 crtc->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN |
1060                                         (((HDisplay * (HORZ_STRETCH_BLEND + 1)) / par->lcd_width) & HORZ_STRETCH_BLEND));
1061                         } while (0);
1062                 }
1063
1064                 if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) {
1065                         crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
1066                                 (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
1067
1068                         if (!M64_HAS(LT_LCD_REGS) &&
1069                             xres <= (M64_HAS(MOBIL_BUS)?1024:800))
1070                                 crtc->ext_vert_stretch |= VERT_STRETCH_MODE;
1071                 } else {
1072                         /*
1073                          * Don't use vertical blending if the mode is too wide or not
1074                          * vertically stretched.
1075                          */
1076                         crtc->vert_stretching = 0;
1077                 }
1078                 /* copy to shadow crtc */
1079                 crtc->shadow_h_tot_disp = crtc->h_tot_disp;
1080                 crtc->shadow_h_sync_strt_wid = crtc->h_sync_strt_wid;
1081                 crtc->shadow_v_tot_disp = crtc->v_tot_disp;
1082                 crtc->shadow_v_sync_strt_wid = crtc->v_sync_strt_wid;
1083         }
1084 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1085
1086         if (M64_HAS(MAGIC_FIFO)) {
1087                 /* FIXME: display FIFO low watermark values */
1088                 crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM);
1089         }
1090         crtc->dp_pix_width = dp_pix_width;
1091         crtc->dp_chain_mask = dp_chain_mask;
1092
1093         return 0;
1094 }
1095
1096 static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var)
1097 {
1098         u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1099         u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
1100             h_sync_pol;
1101         u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1102         u32 pix_width;
1103         u32 double_scan, interlace;
1104
1105         /* input */
1106         h_total = crtc->h_tot_disp & 0x1ff;
1107         h_disp = (crtc->h_tot_disp >> 16) & 0xff;
1108         h_sync_strt = (crtc->h_sync_strt_wid & 0xff) | ((crtc->h_sync_strt_wid >> 4) & 0x100);
1109         h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
1110         h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
1111         h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
1112         v_total = crtc->v_tot_disp & 0x7ff;
1113         v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
1114         v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1115         v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
1116         v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
1117         c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1118         pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1119         double_scan = crtc->gen_cntl & CRTC_DBL_SCAN_EN;
1120         interlace = crtc->gen_cntl & CRTC_INTERLACE_EN;
1121
1122         /* convert */
1123         xres = (h_disp + 1) * 8;
1124         yres = v_disp + 1;
1125         left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
1126         right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
1127         hslen = h_sync_wid * 8;
1128         upper = v_total - v_sync_strt - v_sync_wid;
1129         lower = v_sync_strt - v_disp;
1130         vslen = v_sync_wid;
1131         sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1132             (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1133             (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1134
1135         switch (pix_width) {
1136 #if 0
1137         case CRTC_PIX_WIDTH_4BPP:
1138                 bpp = 4;
1139                 var->red.offset = 0;
1140                 var->red.length = 8;
1141                 var->green.offset = 0;
1142                 var->green.length = 8;
1143                 var->blue.offset = 0;
1144                 var->blue.length = 8;
1145                 var->transp.offset = 0;
1146                 var->transp.length = 0;
1147                 break;
1148 #endif
1149         case CRTC_PIX_WIDTH_8BPP:
1150                 bpp = 8;
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         case CRTC_PIX_WIDTH_15BPP:      /* RGB 555 */
1161                 bpp = 16;
1162                 var->red.offset = 10;
1163                 var->red.length = 5;
1164                 var->green.offset = 5;
1165                 var->green.length = 5;
1166                 var->blue.offset = 0;
1167                 var->blue.length = 5;
1168                 var->transp.offset = 0;
1169                 var->transp.length = 0;
1170                 break;
1171         case CRTC_PIX_WIDTH_16BPP:      /* RGB 565 */
1172                 bpp = 16;
1173                 var->red.offset = 11;
1174                 var->red.length = 5;
1175                 var->green.offset = 5;
1176                 var->green.length = 6;
1177                 var->blue.offset = 0;
1178                 var->blue.length = 5;
1179                 var->transp.offset = 0;
1180                 var->transp.length = 0;
1181                 break;
1182         case CRTC_PIX_WIDTH_24BPP:      /* RGB 888 */
1183                 bpp = 24;
1184                 var->red.offset = 16;
1185                 var->red.length = 8;
1186                 var->green.offset = 8;
1187                 var->green.length = 8;
1188                 var->blue.offset = 0;
1189                 var->blue.length = 8;
1190                 var->transp.offset = 0;
1191                 var->transp.length = 0;
1192                 break;
1193         case CRTC_PIX_WIDTH_32BPP:      /* ARGB 8888 */
1194                 bpp = 32;
1195                 var->red.offset = 16;
1196                 var->red.length = 8;
1197                 var->green.offset = 8;
1198                 var->green.length = 8;
1199                 var->blue.offset = 0;
1200                 var->blue.length = 8;
1201                 var->transp.offset = 24;
1202                 var->transp.length = 8;
1203                 break;
1204         default:
1205                 PRINTKE("Invalid pixel width\n");
1206                 return -EINVAL;
1207         }
1208
1209         /* output */
1210         var->xres = xres;
1211         var->yres = yres;
1212         var->xres_virtual = crtc->vxres;
1213         var->yres_virtual = crtc->vyres;
1214         var->bits_per_pixel = bpp;
1215         var->left_margin = left;
1216         var->right_margin = right;
1217         var->upper_margin = upper;
1218         var->lower_margin = lower;
1219         var->hsync_len = hslen;
1220         var->vsync_len = vslen;
1221         var->sync = sync;
1222         var->vmode = FB_VMODE_NONINTERLACED;
1223         /* In double scan mode, the vertical parameters are doubled, so we need to
1224            half them to get the right values.
1225            In interlaced mode the values are already correct, so no correction is
1226            necessary.
1227          */
1228         if (interlace)
1229                 var->vmode = FB_VMODE_INTERLACED;
1230
1231         if (double_scan) {
1232                 var->vmode = FB_VMODE_DOUBLE;
1233                 var->yres>>=1;
1234                 var->upper_margin>>=1;
1235                 var->lower_margin>>=1;
1236                 var->vsync_len>>=1;
1237         }
1238
1239         return 0;
1240 }
1241
1242 /* ------------------------------------------------------------------------- */
1243
1244 static int atyfb_set_par(struct fb_info *info)
1245 {
1246         struct atyfb_par *par = (struct atyfb_par *) info->par;
1247         struct fb_var_screeninfo *var = &info->var;
1248         u32 tmp, pixclock;
1249         int err;
1250 #ifdef DEBUG
1251         struct fb_var_screeninfo debug;
1252         u32 pixclock_in_ps;
1253 #endif
1254         if (par->asleep)
1255                 return 0;
1256
1257         if ((err = aty_var_to_crtc(info, var, &par->crtc)))
1258                 return err;
1259
1260         pixclock = atyfb_get_pixclock(var, par);
1261
1262         if (pixclock == 0) {
1263                 PRINTKE("Invalid pixclock\n");
1264                 return -EINVAL;
1265         } else {
1266                 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll)))
1267                         return err;
1268         }
1269
1270         par->accel_flags = var->accel_flags; /* hack */
1271
1272         if (var->accel_flags) {
1273                 info->fbops->fb_sync = atyfb_sync;
1274                 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1275         } else {
1276                 info->fbops->fb_sync = NULL;
1277                 info->flags |= FBINFO_HWACCEL_DISABLED;
1278         }
1279
1280         if (par->blitter_may_be_busy)
1281                 wait_for_idle(par);
1282
1283         aty_set_crtc(par, &par->crtc);
1284         par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel, par->accel_flags);
1285         par->pll_ops->set_pll(info, &par->pll);
1286
1287 #ifdef DEBUG
1288         if(par->pll_ops && par->pll_ops->pll_to_var)
1289                 pixclock_in_ps = par->pll_ops->pll_to_var(info, &(par->pll));
1290         else
1291                 pixclock_in_ps = 0;
1292
1293         if(0 == pixclock_in_ps) {
1294                 PRINTKE("ALERT ops->pll_to_var get 0\n");
1295                 pixclock_in_ps = pixclock;
1296         }
1297
1298         memset(&debug, 0, sizeof(debug));
1299         if(!aty_crtc_to_var(&(par->crtc), &debug)) {
1300                 u32 hSync, vRefresh;
1301                 u32 h_disp, h_sync_strt, h_sync_end, h_total;
1302                 u32 v_disp, v_sync_strt, v_sync_end, v_total;
1303
1304                 h_disp = debug.xres;
1305                 h_sync_strt = h_disp + debug.right_margin;
1306                 h_sync_end = h_sync_strt + debug.hsync_len;
1307                 h_total = h_sync_end + debug.left_margin;
1308                 v_disp = debug.yres;
1309                 v_sync_strt = v_disp + debug.lower_margin;
1310                 v_sync_end = v_sync_strt + debug.vsync_len;
1311                 v_total = v_sync_end + debug.upper_margin;
1312
1313                 hSync = 1000000000 / (pixclock_in_ps * h_total);
1314                 vRefresh = (hSync * 1000) / v_total;
1315                 if (par->crtc.gen_cntl & CRTC_INTERLACE_EN)
1316                 vRefresh *= 2;
1317                 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1318                 vRefresh /= 2;
1319
1320                 DPRINTK("atyfb_set_par\n");
1321                 DPRINTK(" Set Visible Mode to %ix%i-%i\n", var->xres, var->yres, var->bits_per_pixel);
1322                 DPRINTK(" Virtual resolution %ix%i, pixclock_in_ps %i (calculated %i)\n",
1323                         var->xres_virtual, var->yres_virtual, pixclock, pixclock_in_ps);
1324                 DPRINTK(" Dot clock:           %i MHz\n", 1000000 / pixclock_in_ps);
1325                 DPRINTK(" Horizontal sync:     %i kHz\n", hSync);
1326                 DPRINTK(" Vertical refresh:    %i Hz\n", vRefresh);
1327                 DPRINTK(" x  style: %i.%03i %i %i %i %i   %i %i %i %i\n",
1328                         1000000 / pixclock_in_ps, 1000000 % pixclock_in_ps,
1329                         h_disp, h_sync_strt, h_sync_end, h_total,
1330                         v_disp, v_sync_strt, v_sync_end, v_total);
1331                 DPRINTK(" fb style: %i  %i %i %i %i %i %i %i %i\n",
1332                         pixclock_in_ps,
1333                         debug.left_margin, h_disp, debug.right_margin, debug.hsync_len,
1334                         debug.upper_margin, v_disp, debug.lower_margin, debug.vsync_len);
1335         }
1336 #endif /* DEBUG */
1337
1338         if (!M64_HAS(INTEGRATED)) {
1339                 /* Don't forget MEM_CNTL */
1340                 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
1341                 switch (var->bits_per_pixel) {
1342                 case 8:
1343                         tmp |= 0x02000000;
1344                         break;
1345                 case 16:
1346                         tmp |= 0x03000000;
1347                         break;
1348                 case 32:
1349                         tmp |= 0x06000000;
1350                         break;
1351                 }
1352                 aty_st_le32(MEM_CNTL, tmp, par);
1353         } else {
1354                 tmp = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
1355                 if (!M64_HAS(MAGIC_POSTDIV))
1356                         tmp |= par->mem_refresh_rate << 20;
1357                 switch (var->bits_per_pixel) {
1358                 case 8:
1359                 case 24:
1360                         tmp |= 0x00000000;
1361                         break;
1362                 case 16:
1363                         tmp |= 0x04000000;
1364                         break;
1365                 case 32:
1366                         tmp |= 0x08000000;
1367                         break;
1368                 }
1369                 if (M64_HAS(CT_BUS)) {
1370                         aty_st_le32(DAC_CNTL, 0x87010184, par);
1371                         aty_st_le32(BUS_CNTL, 0x680000f9, par);
1372                 } else if (M64_HAS(VT_BUS)) {
1373                         aty_st_le32(DAC_CNTL, 0x87010184, par);
1374                         aty_st_le32(BUS_CNTL, 0x680000f9, par);
1375                 } else if (M64_HAS(MOBIL_BUS)) {
1376                         aty_st_le32(DAC_CNTL, 0x80010102, par);
1377                         aty_st_le32(BUS_CNTL, 0x7b33a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1378                 } else {
1379                         /* GT */
1380                         aty_st_le32(DAC_CNTL, 0x86010102, par);
1381                         aty_st_le32(BUS_CNTL, 0x7b23a040 | (par->aux_start ? BUS_APER_REG_DIS : 0), par);
1382                         aty_st_le32(EXT_MEM_CNTL, aty_ld_le32(EXT_MEM_CNTL, par) | 0x5000001, par);
1383                 }
1384                 aty_st_le32(MEM_CNTL, tmp, par);
1385         }
1386         aty_st_8(DAC_MASK, 0xff, par);
1387
1388         info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
1389         info->fix.visual = var->bits_per_pixel <= 8 ?
1390                 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1391
1392         /* Initialize the graphics engine */
1393         if (par->accel_flags & FB_ACCELF_TEXT)
1394                 aty_init_engine(par, info);
1395
1396 #ifdef CONFIG_BOOTX_TEXT
1397         btext_update_display(info->fix.smem_start,
1398                 (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
1399                 ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
1400                 var->bits_per_pixel,
1401                 par->crtc.vxres * var->bits_per_pixel / 8);
1402 #endif /* CONFIG_BOOTX_TEXT */
1403 #if 0
1404         /* switch to accelerator mode */
1405         if (!(par->crtc.gen_cntl & CRTC_EXT_DISP_EN))
1406                 aty_st_le32(CRTC_GEN_CNTL, par->crtc.gen_cntl | CRTC_EXT_DISP_EN, par);
1407 #endif
1408 #ifdef DEBUG
1409 {
1410         /* dump non shadow CRTC, pll, LCD registers */
1411         int i; u32 base;
1412
1413         /* CRTC registers */
1414         base = 0x2000;
1415         printk("debug atyfb: Mach64 non-shadow register values:");
1416         for (i = 0; i < 256; i = i+4) {
1417                 if(i%16 == 0) printk("\ndebug atyfb: 0x%04X: ", base + i);
1418                 printk(" %08X", aty_ld_le32(i, par));
1419         }
1420         printk("\n\n");
1421
1422 #ifdef CONFIG_FB_ATY_CT
1423         /* PLL registers */
1424         base = 0x00;
1425         printk("debug atyfb: Mach64 PLL register values:");
1426         for (i = 0; i < 64; i++) {
1427                 if(i%16 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1428                 if(i%4 == 0)  printk(" ");
1429                 printk("%02X", aty_ld_pll_ct(i, par));
1430         }
1431         printk("\n\n");
1432 #endif  /* CONFIG_FB_ATY_CT */
1433
1434 #ifdef CONFIG_FB_ATY_GENERIC_LCD
1435         if (par->lcd_table != 0) {
1436                 /* LCD registers */
1437                 base = 0x00;
1438                 printk("debug atyfb: LCD register values:");
1439                 if(M64_HAS(LT_LCD_REGS)) {
1440                     for(i = 0; i <= POWER_MANAGEMENT; i++) {
1441                         if(i == EXT_VERT_STRETCH)
1442                             continue;
1443                         printk("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]);
1444                         printk(" %08X", aty_ld_lcd(i, par));
1445                     }
1446
1447                 } else {
1448                     for (i = 0; i < 64; i++) {
1449                         if(i%4 == 0) printk("\ndebug atyfb: 0x%02X: ", base + i);
1450                         printk(" %08X", aty_ld_lcd(i, par));
1451                     }
1452                 }
1453                 printk("\n\n");
1454         }
1455 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
1456 }
1457 #endif /* DEBUG */
1458         return 0;
1459 }
1460
1461 static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1462 {
1463         struct atyfb_par *par = (struct atyfb_par *) info->par;
1464         int err;
1465         struct crtc crtc;
1466         union aty_pll pll;
1467         u32 pixclock;
1468
1469         memcpy(&pll, &(par->pll), sizeof(pll));
1470
1471         if((err = aty_var_to_crtc(info, var, &crtc)))
1472                 return err;
1473
1474         pixclock = atyfb_get_pixclock(var, par);
1475
1476         if (pixclock == 0) {
1477                 if (!(var->activate & FB_ACTIVATE_TEST))
1478                         PRINTKE("Invalid pixclock\n");
1479                 return -EINVAL;
1480         } else {
1481                 if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll)))
1482                         return err;
1483         }
1484
1485         if (var->accel_flags & FB_ACCELF_TEXT)
1486                 info->var.accel_flags = FB_ACCELF_TEXT;
1487         else
1488                 info->var.accel_flags = 0;
1489
1490 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
1491         if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
1492                 return -EINVAL;
1493 #endif
1494         aty_crtc_to_var(&crtc, var);
1495         var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1496         return 0;
1497 }
1498
1499 static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1500 {
1501         u32 xoffset = info->var.xoffset;
1502         u32 yoffset = info->var.yoffset;
1503         u32 vxres = par->crtc.vxres;
1504         u32 bpp = info->var.bits_per_pixel;
1505
1506         par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
1507 }
1508
1509
1510     /*
1511      *  Open/Release the frame buffer device
1512      */
1513
1514 static int atyfb_open(struct fb_info *info, int user)
1515 {
1516         struct atyfb_par *par = (struct atyfb_par *) info->par;
1517
1518         if (user) {
1519                 par->open++;
1520 #ifdef __sparc__
1521                 par->mmaped = 0;
1522 #endif
1523         }
1524         return (0);
1525 }
1526
1527 static irqreturn_t aty_irq(int irq, void *dev_id)
1528 {
1529         struct atyfb_par *par = dev_id;
1530         int handled = 0;
1531         u32 int_cntl;
1532
1533         spin_lock(&par->int_lock);
1534
1535         int_cntl = aty_ld_le32(CRTC_INT_CNTL, par);
1536
1537         if (int_cntl & CRTC_VBLANK_INT) {
1538                 /* clear interrupt */
1539                 aty_st_le32(CRTC_INT_CNTL, (int_cntl & CRTC_INT_EN_MASK) | CRTC_VBLANK_INT_AK, par);
1540                 par->vblank.count++;
1541                 if (par->vblank.pan_display) {
1542                         par->vblank.pan_display = 0;
1543                         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1544                 }
1545                 wake_up_interruptible(&par->vblank.wait);
1546                 handled = 1;
1547         }
1548
1549         spin_unlock(&par->int_lock);
1550
1551         return IRQ_RETVAL(handled);
1552 }
1553
1554 static int aty_enable_irq(struct atyfb_par *par, int reenable)
1555 {
1556         u32 int_cntl;
1557
1558         if (!test_and_set_bit(0, &par->irq_flags)) {
1559                 if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) {
1560                         clear_bit(0, &par->irq_flags);
1561                         return -EINVAL;
1562                 }
1563                 spin_lock_irq(&par->int_lock);
1564                 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1565                 /* clear interrupt */
1566                 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_AK, par);
1567                 /* enable interrupt */
1568                 aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par);
1569                 spin_unlock_irq(&par->int_lock);
1570         } else if (reenable) {
1571                 spin_lock_irq(&par->int_lock);
1572                 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1573                 if (!(int_cntl & CRTC_VBLANK_INT_EN)) {
1574                         printk("atyfb: someone disabled IRQ [%08x]\n", int_cntl);
1575                         /* re-enable interrupt */
1576                         aty_st_le32(CRTC_INT_CNTL, int_cntl | CRTC_VBLANK_INT_EN, par );
1577                 }
1578                 spin_unlock_irq(&par->int_lock);
1579         }
1580
1581         return 0;
1582 }
1583
1584 static int aty_disable_irq(struct atyfb_par *par)
1585 {
1586         u32 int_cntl;
1587
1588         if (test_and_clear_bit(0, &par->irq_flags)) {
1589                 if (par->vblank.pan_display) {
1590                         par->vblank.pan_display = 0;
1591                         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1592                 }
1593                 spin_lock_irq(&par->int_lock);
1594                 int_cntl = aty_ld_le32(CRTC_INT_CNTL, par) & CRTC_INT_EN_MASK;
1595                 /* disable interrupt */
1596                 aty_st_le32(CRTC_INT_CNTL, int_cntl & ~CRTC_VBLANK_INT_EN, par );
1597                 spin_unlock_irq(&par->int_lock);
1598                 free_irq(par->irq, par);
1599         }
1600
1601         return 0;
1602 }
1603
1604 static int atyfb_release(struct fb_info *info, int user)
1605 {
1606         struct atyfb_par *par = (struct atyfb_par *) info->par;
1607         if (user) {
1608                 par->open--;
1609                 mdelay(1);
1610                 wait_for_idle(par);
1611                 if (!par->open) {
1612 #ifdef __sparc__
1613                         int was_mmaped = par->mmaped;
1614
1615                         par->mmaped = 0;
1616
1617                         if (was_mmaped) {
1618                                 struct fb_var_screeninfo var;
1619
1620                                 /* Now reset the default display config, we have no
1621                                  * idea what the program(s) which mmap'd the chip did
1622                                  * to the configuration, nor whether it restored it
1623                                  * correctly.
1624                                  */
1625                                 var = default_var;
1626                                 if (noaccel)
1627                                         var.accel_flags &= ~FB_ACCELF_TEXT;
1628                                 else
1629                                         var.accel_flags |= FB_ACCELF_TEXT;
1630                                 if (var.yres == var.yres_virtual) {
1631                                         u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
1632                                         var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
1633                                         if (var.yres_virtual < var.yres)
1634                                                 var.yres_virtual = var.yres;
1635                                 }
1636                         }
1637 #endif
1638                         aty_disable_irq(par);
1639                 }
1640         }
1641         return (0);
1642 }
1643
1644     /*
1645      *  Pan or Wrap the Display
1646      *
1647      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1648      */
1649
1650 static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1651 {
1652         struct atyfb_par *par = (struct atyfb_par *) info->par;
1653         u32 xres, yres, xoffset, yoffset;
1654
1655         xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
1656         yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
1657         if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
1658                 yres >>= 1;
1659         xoffset = (var->xoffset + 7) & ~7;
1660         yoffset = var->yoffset;
1661         if (xoffset + xres > par->crtc.vxres || yoffset + yres > par->crtc.vyres)
1662                 return -EINVAL;
1663         info->var.xoffset = xoffset;
1664         info->var.yoffset = yoffset;
1665         if (par->asleep)
1666                 return 0;
1667
1668         set_off_pitch(par, info);
1669         if ((var->activate & FB_ACTIVATE_VBL) && !aty_enable_irq(par, 0)) {
1670                 par->vblank.pan_display = 1;
1671         } else {
1672                 par->vblank.pan_display = 0;
1673                 aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1674         }
1675
1676         return 0;
1677 }
1678
1679 static int aty_waitforvblank(struct atyfb_par *par, u32 crtc)
1680 {
1681         struct aty_interrupt *vbl;
1682         unsigned int count;
1683         int ret;
1684
1685         switch (crtc) {
1686         case 0:
1687                 vbl = &par->vblank;
1688                 break;
1689         default:
1690                 return -ENODEV;
1691         }
1692
1693         ret = aty_enable_irq(par, 0);
1694         if (ret)
1695                 return ret;
1696
1697         count = vbl->count;
1698         ret = wait_event_interruptible_timeout(vbl->wait, count != vbl->count, HZ/10);
1699         if (ret < 0) {
1700                 return ret;
1701         }
1702         if (ret == 0) {
1703                 aty_enable_irq(par, 1);
1704                 return -ETIMEDOUT;
1705         }
1706
1707         return 0;
1708 }
1709
1710
1711 #ifdef DEBUG
1712 #define ATYIO_CLKR              0x41545900      /* ATY\00 */
1713 #define ATYIO_CLKW              0x41545901      /* ATY\01 */
1714
1715 struct atyclk {
1716         u32 ref_clk_per;
1717         u8 pll_ref_div;
1718         u8 mclk_fb_div;
1719         u8 mclk_post_div;       /* 1,2,3,4,8 */
1720         u8 mclk_fb_mult;        /* 2 or 4 */
1721         u8 xclk_post_div;       /* 1,2,3,4,8 */
1722         u8 vclk_fb_div;
1723         u8 vclk_post_div;       /* 1,2,3,4,6,8,12 */
1724         u32 dsp_xclks_per_row;  /* 0-16383 */
1725         u32 dsp_loop_latency;   /* 0-15 */
1726         u32 dsp_precision;      /* 0-7 */
1727         u32 dsp_on;             /* 0-2047 */
1728         u32 dsp_off;            /* 0-2047 */
1729 };
1730
1731 #define ATYIO_FEATR             0x41545902      /* ATY\02 */
1732 #define ATYIO_FEATW             0x41545903      /* ATY\03 */
1733 #endif
1734
1735 #ifndef FBIO_WAITFORVSYNC
1736 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
1737 #endif
1738
1739 static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
1740 {
1741         struct atyfb_par *par = (struct atyfb_par *) info->par;
1742 #ifdef __sparc__
1743         struct fbtype fbtyp;
1744 #endif
1745
1746         switch (cmd) {
1747 #ifdef __sparc__
1748         case FBIOGTYPE:
1749                 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1750                 fbtyp.fb_width = par->crtc.vxres;
1751                 fbtyp.fb_height = par->crtc.vyres;
1752                 fbtyp.fb_depth = info->var.bits_per_pixel;
1753                 fbtyp.fb_cmsize = info->cmap.len;
1754                 fbtyp.fb_size = info->fix.smem_len;
1755                 if (copy_to_user((struct fbtype __user *) arg, &fbtyp, sizeof(fbtyp)))
1756                         return -EFAULT;
1757                 break;
1758 #endif /* __sparc__ */
1759
1760         case FBIO_WAITFORVSYNC:
1761                 {
1762                         u32 crtc;
1763
1764                         if (get_user(crtc, (__u32 __user *) arg))
1765                                 return -EFAULT;
1766
1767                         return aty_waitforvblank(par, crtc);
1768                 }
1769                 break;
1770
1771 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1772         case ATYIO_CLKR:
1773                 if (M64_HAS(INTEGRATED)) {
1774                         struct atyclk clk;
1775                         union aty_pll *pll = &(par->pll);
1776                         u32 dsp_config = pll->ct.dsp_config;
1777                         u32 dsp_on_off = pll->ct.dsp_on_off;
1778                         clk.ref_clk_per = par->ref_clk_per;
1779                         clk.pll_ref_div = pll->ct.pll_ref_div;
1780                         clk.mclk_fb_div = pll->ct.mclk_fb_div;
1781                         clk.mclk_post_div = pll->ct.mclk_post_div_real;
1782                         clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
1783                         clk.xclk_post_div = pll->ct.xclk_post_div_real;
1784                         clk.vclk_fb_div = pll->ct.vclk_fb_div;
1785                         clk.vclk_post_div = pll->ct.vclk_post_div_real;
1786                         clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1787                         clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1788                         clk.dsp_precision = (dsp_config >> 20) & 7;
1789                         clk.dsp_off = dsp_on_off & 0x7ff;
1790                         clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
1791                         if (copy_to_user((struct atyclk __user *) arg, &clk,
1792                                          sizeof(clk)))
1793                                 return -EFAULT;
1794                 } else
1795                         return -EINVAL;
1796                 break;
1797         case ATYIO_CLKW:
1798                 if (M64_HAS(INTEGRATED)) {
1799                         struct atyclk clk;
1800                         union aty_pll *pll = &(par->pll);
1801                         if (copy_from_user(&clk, (struct atyclk __user *) arg, sizeof(clk)))
1802                                 return -EFAULT;
1803                         par->ref_clk_per = clk.ref_clk_per;
1804                         pll->ct.pll_ref_div = clk.pll_ref_div;
1805                         pll->ct.mclk_fb_div = clk.mclk_fb_div;
1806                         pll->ct.mclk_post_div_real = clk.mclk_post_div;
1807                         pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
1808                         pll->ct.xclk_post_div_real = clk.xclk_post_div;
1809                         pll->ct.vclk_fb_div = clk.vclk_fb_div;
1810                         pll->ct.vclk_post_div_real = clk.vclk_post_div;
1811                         pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
1812                                 ((clk.dsp_loop_latency & 0xf)<<16)| ((clk.dsp_precision & 7)<<20);
1813                         pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) | ((clk.dsp_on & 0x7ff)<<16);
1814                         /*aty_calc_pll_ct(info, &pll->ct);*/
1815                         aty_set_pll_ct(info, pll);
1816                 } else
1817                         return -EINVAL;
1818                 break;
1819         case ATYIO_FEATR:
1820                 if (get_user(par->features, (u32 __user *) arg))
1821                         return -EFAULT;
1822                 break;
1823         case ATYIO_FEATW:
1824                 if (put_user(par->features, (u32 __user *) arg))
1825                         return -EFAULT;
1826                 break;
1827 #endif /* DEBUG && CONFIG_FB_ATY_CT */
1828         default:
1829                 return -EINVAL;
1830         }
1831         return 0;
1832 }
1833
1834 static int atyfb_sync(struct fb_info *info)
1835 {
1836         struct atyfb_par *par = (struct atyfb_par *) info->par;
1837
1838         if (par->blitter_may_be_busy)
1839                 wait_for_idle(par);
1840         return 0;
1841 }
1842
1843 #ifdef __sparc__
1844 static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1845 {
1846         struct atyfb_par *par = (struct atyfb_par *) info->par;
1847         unsigned int size, page, map_size = 0;
1848         unsigned long map_offset = 0;
1849         unsigned long off;
1850         int i;
1851
1852         if (!par->mmap_map)
1853                 return -ENXIO;
1854
1855         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1856                 return -EINVAL;
1857
1858         off = vma->vm_pgoff << PAGE_SHIFT;
1859         size = vma->vm_end - vma->vm_start;
1860
1861         /* To stop the swapper from even considering these pages. */
1862         vma->vm_flags |= (VM_IO | VM_RESERVED);
1863
1864         if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1865             ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1866                 off += 0x8000000000000000UL;
1867
1868         vma->vm_pgoff = off >> PAGE_SHIFT;      /* propagate off changes */
1869
1870         /* Each page, see which map applies */
1871         for (page = 0; page < size;) {
1872                 map_size = 0;
1873                 for (i = 0; par->mmap_map[i].size; i++) {
1874                         unsigned long start = par->mmap_map[i].voff;
1875                         unsigned long end = start + par->mmap_map[i].size;
1876                         unsigned long offset = off + page;
1877
1878                         if (start > offset)
1879                                 continue;
1880                         if (offset >= end)
1881                                 continue;
1882
1883                         map_size = par->mmap_map[i].size - (offset - start);
1884                         map_offset =
1885                             par->mmap_map[i].poff + (offset - start);
1886                         break;
1887                 }
1888                 if (!map_size) {
1889                         page += PAGE_SIZE;
1890                         continue;
1891                 }
1892                 if (page + map_size > size)
1893                         map_size = size - page;
1894
1895                 pgprot_val(vma->vm_page_prot) &=
1896                     ~(par->mmap_map[i].prot_mask);
1897                 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1898
1899                 if (remap_pfn_range(vma, vma->vm_start + page,
1900                         map_offset >> PAGE_SHIFT, map_size, vma->vm_page_prot))
1901                         return -EAGAIN;
1902
1903                 page += map_size;
1904         }
1905
1906         if (!map_size)
1907                 return -EINVAL;
1908
1909         if (!par->mmaped)
1910                 par->mmaped = 1;
1911         return 0;
1912 }
1913
1914 static struct {
1915         u32 yoffset;
1916         u8 r[2][256];
1917         u8 g[2][256];
1918         u8 b[2][256];
1919 } atyfb_save;
1920
1921 static void atyfb_save_palette(struct atyfb_par *par, int enter)
1922 {
1923         int i, tmp;
1924
1925         for (i = 0; i < 256; i++) {
1926                 tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
1927                 if (M64_HAS(EXTRA_BRIGHT))
1928                         tmp |= 0x2;
1929                 aty_st_8(DAC_CNTL, tmp, par);
1930                 aty_st_8(DAC_MASK, 0xff, par);
1931
1932                 aty_st_8(DAC_R_INDEX, i, par);
1933                 atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
1934                 atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
1935                 atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
1936                 aty_st_8(DAC_W_INDEX, i, par);
1937                 aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
1938                 aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
1939                 aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
1940         }
1941 }
1942
1943 static void atyfb_palette(int enter)
1944 {
1945         struct atyfb_par *par;
1946         struct fb_info *info;
1947         int i;
1948
1949         for (i = 0; i < FB_MAX; i++) {
1950                 info = registered_fb[i];
1951                 if (info && info->fbops == &atyfb_ops) {
1952                         par = (struct atyfb_par *) info->par;
1953                         
1954                         atyfb_save_palette(par, enter);
1955                         if (enter) {
1956                                 atyfb_save.yoffset = info->var.yoffset;
1957                                 info->var.yoffset = 0;
1958                                 set_off_pitch(par, info);
1959                         } else {
1960                                 info->var.yoffset = atyfb_save.yoffset;
1961                                 set_off_pitch(par, info);
1962                         }
1963                         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
1964                         break;
1965                 }
1966         }
1967 }
1968 #endif /* __sparc__ */
1969
1970
1971
1972 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
1973
1974 /* Power management routines. Those are used for PowerBook sleep.
1975  */
1976 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1977 {
1978         u32 pm;
1979         int timeout;
1980
1981         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1982         pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1983         aty_st_lcd(POWER_MANAGEMENT, pm, par);
1984         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1985
1986         timeout = 2000;
1987         if (sleep) {
1988                 /* Sleep */
1989                 pm &= ~PWR_MGT_ON;
1990                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1991                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1992                 udelay(10);
1993                 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1994                 pm |= SUSPEND_NOW;
1995                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1996                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1997                 udelay(10);
1998                 pm |= PWR_MGT_ON;
1999                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2000                 do {
2001                         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2002                         mdelay(1);
2003                         if ((--timeout) == 0)
2004                                 break;
2005                 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
2006         } else {
2007                 /* Wakeup */
2008                 pm &= ~PWR_MGT_ON;
2009                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2010                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2011                 udelay(10);
2012                 pm &= ~SUSPEND_NOW;
2013                 pm |= (PWR_BLON | AUTO_PWR_UP);
2014                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2015                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2016                 udelay(10);
2017                 pm |= PWR_MGT_ON;
2018                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2019                 do {
2020                         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2021                         mdelay(1);
2022                         if ((--timeout) == 0)
2023                                 break;
2024                 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
2025         }
2026         mdelay(500);
2027
2028         return timeout ? 0 : -EIO;
2029 }
2030
2031 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2032 {
2033         struct fb_info *info = pci_get_drvdata(pdev);
2034         struct atyfb_par *par = (struct atyfb_par *) info->par;
2035
2036 #ifndef CONFIG_PPC_PMAC
2037         /* HACK ALERT ! Once I find a proper way to say to each driver
2038          * individually what will happen with it's PCI slot, I'll change
2039          * that. On laptops, the AGP slot is just unclocked, so D2 is
2040          * expected, while on desktops, the card is powered off
2041          */
2042         return 0;
2043 #endif /* CONFIG_PPC_PMAC */
2044
2045         if (state.event == pdev->dev.power.power_state.event)
2046                 return 0;
2047
2048         acquire_console_sem();
2049
2050         fb_set_suspend(info, 1);
2051
2052         /* Idle & reset engine */
2053         wait_for_idle(par);
2054         aty_reset_engine(par);
2055
2056         /* Blank display and LCD */
2057         atyfb_blank(FB_BLANK_POWERDOWN, info);
2058
2059         par->asleep = 1;
2060         par->lock_blank = 1;
2061
2062         /* Set chip to "suspend" mode */
2063         if (aty_power_mgmt(1, par)) {
2064                 par->asleep = 0;
2065                 par->lock_blank = 0;
2066                 atyfb_blank(FB_BLANK_UNBLANK, info);
2067                 fb_set_suspend(info, 0);
2068                 release_console_sem();
2069                 return -EIO;
2070         }
2071
2072         release_console_sem();
2073
2074         pdev->dev.power.power_state = state;
2075
2076         return 0;
2077 }
2078
2079 static int atyfb_pci_resume(struct pci_dev *pdev)
2080 {
2081         struct fb_info *info = pci_get_drvdata(pdev);
2082         struct atyfb_par *par = (struct atyfb_par *) info->par;
2083
2084         if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2085                 return 0;
2086
2087         acquire_console_sem();
2088
2089         if (pdev->dev.power.power_state.event == 2)
2090                 aty_power_mgmt(0, par);
2091         par->asleep = 0;
2092
2093         /* Restore display */
2094         atyfb_set_par(info);
2095
2096         /* Refresh */
2097         fb_set_suspend(info, 0);
2098
2099         /* Unblank */
2100         par->lock_blank = 0;
2101         atyfb_blank(FB_BLANK_UNBLANK, info);
2102
2103         release_console_sem();
2104
2105         pdev->dev.power.power_state = PMSG_ON;
2106
2107         return 0;
2108 }
2109
2110 #endif /*  defined(CONFIG_PM) && defined(CONFIG_PCI) */
2111
2112 /* Backlight */
2113 #ifdef CONFIG_FB_ATY_BACKLIGHT
2114 #define MAX_LEVEL 0xFF
2115
2116 static struct backlight_properties aty_bl_data;
2117
2118 /* Call with fb_info->bl_mutex held */
2119 static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2120 {
2121         struct fb_info *info = pci_get_drvdata(par->pdev);
2122         int atylevel;
2123
2124         /* Get and convert the value */
2125         atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2126
2127         if (atylevel < 0)
2128                 atylevel = 0;
2129         else if (atylevel > MAX_LEVEL)
2130                 atylevel = MAX_LEVEL;
2131
2132         return atylevel;
2133 }
2134
2135 /* Call with fb_info->bl_mutex held */
2136 static int __aty_bl_update_status(struct backlight_device *bd)
2137 {
2138         struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2139         unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2140         int level;
2141
2142         if (bd->props->power != FB_BLANK_UNBLANK ||
2143             bd->props->fb_blank != FB_BLANK_UNBLANK)
2144                 level = 0;
2145         else
2146                 level = bd->props->brightness;
2147
2148         reg |= (BLMOD_EN | BIASMOD_EN);
2149         if (level > 0) {
2150                 reg &= ~BIAS_MOD_LEVEL_MASK;
2151                 reg |= (aty_bl_get_level_brightness(par, level) << BIAS_MOD_LEVEL_SHIFT);
2152         } else {
2153                 reg &= ~BIAS_MOD_LEVEL_MASK;
2154                 reg |= (aty_bl_get_level_brightness(par, 0) << BIAS_MOD_LEVEL_SHIFT);
2155         }
2156         aty_st_lcd(LCD_MISC_CNTL, reg, par);
2157
2158         return 0;
2159 }
2160
2161 static int aty_bl_update_status(struct backlight_device *bd)
2162 {
2163         struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2164         struct fb_info *info = pci_get_drvdata(par->pdev);
2165         int ret;
2166
2167         mutex_lock(&info->bl_mutex);
2168         ret = __aty_bl_update_status(bd);
2169         mutex_unlock(&info->bl_mutex);
2170
2171         return ret;
2172 }
2173
2174 static int aty_bl_get_brightness(struct backlight_device *bd)
2175 {
2176         return bd->props->brightness;
2177 }
2178
2179 static struct backlight_properties aty_bl_data = {
2180         .owner    = THIS_MODULE,
2181         .get_brightness = aty_bl_get_brightness,
2182         .update_status  = aty_bl_update_status,
2183         .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
2184 };
2185
2186 static void aty_bl_set_power(struct fb_info *info, int power)
2187 {
2188         mutex_lock(&info->bl_mutex);
2189
2190         if (info->bl_dev) {
2191                 down(&info->bl_dev->sem);
2192                 info->bl_dev->props->power = power;
2193                 __aty_bl_update_status(info->bl_dev);
2194                 up(&info->bl_dev->sem);
2195         }
2196
2197         mutex_unlock(&info->bl_mutex);
2198 }
2199
2200 static void aty_bl_init(struct atyfb_par *par)
2201 {
2202         struct fb_info *info = pci_get_drvdata(par->pdev);
2203         struct backlight_device *bd;
2204         char name[12];
2205
2206 #ifdef CONFIG_PMAC_BACKLIGHT
2207         if (!pmac_has_backlight_type("ati"))
2208                 return;
2209 #endif
2210
2211         snprintf(name, sizeof(name), "atybl%d", info->node);
2212
2213         bd = backlight_device_register(name, par, &aty_bl_data);
2214         if (IS_ERR(bd)) {
2215                 info->bl_dev = NULL;
2216                 printk(KERN_WARNING "aty: Backlight registration failed\n");
2217                 goto error;
2218         }
2219
2220         mutex_lock(&info->bl_mutex);
2221         info->bl_dev = bd;
2222         fb_bl_default_curve(info, 0,
2223                 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2224                 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2225         mutex_unlock(&info->bl_mutex);
2226
2227         down(&bd->sem);
2228         bd->props->brightness = aty_bl_data.max_brightness;
2229         bd->props->power = FB_BLANK_UNBLANK;
2230         bd->props->update_status(bd);
2231         up(&bd->sem);
2232
2233 #ifdef CONFIG_PMAC_BACKLIGHT
2234         mutex_lock(&pmac_backlight_mutex);
2235         if (!pmac_backlight)
2236                 pmac_backlight = bd;
2237         mutex_unlock(&pmac_backlight_mutex);
2238 #endif
2239
2240         printk("aty: Backlight initialized (%s)\n", name);
2241
2242         return;
2243
2244 error:
2245         return;
2246 }
2247
2248 static void aty_bl_exit(struct atyfb_par *par)
2249 {
2250         struct fb_info *info = pci_get_drvdata(par->pdev);
2251
2252 #ifdef CONFIG_PMAC_BACKLIGHT
2253         mutex_lock(&pmac_backlight_mutex);
2254 #endif
2255
2256         mutex_lock(&info->bl_mutex);
2257         if (info->bl_dev) {
2258 #ifdef CONFIG_PMAC_BACKLIGHT
2259                 if (pmac_backlight == info->bl_dev)
2260                         pmac_backlight = NULL;
2261 #endif
2262
2263                 backlight_device_unregister(info->bl_dev);
2264
2265                 printk("aty: Backlight unloaded\n");
2266         }
2267         mutex_unlock(&info->bl_mutex);
2268
2269 #ifdef CONFIG_PMAC_BACKLIGHT
2270         mutex_unlock(&pmac_backlight_mutex);
2271 #endif
2272 }
2273
2274 #endif /* CONFIG_FB_ATY_BACKLIGHT */
2275
2276 static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2277 {
2278         const int ragepro_tbl[] = {
2279                 44, 50, 55, 66, 75, 80, 100
2280         };
2281         const int ragexl_tbl[] = {
2282                 50, 66, 75, 83, 90, 95, 100, 105,
2283                 110, 115, 120, 125, 133, 143, 166
2284         };
2285         const int *refresh_tbl;
2286         int i, size;
2287
2288         if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
2289                 refresh_tbl = ragexl_tbl;
2290                 size = ARRAY_SIZE(ragexl_tbl);
2291         } else {
2292                 refresh_tbl = ragepro_tbl;
2293                 size = ARRAY_SIZE(ragepro_tbl);
2294         }
2295
2296         for (i=0; i < size; i++) {
2297                 if (xclk < refresh_tbl[i])
2298                 break;
2299         }
2300         par->mem_refresh_rate = i;
2301 }
2302
2303     /*
2304      *  Initialisation
2305      */
2306
2307 static struct fb_info *fb_list = NULL;
2308
2309 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2310 static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2311                                                 struct fb_var_screeninfo *var)
2312 {
2313         int ret = -EINVAL;
2314
2315         if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2316                 *var = default_var;
2317                 var->xres = var->xres_virtual = par->lcd_hdisp;
2318                 var->right_margin = par->lcd_right_margin;
2319                 var->left_margin = par->lcd_hblank_len -
2320                         (par->lcd_right_margin + par->lcd_hsync_dly +
2321                          par->lcd_hsync_len);
2322                 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2323                 var->yres = var->yres_virtual = par->lcd_vdisp;
2324                 var->lower_margin = par->lcd_lower_margin;
2325                 var->upper_margin = par->lcd_vblank_len -
2326                         (par->lcd_lower_margin + par->lcd_vsync_len);
2327                 var->vsync_len = par->lcd_vsync_len;
2328                 var->pixclock = par->lcd_pixclock;
2329                 ret = 0;
2330         }
2331
2332         return ret;
2333 }
2334 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2335
2336 static int __devinit aty_init(struct fb_info *info)
2337 {
2338         struct atyfb_par *par = (struct atyfb_par *) info->par;
2339         const char *ramname = NULL, *xtal;
2340         int gtb_memsize, has_var = 0;
2341         struct fb_var_screeninfo var;
2342         u32 i;
2343
2344         init_waitqueue_head(&par->vblank.wait);
2345         spin_lock_init(&par->int_lock);
2346
2347 #ifdef CONFIG_PPC_PMAC
2348         /* The Apple iBook1 uses non-standard memory frequencies. We detect it
2349          * and set the frequency manually. */
2350         if (machine_is_compatible("PowerBook2,1")) {
2351                 par->pll_limits.mclk = 70;
2352                 par->pll_limits.xclk = 53;
2353         }
2354 #endif
2355         if (pll)
2356                 par->pll_limits.pll_max = pll;
2357         if (mclk)
2358                 par->pll_limits.mclk = mclk;
2359         if (xclk)
2360                 par->pll_limits.xclk = xclk;
2361
2362         aty_calc_mem_refresh(par, par->pll_limits.xclk);
2363         par->pll_per = 1000000/par->pll_limits.pll_max;
2364         par->mclk_per = 1000000/par->pll_limits.mclk;
2365         par->xclk_per = 1000000/par->pll_limits.xclk;
2366
2367         par->ref_clk_per = 1000000000000ULL / 14318180;
2368         xtal = "14.31818";
2369
2370 #ifdef CONFIG_FB_ATY_GX
2371         if (!M64_HAS(INTEGRATED)) {
2372                 u32 stat0;
2373                 u8 dac_type, dac_subtype, clk_type;
2374                 stat0 = aty_ld_le32(CONFIG_STAT0, par);
2375                 par->bus_type = (stat0 >> 0) & 0x07;
2376                 par->ram_type = (stat0 >> 3) & 0x07;
2377                 ramname = aty_gx_ram[par->ram_type];
2378                 /* FIXME: clockchip/RAMDAC probing? */
2379                 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
2380 #ifdef CONFIG_ATARI
2381                 clk_type = CLK_ATI18818_1;
2382                 dac_type = (stat0 >> 9) & 0x07;
2383                 if (dac_type == 0x07)
2384                         dac_subtype = DAC_ATT20C408;
2385                 else
2386                         dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) | dac_type;
2387 #else
2388                 dac_type = DAC_IBMRGB514;
2389                 dac_subtype = DAC_IBMRGB514;
2390                 clk_type = CLK_IBMRGB514;
2391 #endif
2392                 switch (dac_subtype) {
2393                 case DAC_IBMRGB514:
2394                         par->dac_ops = &aty_dac_ibm514;
2395                         break;
2396                 case DAC_ATI68860_B:
2397                 case DAC_ATI68860_C:
2398                         par->dac_ops = &aty_dac_ati68860b;
2399                         break;
2400                 case DAC_ATT20C408:
2401                 case DAC_ATT21C498:
2402                         par->dac_ops = &aty_dac_att21c498;
2403                         break;
2404                 default:
2405                         PRINTKI("aty_init: DAC type not implemented yet!\n");
2406                         par->dac_ops = &aty_dac_unsupported;
2407                         break;
2408                 }
2409                 switch (clk_type) {
2410 #ifdef CONFIG_ATARI
2411                 case CLK_ATI18818_1:
2412                         par->pll_ops = &aty_pll_ati18818_1;
2413                         break;
2414 #else
2415                 case CLK_IBMRGB514:
2416                         par->pll_ops = &aty_pll_ibm514;
2417                         break;
2418 #endif
2419 #if 0 /* dead code */
2420                 case CLK_STG1703:
2421                         par->pll_ops = &aty_pll_stg1703;
2422                         break;
2423                 case CLK_CH8398:
2424                         par->pll_ops = &aty_pll_ch8398;
2425                         break;
2426                 case CLK_ATT20C408:
2427                         par->pll_ops = &aty_pll_att20c408;
2428                         break;
2429 #endif
2430                 default:
2431                         PRINTKI("aty_init: CLK type not implemented yet!");
2432                         par->pll_ops = &aty_pll_unsupported;
2433                         break;
2434                 }
2435         }
2436 #endif /* CONFIG_FB_ATY_GX */
2437 #ifdef CONFIG_FB_ATY_CT
2438         if (M64_HAS(INTEGRATED)) {
2439                 par->dac_ops = &aty_dac_ct;
2440                 par->pll_ops = &aty_pll_ct;
2441                 par->bus_type = PCI;
2442                 par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
2443                 ramname = aty_ct_ram[par->ram_type];
2444                 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2445                 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2446                         par->pll_limits.mclk = 63;
2447         }
2448
2449         if (M64_HAS(GTB_DSP)) {
2450                 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2451
2452                 if (pll_ref_div) {
2453                         int diff1, diff2;
2454                         diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2455                         diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2456                         if (diff1 < 0)
2457                                 diff1 = -diff1;
2458                         if (diff2 < 0)
2459                                 diff2 = -diff2;
2460                         if (diff2 < diff1) {
2461                                 par->ref_clk_per = 1000000000000ULL / 29498928;
2462                                 xtal = "29.498928";
2463                         }
2464                 }
2465         }
2466 #endif /* CONFIG_FB_ATY_CT */
2467
2468         /* save previous video mode */
2469         aty_get_crtc(par, &saved_crtc);
2470         if(par->pll_ops->get_pll)
2471                 par->pll_ops->get_pll(info, &saved_pll);
2472
2473         i = aty_ld_le32(MEM_CNTL, par);
2474         gtb_memsize = M64_HAS(GTB_DSP);
2475         if (gtb_memsize)
2476                 switch (i & 0xF) {      /* 0xF used instead of MEM_SIZE_ALIAS */
2477                 case MEM_SIZE_512K:
2478                         info->fix.smem_len = 0x80000;
2479                         break;
2480                 case MEM_SIZE_1M:
2481                         info->fix.smem_len = 0x100000;
2482                         break;
2483                 case MEM_SIZE_2M_GTB:
2484                         info->fix.smem_len = 0x200000;
2485                         break;
2486                 case MEM_SIZE_4M_GTB:
2487                         info->fix.smem_len = 0x400000;
2488                         break;
2489                 case MEM_SIZE_6M_GTB:
2490                         info->fix.smem_len = 0x600000;
2491                         break;
2492                 case MEM_SIZE_8M_GTB:
2493                         info->fix.smem_len = 0x800000;
2494                         break;
2495                 default:
2496                         info->fix.smem_len = 0x80000;
2497         } else
2498                 switch (i & MEM_SIZE_ALIAS) {
2499                 case MEM_SIZE_512K:
2500                         info->fix.smem_len = 0x80000;
2501                         break;
2502                 case MEM_SIZE_1M:
2503                         info->fix.smem_len = 0x100000;
2504                         break;
2505                 case MEM_SIZE_2M:
2506                         info->fix.smem_len = 0x200000;
2507                         break;
2508                 case MEM_SIZE_4M:
2509                         info->fix.smem_len = 0x400000;
2510                         break;
2511                 case MEM_SIZE_6M:
2512                         info->fix.smem_len = 0x600000;
2513                         break;
2514                 case MEM_SIZE_8M:
2515                         info->fix.smem_len = 0x800000;
2516                         break;
2517                 default:
2518                         info->fix.smem_len = 0x80000;
2519                 }
2520
2521         if (M64_HAS(MAGIC_VRAM_SIZE)) {
2522                 if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
2523                         info->fix.smem_len += 0x400000;
2524         }
2525
2526         if (vram) {
2527                 info->fix.smem_len = vram * 1024;
2528                 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2529                 if (info->fix.smem_len <= 0x80000)
2530                         i |= MEM_SIZE_512K;
2531                 else if (info->fix.smem_len <= 0x100000)
2532                         i |= MEM_SIZE_1M;
2533                 else if (info->fix.smem_len <= 0x200000)
2534                         i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2535                 else if (info->fix.smem_len <= 0x400000)
2536                         i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2537                 else if (info->fix.smem_len <= 0x600000)
2538                         i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2539                 else
2540                         i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2541                 aty_st_le32(MEM_CNTL, i, par);
2542         }
2543
2544         /*
2545          *  Reg Block 0 (CT-compatible block) is at mmio_start
2546          *  Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
2547          */
2548         if (M64_HAS(GX)) {
2549                 info->fix.mmio_len = 0x400;
2550                 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
2551         } else if (M64_HAS(CT)) {
2552                 info->fix.mmio_len = 0x400;
2553                 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
2554         } else if (M64_HAS(VT)) {
2555                 info->fix.mmio_start -= 0x400;
2556                 info->fix.mmio_len = 0x800;
2557                 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
2558         } else {/* GT */
2559                 info->fix.mmio_start -= 0x400;
2560                 info->fix.mmio_len = 0x800;
2561                 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
2562         }
2563
2564         PRINTKI("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
2565                info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
2566                info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
2567                par->pll_limits.mclk, par->pll_limits.xclk);
2568
2569 #if defined(DEBUG) && defined(CONFIG_ATY_CT)
2570         if (M64_HAS(INTEGRATED)) {
2571                 int i;
2572                 printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
2573                        "DSP_CONFIG DSP_ON_OFF CLOCK_CNTL\n"
2574                        "debug atyfb: %08x %08x %08x %08x     %08x      %08x   %08x   %08x\n"
2575                        "debug atyfb: PLL",
2576                         aty_ld_le32(BUS_CNTL, par), aty_ld_le32(DAC_CNTL, par),
2577                         aty_ld_le32(MEM_CNTL, par), aty_ld_le32(EXT_MEM_CNTL, par),
2578                         aty_ld_le32(CRTC_GEN_CNTL, par), aty_ld_le32(DSP_CONFIG, par),
2579                         aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par));
2580                 for (i = 0; i < 40; i++)
2581                         printk(" %02x", aty_ld_pll_ct(i, par));
2582                 printk("\n");
2583         }
2584 #endif
2585         if(par->pll_ops->init_pll)
2586                 par->pll_ops->init_pll(info, &par->pll);
2587
2588         /*
2589          *  Last page of 8 MB (4 MB on ISA) aperture is MMIO,
2590          *  unless the auxiliary register aperture is used.
2591          */
2592
2593         if (!par->aux_start &&
2594                 (info->fix.smem_len == 0x800000 || (par->bus_type == ISA && info->fix.smem_len == 0x400000)))
2595                 info->fix.smem_len -= GUI_RESERVE;
2596
2597         /*
2598          *  Disable register access through the linear aperture
2599          *  if the auxiliary aperture is used so we can access
2600          *  the full 8 MB of video RAM on 8 MB boards.
2601          */
2602         if (par->aux_start)
2603                 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2604
2605 #ifdef CONFIG_MTRR
2606         par->mtrr_aper = -1;
2607         par->mtrr_reg = -1;
2608         if (!nomtrr) {
2609                 /* Cover the whole resource. */
2610                  par->mtrr_aper = mtrr_add(par->res_start, par->res_size, MTRR_TYPE_WRCOMB, 1);
2611                  if (par->mtrr_aper >= 0 && !par->aux_start) {
2612                         /* Make a hole for mmio. */
2613                         par->mtrr_reg = mtrr_add(par->res_start + 0x800000 - GUI_RESERVE,
2614                                 GUI_RESERVE, MTRR_TYPE_UNCACHABLE, 1);
2615                         if (par->mtrr_reg < 0) {
2616                                 mtrr_del(par->mtrr_aper, 0, 0);
2617                                 par->mtrr_aper = -1;
2618                         }
2619                  }
2620         }
2621 #endif
2622
2623         info->fbops = &atyfb_ops;
2624         info->pseudo_palette = pseudo_palette;
2625         info->flags = FBINFO_DEFAULT           |
2626                       FBINFO_HWACCEL_IMAGEBLIT |
2627                       FBINFO_HWACCEL_FILLRECT  |
2628                       FBINFO_HWACCEL_COPYAREA  |
2629                       FBINFO_HWACCEL_YPAN;
2630
2631 #ifdef CONFIG_PMAC_BACKLIGHT
2632         if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
2633                 /* these bits let the 101 powerbook wake up from sleep -- paulus */
2634                 aty_st_lcd(POWER_MANAGEMENT, aty_ld_lcd(POWER_MANAGEMENT, par)
2635                            | (USE_F32KHZ | TRISTATE_MEM_EN), par);
2636         } else
2637 #endif
2638         if (M64_HAS(MOBIL_BUS)) {
2639 #ifdef CONFIG_FB_ATY_BACKLIGHT
2640                 aty_bl_init (par);
2641 #endif
2642         }
2643
2644         memset(&var, 0, sizeof(var));
2645 #ifdef CONFIG_PPC
2646         if (machine_is(powermac)) {
2647                 /*
2648                  *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2649                  *         applies to all Mac video cards
2650                  */
2651                 if (mode) {
2652                         if (mac_find_mode(&var, info, mode, 8))
2653                                 has_var = 1;
2654                 } else {
2655                         if (default_vmode == VMODE_CHOOSE) {
2656                                 int sense;
2657                                 if (M64_HAS(G3_PB_1024x768))
2658                                         /* G3 PowerBook with 1024x768 LCD */
2659                                         default_vmode = VMODE_1024_768_60;
2660                                 else if (machine_is_compatible("iMac"))
2661                                         default_vmode = VMODE_1024_768_75;
2662                                 else if (machine_is_compatible
2663                                          ("PowerBook2,1"))
2664                                         /* iBook with 800x600 LCD */
2665                                         default_vmode = VMODE_800_600_60;
2666                                 else
2667                                         default_vmode = VMODE_640_480_67;
2668                                 sense = read_aty_sense(par);
2669                                 PRINTKI("monitor sense=%x, mode %d\n",
2670                                         sense,  mac_map_monitor_sense(sense));
2671                         }
2672                         if (default_vmode <= 0 || default_vmode > VMODE_MAX)
2673                                 default_vmode = VMODE_640_480_60;
2674                         if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2675                                 default_cmode = CMODE_8;
2676                         if (!mac_vmode_to_var(default_vmode, default_cmode,
2677                                                &var))
2678                                 has_var = 1;
2679                 }
2680         }
2681
2682 #endif /* !CONFIG_PPC */
2683
2684 #if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2685         if (!atyfb_get_timings_from_lcd(par, &var))
2686                 has_var = 1;
2687 #endif
2688
2689         if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2690                 has_var = 1;
2691
2692         if (!has_var)
2693                 var = default_var;
2694
2695         if (noaccel)
2696                 var.accel_flags &= ~FB_ACCELF_TEXT;
2697         else
2698                 var.accel_flags |= FB_ACCELF_TEXT;
2699
2700         if (comp_sync != -1) {
2701                 if (!comp_sync)
2702                         var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
2703                 else
2704                         var.sync |= FB_SYNC_COMP_HIGH_ACT;
2705         }
2706
2707         if (var.yres == var.yres_virtual) {
2708                 u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
2709                 var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
2710                 if (var.yres_virtual < var.yres)
2711                         var.yres_virtual = var.yres;
2712         }
2713
2714         if (atyfb_check_var(&var, info)) {
2715                 PRINTKE("can't set default video mode\n");
2716                 goto aty_init_exit;
2717         }
2718
2719 #ifdef __sparc__
2720         atyfb_save_palette(par, 0);
2721 #endif
2722
2723 #ifdef CONFIG_FB_ATY_CT
2724         if (!noaccel && M64_HAS(INTEGRATED))
2725                 aty_init_cursor(info);
2726 #endif /* CONFIG_FB_ATY_CT */
2727         info->var = var;
2728
2729         fb_alloc_cmap(&info->cmap, 256, 0);
2730
2731         if (register_framebuffer(info) < 0)
2732                 goto aty_init_exit;
2733
2734         fb_list = info;
2735
2736         PRINTKI("fb%d: %s frame buffer device on %s\n",
2737                 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
2738         return 0;
2739
2740 aty_init_exit:
2741         /* restore video mode */
2742         aty_set_crtc(par, &saved_crtc);
2743         par->pll_ops->set_pll(info, &saved_pll);
2744
2745 #ifdef CONFIG_MTRR
2746         if (par->mtrr_reg >= 0) {
2747             mtrr_del(par->mtrr_reg, 0, 0);
2748             par->mtrr_reg = -1;
2749         }
2750         if (par->mtrr_aper >= 0) {
2751             mtrr_del(par->mtrr_aper, 0, 0);
2752             par->mtrr_aper = -1;
2753         }
2754 #endif
2755         return -1;
2756 }
2757
2758 #ifdef CONFIG_ATARI
2759 static int __devinit store_video_par(char *video_str, unsigned char m64_num)
2760 {
2761         char *p;
2762         unsigned long vmembase, size, guiregbase;
2763
2764         PRINTKI("store_video_par() '%s' \n", video_str);
2765
2766         if (!(p = strsep(&video_str, ";")) || !*p)
2767                 goto mach64_invalid;
2768         vmembase = simple_strtoul(p, NULL, 0);
2769         if (!(p = strsep(&video_str, ";")) || !*p)
2770                 goto mach64_invalid;
2771         size = simple_strtoul(p, NULL, 0);
2772         if (!(p = strsep(&video_str, ";")) || !*p)
2773                 goto mach64_invalid;
2774         guiregbase = simple_strtoul(p, NULL, 0);
2775
2776         phys_vmembase[m64_num] = vmembase;
2777         phys_size[m64_num] = size;
2778         phys_guiregbase[m64_num] = guiregbase;
2779         PRINTKI("stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2780                guiregbase);
2781         return 0;
2782
2783       mach64_invalid:
2784         phys_vmembase[m64_num] = 0;
2785         return -1;
2786 }
2787 #endif /* CONFIG_ATARI */
2788
2789     /*
2790      *  Blank the display.
2791      */
2792
2793 static int atyfb_blank(int blank, struct fb_info *info)
2794 {
2795         struct atyfb_par *par = (struct atyfb_par *) info->par;
2796         u32 gen_cntl;
2797
2798         if (par->lock_blank || par->asleep)
2799                 return 0;
2800
2801 #ifdef CONFIG_FB_ATY_BACKLIGHT
2802         if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2803                 aty_bl_set_power(info, FB_BLANK_POWERDOWN);
2804 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2805         if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2806             (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2807                 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2808                 pm &= ~PWR_BLON;
2809                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2810         }
2811 #endif
2812
2813         gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2814         gen_cntl &= ~0x400004c;
2815         switch (blank) {
2816                 case FB_BLANK_UNBLANK:
2817                         break;
2818                 case FB_BLANK_NORMAL:
2819                         gen_cntl |= 0x4000040;
2820                         break;
2821                 case FB_BLANK_VSYNC_SUSPEND:
2822                         gen_cntl |= 0x4000048;
2823                         break;
2824                 case FB_BLANK_HSYNC_SUSPEND:
2825                         gen_cntl |= 0x4000044;
2826                         break;
2827                 case FB_BLANK_POWERDOWN:
2828                         gen_cntl |= 0x400004c;
2829                         break;
2830         }
2831         aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2832
2833 #ifdef CONFIG_FB_ATY_BACKLIGHT
2834         if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2835                 aty_bl_set_power(info, FB_BLANK_UNBLANK);
2836 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2837         if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2838             (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2839                 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
2840                 pm |= PWR_BLON;
2841                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
2842         }
2843 #endif
2844
2845         return 0;
2846 }
2847
2848 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2849                        const struct atyfb_par *par)
2850 {
2851         aty_st_8(DAC_W_INDEX, regno, par);
2852         aty_st_8(DAC_DATA, red, par);
2853         aty_st_8(DAC_DATA, green, par);
2854         aty_st_8(DAC_DATA, blue, par);
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  &nbs