ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / video / aty / atyfb_base.c
1 /*
2  *  ATI Frame Buffer Device Driver Core
3  *
4  *      Copyright (C) 1997-2001  Geert Uytterhoeven
5  *      Copyright (C) 1998  Bernd Harries
6  *      Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
7  *
8  *  This driver supports the following ATI graphics chips:
9  *    - ATI Mach64
10  *
11  *  To do: add support for
12  *    - ATI Rage128 (from aty128fb.c)
13  *    - ATI Radeon (from radeonfb.c)
14  *
15  *  This driver is partly based on the PowerMac console driver:
16  *
17  *      Copyright (C) 1996 Paul Mackerras
18  *
19  *  and on the PowerMac ATI/mach64 display driver:
20  *
21  *      Copyright (C) 1997 Michael AK Tesch
22  *
23  *            with work by Jon Howell
24  *                         Harry AC Eaton
25  *                         Anthony Tong <atong@uiuc.edu>
26  *
27  *  This file is subject to the terms and conditions of the GNU General Public
28  *  License. See the file COPYING in the main directory of this archive for
29  *  more details.
30  *  
31  *  Many thanks to Nitya from ATI devrel for support and patience !
32  */
33
34 /******************************************************************************
35
36   TODO:
37
38     - cursor support on all cards and all ramdacs.
39     - cursor parameters controlable via ioctl()s.
40     - guess PLL and MCLK based on the original PLL register values initialized
41       by the BIOS or Open Firmware (if they are initialized).
42
43                                                 (Anyone to help with this?)
44
45 ******************************************************************************/
46
47
48 #include <linux/config.h>
49 #include <linux/module.h>
50 #include <linux/kernel.h>
51 #include <linux/errno.h>
52 #include <linux/string.h>
53 #include <linux/mm.h>
54 #include <linux/slab.h>
55 #include <linux/vmalloc.h>
56 #include <linux/delay.h>
57 #include <linux/selection.h>
58 #include <linux/console.h>
59 #include <linux/fb.h>
60 #include <linux/init.h>
61 #include <linux/pci.h>
62 #include <linux/vt_kern.h>
63 #include <linux/kd.h>
64
65 #include <asm/io.h>
66 #include <asm/uaccess.h>
67
68 #include <video/mach64.h>
69 #include "atyfb.h"
70
71 #ifdef __powerpc__
72 #include <asm/prom.h>
73 #include "../macmodes.h"
74 #endif
75 #ifdef __sparc__
76 #include <asm/pbm.h>
77 #include <asm/fbio.h>
78 #endif
79
80 #ifdef CONFIG_ADB_PMU
81 #include <linux/adb.h>
82 #include <linux/pmu.h>
83 #endif
84 #ifdef CONFIG_BOOTX_TEXT
85 #include <asm/btext.h>
86 #endif
87 #ifdef CONFIG_PMAC_BACKLIGHT
88 #include <asm/backlight.h>
89 #endif
90
91
92 /*
93  * Debug flags.
94  */
95 #undef DEBUG
96
97 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
98 /*  - must be large enough to catch all GUI-Regs   */
99 /*  - must be aligned to a PAGE boundary           */
100 #define GUI_RESERVE     (1 * PAGE_SIZE)
101
102
103 /* FIXME: remove the FAIL definition */
104 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
105
106
107     /*
108      *  The Hardware parameters for each card
109      */
110
111 struct aty_cmap_regs {
112         u8 windex;
113         u8 lut;
114         u8 mask;
115         u8 rindex;
116         u8 cntl;
117 };
118
119 struct pci_mmap_map {
120         unsigned long voff;
121         unsigned long poff;
122         unsigned long size;
123         unsigned long prot_flag;
124         unsigned long prot_mask;
125 };
126
127 static struct fb_fix_screeninfo atyfb_fix __initdata = {
128         .id             = "ATY Mach64",
129         .type           = FB_TYPE_PACKED_PIXELS,
130         .visual         = FB_VISUAL_PSEUDOCOLOR,
131         .xpanstep       = 8,
132         .ypanstep       = 1,
133 };
134
135     /*
136      *  Frame buffer device API
137      */
138
139 static int atyfb_open(struct fb_info *info, int user);
140 static int atyfb_release(struct fb_info *info, int user);
141 static int atyfb_check_var(struct fb_var_screeninfo *var,
142                            struct fb_info *info);
143 static int atyfb_set_par(struct fb_info *info); 
144 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
145                            u_int transp, struct fb_info *info);
146 static int atyfb_pan_display(struct fb_var_screeninfo *var,
147                              struct fb_info *info);
148 static int atyfb_blank(int blank, struct fb_info *info);
149 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
150                        u_long arg, struct fb_info *info);
151 extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
152 extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
153 extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);
154 #ifdef __sparc__
155 static int atyfb_mmap(struct fb_info *info, struct file *file,
156                       struct vm_area_struct *vma);
157 #endif
158 static int atyfb_sync(struct fb_info *info);
159
160     /*
161      *  Internal routines
162      */
163
164 static int aty_init(struct fb_info *info, const char *name);
165 #ifdef CONFIG_ATARI
166 static int store_video_par(char *videopar, unsigned char m64_num);
167 #endif
168
169 static void aty_set_crtc(const struct atyfb_par *par,
170                          const struct crtc *crtc);
171 static int aty_var_to_crtc(const struct fb_info *info,
172                            const struct fb_var_screeninfo *var,
173                            struct crtc *crtc);
174 static int aty_crtc_to_var(const struct crtc *crtc,
175                            struct fb_var_screeninfo *var);
176 static void set_off_pitch(struct atyfb_par *par,
177                           const struct fb_info *info);
178 #ifdef CONFIG_PPC
179 static int read_aty_sense(const struct atyfb_par *par);
180 #endif
181
182
183     /*
184      *  Interface used by the world
185      */
186
187 int atyfb_init(void);
188 #ifndef MODULE
189 int atyfb_setup(char *);
190 #endif
191
192 static struct fb_ops atyfb_ops = {
193         .owner          = THIS_MODULE,
194         .fb_open        = atyfb_open,
195         .fb_release     = atyfb_release,
196         .fb_check_var   = atyfb_check_var,
197         .fb_set_par     = atyfb_set_par,
198         .fb_setcolreg   = atyfb_setcolreg,
199         .fb_pan_display = atyfb_pan_display,
200         .fb_blank       = atyfb_blank,
201         .fb_ioctl       = atyfb_ioctl,
202         .fb_fillrect    = atyfb_fillrect,
203         .fb_copyarea    = atyfb_copyarea,
204         .fb_imageblit   = atyfb_imageblit,
205         .fb_cursor      = soft_cursor,
206 #ifdef __sparc__
207         .fb_mmap        = atyfb_mmap,
208 #endif
209         .fb_sync        = atyfb_sync,
210 };
211
212 static char curblink __initdata = 1;
213 static char noaccel __initdata = 0;
214 static u32 default_vram __initdata = 0;
215 static int default_pll __initdata = 0;
216 static int default_mclk __initdata = 0;
217
218 #ifndef MODULE
219 static char *mode_option __initdata = NULL;
220 #endif
221
222 #ifdef CONFIG_PPC
223 static int default_vmode __initdata = VMODE_CHOOSE;
224 static int default_cmode __initdata = CMODE_CHOOSE;
225 #endif
226
227 #ifdef CONFIG_ATARI
228 static unsigned int mach64_count __initdata = 0;
229 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
230 static unsigned long phys_size[FB_MAX] __initdata = { 0, };
231 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
232 #endif
233
234 #ifdef CONFIG_FB_ATY_GX
235 static char m64n_gx[] __initdata = "mach64GX (ATI888GX00)";
236 static char m64n_cx[] __initdata = "mach64CX (ATI888CX00)";
237 #endif /* CONFIG_FB_ATY_GX */
238 #ifdef CONFIG_FB_ATY_CT
239 static char m64n_ct[] __initdata = "mach64CT (ATI264CT)";
240 static char m64n_et[] __initdata = "mach64ET (ATI264ET)";
241 static char m64n_vta3[] __initdata = "mach64VTA3 (ATI264VT)";
242 static char m64n_vta4[] __initdata = "mach64VTA4 (ATI264VT)";
243 static char m64n_vtb[] __initdata = "mach64VTB (ATI264VTB)";
244 static char m64n_vt4[] __initdata = "mach64VT4 (ATI264VT4)";
245 static char m64n_gt[] __initdata = "3D RAGE (GT)";
246 static char m64n_gtb[] __initdata = "3D RAGE II+ (GTB)";
247 static char m64n_iic_p[] __initdata = "3D RAGE IIC (PCI)";
248 static char m64n_iic_a[] __initdata = "3D RAGE IIC (AGP)";
249 static char m64n_lt[] __initdata = "3D RAGE LT";
250 static char m64n_ltg[] __initdata = "3D RAGE LT-G";
251 static char m64n_gtc_ba[] __initdata = "3D RAGE PRO (BGA, AGP)";
252 static char m64n_gtc_ba1[] __initdata = "3D RAGE PRO (BGA, AGP, 1x only)";
253 static char m64n_gtc_bp[] __initdata = "3D RAGE PRO (BGA, PCI)";
254 static char m64n_gtc_pp[] __initdata = "3D RAGE PRO (PQFP, PCI)";
255 static char m64n_gtc_ppl[] __initdata =
256     "3D RAGE PRO (PQFP, PCI, limited 3D)";
257 static char m64n_xl[] __initdata = "3D RAGE (XL)";
258 static char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";
259 static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
260 static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
261 static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
262 #endif /* CONFIG_FB_ATY_CT */
263
264 static struct {
265         u16 pci_id, chip_type;
266         u8 rev_mask, rev_val;
267         const char *name;
268         int pll, mclk;
269         u32 features;
270 } aty_chips[] __initdata = {
271 #ifdef CONFIG_FB_ATY_GX
272         /* Mach64 GX */
273         {
274         0x4758, 0x00d7, 0x00, 0x00, m64n_gx, 135, 50, M64F_GX}, {
275         0x4358, 0x0057, 0x00, 0x00, m64n_cx, 135, 50, M64F_GX},
276 #endif                          /* CONFIG_FB_ATY_GX */
277 #ifdef CONFIG_FB_ATY_CT
278             /* Mach64 CT */
279         {
280         0x4354, 0x4354, 0x00, 0x00, m64n_ct, 135, 60,
281                     M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |
282                     M64F_MAGIC_FIFO}, {
283         0x4554, 0x4554, 0x00, 0x00, m64n_et, 135, 60,
284                     M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |
285                     M64F_MAGIC_FIFO},
286             /* Mach64 VT */
287         {
288         0x5654, 0x5654, 0xc7, 0x00, m64n_vta3, 170, 67,
289                     M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
290                     M64F_MAGIC_FIFO | M64F_FIFO_24}, {
291         0x5654, 0x5654, 0xc7, 0x40, m64n_vta4, 200, 67,
292                     M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
293                     M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV}, {
294         0x5654, 0x5654, 0x00, 0x00, m64n_vtb, 200, 67,
295                     M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
296                     M64F_GTB_DSP | M64F_FIFO_24}, {
297         0x5655, 0x5655, 0x00, 0x00, m64n_vtb, 200, 67,
298                     M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
299                     M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL}, {
300         0x5656, 0x5656, 0x00, 0x00, m64n_vt4, 230, 83,
301                     M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP},
302             /* Mach64 GT (3D RAGE) */
303         {
304         0x4754, 0x4754, 0x07, 0x00, m64n_gt, 135, 63,
305                     M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO |
306                     M64F_FIFO_24 | M64F_EXTRA_BRIGHT}, {
307         0x4754, 0x4754, 0x07, 0x01, m64n_gt, 170, 67,
308                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
309                     M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
310                     M64F_EXTRA_BRIGHT}, {
311         0x4754, 0x4754, 0x07, 0x02, m64n_gt, 200, 67,
312                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
313                     M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
314                     M64F_EXTRA_BRIGHT}, {
315         0x4755, 0x4755, 0x00, 0x00, m64n_gtb, 200, 67,
316                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
317                     M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
318                     M64F_EXTRA_BRIGHT}, {
319         0x4756, 0x4756, 0x00, 0x00, m64n_iic_p, 230, 83,
320                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
321                     M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
322                     M64F_EXTRA_BRIGHT}, {
323         0x4757, 0x4757, 0x00, 0x00, m64n_iic_a, 230, 83,
324                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
325                     M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
326                     M64F_EXTRA_BRIGHT}, {
327         0x475a, 0x475a, 0x00, 0x00, m64n_iic_a, 230, 83,
328                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
329                     M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
330                     M64F_EXTRA_BRIGHT},
331             /* Mach64 LT */
332         {
333         0x4c54, 0x4c54, 0x00, 0x00, m64n_lt, 135, 63,
334                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP}, {
335         0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg, 230, 63,
336                     M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
337                     M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT |
338                     M64F_LT_SLEEP | M64F_G3_PB_1024x768},
339             /* Mach64 GTC (3D RAGE PRO) */
340         {
341         0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba, 230, 100,
342                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
343                     M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
344                     M64F_EXTRA_BRIGHT}, {
345         0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100,
346                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
347                     M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
348                     M64F_EXTRA_BRIGHT}, {
349         0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp, 230, 100,
350                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
351                     M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
352                     M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE}, {
353         0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp, 230, 100,
354                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
355                     M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
356                     M64F_EXTRA_BRIGHT}, {
357         0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100,
358                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
359                     M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
360                     M64F_EXTRA_BRIGHT},
361             /* 3D RAGE XL */
362         {
363         0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 100,
364                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
365                     M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
366                     M64F_EXTRA_BRIGHT | M64F_XL_DLL},
367             /* Mach64 LT PRO */
368         {
369         0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a, 230, 100,
370                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
371                     M64F_GTB_DSP}, {
372         0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p, 230, 100,
373                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
374                     M64F_GTB_DSP}, {
375         0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p, 230, 100,
376                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
377                     M64F_GTB_DSP | M64F_EXTRA_BRIGHT |
378                     M64F_G3_PB_1_1 | M64F_G3_PB_1024x768}, {
379         0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p, 230, 100,
380                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
381                     M64F_GTB_DSP},
382             /* 3D RAGE Mobility */
383         {
384         0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50,
385                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
386                     M64F_GTB_DSP | M64F_MOBIL_BUS}, {
387         0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50,
388                     M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
389                     M64F_GTB_DSP | M64F_MOBIL_BUS},
390 #endif                          /* CONFIG_FB_ATY_CT */
391 };
392
393 static char ram_dram[] __initdata = "DRAM";
394 #ifdef CONFIG_FB_ATY_GX
395 static char ram_vram[] __initdata = "VRAM";
396 #endif /* CONFIG_FB_ATY_GX */
397 #ifdef CONFIG_FB_ATY_CT
398 static char ram_edo[] __initdata = "EDO";
399 static char ram_sdram[] __initdata = "SDRAM";
400 static char ram_sgram[] __initdata = "SGRAM";
401 static char ram_wram[] __initdata = "WRAM";
402 static char ram_off[] __initdata = "OFF";
403 #endif /* CONFIG_FB_ATY_CT */
404 static char ram_resv[] __initdata = "RESV";
405
406 static u32 pseudo_palette[17];
407
408 #ifdef CONFIG_FB_ATY_GX
409 static char *aty_gx_ram[8] __initdata = {
410         ram_dram, ram_vram, ram_vram, ram_dram,
411         ram_dram, ram_vram, ram_vram, ram_resv
412 };
413 #endif                          /* CONFIG_FB_ATY_GX */
414
415 #ifdef CONFIG_FB_ATY_CT
416 static char *aty_ct_ram[8] __initdata = {
417         ram_off, ram_dram, ram_edo, ram_edo,
418         ram_sdram, ram_sgram, ram_wram, ram_resv
419 };
420 #endif                          /* CONFIG_FB_ATY_CT */
421
422
423 #if defined(CONFIG_PPC)
424
425     /*
426      *  Apple monitor sense
427      */
428
429 static int __init read_aty_sense(const struct atyfb_par *par)
430 {
431         int sense, i;
432
433         aty_st_le32(GP_IO, 0x31003100, par);    /* drive outputs high */
434         __delay(200);
435         aty_st_le32(GP_IO, 0, par);     /* turn off outputs */
436         __delay(2000);
437         i = aty_ld_le32(GP_IO, par);    /* get primary sense value */
438         sense = ((i & 0x3000) >> 3) | (i & 0x100);
439
440         /* drive each sense line low in turn and collect the other 2 */
441         aty_st_le32(GP_IO, 0x20000000, par);    /* drive A low */
442         __delay(2000);
443         i = aty_ld_le32(GP_IO, par);
444         sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
445         aty_st_le32(GP_IO, 0x20002000, par);    /* drive A high again */
446         __delay(200);
447
448         aty_st_le32(GP_IO, 0x10000000, par);    /* drive B low */
449         __delay(2000);
450         i = aty_ld_le32(GP_IO, par);
451         sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
452         aty_st_le32(GP_IO, 0x10001000, par);    /* drive B high again */
453         __delay(200);
454
455         aty_st_le32(GP_IO, 0x01000000, par);    /* drive C low */
456         __delay(2000);
457         sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;
458         aty_st_le32(GP_IO, 0, par);     /* turn off outputs */
459         return sense;
460 }
461
462 #endif                          /* defined(CONFIG_PPC) */
463
464 #if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT)
465 static void aty_st_lcd(int index, u32 val, const struct atyfb_par *par)
466 {
467         unsigned long temp;
468
469         /* write addr byte */
470         temp = aty_ld_le32(LCD_INDEX, par);
471         aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
472         /* write the register value */
473         aty_st_le32(LCD_DATA, val, par);
474 }
475
476 static u32 aty_ld_lcd(int index, const struct atyfb_par *par)
477 {
478         unsigned long temp;
479
480         /* write addr byte */
481         temp = aty_ld_le32(LCD_INDEX, par);
482         aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);
483         /* read the register value */
484         return aty_ld_le32(LCD_DATA, par);
485 }
486 #endif                          /* CONFIG_PMAC_PBOOK || CONFIG_PMAC_BACKLIGHT */
487
488 /* ------------------------------------------------------------------------- */
489
490     /*
491      *  CRTC programming
492      */
493
494 static void aty_set_crtc(const struct atyfb_par *par,
495                          const struct crtc *crtc)
496 {
497         aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, par);
498         aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, par);
499         aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, par);
500         aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, par);
501         aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, par);
502         aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, par);
503         aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, par);
504 }
505
506 static int aty_var_to_crtc(const struct fb_info *info,
507                            const struct fb_var_screeninfo *var,
508                            struct crtc *crtc)
509 {
510         struct atyfb_par *par = (struct atyfb_par *) info->par;
511         u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
512         u32 left, right, upper, lower, hslen, vslen, sync, vmode;
513         u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
514             h_sync_pol;
515         u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
516         u32 pix_width, dp_pix_width, dp_chain_mask;
517
518         /* input */
519         xres = var->xres;
520         yres = var->yres;
521         vxres = var->xres_virtual;
522         vyres = var->yres_virtual;
523         xoffset = var->xoffset;
524         yoffset = var->yoffset;
525         bpp = var->bits_per_pixel;
526         left = var->left_margin;
527         right = var->right_margin;
528         upper = var->upper_margin;
529         lower = var->lower_margin;
530         hslen = var->hsync_len;
531         vslen = var->vsync_len;
532         sync = var->sync;
533         vmode = var->vmode;
534
535         /* convert (and round up) and validate */
536         xres = (xres + 7) & ~7;
537         xoffset = (xoffset + 7) & ~7;
538         vxres = (vxres + 7) & ~7;
539         if (vxres < xres + xoffset)
540                 vxres = xres + xoffset;
541         h_disp = xres / 8 - 1;
542         if (h_disp > 0xff)
543                 FAIL("h_disp too large");
544         h_sync_strt = h_disp + (right / 8);
545         if (h_sync_strt > 0x1ff)
546                 FAIL("h_sync_start too large");
547         h_sync_dly = right & 7;
548         h_sync_wid = (hslen + 7) / 8;
549         if (h_sync_wid > 0x1f)
550                 FAIL("h_sync_wid too large");
551         h_total = h_sync_strt + h_sync_wid + (h_sync_dly + left + 7) / 8;
552         if (h_total > 0x1ff)
553                 FAIL("h_total too large");
554         h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
555
556         if (vyres < yres + yoffset)
557                 vyres = yres + yoffset;
558         v_disp = yres - 1;
559         if (v_disp > 0x7ff)
560                 FAIL("v_disp too large");
561         v_sync_strt = v_disp + lower;
562         if (v_sync_strt > 0x7ff)
563                 FAIL("v_sync_strt too large");
564         v_sync_wid = vslen;
565         if (v_sync_wid > 0x1f)
566                 FAIL("v_sync_wid too large");
567         v_total = v_sync_strt + v_sync_wid + upper;
568         if (v_total > 0x7ff)
569                 FAIL("v_total too large");
570         v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
571
572         c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
573
574         if (bpp <= 8) {
575                 bpp = 8;
576                 pix_width = CRTC_PIX_WIDTH_8BPP;
577                 dp_pix_width =
578                     HOST_8BPP | SRC_8BPP | DST_8BPP |
579                     BYTE_ORDER_LSB_TO_MSB;
580                 dp_chain_mask = 0x8080;
581         } else if (bpp <= 16) {
582                 bpp = 16;
583                 pix_width = CRTC_PIX_WIDTH_15BPP;
584                 dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
585                     BYTE_ORDER_LSB_TO_MSB;
586                 dp_chain_mask = 0x4210;
587         } else if (bpp <= 24 && M64_HAS(INTEGRATED)) {
588                 bpp = 24;
589                 pix_width = CRTC_PIX_WIDTH_24BPP;
590                 dp_pix_width =
591                     HOST_8BPP | SRC_8BPP | DST_8BPP |
592                     BYTE_ORDER_LSB_TO_MSB;
593                 dp_chain_mask = 0x8080;
594         } else if (bpp <= 32) {
595                 bpp = 32;
596                 pix_width = CRTC_PIX_WIDTH_32BPP;
597                 dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
598                     BYTE_ORDER_LSB_TO_MSB;
599                 dp_chain_mask = 0x8080;
600         } else
601                 FAIL("invalid bpp");
602
603         if (vxres * vyres * bpp / 8 > info->fix.smem_len)
604                 FAIL("not enough video RAM");
605
606         if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
607                 FAIL("invalid vmode");
608
609         /* output */
610         crtc->vxres = vxres;
611         crtc->vyres = vyres;
612         crtc->h_tot_disp = h_total | (h_disp << 16);
613         crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly << 8) |
614             ((h_sync_strt & 0x100) << 4) | (h_sync_wid << 16) |
615             (h_sync_pol << 21);
616         crtc->v_tot_disp = v_total | (v_disp << 16);
617         crtc->v_sync_strt_wid =
618             v_sync_strt | (v_sync_wid << 16) | (v_sync_pol << 21);
619         crtc->off_pitch =
620             ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
621         crtc->gen_cntl =
622             pix_width | c_sync | CRTC_EXT_DISP_EN | CRTC_ENABLE;
623         if (M64_HAS(MAGIC_FIFO)) {
624                 /* Not VTB/GTB */
625                 /* FIXME: magic FIFO values */
626                 crtc->gen_cntl |=
627                     aty_ld_le32(CRTC_GEN_CNTL, par) & 0x000e0000;
628         }
629         crtc->dp_pix_width = dp_pix_width;
630         crtc->dp_chain_mask = dp_chain_mask;
631
632         return 0;
633 }
634
635
636 static int aty_crtc_to_var(const struct crtc *crtc,
637                            struct fb_var_screeninfo *var)
638 {
639         u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
640         u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid,
641             h_sync_pol;
642         u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
643         u32 pix_width;
644
645         /* input */
646         h_total = crtc->h_tot_disp & 0x1ff;
647         h_disp = (crtc->h_tot_disp >> 16) & 0xff;
648         h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
649             ((crtc->h_sync_strt_wid >> 4) & 0x100);
650         h_sync_dly = (crtc->h_sync_strt_wid >> 8) & 0x7;
651         h_sync_wid = (crtc->h_sync_strt_wid >> 16) & 0x1f;
652         h_sync_pol = (crtc->h_sync_strt_wid >> 21) & 0x1;
653         v_total = crtc->v_tot_disp & 0x7ff;
654         v_disp = (crtc->v_tot_disp >> 16) & 0x7ff;
655         v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
656         v_sync_wid = (crtc->v_sync_strt_wid >> 16) & 0x1f;
657         v_sync_pol = (crtc->v_sync_strt_wid >> 21) & 0x1;
658         c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
659         pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
660
661         /* convert */
662         xres = (h_disp + 1) * 8;
663         yres = v_disp + 1;
664         left = (h_total - h_sync_strt - h_sync_wid) * 8 - h_sync_dly;
665         right = (h_sync_strt - h_disp) * 8 + h_sync_dly;
666         hslen = h_sync_wid * 8;
667         upper = v_total - v_sync_strt - v_sync_wid;
668         lower = v_sync_strt - v_disp;
669         vslen = v_sync_wid;
670         sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
671             (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
672             (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
673
674         switch (pix_width) {
675 #if 0
676         case CRTC_PIX_WIDTH_4BPP:
677                 bpp = 4;
678                 var->red.offset = 0;
679                 var->red.length = 8;
680                 var->green.offset = 0;
681                 var->green.length = 8;
682                 var->blue.offset = 0;
683                 var->blue.length = 8;
684                 var->transp.offset = 0;
685                 var->transp.length = 0;
686                 break;
687 #endif
688         case CRTC_PIX_WIDTH_8BPP:
689                 bpp = 8;
690                 var->red.offset = 0;
691                 var->red.length = 8;
692                 var->green.offset = 0;
693                 var->green.length = 8;
694                 var->blue.offset = 0;
695                 var->blue.length = 8;
696                 var->transp.offset = 0;
697                 var->transp.length = 0;
698                 break;
699         case CRTC_PIX_WIDTH_15BPP:      /* RGB 555 */
700                 bpp = 16;
701                 var->red.offset = 10;
702                 var->red.length = 5;
703                 var->green.offset = 5;
704                 var->green.length = 5;
705                 var->blue.offset = 0;
706                 var->blue.length = 5;
707                 var->transp.offset = 0;
708                 var->transp.length = 0;
709                 break;
710 #if 0
711         case CRTC_PIX_WIDTH_16BPP:      /* RGB 565 */
712                 bpp = 16;
713                 var->red.offset = 11;
714                 var->red.length = 5;
715                 var->green.offset = 5;
716                 var->green.length = 6;
717                 var->blue.offset = 0;
718                 var->blue.length = 5;
719                 var->transp.offset = 0;
720                 var->transp.length = 0;
721                 break;
722 #endif
723         case CRTC_PIX_WIDTH_24BPP:      /* RGB 888 */
724                 bpp = 24;
725                 var->red.offset = 16;
726                 var->red.length = 8;
727                 var->green.offset = 8;
728                 var->green.length = 8;
729                 var->blue.offset = 0;
730                 var->blue.length = 8;
731                 var->transp.offset = 0;
732                 var->transp.length = 0;
733                 break;
734         case CRTC_PIX_WIDTH_32BPP:      /* ARGB 8888 */
735                 bpp = 32;
736                 var->red.offset = 16;
737                 var->red.length = 8;
738                 var->green.offset = 8;
739                 var->green.length = 8;
740                 var->blue.offset = 0;
741                 var->blue.length = 8;
742                 var->transp.offset = 24;
743                 var->transp.length = 8;
744                 break;
745         default:
746                 FAIL("Invalid pixel width");
747         }
748
749         /* output */
750         var->xres = xres;
751         var->yres = yres;
752         var->xres_virtual = crtc->vxres;
753         var->yres_virtual = crtc->vyres;
754         var->bits_per_pixel = bpp;
755         var->left_margin = left;
756         var->right_margin = right;
757         var->upper_margin = upper;
758         var->lower_margin = lower;
759         var->hsync_len = hslen;
760         var->vsync_len = vslen;
761         var->sync = sync;
762         var->vmode = FB_VMODE_NONINTERLACED;
763
764         return 0;
765 }
766
767 /* ------------------------------------------------------------------------- */
768
769 static int atyfb_set_par(struct fb_info *info)
770 {
771         struct atyfb_par *par = (struct atyfb_par *) info->par;
772         struct fb_var_screeninfo *var = &info->var;
773         u8 tmp;
774         u32 i;
775         int err;
776
777         if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
778             (err = par->pll_ops->var_to_pll(info, var->pixclock,
779                                         var->bits_per_pixel, &par->pll)))
780                 return err;
781
782         par->accel_flags = var->accel_flags;    /* hack */
783
784         if (par->blitter_may_be_busy)
785                 wait_for_idle(par);
786         tmp = aty_ld_8(CRTC_GEN_CNTL + 3, par);
787         aty_set_crtc(par, &par->crtc);
788         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, 0, par);
789         /* better call aty_StrobeClock ?? */
790         aty_st_8(CLOCK_CNTL + par->clk_wr_offset, CLOCK_STROBE, par);
791
792         par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel,
793                               par->accel_flags);
794         par->pll_ops->set_pll(info, &par->pll);
795
796         if (!M64_HAS(INTEGRATED)) {
797                 /* Don't forget MEM_CNTL */
798                 i = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
799                 switch (var->bits_per_pixel) {
800                 case 8:
801                         i |= 0x02000000;
802                         break;
803                 case 16:
804                         i |= 0x03000000;
805                         break;
806                 case 32:
807                         i |= 0x06000000;
808                         break;
809                 }
810                 aty_st_le32(MEM_CNTL, i, par);
811         } else {
812                 i = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
813                 if (!M64_HAS(MAGIC_POSTDIV))
814                         i |= par->mem_refresh_rate << 20;
815                 switch (var->bits_per_pixel) {
816                 case 8:
817                 case 24:
818                         i |= 0x00000000;
819                         break;
820                 case 16:
821                         i |= 0x04000000;
822                         break;
823                 case 32:
824                         i |= 0x08000000;
825                         break;
826                 }
827                 if (M64_HAS(CT_BUS)) {
828                         aty_st_le32(DAC_CNTL, 0x87010184, par);
829                         aty_st_le32(BUS_CNTL, 0x680000f9, par);
830                 } else if (M64_HAS(VT_BUS)) {
831                         aty_st_le32(DAC_CNTL, 0x87010184, par);
832                         aty_st_le32(BUS_CNTL, 0x680000f9, par);
833                 } else if (M64_HAS(MOBIL_BUS)) {
834                         aty_st_le32(DAC_CNTL, 0x80010102, par);
835                         aty_st_le32(BUS_CNTL, 0x7b33a040, par);
836                 } else {
837                         /* GT */
838                         aty_st_le32(DAC_CNTL, 0x86010102, par);
839                         aty_st_le32(BUS_CNTL, 0x7b23a040, par);
840                         aty_st_le32(EXT_MEM_CNTL,
841                                     aty_ld_le32(EXT_MEM_CNTL,
842                                                 par) | 0x5000001, par);
843                 }
844                 aty_st_le32(MEM_CNTL, i, par);
845         }
846         aty_st_8(DAC_MASK, 0xff, par);
847
848         info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
849         info->fix.visual = var->bits_per_pixel <= 8 ?
850                 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
851
852         /* Initialize the graphics engine */
853         if (par->accel_flags & FB_ACCELF_TEXT)
854                 aty_init_engine(par, info);
855
856 #ifdef CONFIG_BOOTX_TEXT
857         btext_update_display(info->fix.smem_start,
858                              (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
859                              ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
860                              var->bits_per_pixel,
861                              par->crtc.vxres * var->bits_per_pixel / 8);
862 #endif                          /* CONFIG_BOOTX_TEXT */
863         return 0;
864 }
865
866 static int atyfb_check_var(struct fb_var_screeninfo *var,
867                            struct fb_info *info)
868 {
869         struct atyfb_par *par = (struct atyfb_par *) info->par;
870         struct crtc crtc;
871         union aty_pll pll;
872         int err;
873
874         if ((err = aty_var_to_crtc(info, var, &crtc)) ||
875             (err = par->pll_ops->var_to_pll(info, var->pixclock,
876                                         var->bits_per_pixel, &pll)))
877                 return err;
878
879 #if 0   /* fbmon is not done. uncomment for 2.5.x -brad */
880         if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
881                 return -EINVAL;
882 #endif
883         aty_crtc_to_var(&crtc, var);
884         var->pixclock = par->pll_ops->pll_to_var(info, &pll);
885         return 0;
886 }
887
888 static void set_off_pitch(struct atyfb_par *par,
889                           const struct fb_info *info)
890 {
891         u32 xoffset = info->var.xoffset;
892         u32 yoffset = info->var.yoffset;
893         u32 vxres = par->crtc.vxres;
894         u32 bpp = info->var.bits_per_pixel;
895
896         par->crtc.off_pitch =
897             ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
898         aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, par);
899 }
900
901
902     /*
903      *  Open/Release the frame buffer device
904      */
905
906 static int atyfb_open(struct fb_info *info, int user)
907 {
908 #ifdef __sparc__
909         struct atyfb_par *par = (struct atyfb_par *) info->par;
910
911         if (user) {
912                 par->open++;
913                 par->mmaped = 0;
914         }
915 #endif
916         return (0);
917 }
918
919 struct fb_var_screeninfo default_var = {
920         /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
921         640, 480, 640, 480, 0, 0, 8, 0,
922         {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
923         0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
924         0, FB_VMODE_NONINTERLACED
925 };
926
927 static int atyfb_release(struct fb_info *info, int user)
928 {
929 #ifdef __sparc__
930         struct atyfb_par *par = (struct atyfb_par *) info->par; 
931
932         if (user) {
933                 par->open--;
934                 mdelay(1);
935                 wait_for_idle(par);
936                 if (!par->open) {
937                         int was_mmaped = par->mmaped;
938
939                         par->mmaped = 0;
940
941                         if (was_mmaped) {
942                                 struct fb_var_screeninfo var;
943
944                                 /* Now reset the default display config, we have no
945                                  * idea what the program(s) which mmap'd the chip did
946                                  * to the configuration, nor whether it restored it
947                                  * correctly.
948                                  */
949                                 var = default_var;
950                                 if (noaccel)
951                                         var.accel_flags &= ~FB_ACCELF_TEXT;
952                                 else
953                                         var.accel_flags |= FB_ACCELF_TEXT;
954                                 if (var.yres == var.yres_virtual) {
955                                         u32 vram =
956                                             (info->fix.smem_len -
957                                              (PAGE_SIZE << 2));
958                                         var.yres_virtual =
959                                             ((vram * 8) /
960                                              var.bits_per_pixel) /
961                                             var.xres_virtual;
962                                         if (var.yres_virtual < var.yres)
963                                                 var.yres_virtual =
964                                                     var.yres;
965                                 }
966                         }
967                 }
968         } 
969 #endif
970         return (0);
971 }
972
973     /*
974      *  Pan or Wrap the Display
975      *
976      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
977      */
978
979 static int atyfb_pan_display(struct fb_var_screeninfo *var,
980                              struct fb_info *info)
981 {
982         struct atyfb_par *par = (struct atyfb_par *) info->par;
983         u32 xres, yres, xoffset, yoffset;
984
985         xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
986         yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
987         xoffset = (var->xoffset + 7) & ~7;
988         yoffset = var->yoffset;
989         if (xoffset + xres > par->crtc.vxres
990             || yoffset + yres > par->crtc.vyres)
991                 return -EINVAL;
992         info->var.xoffset = xoffset;
993         info->var.yoffset = yoffset;
994         set_off_pitch(par, info);
995         return 0;
996 }
997
998 #ifdef DEBUG
999 #define ATYIO_CLKR              0x41545900      /* ATY\00 */
1000 #define ATYIO_CLKW              0x41545901      /* ATY\01 */
1001
1002 struct atyclk {
1003         u32 ref_clk_per;
1004         u8 pll_ref_div;
1005         u8 mclk_fb_div;
1006         u8 mclk_post_div;       /* 1,2,3,4,8 */
1007         u8 vclk_fb_div;
1008         u8 vclk_post_div;       /* 1,2,3,4,6,8,12 */
1009         u32 dsp_xclks_per_row;  /* 0-16383 */
1010         u32 dsp_loop_latency;   /* 0-15 */
1011         u32 dsp_precision;      /* 0-7 */
1012         u32 dsp_on;             /* 0-2047 */
1013         u32 dsp_off;            /* 0-2047 */
1014 };
1015
1016 #define ATYIO_FEATR             0x41545902      /* ATY\02 */
1017 #define ATYIO_FEATW             0x41545903      /* ATY\03 */
1018 #endif
1019
1020 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
1021                        u_long arg, struct fb_info *info)
1022 {
1023 #if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
1024         struct atyfb_par *par = (struct atyfb_par *) info->par;
1025 #endif                          /* __sparc__ || DEBUG */
1026 #ifdef __sparc__
1027         struct fbtype fbtyp;
1028 #endif
1029
1030         switch (cmd) {
1031 #ifdef __sparc__
1032         case FBIOGTYPE:
1033                 fbtyp.fb_type = FBTYPE_PCI_GENERIC;
1034                 fbtyp.fb_width = par->crtc.vxres;
1035                 fbtyp.fb_height = par->crtc.vyres;
1036                 fbtyp.fb_depth = info->var.bits_per_pixel;
1037                 fbtyp.fb_cmsize = info->cmap.len;
1038                 fbtyp.fb_size = info->fix.smem_len;
1039                 if (copy_to_user
1040                     ((struct fbtype *) arg, &fbtyp, sizeof(fbtyp)))
1041                         return -EFAULT;
1042                 break;
1043 #endif                          /* __sparc__ */
1044 #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
1045         case ATYIO_CLKR:
1046                 if (M64_HAS(INTEGRATED)) {
1047                         struct atyclk clk;
1048                         union aty_pll *pll = par->pll;
1049                         u32 dsp_config = pll->ct.dsp_config;
1050                         u32 dsp_on_off = pll->ct.dsp_on_off;
1051                         clk.ref_clk_per = par->ref_clk_per;
1052                         clk.pll_ref_div = pll->ct.pll_ref_div;
1053                         clk.mclk_fb_div = pll->ct.mclk_fb_div;
1054                         clk.mclk_post_div = pll->ct.mclk_post_div_real;
1055                         clk.vclk_fb_div = pll->ct.vclk_fb_div;
1056                         clk.vclk_post_div = pll->ct.vclk_post_div_real;
1057                         clk.dsp_xclks_per_row = dsp_config & 0x3fff;
1058                         clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
1059                         clk.dsp_precision = (dsp_config >> 20) & 7;
1060                         clk.dsp_on = dsp_on_off & 0x7ff;
1061                         clk.dsp_off = (dsp_on_off >> 16) & 0x7ff;
1062                         if (copy_to_user
1063                             ((struct atyclk *) arg, &clk, sizeof(clk)))
1064                                 return -EFAULT;
1065                 } else
1066                         return -EINVAL;
1067                 break;
1068         case ATYIO_CLKW:
1069                 if (M64_HAS(INTEGRATED)) {
1070                         struct atyclk clk;
1071                         union aty_pll *pll = par->pll;
1072                         if (copy_from_user
1073                             (&clk, (struct atyclk *) arg, sizeof(clk)))
1074                                 return -EFAULT;
1075                         par->ref_clk_per = clk.ref_clk_per;
1076                         pll->ct.pll_ref_div = clk.pll_ref_div;
1077                         pll->ct.mclk_fb_div = clk.mclk_fb_div;
1078                         pll->ct.mclk_post_div_real = clk.mclk_post_div;
1079                         pll->ct.vclk_fb_div = clk.vclk_fb_div;
1080                         pll->ct.vclk_post_div_real = clk.vclk_post_div;
1081                         pll->ct.dsp_config =
1082                             (clk.
1083                              dsp_xclks_per_row & 0x3fff) | ((clk.
1084                                                              dsp_loop_latency
1085                                                              & 0xf) << 16)
1086                             | ((clk.dsp_precision & 7) << 20);
1087                         pll->ct.dsp_on_off =
1088                             (clk.
1089                              dsp_on & 0x7ff) | ((clk.
1090                                                  dsp_off & 0x7ff) << 16);
1091                         aty_calc_pll_ct(info, &pll->ct);
1092                         aty_set_pll_ct(info, pll);
1093                 } else
1094                         return -EINVAL;
1095                 break;
1096         case ATYIO_FEATR:
1097                 if (get_user(par->features, (u32 *) arg))
1098                         return -EFAULT;
1099                 break;
1100         case ATYIO_FEATW:
1101                 if (put_user(par->features, (u32 *) arg))
1102                         return -EFAULT;
1103                 break;
1104 #endif                          /* DEBUG && CONFIG_FB_ATY_CT */
1105         default:
1106                 return -EINVAL;
1107         }
1108         return 0;
1109 }
1110
1111 static int atyfb_sync(struct fb_info *info)
1112 {
1113         struct atyfb_par *par = (struct atyfb_par *) info->par;
1114
1115         if (par->blitter_may_be_busy)
1116                 wait_for_idle(par);
1117         return 0;
1118 }
1119
1120 #ifdef __sparc__
1121 static int atyfb_mmap(struct fb_info *info, struct file *file,
1122                       struct vm_area_struct *vma)
1123 {
1124         struct atyfb_par *par = (struct atyfb_par *) info->par;
1125         unsigned int size, page, map_size = 0;
1126         unsigned long map_offset = 0;
1127         unsigned long off;
1128         int i;
1129
1130         if (!par->mmap_map)
1131                 return -ENXIO;
1132
1133         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1134                 return -EINVAL;
1135
1136         off = vma->vm_pgoff << PAGE_SHIFT;
1137         size = vma->vm_end - vma->vm_start;
1138
1139         /* To stop the swapper from even considering these pages. */
1140         vma->vm_flags |= (VM_SHM | VM_LOCKED);
1141
1142         if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
1143             ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
1144                 off += 0x8000000000000000UL;
1145
1146         vma->vm_pgoff = off >> PAGE_SHIFT;      /* propagate off changes */
1147
1148         /* Each page, see which map applies */
1149         for (page = 0; page < size;) {
1150                 map_size = 0;
1151                 for (i = 0; par->mmap_map[i].size; i++) {
1152                         unsigned long start = par->mmap_map[i].voff;
1153                         unsigned long end = start + par->mmap_map[i].size;
1154                         unsigned long offset = off + page;
1155
1156                         if (start > offset)
1157                                 continue;
1158                         if (offset >= end)
1159                                 continue;
1160
1161                         map_size = par->mmap_map[i].size - (offset - start);
1162                         map_offset =
1163                             par->mmap_map[i].poff + (offset - start);
1164                         break;
1165                 }
1166                 if (!map_size) {
1167                         page += PAGE_SIZE;
1168                         continue;
1169                 }
1170                 if (page + map_size > size)
1171                         map_size = size - page;
1172
1173                 pgprot_val(vma->vm_page_prot) &=
1174                     ~(par->mmap_map[i].prot_mask);
1175                 pgprot_val(vma->vm_page_prot) |= par->mmap_map[i].prot_flag;
1176
1177                 if (remap_page_range(vma, vma->vm_start + page, map_offset,
1178                                      map_size, vma->vm_page_prot))
1179                         return -EAGAIN;
1180
1181                 page += map_size;
1182         }
1183
1184         if (!map_size)
1185                 return -EINVAL;
1186
1187         vma->vm_flags |= VM_IO;
1188
1189         if (!par->mmaped)
1190                 par->mmaped = 1;
1191         return 0;
1192 }
1193
1194 static struct {
1195         u32 yoffset;
1196         u8 r[2][256];
1197         u8 g[2][256];
1198         u8 b[2][256];
1199 } atyfb_save;
1200
1201 static void atyfb_save_palette(struct atyfb_par *par, int enter)
1202 {
1203         int i, tmp;
1204
1205         for (i = 0; i < 256; i++) {
1206                 tmp = aty_ld_8(DAC_CNTL, par) & 0xfc;
1207                 if (M64_HAS(EXTRA_BRIGHT))
1208                         tmp |= 0x2;
1209                 aty_st_8(DAC_CNTL, tmp, par);
1210                 aty_st_8(DAC_MASK, 0xff, par);
1211
1212                 writeb(i, &par->aty_cmap_regs->rindex);
1213                 atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut);
1214                 atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut);
1215                 atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut);
1216                 writeb(i, &par->aty_cmap_regs->windex);
1217                 writeb(atyfb_save.r[1 - enter][i],
1218                        &par->aty_cmap_regs->lut);
1219                 writeb(atyfb_save.g[1 - enter][i],
1220                        &par->aty_cmap_regs->lut);
1221                 writeb(atyfb_save.b[1 - enter][i],
1222                        &par->aty_cmap_regs->lut);
1223         }
1224 }
1225
1226 static void atyfb_palette(int enter)
1227 {
1228         struct atyfb_par *par;
1229         struct fb_info *info;
1230         int i;
1231
1232         for (i = 0; i < FB_MAX; i++) {
1233                 info = registered_fb[i];
1234                 if (info &&
1235                     info->fbops == &atyfb_ops &&
1236                     info->display_fg &&
1237                     info->display_fg->vc_num == i) {
1238                         par = (struct atyfb_par *) info->par;
1239                         
1240                         atyfb_save_palette(par, enter);
1241                         if (enter) {
1242                                 atyfb_save.yoffset = info->var.yoffset;
1243                                 info->var.yoffset = 0;
1244                                 set_off_pitch(par, info);
1245                         } else {
1246                                 info->var.yoffset = atyfb_save.yoffset;
1247                                 set_off_pitch(par, info);
1248                         }
1249                         break;
1250                 }
1251         }
1252 }
1253 #endif                          /* __sparc__ */
1254
1255
1256
1257 #ifdef CONFIG_PMAC_PBOOK
1258
1259 static struct fb_info *first_display = NULL;
1260
1261 /* Power management routines. Those are used for PowerBook sleep.
1262  *
1263  * It appears that Rage LT and Rage LT Pro have different power
1264  * management registers. There's is some confusion about which
1265  * chipID is a Rage LT or LT pro :(
1266  */
1267 static int aty_power_mgmt_LT(int sleep, struct atyfb_par *par)
1268 {
1269         unsigned int pm;
1270         int timeout;
1271
1272         pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1273         pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1274         aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1275         pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1276
1277         timeout = 200000;
1278         if (sleep) {
1279                 /* Sleep */
1280                 pm &= ~PWR_MGT_ON;
1281                 aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1282                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1283                 udelay(10);
1284                 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1285                 pm |= SUSPEND_NOW;
1286                 aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1287                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1288                 udelay(10);
1289                 pm |= PWR_MGT_ON;
1290                 aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1291                 do {
1292                         pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1293                         udelay(10);
1294                         if ((--timeout) == 0)
1295                                 break;
1296                 } while ((pm & PWR_MGT_STATUS_MASK) !=
1297                          PWR_MGT_STATUS_SUSPEND);
1298         } else {
1299                 /* Wakeup */
1300                 pm &= ~PWR_MGT_ON;
1301                 aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1302                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1303                 udelay(10);
1304                 pm |= (PWR_BLON | AUTO_PWR_UP);
1305                 pm &= ~SUSPEND_NOW;
1306                 aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1307                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1308                 udelay(10);
1309                 pm |= PWR_MGT_ON;
1310                 aty_st_le32(POWER_MANAGEMENT_LG, pm, par);
1311                 do {
1312                         pm = aty_ld_le32(POWER_MANAGEMENT_LG, par);
1313                         udelay(10);
1314                         if ((--timeout) == 0)
1315                                 break;
1316                 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
1317         }
1318         mdelay(500);
1319
1320         return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
1321 }
1322
1323 static int aty_power_mgmt_LTPro(int sleep, struct atyfb_par *par)
1324 {
1325         unsigned int pm;
1326         int timeout;
1327
1328         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1329         pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
1330         aty_st_lcd(POWER_MANAGEMENT, pm, par);
1331         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1332
1333         timeout = 200;
1334         if (sleep) {
1335                 /* Sleep */
1336                 pm &= ~PWR_MGT_ON;
1337                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1338                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1339                 udelay(10);
1340                 pm &= ~(PWR_BLON | AUTO_PWR_UP);
1341                 pm |= SUSPEND_NOW;
1342                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1343                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1344                 udelay(10);
1345                 pm |= PWR_MGT_ON;
1346                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1347                 do {
1348                         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1349                         mdelay(1);
1350                         if ((--timeout) == 0)
1351                                 break;
1352                 } while ((pm & PWR_MGT_STATUS_MASK) !=
1353                          PWR_MGT_STATUS_SUSPEND);
1354         } else {
1355                 /* Wakeup */
1356                 pm &= ~PWR_MGT_ON;
1357                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1358                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1359                 udelay(10);
1360                 pm &= ~SUSPEND_NOW;
1361                 pm |= (PWR_BLON | AUTO_PWR_UP);
1362                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1363                 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1364                 udelay(10);
1365                 pm |= PWR_MGT_ON;
1366                 aty_st_lcd(POWER_MANAGEMENT, pm, par);
1367                 do {
1368                         pm = aty_ld_lcd(POWER_MANAGEMENT, par);
1369                         mdelay(1);
1370                         if ((--timeout) == 0)
1371                                 break;
1372                 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
1373         }
1374
1375         return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
1376 }
1377
1378 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1379 {
1380         return M64_HAS(LT_SLEEP) ? aty_power_mgmt_LT(sleep, par)
1381             : aty_power_mgmt_LTPro(sleep, par);
1382 }
1383
1384 /*
1385  * Save the contents of the frame buffer when we go to sleep,
1386  * and restore it when we wake up again.
1387  */
1388 static int aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
1389 {
1390         struct fb_info *info;
1391         struct atyfb_par *par; 
1392         int result;
1393
1394         result = PBOOK_SLEEP_OK;
1395
1396         for (info = first_display; info != NULL; info = par->next) {
1397                 int nb;
1398
1399                 par = (struct atyfb_par *) info->par;
1400                 nb = info->var.yres * info->fix.line_length;
1401
1402                 switch (when) {
1403                 case PBOOK_SLEEP_REQUEST:
1404                         par->save_framebuffer = vmalloc(nb);
1405                         if (par->save_framebuffer == NULL)
1406                                 return PBOOK_SLEEP_REFUSE;
1407                         break;
1408                 case PBOOK_SLEEP_REJECT:
1409                         if (par->save_framebuffer) {
1410                                 vfree(par->save_framebuffer);
1411                                 par->save_framebuffer = 0;
1412                         }
1413                         break;
1414                 case PBOOK_SLEEP_NOW:
1415                         if (par->blitter_may_be_busy)
1416                                 wait_for_idle(par);
1417                         /* Stop accel engine (stop bus mastering) */
1418                         if (par->accel_flags & FB_ACCELF_TEXT)
1419                                 aty_reset_engine(par);
1420
1421                         /* Backup fb content */
1422                         if (par->save_framebuffer)
1423                                 memcpy_fromio(par->save_framebuffer,
1424                                               (void *) info->screen_base, nb);
1425
1426                         /* Blank display and LCD */
1427                         atyfb_blank(VESA_POWERDOWN + 1, info);
1428
1429                         /* Set chip to "suspend" mode */
1430                         result = aty_power_mgmt(1, par);
1431                         break;
1432                 case PBOOK_WAKE:
1433                         /* Wakeup chip */
1434                         result = aty_power_mgmt(0, par);
1435
1436                         /* Restore fb content */
1437                         if (par->save_framebuffer) {
1438                                 memcpy_toio((void *) info->screen_base,
1439                                             par->save_framebuffer, nb);
1440                                 vfree(par->save_framebuffer);
1441                                 par->save_framebuffer = 0;
1442                         }
1443                         /* Restore display */
1444                         atyfb_set_par(info);
1445                         atyfb_blank(0, info);
1446                         break;
1447                 }
1448         }
1449         return result;
1450 }
1451
1452 static struct pmu_sleep_notifier aty_sleep_notifier = {
1453         aty_sleep_notify, SLEEP_LEVEL_VIDEO,
1454 };
1455 #endif                          /* CONFIG_PMAC_PBOOK */
1456
1457 #ifdef CONFIG_PMAC_BACKLIGHT
1458
1459     /*
1460      *   LCD backlight control
1461      */
1462
1463 static int backlight_conv[] = {
1464         0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
1465         0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
1466 };
1467
1468 static int aty_set_backlight_enable(int on, int level, void *data)
1469 {
1470         struct fb_info *info = (struct fb_info *) data;
1471         struct atyfb_par *par = (struct atyfb_par *) info->par;
1472         unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
1473
1474         reg |= (BLMOD_EN | BIASMOD_EN);
1475         if (on && level > BACKLIGHT_OFF) {
1476                 reg &= ~BIAS_MOD_LEVEL_MASK;
1477                 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
1478         } else {
1479                 reg &= ~BIAS_MOD_LEVEL_MASK;
1480                 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
1481         }
1482         aty_st_lcd(LCD_MISC_CNTL, reg, par);
1483         return 0;
1484 }
1485
1486 static int aty_set_backlight_level(int level, void *data)
1487 {
1488         return aty_set_backlight_enable(1, level, data);
1489 }
1490
1491 static struct backlight_controller aty_backlight_controller = {
1492         aty_set_backlight_enable,
1493         aty_set_backlight_level
1494 };
1495 #endif                          /* CONFIG_PMAC_BACKLIGHT */
1496
1497
1498
1499     /*
1500      *  Initialisation
1501      */
1502
1503 static struct fb_info *fb_list = NULL;
1504
1505 static int __init aty_init(struct fb_info *info, const char *name)
1506 {
1507         struct atyfb_par *par = (struct atyfb_par *) info->par;
1508         const char *chipname = NULL, *ramname = NULL, *xtal;
1509         int j, pll, mclk, gtb_memsize;
1510         struct fb_var_screeninfo var;
1511         u32 chip_id, i;
1512         u16 type;
1513         u8 rev;
1514 #if defined(CONFIG_PPC)
1515         int sense;
1516 #endif
1517         u8 pll_ref_div;
1518
1519         par->aty_cmap_regs =
1520             (struct aty_cmap_regs *) (par->ati_regbase + 0xc0);
1521         chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
1522         type = chip_id & CFG_CHIP_TYPE;
1523         rev = (chip_id & CFG_CHIP_REV) >> 24;
1524         for (j = 0; j < (sizeof(aty_chips) / sizeof(*aty_chips)); j++)
1525                 if (type == aty_chips[j].chip_type &&
1526                     (rev & aty_chips[j].rev_mask) ==
1527                     aty_chips[j].rev_val) {
1528                         chipname = aty_chips[j].name;
1529                         pll = aty_chips[j].pll;
1530                         mclk = aty_chips[j].mclk;
1531                         par->features = aty_chips[j].features;
1532                         goto found;
1533                 }
1534         printk("atyfb: Unknown mach64 0x%04x rev 0x%04x\n", type, rev);
1535         return 0;
1536
1537       found:
1538         printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, type, rev);
1539 #ifdef CONFIG_FB_ATY_GX
1540         if (!M64_HAS(INTEGRATED)) {
1541                 u32 stat0;
1542                 u8 dac_type, dac_subtype, clk_type;
1543                 stat0 = aty_ld_le32(CONFIG_STAT0, par);
1544                 par->bus_type = (stat0 >> 0) & 0x07;
1545                 par->ram_type = (stat0 >> 3) & 0x07;
1546                 ramname = aty_gx_ram[par->ram_type];
1547                 /* FIXME: clockchip/RAMDAC probing? */
1548                 dac_type = (aty_ld_le32(DAC_CNTL, par) >> 16) & 0x07;
1549 #ifdef CONFIG_ATARI
1550                 clk_type = CLK_ATI18818_1;
1551                 dac_type = (stat0 >> 9) & 0x07;
1552                 if (dac_type == 0x07)
1553                         dac_subtype = DAC_ATT20C408;
1554                 else
1555                         dac_subtype =
1556                             (aty_ld_8(SCRATCH_REG1 + 1, par) & 0xF0) |
1557                             dac_type;
1558 #else
1559                 dac_type = DAC_IBMRGB514;
1560                 dac_subtype = DAC_IBMRGB514;
1561                 clk_type = CLK_IBMRGB514;
1562 #endif
1563                 switch (dac_subtype) {
1564                 case DAC_IBMRGB514:
1565                         par->dac_ops = &aty_dac_ibm514;
1566                         break;
1567                 case DAC_ATI68860_B:
1568                 case DAC_ATI68860_C:
1569                         par->dac_ops = &aty_dac_ati68860b;
1570                         break;
1571                 case DAC_ATT20C408:
1572                 case DAC_ATT21C498:
1573                         par->dac_ops = &aty_dac_att21c498;
1574                         break;
1575                 default:
1576                         printk
1577                             (" atyfb_set_par: DAC type not implemented yet!\n");
1578                         par->dac_ops = &aty_dac_unsupported;
1579                         break;
1580                 }
1581                 switch (clk_type) {
1582                 case CLK_ATI18818_1:
1583                         par->pll_ops = &aty_pll_ati18818_1;
1584                         break;
1585                 case CLK_STG1703:
1586                         par->pll_ops = &aty_pll_stg1703;
1587                         break;
1588                 case CLK_CH8398:
1589                         par->pll_ops = &aty_pll_ch8398;
1590                         break;
1591                 case CLK_ATT20C408:
1592                         par->pll_ops = &aty_pll_att20c408;
1593                         break;
1594                 case CLK_IBMRGB514:
1595                         par->pll_ops = &aty_pll_ibm514;
1596                         break;
1597                 default:
1598                         printk
1599                             (" atyfb_set_par: CLK type not implemented yet!");
1600                         par->pll_ops = &aty_pll_unsupported;
1601                         break;
1602                 }
1603         }
1604 #endif                          /* CONFIG_FB_ATY_GX */
1605 #ifdef CONFIG_FB_ATY_CT
1606         if (M64_HAS(INTEGRATED)) {
1607                 par->bus_type = PCI;
1608                 par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
1609                 ramname = aty_ct_ram[par->ram_type];
1610                 par->dac_ops = &aty_dac_ct;
1611                 par->pll_ops = &aty_pll_ct;
1612                 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
1613                 if (mclk == 67 && par->ram_type < SDRAM)
1614                         mclk = 63;
1615         }
1616 #endif                          /* CONFIG_FB_ATY_CT */
1617
1618         par->ref_clk_per = 1000000000000ULL / 14318180;
1619         xtal = "14.31818";
1620         if (M64_HAS(GTB_DSP)
1621             && (pll_ref_div = aty_ld_pll(PLL_REF_DIV, par))) {
1622                 int diff1, diff2;
1623                 diff1 = 510 * 14 / pll_ref_div - pll;
1624                 diff2 = 510 * 29 / pll_ref_div - pll;
1625                 if (diff1 < 0)
1626                         diff1 = -diff1;
1627                 if (diff2 < 0)
1628                         diff2 = -diff2;
1629                 if (diff2 < diff1) {
1630                         par->ref_clk_per = 1000000000000ULL / 29498928;
1631                         xtal = "29.498928";
1632                 }
1633         }
1634
1635         i = aty_ld_le32(MEM_CNTL, par);
1636         gtb_memsize = M64_HAS(GTB_DSP);
1637         if (gtb_memsize)
1638                 switch (i & 0xF) {      /* 0xF used instead of MEM_SIZE_ALIAS */
1639                 case MEM_SIZE_512K:
1640                         info->fix.smem_len = 0x80000;
1641                         break;
1642                 case MEM_SIZE_1M:
1643                         info->fix.smem_len = 0x100000;
1644                         break;
1645                 case MEM_SIZE_2M_GTB:
1646                         info->fix.smem_len = 0x200000;
1647                         break;
1648                 case MEM_SIZE_4M_GTB:
1649                         info->fix.smem_len = 0x400000;
1650                         break;
1651                 case MEM_SIZE_6M_GTB:
1652                         info->fix.smem_len = 0x600000;
1653                         break;
1654                 case MEM_SIZE_8M_GTB:
1655                         info->fix.smem_len = 0x800000;
1656                         break;
1657                 default:
1658                         info->fix.smem_len = 0x80000;
1659         } else
1660                 switch (i & MEM_SIZE_ALIAS) {
1661                 case MEM_SIZE_512K:
1662                         info->fix.smem_len = 0x80000;
1663                         break;
1664                 case MEM_SIZE_1M:
1665                         info->fix.smem_len = 0x100000;
1666                         break;
1667                 case MEM_SIZE_2M:
1668                         info->fix.smem_len = 0x200000;
1669                         break;
1670                 case MEM_SIZE_4M:
1671                         info->fix.smem_len = 0x400000;
1672                         break;
1673                 case MEM_SIZE_6M:
1674                         info->fix.smem_len = 0x600000;
1675                         break;
1676                 case MEM_SIZE_8M:
1677                         info->fix.smem_len = 0x800000;
1678                         break;
1679                 default:
1680                         info->fix.smem_len = 0x80000;
1681                 }
1682
1683         if (M64_HAS(MAGIC_VRAM_SIZE)) {
1684                 if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
1685                         info->fix.smem_len += 0x400000;
1686         }
1687
1688         if (default_vram) {
1689                 info->fix.smem_len = default_vram * 1024;
1690                 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
1691                 if (info->fix.smem_len <= 0x80000)
1692                         i |= MEM_SIZE_512K;
1693                 else if (info->fix.smem_len <= 0x100000)
1694                         i |= MEM_SIZE_1M;
1695                 else if (info->fix.smem_len <= 0x200000)
1696                         i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
1697                 else if (info->fix.smem_len <= 0x400000)
1698                         i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
1699                 else if (info->fix.smem_len <= 0x600000)
1700                         i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
1701                 else
1702                         i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
1703                 aty_st_le32(MEM_CNTL, i, par);
1704         }
1705
1706         /*
1707          *  Reg Block 0 (CT-compatible block) is at mmio_start 
1708          *  Reg Block 1 (multimedia extensions) is at mmio_start - 0x400
1709          */
1710         if (M64_HAS(GX)) {
1711                 info->fix.mmio_len = 0x400;
1712                 info->fix.accel = FB_ACCEL_ATI_MACH64GX;
1713         } else if (M64_HAS(CT)) {
1714                 info->fix.mmio_len = 0x400;
1715                 info->fix.accel = FB_ACCEL_ATI_MACH64CT;
1716         } else if (M64_HAS(VT)) {
1717                 info->fix.mmio_start = -0x400;
1718                 info->fix.mmio_len = 0x800;
1719                 info->fix.accel = FB_ACCEL_ATI_MACH64VT;
1720         } else {                /* if (M64_HAS(GT)) */
1721
1722                 info->fix.mmio_start = -0x400;
1723                 info->fix.mmio_len = 0x800;
1724                 info->fix.accel = FB_ACCEL_ATI_MACH64GT;
1725         }
1726
1727         if (default_pll)
1728                 pll = default_pll;
1729         if (default_mclk)
1730                 mclk = default_mclk;
1731
1732         printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
1733                info->fix.smem_len ==
1734                0x80000 ? 512 : (info->fix.smem_len >> 20),
1735                info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname,
1736                xtal, pll, mclk);
1737
1738         if (mclk < 44)
1739                 par->mem_refresh_rate = 0;      /* 000 = 10 Mhz - 43 Mhz */
1740         else if (mclk < 50)
1741                 par->mem_refresh_rate = 1;      /* 001 = 44 Mhz - 49 Mhz */
1742         else if (mclk < 55)
1743                 par->mem_refresh_rate = 2;      /* 010 = 50 Mhz - 54 Mhz */
1744         else if (mclk < 66)
1745                 par->mem_refresh_rate = 3;      /* 011 = 55 Mhz - 65 Mhz */
1746         else if (mclk < 75)
1747                 par->mem_refresh_rate = 4;      /* 100 = 66 Mhz - 74 Mhz */
1748         else if (mclk < 80)
1749                 par->mem_refresh_rate = 5;      /* 101 = 75 Mhz - 79 Mhz */
1750         else if (mclk < 100)
1751                 par->mem_refresh_rate = 6;      /* 110 = 80 Mhz - 100 Mhz */
1752         else
1753                 par->mem_refresh_rate = 7;      /* 111 = 100 Mhz and above */
1754         par->pll_per = 1000000 / pll;
1755         par->mclk_per = 1000000 / mclk;
1756
1757 #ifdef DEBUG
1758         if (M64_HAS(INTEGRATED)) {
1759                 int i;
1760                 printk
1761                     ("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
1762                      "DSP_CONFIG DSP_ON_OFF\n"
1763                      "%08x %08x %08x %08x     %08x      %08x   %08x\n"
1764                      "PLL", aty_ld_le32(BUS_CNTL, par),
1765                      aty_ld_le32(DAC_CNTL, par), aty_ld_le32(MEM_CNTL,
1766                                                              par),
1767                      aty_ld_le32(EXT_MEM_CNTL, par),
1768                      aty_ld_le32(CRTC_GEN_CNTL, par),
1769                      aty_ld_le32(DSP_CONFIG, par), aty_ld_le32(DSP_ON_OFF,
1770                                                                par));
1771                 for (i = 0; i < 16; i++)
1772                         printk(" %02x", aty_ld_pll(i, par));
1773                 printk("\n");
1774         }
1775 #endif
1776
1777         /*
1778          *  Last page of 8 MB (4 MB on ISA) aperture is MMIO
1779          *  FIXME: we should use the auxiliary aperture instead so we can access
1780          *  the full 8 MB of video RAM on 8 MB boards
1781          */
1782         if (info->fix.smem_len == 0x800000 ||
1783             (par->bus_type == ISA 
1784              && info->fix.smem_len == 0x400000))
1785                 info->fix.smem_len -= GUI_RESERVE;
1786
1787         /* Clear the video memory */
1788         fb_memset((void *) info->screen_base, 0,
1789                   info->fix.smem_len);
1790
1791         info->fbops = &atyfb_ops;
1792         info->pseudo_palette = pseudo_palette;
1793         info->flags = FBINFO_FLAG_DEFAULT;
1794
1795 #ifdef CONFIG_PMAC_BACKLIGHT
1796         if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) {
1797                 /* these bits let the 101 powerbook wake up from sleep -- paulus */
1798                 aty_st_lcd(POWER_MANAGEMENT,
1799                            aty_ld_lcd(POWER_MANAGEMENT, par)
1800                            | (USE_F32KHZ | TRISTATE_MEM_EN), par);
1801         }
1802         if (M64_HAS(MOBIL_BUS))
1803                 register_backlight_controller(&aty_backlight_controller,
1804                                               info, "ati");
1805 #endif                          /* CONFIG_PMAC_BACKLIGHT */
1806
1807 #ifdef MODULE
1808         var = default_var;
1809 #else                           /* !MODULE */
1810         memset(&var, 0, sizeof(var));
1811 #ifdef CONFIG_PPC
1812         if (_machine == _MACH_Pmac) {
1813                 /*
1814                  *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
1815                  *         applies to all Mac video cards
1816                  */
1817                 if (mode_option) {
1818                         if (!mac_find_mode
1819                             (&var, info, mode_option, 8))
1820                                 var = default_var;
1821                 } else {
1822                         if (default_vmode == VMODE_CHOOSE) {
1823                                 if (M64_HAS(G3_PB_1024x768))
1824                                         /* G3 PowerBook with 1024x768 LCD */
1825                                         default_vmode = VMODE_1024_768_60;
1826                                 else if (machine_is_compatible("iMac"))
1827                                         default_vmode = VMODE_1024_768_75;
1828                                 else if (machine_is_compatible
1829                                          ("PowerBook2,1"))
1830                                         /* iBook with 800x600 LCD */
1831                                         default_vmode = VMODE_800_600_60;
1832                                 else
1833                                         default_vmode = VMODE_640_480_67;
1834                                 sense = read_aty_sense(par);
1835                                 printk(KERN_INFO
1836                                        "atyfb: monitor sense=%x, mode %d\n",
1837                                        sense,
1838                                        mac_map_monitor_sense(sense));
1839                         }
1840                         if (default_vmode <= 0
1841                             || default_vmode > VMODE_MAX)
1842                                 default_vmode = VMODE_640_480_60;
1843                         if (default_cmode < CMODE_8
1844                             || default_cmode > CMODE_32)
1845                                 default_cmode = CMODE_8;
1846                         if (mac_vmode_to_var
1847                             (default_vmode, default_cmode, &var))
1848                                 var = default_var;
1849                 }
1850         } else
1851             if (!fb_find_mode
1852                 (&var, info, mode_option, NULL, 0, NULL, 8))
1853                 var = default_var;
1854 #else                           /* !CONFIG_PPC */
1855 #ifdef __sparc__
1856         if (mode_option) {
1857                 if (!fb_find_mode
1858                     (&var, info, mode_option, NULL, 0, NULL, 8))
1859                         var = default_var;
1860         } else
1861                 var = default_var;
1862 #else
1863         if (!fb_find_mode
1864             (&var, info, mode_option, NULL, 0, NULL, 8))
1865                 var = default_var;
1866 #endif                          /* !__sparc__ */
1867 #endif                          /* !CONFIG_PPC */
1868 #endif                          /* !MODULE */
1869         if (noaccel)
1870                 var.accel_flags &= ~FB_ACCELF_TEXT;
1871         else
1872                 var.accel_flags |= FB_ACCELF_TEXT;
1873
1874         if (var.yres == var.yres_virtual) {
1875                 u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2));
1876                 var.yres_virtual =
1877                     ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
1878                 if (var.yres_virtual < var.yres)
1879                         var.yres_virtual = var.yres;
1880         }
1881
1882         if (atyfb_check_var(&var, info)) {
1883                 printk("atyfb: can't set default video mode\n");
1884                 return 0;
1885         }
1886 #ifdef __sparc__
1887         atyfb_save_palette(par, 0);
1888 #endif
1889
1890 #ifdef CONFIG_FB_ATY_CT
1891         if (curblink && M64_HAS(INTEGRATED))
1892                 par->cursor = aty_init_cursor(info);
1893 #endif                          /* CONFIG_FB_ATY_CT */
1894         info->var = var;
1895
1896         fb_alloc_cmap(&info->cmap, 256, 0);
1897
1898         if (register_framebuffer(info) < 0)
1899                 return 0;
1900
1901         fb_list = info;
1902
1903         printk("fb%d: %s frame buffer device on %s\n",
1904                info->node, info->fix.id, name);
1905         return 1;
1906 }
1907
1908 int __init atyfb_init(void)
1909 {
1910 #if defined(CONFIG_PCI)
1911         unsigned long addr, res_start, res_size;
1912         struct atyfb_par *default_par;
1913         struct pci_dev *pdev = NULL;
1914         struct fb_info *info;
1915         int i;
1916 #ifdef __sparc__
1917         extern void (*prom_palette) (int);
1918         extern int con_is_present(void);
1919         struct pcidev_cookie *pcp;
1920         char prop[128];
1921         int node, len, j;
1922         u32 mem, chip_id;
1923
1924         /* Do not attach when we have a serial console. */
1925         if (!con_is_present())
1926                 return -ENXIO;
1927 #else
1928         u16 tmp;
1929 #endif
1930
1931         while ((pdev =
1932                 pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
1933                 if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
1934                         struct resource *rp;
1935
1936                         for (i =
1937                              sizeof(aty_chips) / sizeof(*aty_chips) - 1;
1938                              i >= 0; i--)
1939                                 if (pdev->device == aty_chips[i].pci_id)
1940                                         break;
1941                         if (i < 0)
1942                                 continue;
1943
1944                         info =
1945                             kmalloc(sizeof(struct fb_info), GFP_ATOMIC);
1946                         if (!info) {
1947                                 printk
1948                                     ("atyfb_init: can't alloc fb_info\n");
1949                                 return -ENXIO;
1950                         }
1951                         memset(info, 0, sizeof(struct fb_info));
1952
1953                         default_par =
1954                             kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
1955                         if (!default_par) {
1956                                 printk
1957                                     ("atyfb_init: can't alloc atyfb_par\n");
1958                                 kfree(info);
1959                                 return -ENXIO;
1960                         }
1961                         memset(default_par, 0, sizeof(struct atyfb_par));
1962
1963                         info->fix = atyfb_fix;
1964                         info->par = default_par;
1965
1966                         rp = &pdev->resource[0];
1967                         if (rp->flags & IORESOURCE_IO)
1968                                 rp = &pdev->resource[1];
1969                         addr = rp->start;
1970                         if (!addr)
1971                                 continue;
1972
1973                         res_start = rp->start;
1974                         res_size = rp->end - rp->start + 1;
1975                         if (!request_mem_region
1976                             (res_start, res_size, "atyfb"))
1977                                 continue;
1978
1979 #ifdef __sparc__
1980                         /*
1981                          * Map memory-mapped registers.
1982                          */
1983                         default_par->ati_regbase = addr + 0x7ffc00UL;
1984                         info->fix.mmio_start = addr + 0x7ffc00UL;
1985
1986                         /*
1987                          * Map in big-endian aperture.
1988                          */
1989                         info->screen_base = (char *) (addr + 0x800000UL);
1990                         info->fix.smem_start = addr + 0x800000UL;
1991
1992                         /*
1993                          * Figure mmap addresses from PCI config space.
1994                          * Split Framebuffer in big- and little-endian halfs.
1995                          */
1996                         for (i = 0; i < 6 && pdev->resource[i].start; i++)
1997                                 /* nothing */ ;
1998                         j = i + 4;
1999
2000                         default_par->mmap_map =
2001                             kmalloc(j * sizeof(*default_par->mmap_map),
2002                                     GFP_ATOMIC);
2003                         if (!default_par->mmap_map) {
2004                                 printk
2005                                     ("atyfb_init: can't alloc mmap_map\n");
2006                                 kfree(info);
2007                                 release_mem_region(res_start, res_size);
2008                                 return -ENXIO;
2009                         }
2010                         memset(default_par->mmap_map, 0,
2011                                j * sizeof(*default_par->mmap_map));
2012
2013                         for (i = 0, j = 2;
2014                              i < 6 && pdev->resource[i].start; i++) {
2015                                 struct resource *rp = &pdev->resource[i];
2016                                 int io, breg =
2017                                     PCI_BASE_ADDRESS_0 + (i << 2);
2018                                 unsigned long base;
2019                                 u32 size, pbase;
2020
2021                                 base = rp->start;
2022
2023                                 io = (rp->flags & IORESOURCE_IO);
2024
2025                                 size = rp->end - base + 1;
2026
2027                                 pci_read_config_dword(pdev, breg, &pbase);
2028
2029                                 if (io)
2030                                         size &= ~1;
2031
2032                                 /*
2033                                  * Map the framebuffer a second time, this time without
2034                                  * the braindead _PAGE_IE setting. This is used by the
2035                                  * fixed Xserver, but we need to maintain the old mapping
2036                                  * to stay compatible with older ones...
2037                                  */
2038                                 if (base == addr) {
2039                                         default_par->mmap_map[j].voff =
2040                                             (pbase +
2041                                              0x10000000) & PAGE_MASK;
2042                                         default_par->mmap_map[j].poff =
2043                                             base & PAGE_MASK;
2044                                         default_par->mmap_map[j].size =
2045                                             (size +
2046                                              ~PAGE_MASK) & PAGE_MASK;
2047                                         default_par->mmap_map[j].prot_mask =
2048                                             _PAGE_CACHE;
2049                                         default_par->mmap_map[j].prot_flag =
2050                                             _PAGE_E;
2051                                         j++;
2052                                 }
2053
2054                                 /*
2055                                  * Here comes the old framebuffer mapping with _PAGE_IE
2056                                  * set for the big endian half of the framebuffer...
2057                                  */
2058                                 if (base == addr) {
2059                                         default_par->mmap_map[j].voff =
2060                                             (pbase + 0x800000) & PAGE_MASK;
2061                                         default_par->mmap_map[j].poff =
2062                                             (base + 0x800000) & PAGE_MASK;
2063                                         default_par->mmap_map[j].size = 0x800000;
2064                                         default_par->mmap_map[j].prot_mask =
2065                                             _PAGE_CACHE;
2066                                         default_par->mmap_map[j].prot_flag =
2067                                             _PAGE_E | _PAGE_IE;
2068                                         size -= 0x800000;
2069                                         j++;
2070                                 }
2071
2072                                 default_par->mmap_map[j].voff = pbase & PAGE_MASK;
2073                                 default_par->mmap_map[j].poff = base & PAGE_MASK;
2074                                 default_par->mmap_map[j].size =
2075                                     (size + ~PAGE_MASK) & PAGE_MASK;
2076                                 default_par->mmap_map[j].prot_mask = _PAGE_CACHE;
2077                                 default_par->mmap_map[j].prot_flag = _PAGE_E;
2078                                 j++;
2079                         }
2080
2081                         if (pdev->device != XL_CHIP_ID) {
2082                                 /*
2083                                  * Fix PROMs idea of MEM_CNTL settings...
2084                                  */
2085                                 mem = aty_ld_le32(MEM_CNTL, default_par);
2086                                 chip_id = aty_ld_le32(CONFIG_CHIP_ID, default_par);
2087                                 if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID)
2088                                     && !((chip_id >> 24) & 1)) {
2089                                         switch (mem & 0x0f) {
2090                                         case 3:
2091                                                 mem = (mem & ~(0x0f)) | 2;
2092                                                 break;
2093                                         case 7:
2094                                                 mem = (mem & ~(0x0f)) | 3;
2095                                                 break;
2096                                         case 9:
2097                                                 mem = (mem & ~(0x0f)) | 4;
2098                                                 break;
2099                                         case 11:
2100                                                 mem = (mem & ~(0x0f)) | 5;
2101                                                 break;
2102                                         default:
2103                                                 break;
2104                                         }
2105                                         if ((aty_ld_le32(CONFIG_STAT0, default_par) & 7) >= SDRAM)
2106                                                 mem &= ~(0x00700000);
2107                                 }
2108                                 mem &= ~(0xcf80e000);   /* Turn off all undocumented bits. */
2109                                 aty_st_le32(MEM_CNTL, mem, default_par);
2110                         }
2111
2112                         /*
2113                          * If this is the console device, we will set default video
2114                          * settings to what the PROM left us with.
2115                          */
2116                         node = prom_getchild(prom_root_node);
2117                         node = prom_searchsiblings(node, "aliases");
2118                         if (node) {
2119                                 len =
2120                                     prom_getproperty(node, "screen", prop,
2121                                                      sizeof(prop));
2122                                 if (len > 0) {
2123                                         prop[len] = '\0';
2124                                         node = prom_finddevice(prop);
2125                                 } else {
2126                                         node = 0;
2127                                 }
2128                         }
2129
2130                         pcp = pdev->sysdata;
2131                         if (node == pcp->prom_node) {
2132
2133                                 struct fb_var_screeninfo *var =
2134                                     &default_var;
2135                                 unsigned int N, P, Q, M, T, R;
2136                                 u32 v_total, h_total;
2137                                 struct crtc crtc;
2138                                 u8 pll_regs[16];
2139                                 u8 clock_cntl;
2140
2141                                 crtc.vxres =
2142                                     prom_getintdefault(node, "width",
2143                                                        1024);
2144                                 crtc.vyres =
2145                                     prom_getintdefault(node, "height",
2146                                                        768);
2147                                 var->bits_per_pixel =
2148                                     prom_getintdefault(node, "depth", 8);
2149                                 var->xoffset = var->yoffset = 0;
2150                                 crtc.h_tot_disp =
2151                                     aty_ld_le32(CRTC_H_TOTAL_DISP, default_par);
2152                                 crtc.h_sync_strt_wid =
2153                                     aty_ld_le32(CRTC_H_SYNC_STRT_WID,
2154                                                 default_par);
2155                                 crtc.v_tot_disp =
2156                                     aty_ld_le32(CRTC_V_TOTAL_DISP, default_par);
2157                                 crtc.v_sync_strt_wid =
2158                                     aty_ld_le32(CRTC_V_SYNC_STRT_WID,
2159                                                 default_par);
2160                                 crtc.gen_cntl =
2161                                     aty_ld_le32(CRTC_GEN_CNTL, default_par);
2162                                 aty_crtc_to_var(&crtc, var);
2163
2164                                 h_total = var->xres + var->right_margin +
2165                                     var->hsync_len + var->left_margin;
2166                                 v_total = var->yres + var->lower_margin +
2167                                     var->vsync_len + var->upper_margin;
2168
2169                                 /*
2170                                  * Read the PLL to figure actual Refresh Rate.
2171                                  */
2172                                 clock_cntl = aty_ld_8(CLOCK_CNTL, default_par);
2173                                 /* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
2174                                 for (i = 0; i < 16; i++)
2175                                         pll_regs[i] = aty_ld_pll(i, default_par);
2176
2177                                 /*
2178                                  * PLL Reference Divider M:
2179                                  */
2180                                 M = pll_regs[2];
2181
2182                                 /*
2183                                  * PLL Feedback Divider N (Dependant on CLOCK_CNTL):
2184                                  */
2185                                 N = pll_regs[7 + (clock_cntl & 3)];
2186
2187                                 /*
2188                                  * PLL Post Divider P (Dependant on CLOCK_CNTL):
2189                                  */
2190                                 P = 1 << (pll_regs[6] >>
2191                                           ((clock_cntl & 3) << 1));
2192
2193                                 /*
2194                                  * PLL Divider Q:
2195                                  */
2196                                 Q = N / P;
2197
2198                                 /*
2199                                  * Target Frequency:
2200                                  *
2201                                  *      T * M
2202                                  * Q = -------
2203                                  *      2 * R
2204                                  *
2205                                  * where R is XTALIN (= 14318 or 29498 kHz).
2206                                  */
2207                                 if (pdev->device == XL_CHIP_ID)
2208                                         R = 29498;
2209                                 else
2210                                         R = 14318;
2211
2212                                 T = 2 * Q * R / M;
2213
2214                                 default_var.pixclock = 1000000000 / T;
2215                         }
2216 #else                           /* __sparc__ */
2217
2218                         info->fix.mmio_start = 0x7ff000 + addr;
2219                         default_par->ati_regbase = (unsigned long)
2220                             ioremap(info->fix.mmio_start, 0x1000);
2221
2222                         if (!default_par->ati_regbase) {
2223                                 kfree(default_par);
2224                                 kfree(info);
2225                                 release_mem_region(res_start, res_size);
2226                                 return -ENOMEM;
2227                         }
2228
2229                         info->fix.mmio_start += 0xc00;
2230                         default_par->ati_regbase += 0xc00;
2231
2232                         /*
2233                          * Enable memory-space accesses using config-space
2234                          * command register.
2235                          */
2236                         pci_read_config_word(pdev, PCI_COMMAND, &tmp);
2237                         if (!(tmp & PCI_COMMAND_MEMORY)) {
2238                                 tmp |= PCI_COMMAND_MEMORY;
2239                                 pci_write_config_word(pdev, PCI_COMMAND,
2240                                                       tmp);
2241                         }
2242 #ifdef __BIG_ENDIAN
2243                         /* Use the big-endian aperture */
2244                         addr += 0x800000;
2245 #endif
2246
2247                         /* Map in frame buffer */
2248                         info->fix.smem_start = addr;
2249                         info->screen_base =
2250                             (char *) ioremap(addr, 0x800000);
2251
2252                         if (!info->screen_base) {
2253                                 kfree(info);
2254                                 release_mem_region(res_start, res_size);
2255                                 return -ENXIO;
2256                         }
2257 #endif                          /* __sparc__ */
2258
2259                         if (!aty_init(info, "PCI")) {
2260 #ifdef __sparc__        
2261                                 if (default_par->mmap_map)
2262                                         kfree(default_par->mmap_map);
2263 #endif
2264                                 kfree(info);
2265                                 release_mem_region(res_start, res_size);
2266                                 return -ENXIO;
2267                         }
2268 #ifdef __sparc__
2269                         if (!prom_palette)
2270                                 prom_palette = atyfb_palette;
2271
2272                         /*
2273                          * Add /dev/fb mmap values.
2274                          */
2275                         default_par->mmap_map[0].voff = 0x8000000000000000UL;
2276                         default_par->mmap_map[0].poff =
2277                             (unsigned long) info->screen_base & PAGE_MASK;
2278                         default_par->mmap_map[0].size =
2279                             info->fix.smem_len;
2280                         default_par->mmap_map[0].prot_mask = _PAGE_CACHE;
2281                         default_par->mmap_map[0].prot_flag = _PAGE_E;
2282                         default_par->mmap_map[1].voff =
2283                             default_par->mmap_map[0].voff +
2284                             info->fix.smem_len;
2285                         default_par->mmap_map[1].poff =
2286                             default_par->ati_regbase & PAGE_MASK;
2287                         default_par->mmap_map[1].size = PAGE_SIZE;
2288                         default_par->mmap_map[1].prot_mask = _PAGE_CACHE;
2289                         default_par->mmap_map[1].prot_flag = _PAGE_E;
2290 #endif                          /* __sparc__ */
2291
2292 #ifdef CONFIG_PMAC_PBOOK
2293                         if (first_display == NULL)
2294                                 pmu_register_sleep_notifier(&aty_sleep_notifier);
2295                         default_par->next = first_display;
2296 #endif
2297                 }
2298         }
2299
2300 #elif defined(CONFIG_ATARI)
2301         struct atyfb_par *default_par;
2302         struct fb_info *info;
2303         int m64_num;
2304         u32 clock_r;
2305
2306         for (m64_num = 0; m64_num < mach64_count; m64_num++) {
2307                 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
2308                     !phys_guiregbase[m64_num]) {
2309                         printk
2310                             (" phys_*[%d] parameters not set => returning early. \n",
2311                              m64_num);
2312                         continue;
2313                 }
2314
2315                 info = kmalloc(sizeof(struct fb_info), GFP_ATOMIC);
2316                 if (!info) {
2317                         printk("atyfb_init: can't alloc fb_info\n");
2318                         return -ENOMEM;
2319                 }
2320                 memset(info, 0, sizeof(struct fb_info));
2321
2322                 default_par = kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
2323                 if (!default_par) {
2324                         printk
2325                             ("atyfb_init: can't alloc atyfb_par\n");
2326                         kfree(info);
2327                         return -ENXIO;
2328                 }
2329                 memset(default_par, 0, sizeof(struct atyfb_par));
2330
2331                 info->fix = atyfb_fix;
2332
2333                 /*
2334                  *  Map the video memory (physical address given) to somewhere in the
2335                  *  kernel address space.
2336                  */
2337                 info->screen_base = ioremap(phys_vmembase[m64_num],
2338                                                            phys_size[m64_num]); 
2339                 info->fix.smem_start = (unsigned long)info->screen_base;        /* Fake! */
2340                 default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
2341                                                           0x10000) + 0xFC00ul;
2342                 info->fix.mmio_start = default_par->ati_regbase; /* Fake! */
2343
2344                 aty_st_le32(CLOCK_CNTL, 0x12345678, default_par);
2345                 clock_r = aty_ld_le32(CLOCK_CNTL, default_par);
2346
2347                 switch (clock_r & 0x003F) {
2348                 case 0x12:
2349                         default_par->clk_wr_offset = 3; /*  */
2350                         break;
2351                 case 0x34:
2352                         default_par->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
2353                         break;
2354                 case 0x16:
2355                         default_par->clk_wr_offset = 1; /*  */
2356                         break;
2357                 case 0x38:
2358                         default_par->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
2359                         break;
2360                 }
2361
2362                 if (!aty_init(info, "ISA bus")) {
2363                         kfree(info);
2364                         /* This is insufficient! kernel_map has added two large chunks!! */
2365                         return -ENXIO;
2366                 }
2367         }
2368 #endif                          /* CONFIG_ATARI */
2369         return 0;
2370 }
2371
2372 #ifndef MODULE
2373 int __init atyfb_setup(char *options)
2374 {
2375         char *this_opt;
2376
2377         if (!options || !*options)
2378                 return 0;
2379
2380         while ((this_opt = strsep(&options, ",")) != NULL) {
2381                 if (!strncmp(this_opt, "noblink", 7)) {
2382                         curblink = 0;
2383                 } else if (!strncmp(this_opt, "noaccel", 7)) {
2384                         noaccel = 1;
2385                 } else if (!strncmp(this_opt, "vram:", 5))
2386                         default_vram =
2387                             simple_strtoul(this_opt + 5, NULL, 0);
2388                 else if (!strncmp(this_opt, "pll:", 4))
2389                         default_pll =
2390                             simple_strtoul(this_opt + 4, NULL, 0);
2391                 else if (!strncmp(this_opt, "mclk:", 5))
2392                         default_mclk =
2393                             simple_strtoul(this_opt + 5, NULL, 0);
2394 #ifdef CONFIG_PPC
2395                 else if (!strncmp(this_opt, "vmode:", 6)) {
2396                         unsigned int vmode =
2397                             simple_strtoul(this_opt + 6, NULL, 0);
2398                         if (vmode > 0 && vmode <= VMODE_MAX)
2399                                 default_vmode = vmode;
2400                 } else if (!strncmp(this_opt, "cmode:", 6)) {
2401                         unsigned int cmode =
2402                             simple_strtoul(this_opt + 6, NULL, 0);
2403                         switch (cmode) {
2404                         case 0:
2405                         case 8:
2406                                 default_cmode = CMODE_8;
2407                                 break;
2408                         case 15:
2409                         case 16:
2410                                 default_cmode = CMODE_16;
2411                                 break;
2412                         case 24:
2413                         case 32:
2414                                 default_cmode = CMODE_32;
2415                                 break;
2416                         }
2417                 }
2418 #endif
2419 #ifdef CONFIG_ATARI
2420                 /*
2421                  * Why do we need this silly Mach64 argument?
2422                  * We are already here because of mach64= so its redundant.
2423                  */
2424                 else if (MACH_IS_ATARI
2425                          && (!strncmp(this_opt, "Mach64:", 7))) {
2426                         static unsigned char m64_num;
2427                         static char mach64_str[80];
2428                         strlcpy(mach64_str, this_opt + 7, sizeof(mach64_str));
2429                         if (!store_video_par(mach64_str, m64_num)) {
2430                                 m64_num++;
2431                                 mach64_count = m64_num;
2432                         }
2433                 }
2434 #endif
2435                 else
2436                         mode_option = this_opt;
2437         }
2438         return 0;
2439 }
2440 #endif                          /* !MODULE */
2441
2442 #ifdef CONFIG_ATARI
2443 static int __init store_video_par(char *video_str, unsigned char m64_num)
2444 {
2445         char *p;
2446         unsigned long vmembase, size, guiregbase;
2447
2448         printk("store_video_par() '%s' \n", video_str);
2449
2450         if (!(p = strsep(&video_str, ";")) || !*p)
2451                 goto mach64_invalid;
2452         vmembase = simple_strtoul(p, NULL, 0);
2453         if (!(p = strsep(&video_str, ";")) || !*p)
2454                 goto mach64_invalid;
2455         size = simple_strtoul(p, NULL, 0);
2456         if (!(p = strsep(&video_str, ";")) || !*p)
2457                 goto mach64_invalid;
2458         guiregbase = simple_strtoul(p, NULL, 0);
2459
2460         phys_vmembase[m64_num] = vmembase;
2461         phys_size[m64_num] = size;
2462         phys_guiregbase[m64_num] = guiregbase;
2463         printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
2464                guiregbase);
2465         return 0;
2466
2467       mach64_invalid:
2468         phys_vmembase[m64_num] = 0;
2469         return -1;
2470 }
2471 #endif                          /* CONFIG_ATARI */
2472
2473 /*
2474 #ifdef CONFIG_FB_ATY_CT
2475    * Erase HW Cursor *
2476     if (par->cursor && (info->currcon >= 0))
2477         atyfb_cursor(&fb_display[par->currcon], CM_ERASE,
2478                      par->cursor->pos.x, par->cursor->pos.y);
2479 #endif * CONFIG_FB_ATY_CT *
2480
2481 #ifdef CONFIG_FB_ATY_CT
2482     * Install hw cursor *
2483     if (par->cursor) {
2484         aty_set_cursor_color(info);
2485         aty_set_cursor_shape(info);
2486     }
2487 #endif * CONFIG_FB_ATY_CT */
2488
2489     /*
2490      *  Blank the display.
2491      */
2492
2493 static int atyfb_blank(int blank, struct fb_info *info)
2494 {
2495         struct atyfb_par *par = (struct atyfb_par *) info->par;
2496         u8 gen_cntl;
2497
2498 #ifdef CONFIG_PMAC_BACKLIGHT
2499         if ((_machine == _MACH_Pmac) && blank)
2500                 set_backlight_enable(0);
2501 #endif                          /* CONFIG_PMAC_BACKLIGHT */
2502
2503         gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par);
2504         if (blank > 0)
2505                 switch (blank - 1) {
2506                 case VESA_NO_BLANKING:
2507                         gen_cntl |= 0x40;
2508                         break;
2509                 case VESA_VSYNC_SUSPEND:
2510                         gen_cntl |= 0x8;
2511                         break;
2512                 case VESA_HSYNC_SUSPEND:
2513                         gen_cntl |= 0x4;
2514                         break;
2515                 case VESA_POWERDOWN:
2516                         gen_cntl |= 0x4c;
2517                         break;
2518         } else
2519                 gen_cntl &= ~(0x4c);
2520         aty_st_8(CRTC_GEN_CNTL, gen_cntl, par);
2521
2522 #ifdef CONFIG_PMAC_BACKLIGHT
2523         if ((_machine == _MACH_Pmac) && !blank)
2524                 set_backlight_enable(1);
2525 #endif                          /* CONFIG_PMAC_BACKLIGHT */
2526         return 0;
2527 }
2528
2529     /*
2530      *  Set a single color register. The values supplied are already
2531      *  rounded down to the hardware's capabilities (according to the
2532      *  entries in the var structure). Return != 0 for invalid regno.
2533      */
2534
2535 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2536                            u_int transp, struct fb_info *info)
2537 {
2538         struct atyfb_par *par = (struct atyfb_par *) info->par;
2539         int i, scale;
2540         u32 *pal = info->pseudo_palette;
2541
2542         if (regno > 255)
2543                 return 1;
2544         red >>= 8;
2545         green >>= 8;
2546         blue >>= 8;
2547         i = aty_ld_8(DAC_CNTL, par) & 0xfc;
2548         if (M64_HAS(EXTRA_BRIGHT))
2549                 i |= 0x2;       /*DAC_CNTL|0x2 turns off the extra brightness for gt */
2550         aty_st_8(DAC_CNTL, i, par);
2551         aty_st_8(DAC_MASK, 0xff, par);
2552         scale = (M64_HAS(INTEGRATED) && info->var.bits_per_pixel == 16) ? 3 : 0;
2553 #ifdef CONFIG_ATARI
2554         out_8(&par->aty_cmap_regs->windex, regno << scale);
2555         out_8(&par->aty_cmap_regs->lut, red);
2556         out_8(&par->aty_cmap_regs->lut, green);
2557         out_8(&par->aty_cmap_regs->lut, blue);
2558 #else
2559         writeb(regno << scale, &par->aty_cmap_regs->windex);
2560         writeb(red, &par->aty_cmap_regs->lut);
2561         writeb(green, &par->aty_cmap_regs->lut);
2562         writeb(blue, &par->aty_cmap_regs->lut);
2563 #endif
2564         if (regno < 16)
2565                 switch (info->var.bits_per_pixel) {
2566                 case 16:
2567                         pal[regno] = (regno << 10) | (regno << 5) | regno;
2568                         break;
2569                 case 24:
2570                         pal[regno] = (regno << 16) | (regno << 8) | regno;
2571                         break;
2572                 case 32:
2573                         i = (regno << 8) | regno;
2574                         pal[regno] = (i << 16) | i;
2575                         break;
2576                 }
2577         return 0;
2578 }
2579
2580 #ifdef MODULE
2581 int __init init_module(void)
2582 {
2583         atyfb_init();
2584         return fb_list ? 0 : -ENXIO;
2585 }
2586
2587 void cleanup_module(void)
2588 {
2589         struct fb_info *info = fb_list;
2590         struct atyfb_par *par = (struct atyfb_par *) info->par;         
2591         unregister_framebuffer(info);
2592
2593 #ifndef __sparc__
2594         if (par->ati_regbase)
2595                 iounmap((void *) par->ati_regbase);
2596         if (info->screen_base)
2597                 iounmap((void *) info->screen_base);
2598 #ifdef __BIG_ENDIAN
2599         if (par->cursor && par->cursor->ram)
2600                 iounmap(par->cursor->ram);
2601 #endif
2602 #endif
2603         if (par->cursor)
2604                 kfree(par->cursor);
2605 #ifdef __sparc__
2606         if (par->mmap_map)
2607                 kfree(par->mmap_map);
2608 #endif
2609         kfree(info);
2610 }
2611
2612 #endif
2613 MODULE_LICENSE("GPL");