File: /usr/src/linux/drivers/video/aty128fb.c

1     /* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $
2      *  linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128
3      *
4      *  Copyright (C) 1999-2000, Brad Douglas <brad@neruo.com>
5      *  Copyright (C) 1999, Anthony Tong <atong@uiuc.edu>
6      *
7      *                Ani Joshi / Jeff Garzik
8      *                      - Code cleanup
9      *
10      *  Based off of Geert's atyfb.c and vfb.c.
11      *
12      *  TODO:
13      *		- panning
14      *		- monitor sensing (DDC)
15      *              - virtual display
16      *		- other platform support (only ppc/x86 supported)
17      *		- hardware cursor support
18      *		- ioctl()'s
19      *
20      *    Please cc: your patches to brad@neruo.com.
21      */
22     
23     /*
24      * A special note of gratitude to ATI's devrel for providing documentation,
25      * example code and hardware. Thanks Nitya.	-atong and brad
26      */
27     
28     
29     #include <linux/config.h>
30     #include <linux/module.h>
31     #include <linux/kernel.h>
32     #include <linux/errno.h>
33     #include <linux/string.h>
34     #include <linux/mm.h>
35     #include <linux/tty.h>
36     #include <linux/slab.h>
37     #include <linux/vmalloc.h>
38     #include <linux/delay.h>
39     #include <linux/interrupt.h>
40     #include <asm/uaccess.h>
41     #include <linux/fb.h>
42     #include <linux/init.h>
43     #include <linux/selection.h>
44     #include <linux/console.h>
45     #include <linux/pci.h>
46     #include <linux/ioport.h>
47     #include <asm/io.h>
48     
49     #ifdef CONFIG_PPC
50     #include <asm/prom.h>
51     #include <asm/pci-bridge.h>
52     #include <video/macmodes.h>
53     #ifdef CONFIG_NVRAM
54     #include <linux/nvram.h>
55     #endif
56     #endif
57     
58     #ifdef CONFIG_ADB_PMU
59     #include <linux/adb.h>
60     #include <linux/pmu.h>
61     #endif
62     
63     #ifdef CONFIG_PMAC_BACKLIGHT
64     #include <asm/backlight.h>
65     #endif
66     
67     #ifdef CONFIG_FB_COMPAT_XPMAC
68     #include <asm/vc_ioctl.h>
69     #endif
70     
71     #include <video/fbcon.h>
72     #include <video/fbcon-cfb8.h>
73     #include <video/fbcon-cfb16.h>
74     #include <video/fbcon-cfb24.h>
75     #include <video/fbcon-cfb32.h>
76     
77     #ifdef CONFIG_MTRR
78     #include <asm/mtrr.h>
79     #endif
80     
81     #include "aty128.h"
82     
83     /* Debug flag */
84     #undef DEBUG
85     
86     #ifdef DEBUG
87     #define DBG(fmt, args...)		printk(KERN_DEBUG "aty128fb: %s " fmt, __FUNCTION__, ##args);
88     #else
89     #define DBG(fmt, args...)
90     #endif
91     
92     #ifndef CONFIG_PPC
93     /* default mode */
94     static struct fb_var_screeninfo default_var __initdata = {
95         /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
96         640, 480, 640, 480, 0, 0, 8, 0,
97         {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
98         0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
99         0, FB_VMODE_NONINTERLACED
100     };
101     
102     #else /* CONFIG_PPC */
103     /* default to 1024x768 at 75Hz on PPC - this will work
104      * on the iMac, the usual 640x480 @ 60Hz doesn't. */
105     static struct fb_var_screeninfo default_var = {
106         /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
107         1024, 768, 1024, 768, 0, 0, 8, 0,
108         {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
109         0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3,
110         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
111     };
112     #endif /* CONFIG_PPC */
113     
114     /* default modedb mode */
115     /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
116     static struct fb_videomode defaultmode __initdata = {
117     	refresh:	60,
118     	xres:		640,
119     	yres:		480,
120     	pixclock:	39722,
121     	left_margin:	48,
122     	right_margin:	16,
123     	upper_margin:	33,
124     	lower_margin:	10,
125     	hsync_len:	96,
126     	vsync_len:	2,
127     	sync:		0,
128     	vmode:		FB_VMODE_NONINTERLACED
129     };
130     
131     /* struct to hold chip description information */
132     struct aty128_chip_info {
133         const char *name;
134         unsigned short device;
135         int chip_gen;
136     };
137     
138     /* Chip generations */
139     enum {
140     	rage_128,
141     	rage_128_pro,
142     	rage_M3
143     };
144     
145     /* supported Rage128 chipsets */
146     static const struct aty128_chip_info aty128_pci_probe_list[] __initdata =
147     {
148         {"Rage128 RE (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RE, rage_128},
149         {"Rage128 RF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RF, rage_128},
150         {"Rage128 RK (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RK, rage_128},
151         {"Rage128 RL (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RL, rage_128},
152         {"Rage128 Pro PF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_PF, rage_128_pro},
153         {"Rage128 Pro PR (PCI)", PCI_DEVICE_ID_ATI_RAGE128_PR, rage_128_pro},
154         {"Rage Mobility M3 (PCI)", PCI_DEVICE_ID_ATI_RAGE128_LE, rage_M3},
155         {"Rage Mobility M3 (AGP)", PCI_DEVICE_ID_ATI_RAGE128_LF, rage_M3},
156         {NULL, 0, rage_128}
157      };
158     
159     /* packed BIOS settings */
160     #ifndef CONFIG_PPC
161     typedef struct {
162     	u8 clock_chip_type;
163     	u8 struct_size;
164     	u8 accelerator_entry;
165     	u8 VGA_entry;
166     	u16 VGA_table_offset;
167     	u16 POST_table_offset;
168     	u16 XCLK;
169     	u16 MCLK;
170     	u8 num_PLL_blocks;
171     	u8 size_PLL_blocks;
172     	u16 PCLK_ref_freq;
173     	u16 PCLK_ref_divider;
174     	u32 PCLK_min_freq;
175     	u32 PCLK_max_freq;
176     	u16 MCLK_ref_freq;
177     	u16 MCLK_ref_divider;
178     	u32 MCLK_min_freq;
179     	u32 MCLK_max_freq;
180     	u16 XCLK_ref_freq;
181     	u16 XCLK_ref_divider;
182     	u32 XCLK_min_freq;
183     	u32 XCLK_max_freq;
184     } __attribute__ ((packed)) PLL_BLOCK;
185     #endif /* !CONFIG_PPC */
186     
187     /* onboard memory information */
188     struct aty128_meminfo {
189         u8 ML;
190         u8 MB;
191         u8 Trcd;
192         u8 Trp;
193         u8 Twr;
194         u8 CL;
195         u8 Tr2w;
196         u8 LoopLatency;
197         u8 DspOn;
198         u8 Rloop;
199         const char *name;
200     };
201     
202     /* various memory configurations */
203     static const struct aty128_meminfo sdr_128   =
204         { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
205     static const struct aty128_meminfo sdr_64    =
206         { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
207     static const struct aty128_meminfo sdr_sgram =
208         { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
209     static const struct aty128_meminfo ddr_sgram =
210         { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
211     
212     static const char *aty128fb_name = "ATY Rage128";
213     static char fontname[40] __initdata = { 0 };
214     
215     static int  noaccel __initdata = 0;
216     static char *font __initdata = NULL;
217     static char *mode __initdata = NULL;
218     static int  nomtrr __initdata = 0;
219     
220     static const char *mode_option __initdata = NULL;
221     
222     #ifdef CONFIG_PPC
223     static int default_vmode __initdata = VMODE_1024_768_60;
224     static int default_cmode __initdata = CMODE_8;
225     #endif
226     
227     #ifdef CONFIG_MTRR
228     static int mtrr = 1;
229     #endif
230     
231     /* PLL constants */
232     struct aty128_constants {
233         u32 dotclock;
234         u32 ppll_min;
235         u32 ppll_max;
236         u32 ref_divider;
237         u32 xclk;
238         u32 fifo_width;
239         u32 fifo_depth;
240     };
241     
242     struct aty128_crtc {
243         u32 gen_cntl;
244         u32 ext_cntl;
245         u32 h_total, h_sync_strt_wid;
246         u32 v_total, v_sync_strt_wid;
247         u32 pitch;
248         u32 offset, offset_cntl;
249         u32 xoffset, yoffset;
250         u32 vxres, vyres;
251         u32 bpp;
252     };
253     
254     struct aty128_pll {
255         u32 post_divider;
256         u32 feedback_divider;
257         u32 vclk;
258     };
259     
260     struct aty128_ddafifo {
261         u32 dda_config;
262         u32 dda_on_off;
263     };
264     
265     /* register values for a specific mode */
266     struct aty128fb_par {
267         struct aty128_crtc crtc;
268         struct aty128_pll pll;
269         struct aty128_ddafifo fifo_reg;
270         u32 accel_flags;
271     };
272     
273     struct fb_info_aty128 {
274         struct fb_info fb_info;
275         struct fb_info_aty128 *next;
276         struct aty128_constants constants;  /* PLL and others      */
277         unsigned long regbase_phys;         /* physical mmio       */
278         void *regbase;                      /* remapped mmio       */
279         unsigned long frame_buffer_phys;    /* physical fb memory  */
280         void *frame_buffer;                 /* remaped framebuffer */
281         u32 vram_size;                      /* onboard video ram   */
282         int chip_gen;
283         const struct aty128_meminfo *mem;   /* onboard mem info    */
284         struct aty128fb_par default_par, current_par;
285         struct display disp;
286         struct { u8 red, green, blue, pad; } palette[256];
287         union {
288     #ifdef FBCON_HAS_CFB16
289         u16 cfb16[16];
290     #endif
291     #ifdef FBCON_HAS_CFB24
292         u32 cfb24[16];
293     #endif
294     #ifdef FBCON_HAS_CFB32
295         u32 cfb32[16];
296     #endif
297         } fbcon_cmap;
298     #ifdef CONFIG_PCI
299         struct pci_dev *pdev;
300     #endif
301     #ifdef CONFIG_MTRR
302         struct { int vram; int vram_valid; } mtrr;
303     #endif
304         int currcon;
305         int blitter_may_be_busy;
306         int fifo_slots;                 /* free slots in FIFO (64 max) */
307     };
308     
309     static struct fb_info_aty128 *board_list = NULL;
310     
311     #define round_div(n, d) ((n+(d/2))/d)
312     
313         /*
314          *  Interface used by the world
315          */
316     
317     int aty128fb_setup(char *options);
318     
319     static int aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con,
320     		       struct fb_info *info);
321     static int aty128fb_get_var(struct fb_var_screeninfo *var, int con,
322     		       struct fb_info *info);
323     static int aty128fb_set_var(struct fb_var_screeninfo *var, int con,
324     		       struct fb_info *info);
325     static int aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
326     			struct fb_info *info);
327     static int aty128fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
328     			struct fb_info *info);
329     static int aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
330     			   struct fb_info *fb);
331     static int aty128fb_rasterimg(struct fb_info *info, int start);
332     
333     
334         /*
335          *  Interface to the low level console driver
336          */
337     
338     int aty128fb_init(void);
339     static int aty128fbcon_switch(int con, struct fb_info *fb);
340     static void aty128fbcon_blank(int blank, struct fb_info *fb);
341     
342         /*
343          *  Internal routines
344          */
345     
346     static void aty128_encode_fix(struct fb_fix_screeninfo *fix,
347     				struct aty128fb_par *par,
348     				const struct fb_info_aty128 *info);
349     static void aty128_set_dispsw(struct display *disp,
350     			struct fb_info_aty128 *info, int bpp, int accel);
351     static int aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
352     				u_int *transp, struct fb_info *info);
353     static int aty128_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
354     				u_int transp, struct fb_info *info);
355     static void do_install_cmap(int con, struct fb_info *info);
356     static int aty128_encode_var(struct fb_var_screeninfo *var,
357                                  const struct aty128fb_par *par,
358                                  const struct fb_info_aty128 *info);
359     static int aty128_decode_var(struct fb_var_screeninfo *var,
360                                  struct aty128fb_par *par,
361                                  const struct fb_info_aty128 *info);
362     static int aty128_pci_register(struct pci_dev *pdev,
363                                    const struct aty128_chip_info *aci);
364     static struct fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128
365     				*board_list, struct fb_info_aty128 *new_node);
366     #if !defined(CONFIG_PPC) && !defined(__sparc__)
367     static void __init aty128_get_pllinfo(struct fb_info_aty128 *info,
368     			char *bios_seg);
369     static char __init *aty128find_ROM(struct fb_info_aty128 *info);
370     #endif
371     static void aty128_timings(struct fb_info_aty128 *info);
372     static void aty128_init_engine(const struct aty128fb_par *par, 
373     				struct fb_info_aty128 *info);
374     static void aty128_reset_engine(const struct fb_info_aty128 *info);
375     static void aty128_flush_pixel_cache(const struct fb_info_aty128 *info);
376     static void do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
377     static void wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
378     static void wait_for_idle(struct fb_info_aty128 *info);
379     static u32 bpp_to_depth(u32 bpp);
380     
381     #ifdef FBCON_HAS_CFB8
382     static struct display_switch fbcon_aty128_8;
383     static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
384                                 int c, int yy, int xx);
385     static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
386                                  const unsigned short *s, int count,
387                                  int yy, int xx);
388     #endif
389     #ifdef FBCON_HAS_CFB16
390     static struct display_switch fbcon_aty128_16;
391     static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
392                                 int c, int yy, int xx);
393     static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
394                                  const unsigned short *s, int count,
395                                  int yy, int xx);
396     #endif
397     #ifdef FBCON_HAS_CFB24
398     static struct display_switch fbcon_aty128_24;
399     static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
400                                 int c, int yy, int xx);
401     static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
402                                  const unsigned short *s, int count,
403                                  int yy, int xx);
404     #endif
405     #ifdef FBCON_HAS_CFB32
406     static struct display_switch fbcon_aty128_32;
407     static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
408                                 int c, int yy, int xx);
409     static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
410                                  const unsigned short *s, int count,
411                                  int yy, int xx);
412     #endif
413     
414     static struct fb_ops aty128fb_ops = {
415     	owner:		THIS_MODULE,
416     	fb_get_fix:	aty128fb_get_fix,
417     	fb_get_var:	aty128fb_get_var,
418     	fb_set_var:	aty128fb_set_var,
419     	fb_get_cmap:	aty128fb_get_cmap,
420     	fb_set_cmap:	aty128fb_set_cmap,
421     	fb_pan_display:	aty128fb_pan_display,
422     	fb_rasterimg:	aty128fb_rasterimg,
423     };
424     
425     #ifdef CONFIG_PMAC_BACKLIGHT
426     static int aty128_set_backlight_enable(int on, int level, void* data);
427     static int aty128_set_backlight_level(int level, void* data);
428     
429     static struct backlight_controller aty128_backlight_controller = {
430     	aty128_set_backlight_enable,
431     	aty128_set_backlight_level
432     };
433     #endif /* CONFIG_PMAC_BACKLIGHT */
434     
435         /*
436          * Functions to read from/write to the mmio registers
437          *	- endian conversions may possibly be avoided by
438          *    using the other register aperture. TODO.
439          */
440     static inline u32
441     _aty_ld_le32(volatile unsigned int regindex, 
442                                   const struct fb_info_aty128 *info)
443     {
444         u32 val;
445     
446     #if defined(__powerpc__)
447         asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(info->regbase));
448     #else
449         val = readl (info->regbase + regindex);
450     #endif
451     
452         return val;
453     }
454     
455     static inline void
456     _aty_st_le32(volatile unsigned int regindex, u32 val, 
457                                    const struct fb_info_aty128 *info)
458     {
459     #if defined(__powerpc__)
460         asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
461                     "r"(info->regbase) : "memory");
462     #else
463         writel (val, info->regbase + regindex);
464     #endif
465     }
466     
467     static inline u8
468     _aty_ld_8(unsigned int regindex, const struct fb_info_aty128 *info)
469     {
470         return readb (info->regbase + regindex);
471     }
472     
473     static inline void
474     _aty_st_8(unsigned int regindex, u8 val, const struct fb_info_aty128 *info)
475     {
476         writeb (val, info->regbase + regindex);
477     }
478     
479     #define aty_ld_le32(regindex)		_aty_ld_le32(regindex, info)
480     #define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, info)
481     #define aty_ld_8(regindex)		_aty_ld_8(regindex, info)
482     #define aty_st_8(regindex, val)		_aty_st_8(regindex, val, info)
483     
484         /*
485          * Functions to read from/write to the pll registers
486          */
487     
488     #define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, info)
489     #define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, info)
490     
491     
492     static u32
493     _aty_ld_pll(unsigned int pll_index,
494     			const struct fb_info_aty128 *info)
495     {       
496         aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x1F);
497         return aty_ld_le32(CLOCK_CNTL_DATA);
498     }
499     
500         
501     static void
502     _aty_st_pll(unsigned int pll_index, u32 val,
503     			const struct fb_info_aty128 *info)
504     {
505         aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x1F) | PLL_WR_EN);
506         aty_st_le32(CLOCK_CNTL_DATA, val);
507     }
508     
509     
510     /* return true when the PLL has completed an atomic update */
511     static int
512     aty_pll_readupdate(const struct fb_info_aty128 *info)
513     {
514         return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
515     }
516     
517     
518     static void
519     aty_pll_wait_readupdate(const struct fb_info_aty128 *info)
520     {
521         unsigned long timeout = jiffies + HZ/100;	// should be more than enough
522         int reset = 1;
523     
524         while (time_before(jiffies, timeout))
525     	if (aty_pll_readupdate(info)) {
526     	    reset = 0;
527     	    break;
528     	}
529     
530         if (reset)	/* reset engine?? */
531     	printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
532     }
533     
534     
535     /* tell PLL to update */
536     static void
537     aty_pll_writeupdate(const struct fb_info_aty128 *info)
538     {
539         aty_pll_wait_readupdate(info);
540     
541         aty_st_pll(PPLL_REF_DIV,
542     	aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
543     }
544     
545     
546     /* write to the scratch register to test r/w functionality */
547     static int __init
548     register_test(const struct fb_info_aty128 *info)
549     {
550         u32 val;
551         int flag = 0;
552     
553         val = aty_ld_le32(BIOS_0_SCRATCH);
554     
555         aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
556         if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
557     	aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
558     
559     	if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
560     	    flag = 1; 
561         }
562     
563         aty_st_le32(BIOS_0_SCRATCH, val);	// restore value
564         return flag;
565     }
566     
567     
568         /*
569          * Accelerator engine functions
570          */
571     static void
572     do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
573     {
574         int i;
575     
576         for (;;) {
577             for (i = 0; i < 2000000; i++) {
578                 info->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
579                 if (info->fifo_slots >= entries)
580                     return;
581             }
582     	aty128_reset_engine(info);
583         }
584     }
585     
586     
587     static void
588     wait_for_idle(struct fb_info_aty128 *info)
589     {
590         int i;
591     
592         do_wait_for_fifo(64, info);
593     
594         for (;;) {
595             for (i = 0; i < 2000000; i++) {
596                 if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
597                     aty128_flush_pixel_cache(info);
598                     info->blitter_may_be_busy = 0;
599                     return;
600                 }
601             }
602             aty128_reset_engine(info);
603         }
604     }
605     
606     
607     static void
608     wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
609     {
610         if (info->fifo_slots < entries)
611             do_wait_for_fifo(64, info);
612         info->fifo_slots -= entries;
613     }
614     
615     
616     static void
617     aty128_flush_pixel_cache(const struct fb_info_aty128 *info)
618     {
619         int i;
620         u32 tmp;
621     
622         tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
623         tmp &= ~(0x00ff);
624         tmp |= 0x00ff;
625         aty_st_le32(PC_NGUI_CTLSTAT, tmp);
626     
627         for (i = 0; i < 2000000; i++)
628             if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
629                 break;
630     }
631     
632     
633     static void
634     aty128_reset_engine(const struct fb_info_aty128 *info)
635     {
636         u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
637     
638         aty128_flush_pixel_cache(info);
639     
640         clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
641         mclk_cntl = aty_ld_pll(MCLK_CNTL);
642     
643         aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
644     
645         gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
646         aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
647         aty_ld_le32(GEN_RESET_CNTL);
648         aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
649         aty_ld_le32(GEN_RESET_CNTL);
650     
651         aty_st_pll(MCLK_CNTL, mclk_cntl);
652         aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
653         aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
654     
655         /* use old pio mode */
656         aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
657     
658         DBG("engine reset");
659     }
660     
661     
662     static void
663     aty128_init_engine(const struct aty128fb_par *par,
664     		struct fb_info_aty128 *info)
665     {
666         u32 pitch_value;
667     
668         wait_for_idle(info);
669     
670         /* 3D scaler not spoken here */
671         wait_for_fifo(1, info);
672         aty_st_le32(SCALE_3D_CNTL, 0x00000000);
673     
674         aty128_reset_engine(info);
675     
676         pitch_value = par->crtc.pitch;
677         if (par->crtc.bpp == 24) {
678             pitch_value = pitch_value * 3;
679         }
680     
681         wait_for_fifo(4, info);
682         /* setup engine offset registers */
683         aty_st_le32(DEFAULT_OFFSET, 0x00000000);
684     
685         /* setup engine pitch registers */
686         aty_st_le32(DEFAULT_PITCH, pitch_value);
687     
688         /* set the default scissor register to max dimensions */
689         aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
690     
691         /* set the drawing controls registers */
692         aty_st_le32(DP_GUI_MASTER_CNTL,
693     		GMC_SRC_PITCH_OFFSET_DEFAULT		|
694     		GMC_DST_PITCH_OFFSET_DEFAULT		|
695     		GMC_SRC_CLIP_DEFAULT			|
696     		GMC_DST_CLIP_DEFAULT			|
697     		GMC_BRUSH_SOLIDCOLOR			|
698     		(bpp_to_depth(par->crtc.bpp) << 8)	|
699     		GMC_SRC_DSTCOLOR			|
700     		GMC_BYTE_ORDER_MSB_TO_LSB		|
701     		GMC_DP_CONVERSION_TEMP_6500		|
702     		ROP3_PATCOPY				|
703     		GMC_DP_SRC_RECT				|
704     		GMC_3D_FCN_EN_CLR			|
705     		GMC_DST_CLR_CMP_FCN_CLEAR		|
706     		GMC_AUX_CLIP_CLEAR			|
707     		GMC_WRITE_MASK_SET);
708     
709         wait_for_fifo(8, info);
710         /* clear the line drawing registers */
711         aty_st_le32(DST_BRES_ERR, 0);
712         aty_st_le32(DST_BRES_INC, 0);
713         aty_st_le32(DST_BRES_DEC, 0);
714     
715         /* set brush color registers */
716         aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
717         aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
718     
719         /* set source color registers */
720         aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF);   /* white */
721         aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000);   /* black */
722     
723         /* default write mask */
724         aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
725     
726         /* Wait for all the writes to be completed before returning */
727         wait_for_idle(info);
728     }
729     
730     
731     /* convert bpp values to their register representation */
732     static u32
733     bpp_to_depth(u32 bpp)
734     {
735         if (bpp <= 8)
736     	return DST_8BPP;
737         else if (bpp <= 16)
738             return DST_15BPP;
739         else if (bpp <= 24)
740     	return DST_24BPP;
741         else if (bpp <= 32)
742     	return DST_32BPP;
743     
744         return -EINVAL;
745     }
746     
747     
748         /*
749          * CRTC programming
750          */
751     
752     /* Program the CRTC registers */
753     static void
754     aty128_set_crtc(const struct aty128_crtc *crtc,
755     		const struct fb_info_aty128 *info)
756     {
757         aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
758         aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
759         aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
760         aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
761         aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
762         aty_st_le32(CRTC_PITCH, crtc->pitch);
763         aty_st_le32(CRTC_OFFSET, crtc->offset);
764         aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
765         /* Disable ATOMIC updating.  Is this the right place?
766          * -- BenH: Breaks on my G4
767          */
768     #if 0
769         aty_st_le32(PPLL_CNTL, aty_ld_le32(PPLL_CNTL) & ~(0x00030000));
770     #endif
771     }
772     
773     
774     static int
775     aty128_var_to_crtc(const struct fb_var_screeninfo *var,
776     			struct aty128_crtc *crtc,
777     			const struct fb_info_aty128 *info)
778     {
779         u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
780         u32 left, right, upper, lower, hslen, vslen, sync, vmode;
781         u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;
782         u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
783         u32 depth, bytpp;
784         u8 hsync_strt_pix[5] = { 0, 0x12, 9, 6, 5 };
785         u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
786     
787         /* input */
788         xres = var->xres;
789         yres = var->yres;
790         vxres   = var->xres_virtual;
791         vyres   = var->yres_virtual;
792         xoffset = var->xoffset;
793         yoffset = var->yoffset;
794         bpp   = var->bits_per_pixel;
795         left  = var->left_margin;
796         right = var->right_margin;
797         upper = var->upper_margin;
798         lower = var->lower_margin;
799         hslen = var->hsync_len;
800         vslen = var->vsync_len;
801         sync  = var->sync;
802         vmode = var->vmode;
803     
804         /* check for mode eligibility
805          * accept only non interlaced modes */
806         if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
807     	return -EINVAL;
808     
809         /* convert (and round up) and validate */
810         xres = (xres + 7) & ~7;
811         xoffset = (xoffset + 7) & ~7;
812     
813         if (vxres < xres + xoffset)
814     	vxres = xres + xoffset;
815     
816         if (vyres < yres + yoffset)
817     	vyres = yres + yoffset;
818     
819         /* convert bpp into ATI register depth */
820         depth = bpp_to_depth(bpp);
821     
822         /* make sure we didn't get an invalid depth */
823         if (depth == -EINVAL) {
824             printk(KERN_ERR "aty128fb: Invalid depth\n");
825             return -EINVAL;
826         }
827     
828         /* convert depth to bpp */
829         bytpp = mode_bytpp[depth];
830     
831         /* make sure there is enough video ram for the mode */
832         if ((u32)(vxres * vyres * bytpp) > info->vram_size) {
833             printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
834             return -EINVAL;
835         }
836     
837         h_disp = (xres >> 3) - 1;
838         h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
839     
840         v_disp = yres - 1;
841         v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
842     
843         /* check to make sure h_total and v_total are in range */
844         if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
845             printk(KERN_ERR "aty128fb: invalid width ranges\n");
846             return -EINVAL;
847         }
848     
849         h_sync_wid = (hslen + 7) >> 3;
850         if (h_sync_wid == 0)
851     	h_sync_wid = 1;
852         else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */
853     	h_sync_wid = 0x3f;
854     
855         h_sync_strt = h_disp + (right >> 3);
856     
857         v_sync_wid = vslen;
858         if (v_sync_wid == 0)
859     	v_sync_wid = 1;
860         else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */
861     	v_sync_wid = 0x1f;
862         
863         v_sync_strt = v_disp + lower;
864     
865         h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
866         v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
867         
868         c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
869     
870         crtc->gen_cntl = 0x3000000L | c_sync | (depth << 8);
871     
872         crtc->h_total = h_total | (h_disp << 16);
873         crtc->v_total = v_total | (v_disp << 16);
874     
875         crtc->h_sync_strt_wid = hsync_strt_pix[bytpp] | (h_sync_strt << 3) |
876                     (h_sync_wid << 16) | (h_sync_pol << 23);
877         crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
878                     (v_sync_pol << 23);
879     
880         crtc->pitch = vxres >> 3;
881     
882         crtc->offset = 0;
883         crtc->offset_cntl = 0;
884     
885         crtc->vxres = vxres;
886         crtc->vyres = vyres;
887         crtc->xoffset = xoffset;
888         crtc->yoffset = yoffset;
889         crtc->bpp = bpp;
890     
891         return 0;
892     }
893     
894     
895     static int
896     aty128_bpp_to_var(int pix_width, struct fb_var_screeninfo *var)
897     {
898     
899         /* fill in pixel info */
900         switch (pix_width) {
901         case CRTC_PIX_WIDTH_8BPP:
902             var->bits_per_pixel = 8;
903     	var->red.offset = 0;
904     	var->red.length = 8;
905     	var->green.offset = 0;
906     	var->green.length = 8;
907     	var->blue.offset = 0;
908     	var->blue.length = 8;
909     	var->transp.offset = 0;
910     	var->transp.length = 0;
911     	break;
912         case CRTC_PIX_WIDTH_15BPP:
913         case CRTC_PIX_WIDTH_16BPP:
914     	var->bits_per_pixel = 16;
915     	var->red.offset = 10;
916     	var->red.length = 5;
917     	var->green.offset = 5;
918     	var->green.length = 5;
919     	var->blue.offset = 0;
920     	var->blue.length = 5;
921     	var->transp.offset = 0;
922     	var->transp.length = 0;
923     	break;
924         case CRTC_PIX_WIDTH_24BPP:
925             var->bits_per_pixel = 24;
926             var->red.offset = 16;
927             var->red.length = 8;
928             var->green.offset = 8;
929             var->green.length = 8;
930             var->blue.offset = 0;
931             var->blue.length = 8;
932             var->transp.offset = 0;
933             var->transp.length = 0;
934             break;
935         case CRTC_PIX_WIDTH_32BPP:
936             var->bits_per_pixel = 32;
937     	var->red.offset = 16;
938     	var->red.length = 8;
939     	var->green.offset = 8;
940     	var->green.length = 8;
941     	var->blue.offset = 0;
942     	var->blue.length = 8;
943     	var->transp.offset = 24;
944     	var->transp.length = 8;
945     	break;
946         default:
947             printk(KERN_ERR "aty128fb: Invalid pixel width\n");
948             return -EINVAL;
949         }
950     
951         return 0;
952     }
953     
954     
955     static int
956     aty128_crtc_to_var(const struct aty128_crtc *crtc,
957     			struct fb_var_screeninfo *var)
958     {
959         u32 xres, yres, left, right, upper, lower, hslen, vslen, sync;
960         u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
961         u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
962         u32 pix_width;
963     
964         /* fun with masking */
965         h_total     = crtc->h_total & 0x1ff;
966         h_disp      = (crtc->h_total >> 16) & 0xff;
967         h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
968         h_sync_dly  = crtc->h_sync_strt_wid & 0x7;
969         h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;
970         h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;
971         v_total     = crtc->v_total & 0x7ff;
972         v_disp      = (crtc->v_total >> 16) & 0x7ff;
973         v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
974         v_sync_wid  = (crtc->v_sync_strt_wid >> 16) & 0x1f;
975         v_sync_pol  = (crtc->v_sync_strt_wid >> 23) & 0x1;
976         c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
977         pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
978     
979         /* do conversions */
980         xres  = (h_disp + 1) << 3;
981         yres  = v_disp + 1;
982         left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
983         right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
984         hslen = h_sync_wid << 3;
985         upper = v_total - v_sync_strt - v_sync_wid;
986         lower = v_sync_strt - v_disp;
987         vslen = v_sync_wid;
988         sync  = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
989                 (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
990                 (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
991     
992         aty128_bpp_to_var(pix_width, var);
993     
994         var->xres = xres;
995         var->yres = yres;
996         var->xres_virtual = crtc->vxres;
997         var->yres_virtual = crtc->vyres;
998         var->xoffset = crtc->xoffset;
999         var->yoffset = crtc->yoffset;
1000         var->left_margin  = left;
1001         var->right_margin = right;
1002         var->upper_margin = upper;
1003         var->lower_margin = lower;
1004         var->hsync_len = hslen;
1005         var->vsync_len = vslen;
1006         var->sync  = sync;
1007         var->vmode = FB_VMODE_NONINTERLACED;
1008     
1009         return 0;
1010     }
1011     
1012     static void
1013     aty128_set_pll(struct aty128_pll *pll, const struct fb_info_aty128 *info)
1014     {
1015         u32 div3;
1016     
1017         unsigned char post_conv[] =	/* register values for post dividers */
1018             { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };
1019     
1020         /* select PPLL_DIV_3 */
1021         aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
1022     
1023         /* reset PLL */
1024         aty_st_pll(PPLL_CNTL,
1025     		aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
1026     
1027         /* write the reference divider */
1028         aty_pll_wait_readupdate(info);
1029         aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider & 0x3ff);
1030         aty_pll_writeupdate(info);
1031     
1032         div3 = aty_ld_pll(PPLL_DIV_3);
1033         div3 &= ~PPLL_FB3_DIV_MASK;
1034         div3 |= pll->feedback_divider;
1035         div3 &= ~PPLL_POST3_DIV_MASK;
1036         div3 |= post_conv[pll->post_divider] << 16;
1037     
1038         /* write feedback and post dividers */
1039         aty_pll_wait_readupdate(info);
1040         aty_st_pll(PPLL_DIV_3, div3);
1041         aty_pll_writeupdate(info);
1042     
1043         aty_pll_wait_readupdate(info);
1044         aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
1045         aty_pll_writeupdate(info);
1046     
1047         /* clear the reset, just in case */
1048         aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
1049     }
1050     
1051     
1052     static int
1053     aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
1054     			const struct fb_info_aty128 *info)
1055     {
1056         const struct aty128_constants c = info->constants;
1057         unsigned char post_dividers[] = {1,2,4,8,3,6,12};
1058         u32 output_freq;
1059         u32 vclk;        /* in .01 MHz */
1060         int i;
1061         u32 n, d;
1062     
1063         vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */
1064     
1065         /* adjust pixel clock if necessary */
1066         if (vclk > c.ppll_max)
1067     	vclk = c.ppll_max;
1068         if (vclk * 12 < c.ppll_min)
1069     	vclk = c.ppll_min/12;
1070     
1071         /* now, find an acceptable divider */
1072         for (i = 0; i < sizeof(post_dividers); i++) {
1073     	output_freq = post_dividers[i] * vclk;
1074     	if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
1075     	    break;
1076         }
1077     
1078         /* calculate feedback divider */
1079         n = c.ref_divider * output_freq;
1080         d = c.dotclock;
1081     
1082         pll->post_divider = post_dividers[i];
1083         pll->feedback_divider = round_div(n, d);
1084         pll->vclk = vclk;
1085     
1086         DBG("post %d feedback %d vlck %d output %d ref_divider %d "
1087     			"vclk_per: %d\n", pll->post_divider,
1088     			pll->feedback_divider, vclk, output_freq,
1089     			c.ref_divider, period_in_ps);
1090     
1091         return 0;
1092     }
1093     
1094     
1095     static int
1096     aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var,
1097     		const struct fb_info_aty128 *info)
1098     {
1099         var->pixclock = 100000000 / pll->vclk;
1100     
1101         return 0;
1102     }
1103     
1104     
1105     static void
1106     aty128_set_fifo(const struct aty128_ddafifo *dsp,
1107     			const struct fb_info_aty128 *info)
1108     {
1109         aty_st_le32(DDA_CONFIG, dsp->dda_config);
1110         aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
1111     }
1112     
1113     
1114     static int
1115     aty128_ddafifo(struct aty128_ddafifo *dsp,
1116     		const struct aty128_pll *pll,
1117     		u32 bpp,
1118     		const struct fb_info_aty128 *info)
1119     {
1120         const struct aty128_meminfo *m = info->mem;
1121         u32 xclk = info->constants.xclk;
1122         u32 fifo_width = info->constants.fifo_width;
1123         u32 fifo_depth = info->constants.fifo_depth;
1124         s32 x, b, p, ron, roff;
1125         u32 n, d;
1126     
1127         /* 15bpp is really 16bpp */
1128         if (bpp == 15)
1129     	bpp = 16;
1130     
1131         n = xclk * fifo_width;
1132         d = pll->vclk * bpp;
1133         x = round_div(n, d);
1134     
1135         ron = 4 * m->MB +
1136     	3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
1137     	2 * m->Trp +
1138     	m->Twr +
1139     	m->CL +
1140     	m->Tr2w +
1141     	x;
1142     
1143         DBG("x %x\n", x);
1144     
1145         b = 0;
1146         while (x) {
1147     	x >>= 1;
1148     	b++;
1149         }
1150         p = b + 1;
1151     
1152         ron <<= (11 - p);
1153     
1154         n <<= (11 - p);
1155         x = round_div(n, d);
1156         roff = x * (fifo_depth - 4);
1157     
1158         if ((ron + m->Rloop) >= roff) {
1159     	printk(KERN_ERR "aty128fb: Mode out of range!\n");
1160     	return -EINVAL;
1161         }
1162     
1163         DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
1164     			p, m->Rloop, x, ron, roff);
1165     
1166         dsp->dda_config = p << 16 | m->Rloop << 20 | x;
1167         dsp->dda_on_off = ron << 16 | roff;
1168     
1169         return 0;
1170     }
1171     
1172     
1173     /*
1174      * This actually sets the video mode.
1175      */
1176     static void
1177     aty128_set_par(struct aty128fb_par *par,
1178     			struct fb_info_aty128 *info)
1179     { 
1180         u32 config;
1181     
1182         info->current_par = *par;
1183         
1184         if (info->blitter_may_be_busy)
1185             wait_for_idle(info);
1186     
1187         /* clear all registers that may interfere with mode setting */
1188         aty_st_le32(OVR_CLR, 0);
1189         aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
1190         aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
1191         aty_st_le32(OV0_SCALE_CNTL, 0);
1192         aty_st_le32(MPP_TB_CONFIG, 0);
1193         aty_st_le32(MPP_GP_CONFIG, 0);
1194         aty_st_le32(SUBPIC_CNTL, 0);
1195         aty_st_le32(VIPH_CONTROL, 0);
1196         aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */
1197         aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */
1198         aty_st_le32(CAP0_TRIG_CNTL, 0);
1199         aty_st_le32(CAP1_TRIG_CNTL, 0);
1200     
1201         aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */
1202     
1203         aty128_set_crtc(&par->crtc, info);
1204         aty128_set_pll(&par->pll, info);
1205         aty128_set_fifo(&par->fifo_reg, info);
1206     
1207         config = aty_ld_le32(CONFIG_CNTL) & ~3;
1208     
1209     #if defined(__BIG_ENDIAN)
1210         if (par->crtc.bpp >= 24)
1211     	config |= 2;	/* make aperture do 32 byte swapping */
1212         else if (par->crtc.bpp > 8)
1213     	config |= 1;	/* make aperture do 16 byte swapping */
1214     #endif
1215     
1216         aty_st_le32(CONFIG_CNTL, config);
1217         aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
1218     
1219         if (par->accel_flags & FB_ACCELF_TEXT)
1220             aty128_init_engine(par, info);
1221     
1222     #ifdef CONFIG_FB_COMPAT_XPMAC
1223         if (!console_fb_info || console_fb_info == &info->fb_info) {
1224             struct fb_var_screeninfo var;
1225             int cmode, vmode;
1226     
1227     	display_info.height = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
1228     	display_info.width = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
1229     	display_info.depth = par->crtc.bpp;
1230     	display_info.pitch = (par->crtc.vxres * par->crtc.bpp) >> 3;
1231             aty128_encode_var(&var, par, info);
1232     	if (mac_var_to_vmode(&var, &vmode, &cmode))
1233     	    display_info.mode = 0;
1234     	else
1235     	    display_info.mode = vmode;
1236     	strcpy(display_info.name, aty128fb_name);
1237     	display_info.fb_address = info->frame_buffer_phys;
1238     	display_info.cmap_adr_address = 0;
1239     	display_info.cmap_data_address = 0;
1240     	display_info.disp_reg_address = info->regbase_phys;
1241         }
1242     #endif /* CONFIG_FB_COMPAT_XPMAC */
1243     }
1244     
1245         /*
1246          *  encode/decode the User Defined Part of the Display
1247          */
1248     
1249     static int
1250     aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par,
1251     			const struct fb_info_aty128 *info)
1252     {
1253         int err;
1254     
1255         if ((err = aty128_var_to_crtc(var, &par->crtc, info)))
1256     	return err;
1257     
1258         if ((err = aty128_var_to_pll(var->pixclock, &par->pll, info)))
1259     	return err;
1260     
1261         if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.bpp, info)))
1262     	return err;
1263     
1264         if (var->accel_flags & FB_ACCELF_TEXT)
1265     	par->accel_flags = FB_ACCELF_TEXT;
1266         else
1267     	par->accel_flags = 0;
1268     
1269         return 0;
1270     }
1271     
1272     
1273     static int
1274     aty128_encode_var(struct fb_var_screeninfo *var,
1275     			const struct aty128fb_par *par,
1276     			const struct fb_info_aty128 *info)
1277     {
1278         int err;
1279     
1280         if ((err = aty128_crtc_to_var(&par->crtc, var)))
1281     	return err;
1282     
1283         if ((err = aty128_pll_to_var(&par->pll, var, info)))
1284     	return err;
1285     
1286         var->red.msb_right = 0;
1287         var->green.msb_right = 0;
1288         var->blue.msb_right = 0;
1289         var->transp.msb_right = 0;
1290     
1291         var->nonstd = 0;
1292         var->activate = 0;
1293     
1294         var->height = -1;
1295         var->width = -1;
1296         var->accel_flags = par->accel_flags;
1297     
1298         return 0;
1299     }           
1300     
1301     
1302         /*
1303          *  Get the User Defined Part of the Display
1304          */
1305     
1306     static int
1307     aty128fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
1308     {
1309         const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
1310     
1311         if (con == -1)
1312     	aty128_encode_var(var, &info->default_par, info); 
1313         else
1314     	*var = fb_display[con].var;
1315         return 0;
1316     }
1317     
1318     
1319         /*
1320          *  Set the User Defined Part of the Display
1321          */
1322     
1323     static int
1324     aty128fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
1325     {
1326         struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
1327         struct aty128fb_par par;
1328         struct display *display;
1329         int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
1330         int accel, err;
1331     
1332         display = (con >= 0) ? &fb_display[con] : fb->disp;
1333     
1334         /* basic (in)sanity checks */
1335         if (!var->xres)
1336             var->xres = 1;
1337         if (!var->yres)
1338             var->yres = 1;
1339         if (var->xres > var->xres_virtual)
1340             var->xres_virtual = var->xres;
1341         if (var->yres > var->yres_virtual)
1342             var->yres_virtual = var->yres;
1343     
1344         switch (var->bits_per_pixel) {
1345             case 0 ... 8:
1346                 var->bits_per_pixel = 8;
1347                 break;
1348             case 9 ... 16:
1349                 var->bits_per_pixel = 16;
1350                 break;
1351             case 17 ... 24:
1352                 var->bits_per_pixel = 24;
1353                 break;
1354             case 25 ... 32:
1355                 var->bits_per_pixel = 32;
1356                 break;
1357             default:
1358                 return -EINVAL;
1359         }
1360     
1361         if ((err = aty128_decode_var(var, &par, info)))
1362     	return err;
1363     
1364         aty128_encode_var(var, &par, info);
1365     
1366         if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
1367     	return 0;
1368     
1369         oldxres = display->var.xres;
1370         oldyres = display->var.yres;
1371         oldvxres = display->var.xres_virtual;
1372         oldvyres = display->var.yres_virtual;
1373         oldbpp = display->var.bits_per_pixel;
1374         oldaccel = display->var.accel_flags;
1375         display->var = *var;
1376         if (oldxres != var->xres || oldyres != var->yres ||
1377     	oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
1378     	oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
1379     
1380     	struct fb_fix_screeninfo fix;
1381     
1382     	aty128_encode_fix(&fix, &par, info);
1383             display->screen_base = info->frame_buffer;
1384     	display->visual = fix.visual;
1385     	display->type = fix.type;
1386     	display->type_aux = fix.type_aux;
1387     	display->ypanstep = fix.ypanstep;
1388     	display->ywrapstep = fix.ywrapstep;
1389     	display->line_length = fix.line_length;
1390     	display->can_soft_blank = 1;
1391     	display->inverse = 0;
1392     
1393     	accel = var->accel_flags & FB_ACCELF_TEXT;
1394             aty128_set_dispsw(display, info, par.crtc.bpp, accel);
1395     
1396     	if (accel)
1397     	    display->scrollmode = SCROLL_YNOMOVE;
1398     	else
1399     	    display->scrollmode = SCROLL_YREDRAW;
1400     
1401     	if (info->fb_info.changevar)
1402     	    (*info->fb_info.changevar)(con);
1403         }
1404     
1405         if (!info->fb_info.display_fg || info->fb_info.display_fg->vc_num == con)
1406     	aty128_set_par(&par, info);
1407     
1408         if (oldbpp != var->bits_per_pixel) {
1409     	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
1410     	    return err;
1411     	do_install_cmap(con, &info->fb_info);
1412         } 
1413     
1414         return 0;
1415     }
1416     
1417     
1418     static void
1419     aty128_set_dispsw(struct display *disp,
1420     			struct fb_info_aty128 *info, int bpp, int accel)
1421     {
1422         switch (bpp) {
1423     #ifdef FBCON_HAS_CFB8
1424         case 8:
1425     	disp->dispsw = accel ? &fbcon_aty128_8 : &fbcon_cfb8;
1426     	break;
1427     #endif
1428     #ifdef FBCON_HAS_CFB16
1429         case 15:
1430         case 16:
1431     	disp->dispsw = accel ? &fbcon_aty128_16 : &fbcon_cfb16;
1432     	disp->dispsw_data = info->fbcon_cmap.cfb16;
1433     	break;
1434     #endif
1435     #ifdef FBCON_HAS_CFB24
1436         case 24:
1437     	disp->dispsw = accel ? &fbcon_aty128_24 : &fbcon_cfb24;
1438     	disp->dispsw_data = info->fbcon_cmap.cfb24;
1439     	break;
1440     #endif
1441     #ifdef FBCON_HAS_CFB32
1442         case 32:
1443     	disp->dispsw = accel ? &fbcon_aty128_32 : &fbcon_cfb32;
1444     	disp->dispsw_data = info->fbcon_cmap.cfb32;
1445     	break;
1446     #endif
1447         default:
1448     	disp->dispsw = &fbcon_dummy;
1449         }
1450     }
1451     
1452     
1453     static void
1454     aty128_encode_fix(struct fb_fix_screeninfo *fix,
1455     			struct aty128fb_par *par,
1456     			const struct fb_info_aty128 *info)
1457     {
1458         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1459         
1460         strcpy(fix->id, aty128fb_name);
1461     
1462         fix->smem_start = (unsigned long)info->frame_buffer_phys;
1463         fix->mmio_start = (unsigned long)info->regbase_phys;
1464     
1465         fix->smem_len = info->vram_size;
1466         fix->mmio_len = 0x1fff;
1467     
1468         fix->type        = FB_TYPE_PACKED_PIXELS;
1469         fix->type_aux    = 0;
1470         fix->line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
1471         fix->visual      = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
1472                                               : FB_VISUAL_DIRECTCOLOR;
1473         fix->ywrapstep = 0;
1474         fix->xpanstep  = 8;
1475         fix->ypanstep  = 1;
1476     
1477         fix->accel = FB_ACCEL_ATI_RAGE128;
1478     
1479         return;
1480     }
1481     
1482     
1483         /*
1484          *  Get the Fixed Part of the Display
1485          */
1486     static int
1487     aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
1488     {
1489         const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
1490         struct aty128fb_par par;
1491     
1492         if (con == -1)
1493     	par = info->default_par;
1494         else
1495     	aty128_decode_var(&fb_display[con].var, &par, info); 
1496     
1497         aty128_encode_fix(fix, &par, info);
1498     
1499         return 0;            
1500     }
1501     
1502     
1503         /*
1504          *  Pan or Wrap the Display
1505          *
1506          *  Not supported (yet!)
1507          */
1508     static int
1509     aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
1510     			   struct fb_info *fb)
1511     {
1512         struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
1513         struct aty128fb_par *par = &info->current_par;
1514         u32 xoffset, yoffset;
1515         u32 offset;
1516         u32 xres, yres;
1517     
1518         xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
1519         yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
1520     
1521         xoffset = (var->xoffset +7) & ~7;
1522         yoffset = var->yoffset;
1523     
1524         if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
1525             return -EINVAL;
1526     
1527         par->crtc.xoffset = xoffset;
1528         par->crtc.yoffset = yoffset;
1529     
1530         offset = ((yoffset * par->crtc.vxres + xoffset) * par->crtc.bpp) >> 6;
1531     
1532         aty_st_le32(CRTC_OFFSET, offset);
1533     
1534         return 0;
1535     }
1536     
1537     
1538         /*
1539          *  Get the Colormap
1540          */
1541     
1542     static int
1543     aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
1544     			struct fb_info *info)
1545     {
1546     #if 1
1547         fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
1548     #else
1549         struct fb_info_aty128 fb = (struct fb_info_aty128 *)info;
1550     
1551         if (con == fb->currcon) /* current console? */
1552     	return fb_get_cmap(cmap, kspc, aty128_getcolreg, info);
1553         else if (fb_display[con].cmap.len) /* non default colormap? */
1554     	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
1555         else {  
1556     	int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 32;
1557     	fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
1558         }
1559     #endif
1560     
1561         return 0;
1562     }
1563     
1564         /*
1565          *  Set the Colormap
1566          */
1567     
1568     static int
1569     aty128fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
1570     			struct fb_info *info)
1571     {
1572         int err;
1573         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;
1574         struct display *disp;  
1575     
1576         if (con >= 0)
1577     	disp = &fb_display[con];
1578         else
1579     	disp = info->disp;
1580     
1581         if (!disp->cmap.len) {      /* no colormap allocated? */
1582             int size = (disp->var.bits_per_pixel <= 8) ? 256 : 32;
1583     	if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
1584     	    return err;
1585         }
1586     
1587         if (con == fb->currcon) /* current console? */
1588     	return fb_set_cmap(cmap, kspc, aty128_setcolreg, info);
1589         else
1590     	fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
1591     
1592         return 0;                
1593     }
1594     
1595     
1596     static int
1597     aty128fb_rasterimg(struct fb_info *info, int start)
1598     {
1599         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;
1600     
1601         if (fb->blitter_may_be_busy)
1602             wait_for_idle(fb);
1603     
1604         return 0;
1605     }
1606     
1607     
1608     int __init
1609     aty128fb_setup(char *options)
1610     {
1611         char *this_opt;
1612     
1613         if (!options || !*options)
1614     	return 0;
1615     
1616         for (this_opt = strtok(options, ","); this_opt;
1617     	 this_opt = strtok(NULL, ",")) {
1618     	if (!strncmp(this_opt, "font:", 5)) {
1619     	    char *p;
1620     	    int i;
1621     	    
1622     	    p = this_opt +5;
1623     	    for (i = 0; i < sizeof(fontname) - 1; i++)
1624     		if (!*p || *p == ' ' || *p == ',')
1625     		    break;
1626     	    memcpy(fontname, this_opt + 5, i);
1627     	    fontname[i] = 0;
1628     	} else if (!strncmp(this_opt, "noaccel", 7)) {
1629     	    noaccel = 1;
1630             }
1631     #ifdef CONFIG_MTRR
1632             else if(!strncmp(this_opt, "nomtrr", 6)) {
1633                 mtrr = 0;
1634             }
1635     #endif
1636     #ifdef CONFIG_PPC
1637             /* vmode and cmode depreciated */
1638     	else if (!strncmp(this_opt, "vmode:", 6)) {
1639                 unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
1640                 if (vmode > 0 && vmode <= VMODE_MAX)
1641                     default_vmode = vmode;
1642             } else if (!strncmp(this_opt, "cmode:", 6)) {
1643                 unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
1644                 switch (cmode) {
1645     	    case 0:
1646     	    case 8:
1647     		default_cmode = CMODE_8;
1648     		break;
1649     	    case 15:
1650     	    case 16:
1651     		default_cmode = CMODE_16;
1652     		break;
1653     	    case 24:
1654     	    case 32:
1655     		default_cmode = CMODE_32;
1656     		break;
1657                 }
1658             }
1659     #endif /* CONFIG_PPC */
1660             else
1661                 mode_option = this_opt;
1662         }
1663         return 0;
1664     }
1665     
1666     
1667         /*
1668          *  Initialisation
1669          */
1670     
1671     static int __init
1672     aty128_init(struct fb_info_aty128 *info, const char *name)
1673     {
1674         struct fb_var_screeninfo var;
1675         u32 dac;
1676         int j, k;
1677         u8 chip_rev;
1678         const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
1679         char *video_card = "Rage128";
1680     
1681         if (!info->vram_size)	/* may have already been probed */
1682     	info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
1683     
1684         /* Get the chip revision */
1685         chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
1686     
1687         /* put a name with the face */
1688         while (aci->name && info->pdev->device != aci->device) { aci++; }
1689         video_card = (char *)aci->name;
1690         info->chip_gen = aci->chip_gen;
1691     
1692         printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
1693     
1694         if (info->vram_size % (1024 * 1024) == 0)
1695     	printk("%dM %s\n", info->vram_size / (1024*1024), info->mem->name);
1696         else
1697     	printk("%dk %s\n", info->vram_size / 1024, info->mem->name);
1698     
1699         /* fill in info */
1700         strcpy(info->fb_info.modename, aty128fb_name);
1701         info->fb_info.node  = -1;
1702         info->fb_info.fbops = &aty128fb_ops;
1703         info->fb_info.disp  = &info->disp;
1704         strcpy(info->fb_info.fontname, fontname);
1705         info->fb_info.changevar  = NULL;
1706         info->fb_info.switch_con = &aty128fbcon_switch;
1707         info->fb_info.updatevar  = NULL;
1708         info->fb_info.blank = &aty128fbcon_blank;
1709         info->fb_info.flags = FBINFO_FLAG_DEFAULT;
1710     
1711         var = default_var;
1712     #ifdef CONFIG_PPC
1713         if (_machine == _MACH_Pmac) {
1714             if (mode_option) {
1715                 if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
1716                     var = default_var;
1717             } else {
1718                 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
1719                     default_vmode = VMODE_1024_768_60;
1720     
1721                 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
1722                     default_cmode = CMODE_8;
1723     
1724                 if (mac_vmode_to_var(default_vmode, default_cmode, &var))
1725                     var = default_var;
1726             }
1727         } else
1728     #endif /* CONFIG_PPC */
1729         {
1730             if (fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0,
1731                               &defaultmode, 8) == 0)
1732                 var = default_var;
1733         }
1734     
1735         if (noaccel)
1736             var.accel_flags &= ~FB_ACCELF_TEXT;
1737         else
1738             var.accel_flags |= FB_ACCELF_TEXT;
1739     
1740         if (aty128_decode_var(&var, &info->default_par, info)) {
1741     	printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
1742     	return 0;
1743         }
1744     
1745         /* load up the palette with default colors */
1746         for (j = 0; j < 16; j++) {
1747             k = color_table[j];
1748             info->palette[j].red = default_red[k];
1749             info->palette[j].green = default_grn[k];
1750             info->palette[j].blue = default_blu[k];
1751         }
1752     
1753         /* setup the DAC the way we like it */
1754         dac = aty_ld_le32(DAC_CNTL);
1755         dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
1756         dac |= DAC_MASK;
1757         aty_st_le32(DAC_CNTL, dac);
1758     
1759         /* turn off bus mastering, just in case */
1760         aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
1761     
1762         aty128fb_set_var(&var, -1, &info->fb_info);
1763         aty128_init_engine(&info->default_par, info);
1764     
1765         board_list = aty128_board_list_add(board_list, info);
1766     
1767         if (register_framebuffer(&info->fb_info) < 0)
1768     	return 0;
1769     
1770     #ifdef CONFIG_PMAC_BACKLIGHT
1771         /* Could be extended to Rage128Pro LVDS output too */
1772         if (info->chip_gen == rage_M3)
1773         	register_backlight_controller(&aty128_backlight_controller, info, "ati");
1774     #endif /* CONFIG_PMAC_BACKLIGHT */
1775     
1776         printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
1777     	   GET_FB_IDX(info->fb_info.node), aty128fb_name, name);
1778     
1779         return 1;	/* success! */
1780     }
1781     
1782     
1783     /* add a new card to the list  ++ajoshi */
1784     static struct
1785     fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list,
1786                                            struct fb_info_aty128 *new_node)
1787     {
1788         struct fb_info_aty128 *i_p = board_list;
1789     
1790         new_node->next = NULL;
1791         if(board_list == NULL)
1792     	return new_node;
1793         while(i_p->next != NULL)
1794     	i_p = i_p->next;
1795         i_p->next = new_node;
1796     
1797         return board_list;
1798     }
1799     
1800     
1801     int __init
1802     aty128fb_init(void)
1803     {
1804     #ifdef CONFIG_PCI
1805         struct pci_dev *pdev = NULL;
1806         const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
1807     
1808         while (aci->name != NULL) {
1809             pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
1810             while (pdev != NULL) {
1811                 if (aty128_pci_register(pdev, aci) == 0)
1812                     return 0;
1813                 pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
1814             }
1815     	aci++;
1816         }
1817     #endif
1818     
1819         return 0;
1820     }
1821     
1822     
1823     #ifdef CONFIG_PCI
1824     /* register a card    ++ajoshi */
1825     static int __init
1826     aty128_pci_register(struct pci_dev *pdev,
1827                                    const struct aty128_chip_info *aci)
1828     {
1829     	struct fb_info_aty128 *info = NULL;
1830     	unsigned long fb_addr, reg_addr;
1831     	int err;
1832     #if !defined(CONFIG_PPC) && !defined(__sparc__)
1833     	char *bios_seg = NULL;
1834     #endif
1835     
1836     	/* Enable device in PCI config */
1837     	if ((err = pci_enable_device(pdev))) {
1838     		printk(KERN_ERR "aty128fb: Cannot enable PCI device: %d\n",
1839     				err);
1840     		goto err_out;
1841     	}
1842     
1843     	fb_addr = pci_resource_start(pdev, 0);
1844     	if (!request_mem_region(fb_addr, pci_resource_len(pdev, 0),
1845     				"aty128fb FB")) {
1846     		printk(KERN_ERR "aty128fb: cannot reserve frame "
1847     				"buffer memory\n");
1848     		goto err_free_fb;
1849     	}
1850     
1851     	reg_addr = pci_resource_start(pdev, 2);
1852     	if (!request_mem_region(reg_addr, pci_resource_len(pdev, 2),
1853     				"aty128fb MMIO")) {
1854     		printk(KERN_ERR "aty128fb: cannot reserve MMIO region\n");
1855     		goto err_free_mmio;
1856     	}
1857     
1858     	/* We have the resources. Now virtualize them */
1859     	if (!(info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC))) {
1860     		printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
1861     		goto err_unmap_out;
1862     	}
1863     	memset(info, 0, sizeof(struct fb_info_aty128));
1864     
1865     	/* Copy PCI device info into info->pdev */
1866     	info->pdev = pdev;
1867     
1868     	info->currcon = -1;
1869     
1870     	/* Virtualize mmio region */
1871     	info->regbase_phys = reg_addr;
1872     	info->regbase = ioremap(reg_addr, 0x1FFF);
1873     
1874     	if (!info->regbase)
1875     		goto err_free_info;
1876     
1877     	/* Grab memory size from the card */
1878     	info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
1879     
1880     	/* Virtualize the framebuffer */
1881     	info->frame_buffer_phys = fb_addr;
1882     	info->frame_buffer = ioremap(fb_addr, info->vram_size);
1883     
1884     	if (!info->frame_buffer) {
1885     		iounmap((void *)info->regbase);
1886     		goto err_free_info;
1887     	}
1888     
1889     	/* If we can't test scratch registers, something is seriously wrong */
1890     	if (!register_test(info)) {
1891     		printk(KERN_ERR "aty128fb: Can't write to video register!\n");
1892     		goto err_out;
1893     	}
1894     
1895     #if !defined(CONFIG_PPC) && !defined(__sparc__)
1896     	if (!(bios_seg = aty128find_ROM(info)))
1897     		printk(KERN_INFO "aty128fb: Rage128 BIOS not located. "
1898     					"Guessing...\n");
1899     	else {
1900     		printk(KERN_INFO "aty128fb: Rage128 BIOS located at "
1901     				"segment %4.4X\n", (unsigned int)bios_seg);
1902     		aty128_get_pllinfo(info, bios_seg);
1903     	}
1904     #endif
1905     	aty128_timings(info);
1906     
1907     	if (!aty128_init(info, "PCI"))
1908     		goto err_out;
1909     
1910     #ifdef CONFIG_MTRR
1911     	if (mtrr) {
1912     		info->mtrr.vram = mtrr_add(info->frame_buffer_phys,
1913     				info->vram_size, MTRR_TYPE_WRCOMB, 1);
1914     		info->mtrr.vram_valid = 1;
1915     		/* let there be speed */
1916     		printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
1917     	}
1918     #endif /* CONFIG_MTRR */
1919     
1920     #ifdef CONFIG_FB_COMPAT_XPMAC
1921         if (!console_fb_info)
1922     	console_fb_info = &info->fb_info;
1923     #endif
1924     
1925     	return 0;
1926     
1927     err_out:
1928     	iounmap(info->frame_buffer);
1929     	iounmap(info->regbase);
1930     err_free_info:
1931     	kfree(info);
1932     err_unmap_out:
1933     	release_mem_region(pci_resource_start(pdev, 2),
1934     			pci_resource_len(pdev, 2));
1935     err_free_mmio:
1936     	release_mem_region(pci_resource_start(pdev, 0),
1937     			pci_resource_len(pdev, 0));
1938     err_free_fb:
1939     	release_mem_region(pci_resource_start(pdev, 1),
1940     			pci_resource_len(pdev, 1));
1941     	return -ENODEV;
1942     }
1943     #endif /* CONFIG_PCI */
1944     
1945     
1946     /* PPC and Sparc cannot read video ROM */
1947     #if !defined(CONFIG_PPC) && !defined(__sparc__)
1948     static char __init
1949     *aty128find_ROM(struct fb_info_aty128 *info)
1950     {
1951     	u32  segstart;
1952     	char *rom_base;
1953     	char *rom;
1954     	int  stage;
1955     	int  i;
1956     	char aty_rom_sig[] = "761295520";   /* ATI ROM Signature      */
1957     	char R128_sig[] = "R128";           /* Rage128 ROM identifier */
1958     
1959     	for (segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
1960             	stage = 1;
1961     
1962     		rom_base = (char *)ioremap(segstart, 0x1000);
1963     
1964     		if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
1965     			stage = 2;
1966     
1967     		if (stage != 2) {
1968     			iounmap(rom_base);
1969     			continue;
1970     		}
1971     		rom = rom_base;
1972     
1973     		for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
1974     			if (aty_rom_sig[0] == *rom)
1975     				if (strncmp(aty_rom_sig, rom,
1976     						strlen(aty_rom_sig)) == 0)
1977     					stage = 3;
1978     			rom++;
1979     		}
1980     		if (stage != 3) {
1981     			iounmap(rom_base);
1982     			continue;
1983     		}
1984     		rom = rom_base;
1985     
1986     		/* ATI signature found.  Let's see if it's a Rage128 */
1987     		for (i = 0; (i < 512) && (stage != 4); i++) {
1988     			if (R128_sig[0] == *rom)
1989     				if (strncmp(R128_sig, rom, 
1990     						strlen(R128_sig)) == 0)
1991     					stage = 4;
1992     			rom++;
1993     		}
1994     		if (stage != 4) {
1995     			iounmap(rom_base);
1996     			continue;
1997     		}
1998     
1999     		return rom_base;
2000     	}
2001     
2002     	return NULL;
2003     }
2004     
2005     
2006     static void __init
2007     aty128_get_pllinfo(struct fb_info_aty128 *info, char *bios_seg)
2008     {
2009     	void *bios_header;
2010     	void *header_ptr;
2011     	u16 bios_header_offset, pll_info_offset;
2012     	PLL_BLOCK pll;
2013     
2014     	bios_header = bios_seg + 0x48L;
2015     	header_ptr  = bios_header;
2016     
2017     	bios_header_offset = readw(header_ptr);
2018     	bios_header = bios_seg + bios_header_offset;
2019     	bios_header += 0x30;
2020     
2021     	header_ptr = bios_header;
2022     	pll_info_offset = readw(header_ptr);
2023     	header_ptr = bios_seg + pll_info_offset;
2024     
2025     	memcpy_fromio(&pll, header_ptr, 50);
2026     
2027     	info->constants.ppll_max = pll.PCLK_max_freq;
2028     	info->constants.ppll_min = pll.PCLK_min_freq;
2029     	info->constants.xclk = (u32)pll.XCLK;
2030     	info->constants.ref_divider = (u32)pll.PCLK_ref_divider;
2031     	info->constants.dotclock = (u32)pll.PCLK_ref_freq;
2032     
2033     	DBG("ppll_max %d ppll_min %d xclk %d ref_divider %d dotclock %d\n",
2034     			info->constants.ppll_max, info->constants.ppll_min,
2035     			info->constants.xclk, info->constants.ref_divider,
2036     			info->constants.dotclock);
2037     
2038     }           
2039     #endif /* !CONFIG_PPC */
2040     
2041     
2042     /* fill in known card constants if pll_block is not available */
2043     static void __init
2044     aty128_timings(struct fb_info_aty128 *info)
2045     {
2046     #ifdef CONFIG_PPC
2047         /* instead of a table lookup, assume OF has properly
2048          * setup the PLL registers and use their values
2049          * to set the XCLK values and reference divider values */
2050     
2051         u32 x_mpll_ref_fb_div;
2052         u32 xclk_cntl;
2053         u32 Nx, M;
2054         unsigned PostDivSet[] =
2055             { 0, 1, 2, 4, 8, 3, 6, 12 };
2056     #endif
2057     
2058         if (!info->constants.dotclock)
2059             info->constants.dotclock = 2950;
2060     
2061     #ifdef CONFIG_PPC
2062         x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
2063         xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
2064         Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
2065         M  = x_mpll_ref_fb_div & 0x0000ff;
2066     
2067         info->constants.xclk = round_div((2 * Nx *
2068             info->constants.dotclock), (M * PostDivSet[xclk_cntl]));
2069     
2070         info->constants.ref_divider =
2071             aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
2072     #endif
2073     
2074         if (!info->constants.ref_divider) {
2075             info->constants.ref_divider = 0x3b;
2076     
2077             aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
2078             aty_pll_writeupdate(info);
2079         }
2080         aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider);
2081         aty_pll_writeupdate(info);
2082     
2083         /* from documentation */
2084         if (!info->constants.ppll_min)
2085             info->constants.ppll_min = 12500;
2086         if (!info->constants.ppll_max)
2087             info->constants.ppll_max = 25000;    /* 23000 on some cards? */
2088         if (!info->constants.xclk)
2089             info->constants.xclk = 0x1d4d;	     /* same as mclk */
2090     
2091         info->constants.fifo_width = 128;
2092         info->constants.fifo_depth = 32;
2093     
2094         switch (aty_ld_le32(MEM_CNTL) & 0x3) {
2095         case 0:
2096     	info->mem = &sdr_128;
2097     	break;
2098         case 1:
2099     	info->mem = &sdr_sgram;
2100     	break;
2101         case 2:
2102     	info->mem = &ddr_sgram;
2103     	break;
2104         default:
2105     	info->mem = &sdr_sgram;
2106         }
2107     }
2108     
2109     
2110     static int
2111     aty128fbcon_switch(int con, struct fb_info *fb)
2112     {
2113         struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
2114         struct aty128fb_par par;
2115     
2116         /* Do we have to save the colormap? */
2117         if (fb_display[info->currcon].cmap.len)
2118         	fb_get_cmap(&fb_display[info->currcon].cmap, 1,
2119     			aty128_getcolreg, fb);
2120     
2121         /* set the current console */
2122         info->currcon = con;
2123     
2124         aty128_decode_var(&fb_display[con].var, &par, info);
2125         aty128_set_par(&par, info);
2126     
2127         aty128_set_dispsw(&fb_display[con], info, par.crtc.bpp,
2128             par.accel_flags & FB_ACCELF_TEXT);
2129     
2130         do_install_cmap(con, fb);
2131     
2132         return 1;
2133     }
2134     
2135     
2136         /*
2137          *  Blank the display.
2138          */
2139     static void
2140     aty128fbcon_blank(int blank, struct fb_info *fb)
2141     {
2142         struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
2143         u8 state = 0;
2144     
2145     #ifdef CONFIG_PMAC_BACKLIGHT
2146         if ((_machine == _MACH_Pmac) && blank)
2147         	set_backlight_enable(0);
2148     #endif /* CONFIG_PMAC_BACKLIGHT */
2149     
2150         if (blank & VESA_VSYNC_SUSPEND)
2151     	state |= 2;
2152         if (blank & VESA_HSYNC_SUSPEND)
2153     	state |= 1;
2154         if (blank & VESA_POWERDOWN)
2155     	state |= 4;
2156     
2157         aty_st_8(CRTC_EXT_CNTL+1, state);
2158     
2159     #ifdef CONFIG_PMAC_BACKLIGHT
2160         if ((_machine == _MACH_Pmac) && !blank)
2161         	set_backlight_enable(1);
2162     #endif /* CONFIG_PMAC_BACKLIGHT */
2163     }
2164     
2165     
2166         /*
2167          *  Read a single color register and split it into
2168          *  colors/transparent. Return != 0 for invalid regno.
2169          */
2170     static int
2171     aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
2172                              u_int *transp, struct fb_info *fb)
2173     {
2174         struct fb_info_aty128 *info = (struct fb_info_aty128 *) fb;
2175     
2176         if (regno > 255)
2177     	return 1;
2178     
2179         *red = (info->palette[regno].red<<8) | info->palette[regno].red;
2180         *green = (info->palette[regno].green<<8) | info->palette[regno].green;
2181         *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
2182         *transp = 0;
2183     
2184         return 0;
2185     }
2186     
2187         /*
2188          *  Set a single color register. The values supplied are already
2189          *  rounded down to the hardware's capabilities (according to the
2190          *  entries in the var structure). Return != 0 for invalid regno.
2191          */
2192     static int
2193     aty128_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
2194                              u_int transp, struct fb_info *fb)
2195     {
2196         struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
2197         u32 col;
2198     
2199         if (regno > 255)
2200     	return 1;
2201     
2202         red >>= 8;
2203         green >>= 8;
2204         blue >>= 8;
2205         info->palette[regno].red = red;
2206         info->palette[regno].green = green;
2207         info->palette[regno].blue = blue;
2208     
2209         /* Note: For now, on M3, we set palette on both heads, which may
2210          * be useless. Can someone with a M3 check this ? */
2211     
2212         /* initialize gamma ramp for hi-color+ */
2213     
2214         if ((info->current_par.crtc.bpp > 8) && (regno == 0)) {
2215             int i;
2216     
2217             if (info->chip_gen == rage_M3)
2218                 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
2219     
2220             for (i=16; i<256; i++) {
2221                 aty_st_8(PALETTE_INDEX, i);
2222                 col = (i << 16) | (i << 8) | i;
2223                 aty_st_le32(PALETTE_DATA, col);
2224             }
2225     
2226             if (info->chip_gen == rage_M3) {
2227                 aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
2228     
2229                 for (i=16; i<256; i++) {
2230                     aty_st_8(PALETTE_INDEX, i);
2231                     col = (i << 16) | (i << 8) | i;
2232                     aty_st_le32(PALETTE_DATA, col);
2233                 }
2234             }
2235         }
2236     
2237         /* initialize palette */
2238     
2239         if (info->chip_gen == rage_M3)
2240             aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
2241     
2242         if (info->current_par.crtc.bpp == 16)
2243             aty_st_8(PALETTE_INDEX, (regno << 3));
2244         else
2245             aty_st_8(PALETTE_INDEX, regno);
2246         col = (red << 16) | (green << 8) | blue;
2247         aty_st_le32(PALETTE_DATA, col);
2248         if (info->chip_gen == rage_M3) {
2249         	aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
2250             if (info->current_par.crtc.bpp == 16)
2251                 aty_st_8(PALETTE_INDEX, (regno << 3));
2252             else
2253                 aty_st_8(PALETTE_INDEX, regno);
2254             aty_st_le32(PALETTE_DATA, col);
2255         }
2256     
2257         if (regno < 16)
2258     	switch (info->current_par.crtc.bpp) {
2259     #ifdef FBCON_HAS_CFB16
2260     	case 9 ... 16:
2261     	    info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
2262                     regno;
2263     	    break;
2264     #endif
2265     #ifdef FBCON_HAS_CFB24
2266     	case 17 ... 24:
2267     	    info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
2268     		regno;
2269     	    break;
2270     #endif
2271     #ifdef FBCON_HAS_CFB32
2272     	case 25 ... 32: {
2273                 u32 i;
2274     
2275                 i = (regno << 8) | regno;
2276                 info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
2277     	    break;
2278             }
2279     #endif
2280     	}
2281         return 0;
2282     }
2283     
2284     
2285     static void
2286     do_install_cmap(int con, struct fb_info *info)
2287     {
2288         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)info;
2289     
2290         if (con != fb->currcon)
2291     	return;
2292     
2293         if (fb_display[con].cmap.len)
2294     	fb_set_cmap(&fb_display[con].cmap, 1, aty128_setcolreg, info);
2295         else {
2296     	int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16;
2297     	fb_set_cmap(fb_default_cmap(size), 1, aty128_setcolreg, info);
2298         }
2299     }
2300     
2301     
2302     #ifdef CONFIG_PMAC_BACKLIGHT
2303     static int backlight_conv[] = {
2304     	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
2305     	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
2306     };
2307     
2308     static int
2309     aty128_set_backlight_enable(int on, int level, void* data)
2310     {
2311     	struct fb_info_aty128 *info = (struct fb_info_aty128 *)data;
2312     	unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
2313     	
2314     	reg |= LVDS_BL_MOD_EN | LVDS_BLON;
2315     	if (on && level > BACKLIGHT_OFF) {
2316     		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
2317     		reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
2318     	} else {
2319     		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
2320     		reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
2321     	}
2322     	aty_st_le32(LVDS_GEN_CNTL, reg);
2323     
2324     	return 0;
2325     }
2326     
2327     static int
2328     aty128_set_backlight_level(int level, void* data)
2329     {
2330     	return aty128_set_backlight_enable(1, level, data);
2331     }
2332     #endif /* CONFIG_PMAC_BACKLIGHT */
2333     
2334         /*
2335          *  Accelerated functions
2336          */
2337     
2338     static inline void
2339     aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
2340     		u_int width, u_int height,
2341     		struct fb_info_aty128 *info)
2342     {
2343         u32 save_dp_datatype, save_dp_cntl, bppval;
2344     
2345         if (!width || !height)
2346             return;
2347     
2348         bppval = bpp_to_depth(info->current_par.crtc.bpp);
2349         if (bppval == DST_24BPP) {
2350             srcx *= 3;
2351             dstx *= 3;
2352             width *= 3;
2353         } else if (bppval == -EINVAL) {
2354             printk("aty128fb: invalid depth\n");
2355             return;
2356         }
2357     
2358         wait_for_fifo(2, info);
2359         save_dp_datatype = aty_ld_le32(DP_DATATYPE);
2360         save_dp_cntl     = aty_ld_le32(DP_CNTL);
2361     
2362         wait_for_fifo(6, info);
2363         aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
2364         aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
2365         aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
2366         aty_st_le32(DP_DATATYPE, save_dp_datatype | bppval | SRC_DSTCOLOR);
2367     
2368         aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
2369         aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
2370     
2371         info->blitter_may_be_busy = 1;
2372     
2373         wait_for_fifo(2, info);
2374         aty_st_le32(DP_DATATYPE, save_dp_datatype);
2375         aty_st_le32(DP_CNTL, save_dp_cntl); 
2376     }
2377     
2378     
2379         /*
2380          * Text mode accelerated functions
2381          */
2382     
2383     static void
2384     fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx,
2385     			int height, int width)
2386     {
2387         sx     *= fontwidth(p);
2388         sy     *= fontheight(p);
2389         dx     *= fontwidth(p);
2390         dy     *= fontheight(p);
2391         width  *= fontwidth(p);
2392         height *= fontheight(p);
2393     
2394         aty128_rectcopy(sx, sy, dx, dy, width, height,
2395     			(struct fb_info_aty128 *)p->fb_info);
2396     }
2397     
2398     
2399     #ifdef FBCON_HAS_CFB8
2400     static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
2401                                 int c, int yy, int xx)
2402     {
2403         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2404     
2405         if (fb->blitter_may_be_busy)
2406             wait_for_idle(fb);
2407     
2408         fbcon_cfb8_putc(conp, p, c, yy, xx);
2409     }
2410     
2411     
2412     static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
2413                                  const unsigned short *s, int count,
2414                                  int yy, int xx)
2415     {
2416         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2417     
2418         if (fb->blitter_may_be_busy)
2419             wait_for_idle(fb);
2420     
2421         fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
2422     }
2423     
2424     
2425     static void fbcon_aty8_clear_margins(struct vc_data *conp,
2426                                          struct display *p, int bottom_only)
2427     {
2428         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2429     
2430         if (fb->blitter_may_be_busy)
2431             wait_for_idle(fb);
2432     
2433         fbcon_cfb8_clear_margins(conp, p, bottom_only);
2434     }
2435     
2436     static struct display_switch fbcon_aty128_8 = {
2437         setup:		fbcon_cfb8_setup,
2438         bmove:		fbcon_aty128_bmove,
2439         clear:		fbcon_cfb8_clear,
2440         putc:		fbcon_aty8_putc,
2441         putcs:		fbcon_aty8_putcs,
2442         revc:		fbcon_cfb8_revc,
2443         clear_margins:	fbcon_aty8_clear_margins,
2444         fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
2445     };
2446     #endif
2447     #ifdef FBCON_HAS_CFB16
2448     static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
2449                                 int c, int yy, int xx)
2450     {
2451         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2452     
2453         if (fb->blitter_may_be_busy)
2454             wait_for_idle(fb);
2455     
2456         fbcon_cfb16_putc(conp, p, c, yy, xx);
2457     }
2458     
2459     
2460     static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
2461                                  const unsigned short *s, int count,
2462                                  int yy, int xx)
2463     {
2464         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2465     
2466         if (fb->blitter_may_be_busy)
2467             wait_for_idle(fb);
2468     
2469         fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
2470     }
2471     
2472     
2473     static void fbcon_aty16_clear_margins(struct vc_data *conp,
2474                                          struct display *p, int bottom_only)
2475     {
2476         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2477     
2478         if (fb->blitter_may_be_busy)
2479             wait_for_idle(fb);
2480     
2481         fbcon_cfb16_clear_margins(conp, p, bottom_only);
2482     }
2483     
2484     static struct display_switch fbcon_aty128_16 = {
2485         setup:		fbcon_cfb16_setup,
2486         bmove:		fbcon_aty128_bmove,
2487         clear:		fbcon_cfb16_clear,
2488         putc:		fbcon_aty16_putc,
2489         putcs:		fbcon_aty16_putcs,
2490         revc:		fbcon_cfb16_revc,
2491         clear_margins:	fbcon_aty16_clear_margins,
2492         fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
2493     };
2494     #endif
2495     #ifdef FBCON_HAS_CFB24
2496     static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
2497                                 int c, int yy, int xx)
2498     {
2499         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2500     
2501         if (fb->blitter_may_be_busy)
2502             wait_for_idle(fb);
2503     
2504         fbcon_cfb24_putc(conp, p, c, yy, xx);
2505     }
2506     
2507     
2508     static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
2509                                  const unsigned short *s, int count,
2510                                  int yy, int xx)
2511     {
2512         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2513     
2514         if (fb->blitter_may_be_busy)
2515             wait_for_idle(fb);
2516     
2517         fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
2518     }
2519     
2520     
2521     static void fbcon_aty24_clear_margins(struct vc_data *conp,
2522                                          struct display *p, int bottom_only)
2523     {
2524         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2525     
2526         if (fb->blitter_may_be_busy)
2527             wait_for_idle(fb);
2528     
2529         fbcon_cfb24_clear_margins(conp, p, bottom_only);
2530     }
2531     
2532     static struct display_switch fbcon_aty128_24 = {
2533         setup:		fbcon_cfb24_setup,
2534         bmove:		fbcon_aty128_bmove,
2535         clear:		fbcon_cfb24_clear,
2536         putc:		fbcon_aty24_putc,
2537         putcs:		fbcon_aty24_putcs,
2538         revc:		fbcon_cfb24_revc,
2539         clear_margins:	fbcon_aty24_clear_margins,
2540         fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
2541     };
2542     #endif
2543     #ifdef FBCON_HAS_CFB32
2544     static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
2545                                 int c, int yy, int xx)
2546     {
2547         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2548     
2549         if (fb->blitter_may_be_busy)
2550             wait_for_idle(fb);
2551     
2552         fbcon_cfb32_putc(conp, p, c, yy, xx);
2553     }
2554     
2555     
2556     static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
2557                                  const unsigned short *s, int count,
2558                                  int yy, int xx)
2559     {
2560         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2561     
2562         if (fb->blitter_may_be_busy)
2563             wait_for_idle(fb);
2564     
2565         fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
2566     }
2567     
2568     
2569     static void fbcon_aty32_clear_margins(struct vc_data *conp,
2570                                          struct display *p, int bottom_only)
2571     {
2572         struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
2573     
2574         if (fb->blitter_may_be_busy)
2575             wait_for_idle(fb);
2576     
2577         fbcon_cfb32_clear_margins(conp, p, bottom_only);
2578     }
2579     
2580     static struct display_switch fbcon_aty128_32 = {
2581         setup:		fbcon_cfb32_setup,
2582         bmove:		fbcon_aty128_bmove,
2583         clear:		fbcon_cfb32_clear,
2584         putc:		fbcon_aty32_putc,
2585         putcs:		fbcon_aty32_putcs,
2586         revc:		fbcon_cfb32_revc,
2587         clear_margins:	fbcon_aty32_clear_margins,
2588         fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
2589     };
2590     #endif
2591     
2592     #ifdef MODULE
2593     MODULE_AUTHOR("(c)1999-2000 Brad Douglas <brad@neruo.com>");
2594     MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
2595     MODULE_PARM(noaccel, "i");
2596     MODULE_PARM_DESC(noaccel, "Disable hardware acceleration (0 or 1=disabled) (default=0)");
2597     MODULE_PARM(font, "s");
2598     MODULE_PARM_DESC(font, "Specify one of the compiled-in fonts (default=none)");
2599     MODULE_PARM(mode, "s");
2600     MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2601     #ifdef CONFIG_MTRR
2602     MODULE_PARM(nomtrr, "i");
2603     MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
2604     #endif
2605     
2606     int __init
2607     init_module(void)
2608     {
2609         if (noaccel) {
2610             noaccel = 1;
2611             printk(KERN_INFO "aty128fb: Parameter NOACCEL set\n");
2612         }
2613         if (font) {
2614             strncpy(fontname, font, sizeof(fontname)-1);
2615             printk(KERN_INFO "aty128fb: Parameter FONT set to %s\n", font);
2616         }
2617         if (mode) {
2618             mode_option = mode;
2619             printk(KERN_INFO "aty128fb: Parameter MODE set to %s\n", mode);
2620         }
2621     #ifdef CONFIG_MTRR
2622         if (nomtrr) {
2623             mtrr = 0;
2624             printk(KERN_INFO "aty128fb: Parameter NOMTRR set\n");
2625         }
2626     #endif
2627         
2628         aty128fb_init();
2629         return 0;
2630     }
2631     
2632     void __exit
2633     cleanup_module(void)
2634     {
2635         struct fb_info_aty128 *info = board_list;
2636     
2637         while (board_list) {
2638             info = board_list;
2639             board_list = board_list->next;
2640     
2641             unregister_framebuffer(&info->fb_info);
2642     #ifdef CONFIG_MTRR
2643             if (info->mtrr.vram_valid)
2644                 mtrr_del(info->mtrr.vram, info->frame_buffer_phys,
2645                          info->vram_size);
2646     #endif /* CONFIG_MTRR */
2647             iounmap(info->regbase);
2648             iounmap(info->frame_buffer);
2649     
2650             release_mem_region(pci_resource_start(info->pdev, 0),
2651                                pci_resource_len(info->pdev, 0));
2652             release_mem_region(pci_resource_start(info->pdev, 1),
2653                                pci_resource_len(info->pdev, 1));
2654             release_mem_region(pci_resource_start(info->pdev, 2),
2655                                pci_resource_len(info->pdev, 2));
2656     
2657             kfree(info);
2658         }
2659     }
2660     #endif /* MODULE */
2661