~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/atyfb.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*  $Id: atyfb.c,v 1.147 2000/08/29 07:01:56 davem Exp $
  2  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  3  *
  4  *      Copyright (C) 1997-1998  Geert Uytterhoeven
  5  *      Copyright (C) 1998  Bernd Harries
  6  *      Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
  7  *
  8  *  This driver is partly based on the PowerMac console driver:
  9  *
 10  *      Copyright (C) 1996 Paul Mackerras
 11  *
 12  *  and on the PowerMac ATI/mach64 display driver:
 13  *
 14  *      Copyright (C) 1997 Michael AK Tesch
 15  *
 16  *            with work by Jon Howell
 17  *                         Harry AC Eaton
 18  *                         Anthony Tong <atong@uiuc.edu>
 19  *
 20  *  This file is subject to the terms and conditions of the GNU General Public
 21  *  License. See the file COPYING in the main directory of this archive for
 22  *  more details.
 23  *  
 24  *  Many thanks to Nitya from ATI devrel for support and patience !
 25  */
 26 
 27 /******************************************************************************
 28 
 29   TODO:
 30 
 31     - cursor support on all cards and all ramdacs.
 32     - cursor parameters controlable via ioctl()s.
 33     - guess PLL and MCLK based on the original PLL register values initialized
 34       by the BIOS or Open Firmware (if they are initialized).
 35 
 36                                                 (Anyone to help with this?)
 37 
 38 ******************************************************************************/
 39 
 40 
 41 #include <linux/config.h>
 42 #include <linux/module.h>
 43 #include <linux/kernel.h>
 44 #include <linux/errno.h>
 45 #include <linux/string.h>
 46 #include <linux/mm.h>
 47 #include <linux/tty.h>
 48 #include <linux/malloc.h>
 49 #include <linux/vmalloc.h>
 50 #include <linux/delay.h>
 51 #include <linux/interrupt.h>
 52 #include <linux/fb.h>
 53 #include <linux/selection.h>
 54 #include <linux/console.h>
 55 #include <linux/init.h>
 56 #include <linux/pci.h>
 57 #include <linux/kd.h>
 58 #include <linux/vt_kern.h>
 59 
 60 #ifdef CONFIG_FB_COMPAT_XPMAC
 61 #include <asm/vc_ioctl.h>
 62 #endif
 63 
 64 #include <asm/io.h>
 65 
 66 #ifdef __powerpc__
 67 #include <linux/adb.h>
 68 #include <asm/prom.h>
 69 #include <asm/pci-bridge.h>
 70 #include <video/macmodes.h>
 71 #endif
 72 #ifdef CONFIG_ADB_PMU
 73 #include <linux/pmu.h>
 74 #endif
 75 #ifdef CONFIG_NVRAM
 76 #include <linux/nvram.h>
 77 #endif
 78 #ifdef CONFIG_PMAC_BACKLIGHT
 79 #include <asm/backlight.h>
 80 #endif
 81 
 82 #ifdef __sparc__
 83 #include <asm/pbm.h>
 84 #include <asm/fbio.h>
 85 #endif
 86 #include <asm/uaccess.h>
 87 
 88 #include <video/fbcon.h>
 89 #include <video/fbcon-cfb8.h>
 90 #include <video/fbcon-cfb16.h>
 91 #include <video/fbcon-cfb24.h>
 92 #include <video/fbcon-cfb32.h>
 93 
 94 #include "aty.h"
 95 
 96 
 97 /*
 98  * Debug flags.
 99  */
100 #undef DEBUG
101 
102 /* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
103 
104 #define REF_FREQ_2595       1432  /*  14.33 MHz  (exact   14.31818) */
105 #define REF_DIV_2595          46  /* really 43 on ICS 2595 !!!  */
106                                   /* ohne Prescaler */
107 #define MAX_FREQ_2595      15938  /* 159.38 MHz  (really 170.486) */
108 #define MIN_FREQ_2595       8000  /*  80.00 MHz  (        85.565) */
109                                   /* mit Prescaler 2, 4, 8 */
110 #define ABS_MIN_FREQ_2595   1000  /*  10.00 MHz  (really  10.697) */
111 #define N_ADJ_2595           257
112 
113 #define STOP_BITS_2595     0x1800
114 
115 
116 #define MIN_N_408               2
117 
118 #define MIN_N_1703              6
119 
120 #define MIN_M           2
121 #define MAX_M           30
122 #define MIN_N           35
123 #define MAX_N           255-8
124 
125 
126 /* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
127 /*  - must be large enough to catch all GUI-Regs   */
128 /*  - must be aligned to a PAGE boundary           */
129 #define GUI_RESERVE     (1 * PAGE_SIZE)
130 
131 
132 /* FIXME: remove the FAIL definition */
133 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
134 
135 
136     /*
137      *  Elements of the Hardware specific atyfb_par structure
138      */
139 
140 struct crtc {
141     u32 vxres;
142     u32 vyres;
143     u32 xoffset;
144     u32 yoffset;
145     u32 bpp;
146     u32 h_tot_disp;
147     u32 h_sync_strt_wid;
148     u32 v_tot_disp;
149     u32 v_sync_strt_wid;
150     u32 off_pitch;
151     u32 gen_cntl;
152     u32 dp_pix_width;   /* acceleration */
153     u32 dp_chain_mask;  /* acceleration */
154 };
155 
156 struct pll_gx {
157     u8 m;
158     u8 n;
159 };
160 
161 struct pll_18818
162 {
163     u32 program_bits;
164     u32 locationAddr;
165     u32 period_in_ps;
166     u32 post_divider;
167 };
168 
169 struct pll_ct {
170     u8 pll_ref_div;
171     u8 pll_gen_cntl;
172     u8 mclk_fb_div;
173     u8 pll_vclk_cntl;
174     u8 vclk_post_div;
175     u8 vclk_fb_div;
176     u8 pll_ext_cntl;
177     u32 dsp_config;     /* Mach64 GTB DSP */
178     u32 dsp_on_off;     /* Mach64 GTB DSP */
179     u8 mclk_post_div_real;
180     u8 vclk_post_div_real;
181 };
182 
183 
184     /*
185      *  The Hardware parameters for each card
186      */
187 
188 struct atyfb_par {
189     struct crtc crtc;
190     union {
191         struct pll_gx gx;
192         struct pll_ct ct;
193         struct pll_18818 ics2595;
194     } pll;
195     u32 accel_flags;
196 };
197 
198 struct aty_cmap_regs {
199     u8 windex;
200     u8 lut;
201     u8 mask;
202     u8 rindex;
203     u8 cntl;
204 };
205 
206 struct pci_mmap_map {
207     unsigned long voff;
208     unsigned long poff;
209     unsigned long size;
210     unsigned long prot_flag;
211     unsigned long prot_mask;
212 };
213 
214 #define DEFAULT_CURSOR_BLINK_RATE       (20)
215 #define CURSOR_DRAW_DELAY               (2)
216 
217 struct aty_cursor {
218     int enable;
219     int on;
220     int vbl_cnt;
221     int blink_rate;
222     u32 offset;
223     struct {
224         u16 x, y;
225     } pos, hot, size;
226     u32 color[2];
227     u8 bits[8][64];
228     u8 mask[8][64];
229     u8 *ram;
230     struct timer_list *timer;
231 };
232 
233 struct fb_info_aty {
234     struct fb_info fb_info;
235     struct fb_info_aty *next;
236     unsigned long ati_regbase_phys;
237     unsigned long ati_regbase;
238     unsigned long frame_buffer_phys;
239     unsigned long frame_buffer;
240     unsigned long clk_wr_offset;
241     struct pci_mmap_map *mmap_map;
242     struct aty_cursor *cursor;
243     struct aty_cmap_regs *aty_cmap_regs;
244     struct { u8 red, green, blue, pad; } palette[256];
245     struct atyfb_par default_par;
246     struct atyfb_par current_par;
247     u32 total_vram;
248     u32 ref_clk_per;
249     u32 pll_per;
250     u32 mclk_per;
251     u16 chip_type;
252 #define Gx info->chip_type
253     u8 chip_rev;
254 #define Rev info->chip_rev
255     u8 bus_type;
256     u8 ram_type;
257     u8 dac_type;
258     u8 dac_subtype;
259     u8 clk_type;
260     u8 mem_refresh_rate;
261     struct display disp;
262     struct display_switch dispsw;
263     union {
264 #ifdef FBCON_HAS_CFB16
265         u16 cfb16[16];
266 #endif
267 #ifdef FBCON_HAS_CFB24
268         u32 cfb24[16];
269 #endif
270 #ifdef FBCON_HAS_CFB32
271         u32 cfb32[16];
272 #endif
273     } fbcon_cmap;
274     u8 blitter_may_be_busy;
275 #ifdef __sparc__
276     u8 mmaped;
277     int open;
278     int vtconsole;
279     int consolecnt;
280 #endif
281 #ifdef CONFIG_PMAC_PBOOK
282     unsigned char *save_framebuffer;
283     unsigned long save_pll[64];
284 #endif
285 };
286 
287 #ifdef CONFIG_PMAC_PBOOK
288   int aty_sleep_notify(struct pmu_sleep_notifier *self, int when);
289   static struct pmu_sleep_notifier aty_sleep_notifier = {
290         aty_sleep_notify, SLEEP_LEVEL_VIDEO,
291   };
292   static struct fb_info_aty* first_display = NULL;
293 #endif
294 
295 #ifdef CONFIG_PMAC_BACKLIGHT
296 static int aty_set_backlight_enable(int on, int level, void* data);
297 static int aty_set_backlight_level(int level, void* data);
298 
299 static struct backlight_controller aty_backlight_controller = {
300         aty_set_backlight_enable,
301         aty_set_backlight_level
302 };
303 #endif /* CONFIG_PMAC_BACKLIGHT */
304 
305     /*
306      *  Frame buffer device API
307      */
308 
309 static int atyfb_open(struct fb_info *info, int user);
310 static int atyfb_release(struct fb_info *info, int user);
311 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
312                          struct fb_info *fb);
313 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
314                          struct fb_info *fb);
315 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
316                          struct fb_info *fb);
317 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
318                              struct fb_info *fb);
319 static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
320                           struct fb_info *info);
321 static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
322                           struct fb_info *info);
323 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
324                        u_long arg, int con, struct fb_info *info);
325 #ifdef __sparc__
326 static int atyfb_mmap(struct fb_info *info, struct file *file,
327                       struct vm_area_struct *vma);
328 #endif
329 static int atyfb_rasterimg(struct fb_info *info, int start);
330 
331 
332     /*
333      *  Interface to the low level console driver
334      */
335 
336 static int atyfbcon_switch(int con, struct fb_info *fb);
337 static int atyfbcon_updatevar(int con, struct fb_info *fb);
338 static void atyfbcon_blank(int blank, struct fb_info *fb);
339 
340 
341     /*
342      *  Text console acceleration
343      */
344 
345 static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
346                             int height, int width);
347 static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
348                             int sx, int height, int width);
349 #ifdef FBCON_HAS_CFB8
350 static struct display_switch fbcon_aty8;
351 static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
352                             int yy, int xx);
353 static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
354                              const unsigned short *s, int count, int yy,
355                              int xx);
356 #endif
357 #ifdef FBCON_HAS_CFB16
358 static struct display_switch fbcon_aty16;
359 static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c,
360                              int yy, int xx);
361 static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
362                               const unsigned short *s, int count, int yy,
363                               int xx);
364 #endif
365 #ifdef FBCON_HAS_CFB24
366 static struct display_switch fbcon_aty24;
367 static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
368                              int yy, int xx);
369 static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
370                               const unsigned short *s, int count, int yy,
371                               int xx);
372 #endif
373 #ifdef FBCON_HAS_CFB32
374 static struct display_switch fbcon_aty32;
375 static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
376                              int yy, int xx);
377 static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
378                               const unsigned short *s, int count, int yy,
379                               int xx);
380 #endif
381 
382 
383     /*
384      *  Internal routines
385      */
386 
387 static int aty_init(struct fb_info_aty *info, const char *name);
388 static struct aty_cursor *aty_init_cursor(struct fb_info_aty *fb);
389 #ifdef CONFIG_ATARI
390 static int store_video_par(char *videopar, unsigned char m64_num);
391 static char *strtoke(char *s, const char *ct);
392 #endif
393 
394 static void reset_engine(const struct fb_info_aty *info);
395 static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info);
396 
397 static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info);
398 static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
399 static u8 aty_ld_pll(int offset, const struct fb_info_aty *info);
400 static void aty_set_crtc(const struct fb_info_aty *info,
401                          const struct crtc *crtc);
402 static int aty_var_to_crtc(const struct fb_info_aty *info,
403                            const struct fb_var_screeninfo *var,
404                            struct crtc *crtc);
405 static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp);
406 static int aty_crtc_to_var(const struct crtc *crtc,
407                            struct fb_var_screeninfo *var);
408 static void aty_set_pll_gx(const struct fb_info_aty *info,
409                            const struct pll_gx *pll);
410 
411 static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info, u32 bpp,
412                                   u32 AccelMode);
413 static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
414                                  const struct pll_18818 *pll, u32 bpp);
415 void aty_dac_waste4(const struct fb_info_aty *info);
416 
417 static int aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll);
418 static u32 aty_pll_18818_to_var(const struct pll_18818 *pll);
419 static void aty_set_pll18818(const struct fb_info_aty *info,
420                              const struct pll_18818 *pll);
421 
422 static void aty_StrobeClock(const struct fb_info_aty *info);
423 
424 static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info);
425 
426 static int aty_var_to_pll_408(u32 period_in_ps, struct pll_18818 *pll);
427 static u32 aty_pll_408_to_var(const struct pll_18818 *pll);
428 static void aty_set_pll_408(const struct fb_info_aty *info,
429                             const struct pll_18818 *pll);
430 
431 static int aty_var_to_pll_1703(u32 period_in_ps, struct pll_18818 *pll);
432 static u32 aty_pll_1703_to_var(const struct pll_18818 *pll);
433 static void aty_set_pll_1703(const struct fb_info_aty *info,
434                              const struct pll_18818 *pll);
435 
436 static int aty_var_to_pll_8398(u32 period_in_ps, struct pll_18818 *pll);
437 static u32 aty_pll_8398_to_var(const struct pll_18818 *pll);
438 static void aty_set_pll_8398(const struct fb_info_aty *info,
439                              const struct pll_18818 *pll);
440 
441 static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll);
442 static u32 aty_pll_gx_to_var(const struct pll_gx *pll,
443                              const struct fb_info_aty *info);
444 static void aty_set_pll_ct(const struct fb_info_aty *info,
445                            const struct pll_ct *pll);
446 static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
447                             struct pll_ct *pll);
448 static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
449                       struct pll_ct *pll);
450 static void aty_calc_pll_ct(const struct fb_info_aty *info,
451                             struct pll_ct *pll);
452 static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
453                              u8 bpp, struct pll_ct *pll);
454 static u32 aty_pll_ct_to_var(const struct pll_ct *pll,
455                              const struct fb_info_aty *info);
456 static void atyfb_set_par(const struct atyfb_par *par,
457                           struct fb_info_aty *info);
458 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
459                             struct atyfb_par *par,
460                             const struct fb_info_aty *info);
461 static int atyfb_encode_var(struct fb_var_screeninfo *var,
462                             const struct atyfb_par *par,
463                             const struct fb_info_aty *info);
464 static void set_off_pitch(struct atyfb_par *par,
465                           const struct fb_info_aty *info);
466 static int encode_fix(struct fb_fix_screeninfo *fix,
467                       const struct atyfb_par *par,
468                       const struct fb_info_aty *info);
469 static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
470                              int bpp, int accel);
471 static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
472                          u_int *transp, struct fb_info *fb);
473 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
474                          u_int transp, struct fb_info *fb);
475 static void do_install_cmap(int con, struct fb_info *info);
476 #ifdef CONFIG_PPC
477 static int read_aty_sense(const struct fb_info_aty *info);
478 #endif
479 
480 
481     /*
482      *  Interface used by the world
483      */
484 
485 int atyfb_init(void);
486 #ifndef MODULE
487 int atyfb_setup(char*);
488 #endif
489 
490 static int currcon = 0;
491 
492 static struct fb_ops atyfb_ops = {
493         owner:          THIS_MODULE,
494         fb_open:        atyfb_open,
495         fb_release:     atyfb_release,
496         fb_get_fix:     atyfb_get_fix,
497         fb_get_var:     atyfb_get_var,
498         fb_set_var:     atyfb_set_var,
499         fb_get_cmap:    atyfb_get_cmap,
500         fb_set_cmap:    atyfb_set_cmap,
501         fb_pan_display: atyfb_pan_display,
502         fb_ioctl:       atyfb_ioctl,
503 #ifdef __sparc__
504         fb_mmap:        atyfb_mmap,
505 #endif
506         fb_rasterimg:   atyfb_rasterimg,
507 };
508 
509 static char atyfb_name[16] = "ATY Mach64";
510 static char fontname[40] __initdata = { 0 };
511 static char curblink __initdata = 1;
512 static char noaccel __initdata = 0;
513 static u32 default_vram __initdata = 0;
514 static int default_pll __initdata = 0;
515 static int default_mclk __initdata = 0;
516 
517 #ifndef MODULE
518 static const char *mode_option __initdata = NULL;
519 #endif
520 
521 #ifdef CONFIG_PPC
522 #ifdef CONFIG_NVRAM_NOT_DEFINED
523 static int default_vmode __initdata = VMODE_NVRAM;
524 static int default_cmode __initdata = CMODE_NVRAM;
525 #else
526 static int default_vmode __initdata = VMODE_CHOOSE;
527 static int default_cmode __initdata = CMODE_CHOOSE;
528 #endif
529 #endif
530 
531 #ifdef CONFIG_ATARI
532 static unsigned int mach64_count __initdata = 0;
533 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
534 static unsigned long phys_size[FB_MAX] __initdata = { 0, };
535 static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
536 #endif
537 
538 
539 static struct aty_features {
540     u16 pci_id;
541     u16 chip_type;
542     const char *name;
543 } aty_features[] __initdata = {
544     /* mach64GX family */
545     { 0x4758, 0x00d7, "mach64GX (ATI888GX00)" },
546     { 0x4358, 0x0057, "mach64CX (ATI888CX00)" },
547 
548     /* mach64CT family */
549     { 0x4354, 0x4354, "mach64CT (ATI264CT)" },
550     { 0x4554, 0x4554, "mach64ET (ATI264ET)" },
551 
552     /* mach64CT family / mach64VT class */
553     { 0x5654, 0x5654, "mach64VT (ATI264VT)" },
554     { 0x5655, 0x5655, "mach64VTB (ATI264VTB)" },
555     { 0x5656, 0x5656, "mach64VT4 (ATI264VT4)" },
556 
557     /* mach64CT family / mach64GT (3D RAGE) class */
558     { 0x4c42, 0x4c42, "3D RAGE LT PRO (AGP)" },
559     { 0x4c44, 0x4c44, "3D RAGE LT PRO" },
560     { 0x4c47, 0x4c47, "3D RAGE LT-G" },
561     { 0x4c49, 0x4c49, "3D RAGE LT PRO" },
562     { 0x4c50, 0x4c50, "3D RAGE LT PRO" },
563     { 0x4c54, 0x4c54, "3D RAGE LT" },
564     { 0x4754, 0x4754, "3D RAGE (GT)" },
565     { 0x4755, 0x4755, "3D RAGE II+ (GTB)" },
566     { 0x4756, 0x4756, "3D RAGE IIC (PCI)" },
567     { 0x4757, 0x4757, "3D RAGE IIC (AGP)" },
568     { 0x475a, 0x475a, "3D RAGE IIC (AGP)" },
569     { 0x4742, 0x4742, "3D RAGE PRO (BGA, AGP)" },
570     { 0x4744, 0x4744, "3D RAGE PRO (BGA, AGP, 1x only)" },
571     { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)" },
572     { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)" },
573     { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },
574     { 0x4c4d, 0x4c4d, "3D RAGE Mobility (PCI)" },
575     { 0x4c4e, 0x4c4e, "3D RAGE Mobility (AGP)" },
576 };
577 
578 static const char *aty_gx_ram[8] __initdata = {
579     "DRAM", "VRAM", "VRAM", "DRAM", "DRAM", "VRAM", "VRAM", "RESV"
580 };
581 
582 static const char *aty_ct_ram[8] __initdata = {
583     "OFF", "DRAM", "EDO", "EDO", "SDRAM", "SGRAM", "WRAM", "RESV"
584 };
585 
586 
587 static inline u32 aty_ld_le32(int regindex,
588                               const struct fb_info_aty *info)
589 {
590     /* Hack for bloc 1, should be cleanly optimized by compiler */
591     if (regindex >= 0x400)
592         regindex -= 0x800;
593 
594 #if defined(__mc68000__)
595     return le32_to_cpu(*((volatile u32 *)(info->ati_regbase+regindex)));
596 #else
597     return readl (info->ati_regbase + regindex);
598 #endif
599 }
600 
601 static inline void aty_st_le32(int regindex, u32 val,
602                                const struct fb_info_aty *info)
603 {
604     /* Hack for bloc 1, should be cleanly optimized by compiler */
605     if (regindex >= 0x400)
606         regindex -= 0x800;
607 
608 #if defined(__mc68000__)
609     *((volatile u32 *)(info->ati_regbase+regindex)) = cpu_to_le32(val);
610 #else
611     writel (val, info->ati_regbase + regindex);
612 #endif
613 }
614 
615 static inline u8 aty_ld_8(int regindex,
616                           const struct fb_info_aty *info)
617 {
618     /* Hack for bloc 1, should be cleanly optimized by compiler */
619     if (regindex >= 0x400)
620         regindex -= 0x800;
621 
622     return readb (info->ati_regbase + regindex);
623 }
624 
625 static inline void aty_st_8(int regindex, u8 val,
626                             const struct fb_info_aty *info)
627 {
628     /* Hack for bloc 1, should be cleanly optimized by compiler */
629     if (regindex >= 0x400)
630         regindex -= 0x800;
631 
632     writeb (val, info->ati_regbase + regindex);
633 }
634 
635 #if defined(CONFIG_PPC) || defined(CONFIG_PMAC_PBOOK)
636 static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
637 {
638     unsigned long temp;
639 
640     /* write addr byte */
641     temp = aty_ld_le32(LCD_INDEX, info);
642     aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
643     /* write the register value */
644     aty_st_le32(LCD_DATA, val, info);
645 }
646 
647 static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
648 {
649     unsigned long temp;
650 
651     /* write addr byte */
652     temp = aty_ld_le32(LCD_INDEX, info);
653     aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
654     /* read the register value */
655     return aty_ld_le32(LCD_DATA, info);
656 }
657 #endif
658 
659     /*
660      *  Generic Mach64 routines
661      */
662 
663     /*
664      *  All writes to draw engine registers are automatically routed through a
665      *  32-bit-wide, 16-entry-deep command FIFO ...
666      *  Register writes to registers with DWORD offsets less than 40h are not
667      *  FIFOed.
668      *  (from Chapter 5 of the Mach64 Programmer's Guide)
669      */
670 
671 static inline void wait_for_fifo(u16 entries, const struct fb_info_aty *info)
672 {
673     while ((aty_ld_le32(FIFO_STAT, info) & 0xffff) >
674            ((u32)(0x8000 >> entries)));
675 }
676 
677 static inline void wait_for_idle(struct fb_info_aty *info)
678 {
679     wait_for_fifo(16, info);
680     while ((aty_ld_le32(GUI_STAT, info) & 1)!= 0);
681     info->blitter_may_be_busy = 0;
682 }
683 
684 static void reset_engine(const struct fb_info_aty *info)
685 {
686     /* reset engine */
687     aty_st_le32(GEN_TEST_CNTL,
688                 aty_ld_le32(GEN_TEST_CNTL, info) & ~GUI_ENGINE_ENABLE, info);
689     /* enable engine */
690     aty_st_le32(GEN_TEST_CNTL,
691                 aty_ld_le32(GEN_TEST_CNTL, info) | GUI_ENGINE_ENABLE, info);
692     /* ensure engine is not locked up by clearing any FIFO or */
693     /* HOST errors */
694     aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, info) | BUS_HOST_ERR_ACK |
695                           BUS_FIFO_ERR_ACK, info);
696 }
697 
698 static void reset_GTC_3D_engine(const struct fb_info_aty *info)
699 {
700         aty_st_le32(SCALE_3D_CNTL, 0xc0, info);
701         mdelay(GTC_3D_RESET_DELAY);
702         aty_st_le32(SETUP_CNTL, 0x00, info);
703         mdelay(GTC_3D_RESET_DELAY);
704         aty_st_le32(SCALE_3D_CNTL, 0x00, info);
705         mdelay(GTC_3D_RESET_DELAY);
706 }
707 
708 static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
709 {
710     u32 pitch_value;
711 
712     /* determine modal information from global mode structure */
713     pitch_value = par->crtc.vxres;
714 
715     if (par->crtc.bpp == 24) {
716         /* In 24 bpp, the engine is in 8 bpp - this requires that all */
717         /* horizontal coordinates and widths must be adjusted */
718         pitch_value = pitch_value * 3;
719     }
720 
721     /* On GTC (RagePro), we need to reset the 3D engine before */
722     if (Gx == LB_CHIP_ID || Gx == LD_CHIP_ID || Gx == LI_CHIP_ID ||
723         Gx == LP_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
724         Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID ||
725         Gx == LM_CHIP_ID || Gx == LN_CHIP_ID)
726         reset_GTC_3D_engine(info);
727 
728     /* Reset engine, enable, and clear any engine errors */
729     reset_engine(info);
730     /* Ensure that vga page pointers are set to zero - the upper */
731     /* page pointers are set to 1 to handle overflows in the */
732     /* lower page */
733     aty_st_le32(MEM_VGA_WP_SEL, 0x00010000, info);
734     aty_st_le32(MEM_VGA_RP_SEL, 0x00010000, info);
735 
736     /* ---- Setup standard engine context ---- */
737 
738     /* All GUI registers here are FIFOed - therefore, wait for */
739     /* the appropriate number of empty FIFO entries */
740     wait_for_fifo(14, info);
741 
742     /* enable all registers to be loaded for context loads */
743     aty_st_le32(CONTEXT_MASK, 0xFFFFFFFF, info);
744 
745     /* set destination pitch to modal pitch, set offset to zero */
746     aty_st_le32(DST_OFF_PITCH, (pitch_value / 8) << 22, info);
747 
748     /* zero these registers (set them to a known state) */
749     aty_st_le32(DST_Y_X, 0, info);
750     aty_st_le32(DST_HEIGHT, 0, info);
751     aty_st_le32(DST_BRES_ERR, 0, info);
752     aty_st_le32(DST_BRES_INC, 0, info);
753     aty_st_le32(DST_BRES_DEC, 0, info);
754 
755     /* set destination drawing attributes */
756     aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
757                           DST_X_LEFT_TO_RIGHT, info);
758 
759     /* set source pitch to modal pitch, set offset to zero */
760     aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, info);
761 
762     /* set these registers to a known state */
763     aty_st_le32(SRC_Y_X, 0, info);
764     aty_st_le32(SRC_HEIGHT1_WIDTH1, 1, info);
765     aty_st_le32(SRC_Y_X_START, 0, info);
766     aty_st_le32(SRC_HEIGHT2_WIDTH2, 1, info);
767 
768     /* set source pixel retrieving attributes */
769     aty_st_le32(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT, info);
770 
771     /* set host attributes */
772     wait_for_fifo(13, info);
773     aty_st_le32(HOST_CNTL, 0, info);
774 
775     /* set pattern attributes */
776     aty_st_le32(PAT_REG0, 0, info);
777     aty_st_le32(PAT_REG1, 0, info);
778     aty_st_le32(PAT_CNTL, 0, info);
779 
780     /* set scissors to modal size */
781     aty_st_le32(SC_LEFT, 0, info);
782     aty_st_le32(SC_TOP, 0, info);
783     aty_st_le32(SC_BOTTOM, par->crtc.vyres-1, info);
784     aty_st_le32(SC_RIGHT, pitch_value-1, info);
785 
786     /* set background color to minimum value (usually BLACK) */
787     aty_st_le32(DP_BKGD_CLR, 0, info);
788 
789     /* set foreground color to maximum value (usually WHITE) */
790     aty_st_le32(DP_FRGD_CLR, 0xFFFFFFFF, info);
791 
792     /* set write mask to effect all pixel bits */
793     aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, info);
794 
795     /* set foreground mix to overpaint and background mix to */
796     /* no-effect */
797     aty_st_le32(DP_MIX, FRGD_MIX_S | BKGD_MIX_D, info);
798 
799     /* set primary source pixel channel to foreground color */
800     /* register */
801     aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR, info);
802 
803     /* set compare functionality to false (no-effect on */
804     /* destination) */
805     wait_for_fifo(3, info);
806     aty_st_le32(CLR_CMP_CLR, 0, info);
807     aty_st_le32(CLR_CMP_MASK, 0xFFFFFFFF, info);
808     aty_st_le32(CLR_CMP_CNTL, 0, info);
809 
810     /* set pixel depth */
811     wait_for_fifo(2, info);
812     aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, info);
813     aty_st_le32(DP_CHAIN_MASK, par->crtc.dp_chain_mask, info);
814 
815     wait_for_fifo(5, info);
816     aty_st_le32(SCALE_3D_CNTL, 0, info);
817     aty_st_le32(Z_CNTL, 0, info);
818     aty_st_le32(CRTC_INT_CNTL, aty_ld_le32(CRTC_INT_CNTL, info) & ~0x20, info);
819     aty_st_le32(GUI_TRAJ_CNTL, 0x100023, info);
820 
821     /* insure engine is idle before leaving */
822     wait_for_idle(info);
823 }
824 
825 static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info)
826 {
827     aty_st_8(DAC_CNTL, 1, info);
828     /* right addr byte */
829     aty_st_8(DAC_W_INDEX, offset & 0xff, info);
830     /* left addr byte */
831     aty_st_8(DAC_DATA, (offset >> 8) & 0xff, info);
832     aty_st_8(DAC_MASK, val, info);
833     aty_st_8(DAC_CNTL, 0, info);
834 }
835 
836 static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
837 {
838     /* write addr byte */
839     aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
840     /* write the register value */
841     aty_st_8(CLOCK_CNTL + 2, val, info);
842     aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
843 }
844 
845 static u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
846 {
847     u8 res;
848 
849     /* write addr byte */
850     aty_st_8(CLOCK_CNTL + 1, (offset << 2), info);
851     /* read the register value */
852     res = aty_ld_8(CLOCK_CNTL + 2, info);
853     return res;
854 }
855 
856 #if defined(CONFIG_PPC)
857 
858     /*
859      *  Apple monitor sense
860      */
861 
862 static int read_aty_sense(const struct fb_info_aty *info)
863 {
864     int sense, i;
865 
866     aty_st_le32(GP_IO, 0x31003100, info);       /* drive outputs high */
867     __delay(200);
868     aty_st_le32(GP_IO, 0, info);                /* turn off outputs */
869     __delay(2000);
870     i = aty_ld_le32(GP_IO, info);               /* get primary sense value */
871     sense = ((i & 0x3000) >> 3) | (i & 0x100);
872 
873     /* drive each sense line low in turn and collect the other 2 */
874     aty_st_le32(GP_IO, 0x20000000, info);       /* drive A low */
875     __delay(2000);
876     i = aty_ld_le32(GP_IO, info);
877     sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
878     aty_st_le32(GP_IO, 0x20002000, info);       /* drive A high again */
879     __delay(200);
880 
881     aty_st_le32(GP_IO, 0x10000000, info);       /* drive B low */
882     __delay(2000);
883     i = aty_ld_le32(GP_IO, info);
884     sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
885     aty_st_le32(GP_IO, 0x10001000, info);       /* drive B high again */
886     __delay(200);
887 
888     aty_st_le32(GP_IO, 0x01000000, info);       /* drive C low */
889     __delay(2000);
890     sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12;
891     aty_st_le32(GP_IO, 0, info);                /* turn off outputs */
892 
893     return sense;
894 }
895 
896 #endif /* defined(CONFIG_PPC) */
897 
898 /* ------------------------------------------------------------------------- */
899 
900     /*
901      *  Hardware Cursor support.
902      */
903 
904 static u8 cursor_pixel_map[2] = { 0, 15 };
905 static u8 cursor_color_map[2] = { 0, 0xff };
906 
907 static u8 cursor_bits_lookup[16] =
908 {
909         0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
910         0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
911 };
912 
913 static u8 cursor_mask_lookup[16] =
914 {
915         0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
916         0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
917 };
918 
919 static void
920 aty_set_cursor_color(struct fb_info_aty *fb, u8 *pixel,
921                      u8 *red, u8 *green, u8 *blue)
922 {
923         struct aty_cursor *c = fb->cursor;
924         int i;
925 
926         if (!c)
927                 return;
928 
929 #ifdef __sparc__
930         if (fb->mmaped && (!fb->fb_info.display_fg
931             || fb->fb_info.display_fg->vc_num == fb->vtconsole))
932                 return;
933 #endif
934 
935         for (i = 0; i < 2; i++) {
936                 c->color[i] =  (u32)red[i] << 24;
937                 c->color[i] |= (u32)green[i] << 16;
938                 c->color[i] |= (u32)blue[i] <<  8;
939                 c->color[i] |= (u32)pixel[i];
940         }
941 
942         wait_for_fifo(2, fb);
943         aty_st_le32(CUR_CLR0, c->color[0], fb);
944         aty_st_le32(CUR_CLR1, c->color[1], fb);
945 }
946 
947 static void
948 aty_set_cursor_shape(struct fb_info_aty *fb)
949 {
950         struct aty_cursor *c = fb->cursor;
951         u8 *ram, m, b;
952         int x, y;
953 
954         if (!c)
955                 return;
956 
957 #ifdef __sparc__
958         if (fb->mmaped && (!fb->fb_info.display_fg
959             || fb->fb_info.display_fg->vc_num == fb->vtconsole))
960                 return;
961 #endif
962 
963         ram = c->ram;
964         for (y = 0; y < c->size.y; y++) {
965                 for (x = 0; x < c->size.x >> 2; x++) {
966                         m = c->mask[x][y];
967                         b = c->bits[x][y];
968                         fb_writeb (cursor_mask_lookup[m >> 4] |
969                                    cursor_bits_lookup[(b & m) >> 4],
970                                    ram++);
971                         fb_writeb (cursor_mask_lookup[m & 0x0f] |
972                                    cursor_bits_lookup[(b & m) & 0x0f],
973                                    ram++);
974                 }
975                 for ( ; x < 8; x++) {
976                         fb_writeb (0xaa, ram++);
977                         fb_writeb (0xaa, ram++);
978                 }
979         }
980         fb_memset (ram, 0xaa, (64 - c->size.y) * 16);
981 }
982 
983 static void
984 aty_set_cursor(struct fb_info_aty *fb, int on)
985 {
986         struct atyfb_par *par = &fb->current_par;
987         struct aty_cursor *c = fb->cursor;
988         u16 xoff, yoff;
989         int x, y;
990 
991         if (!c)
992                 return;
993 
994 #ifdef __sparc__
995         if (fb->mmaped && (!fb->fb_info.display_fg
996             || fb->fb_info.display_fg->vc_num == fb->vtconsole))
997                 return;
998 #endif
999 
1000         if (on) {
1001                 x = c->pos.x - c->hot.x - par->crtc.xoffset;
1002                 if (x < 0) {
1003                         xoff = -x;
1004                         x = 0;
1005                 } else {
1006                         xoff = 0;
1007                 }
1008 
1009                 y = c->pos.y - c->hot.y - par->crtc.yoffset;
1010                 if (y < 0) {
1011                         yoff = -y;
1012                         y = 0;
1013                 } else {
1014                         yoff = 0;
1015                 }
1016 
1017                 wait_for_fifo(4, fb);
1018                 aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1), fb);
1019                 aty_st_le32(CUR_HORZ_VERT_OFF,
1020                             ((u32)(64 - c->size.y + yoff) << 16) | xoff, fb);
1021                 aty_st_le32(CUR_HORZ_VERT_POSN, ((u32)y << 16) | x, fb);
1022                 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, fb)
1023                                                        | HWCURSOR_ENABLE, fb);
1024         } else {
1025                 wait_for_fifo(1, fb);
1026                 aty_st_le32(GEN_TEST_CNTL,
1027                             aty_ld_le32(GEN_TEST_CNTL, fb) & ~HWCURSOR_ENABLE,
1028                             fb);
1029         }
1030         if (fb->blitter_may_be_busy)
1031                 wait_for_idle(fb);
1032 }
1033 
1034 static void
1035 aty_cursor_timer_handler(unsigned long dev_addr)
1036 {
1037         struct fb_info_aty *fb = (struct fb_info_aty *)dev_addr;
1038 
1039         if (!fb->cursor)
1040                 return;
1041 
1042         if (!fb->cursor->enable)
1043                 goto out;
1044 
1045         if (fb->cursor->vbl_cnt && --fb->cursor->vbl_cnt == 0) {
1046                 fb->cursor->on ^= 1;
1047                 aty_set_cursor(fb, fb->cursor->on);
1048                 fb->cursor->vbl_cnt = fb->cursor->blink_rate;
1049         }
1050 
1051 out:
1052         fb->cursor->timer->expires = jiffies + (HZ / 50);
1053         add_timer(fb->cursor->timer);
1054 }
1055 
1056 static void
1057 atyfb_cursor(struct display *p, int mode, int x, int y)
1058 {
1059         struct fb_info_aty *fb = (struct fb_info_aty *)p->fb_info;
1060         struct aty_cursor *c = fb->cursor;
1061 
1062         if (!c)
1063                 return;
1064 
1065 #ifdef __sparc__
1066         if (fb->mmaped && (!fb->fb_info.display_fg
1067             || fb->fb_info.display_fg->vc_num == fb->vtconsole))
1068                 return;
1069 #endif
1070 
1071         x *= fontwidth(p);
1072         y *= fontheight(p);
1073         if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
1074                 return;
1075 
1076         c->enable = 0;
1077         if (c->on)
1078                 aty_set_cursor(fb, 0);
1079         c->pos.x = x;
1080         c->pos.y = y;
1081 
1082         switch (mode) {
1083         case CM_ERASE:
1084                 c->on = 0;
1085                 break;
1086 
1087         case CM_DRAW:
1088         case CM_MOVE:
1089                 if (c->on)
1090                         aty_set_cursor(fb, 1);
1091                 else
1092                         c->vbl_cnt = CURSOR_DRAW_DELAY;
1093                 c->enable = 1;
1094                 break;
1095         }
1096 }
1097 
1098 static struct fb_info_aty *fb_list = NULL;
1099 
1100 static struct aty_cursor * __init
1101 aty_init_cursor(struct fb_info_aty *fb)
1102 {
1103         struct aty_cursor *cursor;
1104         unsigned long addr;
1105 
1106         cursor = kmalloc(sizeof(struct aty_cursor), GFP_ATOMIC);
1107         if (!cursor)
1108                 return 0;
1109         memset(cursor, 0, sizeof(*cursor));
1110 
1111         cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
1112         if (!cursor->timer) {
1113                 kfree(cursor);
1114                 return 0;
1115         }
1116         memset(cursor->timer, 0, sizeof(*cursor->timer));
1117 
1118         cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
1119         fb->total_vram -= PAGE_SIZE;
1120         cursor->offset = fb->total_vram;
1121 
1122 #ifdef __sparc__
1123         addr = fb->frame_buffer - 0x800000 + cursor->offset;
1124         cursor->ram = (u8 *)addr;
1125 #else
1126 #ifdef __BIG_ENDIAN
1127         addr = fb->frame_buffer_phys - 0x800000 + cursor->offset;
1128         cursor->ram = (u8 *)ioremap(addr, 1024);
1129 #else
1130         addr = fb->frame_buffer + cursor->offset;
1131         cursor->ram = (u8 *)addr;
1132 #endif
1133 #endif
1134 
1135         if (! cursor->ram) {
1136                 kfree(cursor);
1137                 return NULL;
1138         }
1139 
1140         if (curblink) {
1141                 init_timer(cursor->timer);
1142                 cursor->timer->expires = jiffies + (HZ / 50);
1143                 cursor->timer->data = (unsigned long)fb;
1144                 cursor->timer->function = aty_cursor_timer_handler;
1145                 add_timer(cursor->timer);
1146         }
1147 
1148         return cursor;
1149 }
1150 
1151 static int
1152 atyfb_set_font(struct display *d, int width, int height)
1153 {
1154     struct fb_info_aty *fb = (struct fb_info_aty *)d->fb_info;
1155     struct aty_cursor *c = fb->cursor;
1156     int i, j;
1157 
1158     if (c) {
1159         if (!width || !height) {
1160             width = 8;
1161             height = 16;
1162         }
1163 
1164         c->hot.x = 0;
1165         c->hot.y = 0;
1166         c->size.x = width;
1167         c->size.y = height;
1168 
1169         memset(c->bits, 0xff, sizeof(c->bits));
1170         memset(c->mask, 0, sizeof(c->mask));
1171 
1172         for (i = 0, j = width; j >= 0; j -= 8, i++) {
1173             c->mask[i][height-2] = (j >= 8) ? 0xff : (0xff << (8 - j));
1174             c->mask[i][height-1] = (j >= 8) ? 0xff : (0xff << (8 - j));
1175         }
1176 
1177         aty_set_cursor_color(fb, cursor_pixel_map, cursor_color_map,
1178                              cursor_color_map, cursor_color_map);
1179         aty_set_cursor_shape(fb);
1180     }
1181     return 1;
1182 }
1183 
1184 
1185 
1186 
1187 /* ------------------------------------------------------------------------- */
1188 
1189     /*
1190      *  CRTC programming
1191      */
1192 
1193 static void aty_set_crtc(const struct fb_info_aty *info,
1194                          const struct crtc *crtc)
1195 {
1196     aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, info);
1197     aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, info);
1198     aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, info);
1199     aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, info);
1200     aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, info);
1201     aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, info);
1202     aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, info);
1203 }
1204 
1205 static int aty_var_to_crtc(const struct fb_info_aty *info,
1206                            const struct fb_var_screeninfo *var,
1207                            struct crtc *crtc)
1208 {
1209     u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
1210     u32 left, right, upper, lower, hslen, vslen, sync, vmode;
1211     u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1212     u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1213     u32 pix_width, dp_pix_width, dp_chain_mask;
1214 
1215     /* input */
1216     xres = var->xres;
1217     yres = var->yres;
1218     vxres = var->xres_virtual;
1219     vyres = var->yres_virtual;
1220     xoffset = var->xoffset;
1221     yoffset = var->yoffset;
1222     bpp = var->bits_per_pixel;
1223     left = var->left_margin;
1224     right = var->right_margin;
1225     upper = var->upper_margin;
1226     lower = var->lower_margin;
1227     hslen = var->hsync_len;
1228     vslen = var->vsync_len;
1229     sync = var->sync;
1230     vmode = var->vmode;
1231 
1232     /* convert (and round up) and validate */
1233     xres = (xres+7) & ~7;
1234     xoffset = (xoffset+7) & ~7;
1235     vxres = (vxres+7) & ~7;
1236     if (vxres < xres+xoffset)
1237         vxres = xres+xoffset;
1238     h_disp = xres/8-1;
1239     if (h_disp > 0xff)
1240         FAIL("h_disp too large");
1241     h_sync_strt = h_disp+(right/8);
1242     if (h_sync_strt > 0x1ff)
1243         FAIL("h_sync_start too large");
1244     h_sync_dly = right & 7;
1245     h_sync_wid = (hslen+7)/8;
1246     if (h_sync_wid > 0x1f)
1247         FAIL("h_sync_wid too large");
1248     h_total = h_sync_strt+h_sync_wid+(h_sync_dly+left+7)/8;
1249     if (h_total > 0x1ff)
1250         FAIL("h_total too large");
1251     h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1252 
1253     if (vyres < yres+yoffset)
1254         vyres = yres+yoffset;
1255     v_disp = yres-1;
1256     if (v_disp > 0x7ff)
1257         FAIL("v_disp too large");
1258     v_sync_strt = v_disp+lower;
1259     if (v_sync_strt > 0x7ff)
1260         FAIL("v_sync_strt too large");
1261     v_sync_wid = vslen;
1262     if (v_sync_wid > 0x1f)
1263         FAIL("v_sync_wid too large");
1264     v_total = v_sync_strt+v_sync_wid+upper;
1265     if (v_total > 0x7ff)
1266         FAIL("v_total too large");
1267     v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1268 
1269     c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? CRTC_CSYNC_EN : 0;
1270 
1271     if (bpp <= 8) {
1272         bpp = 8;
1273         pix_width = CRTC_PIX_WIDTH_8BPP;
1274         dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
1275         dp_chain_mask = 0x8080;
1276     } else if (bpp <= 16) {
1277         bpp = 16;
1278         pix_width = CRTC_PIX_WIDTH_15BPP;
1279         dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
1280                        BYTE_ORDER_LSB_TO_MSB;
1281         dp_chain_mask = 0x4210;
1282     } else if ((bpp <= 24) && (Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
1283         bpp = 24;
1284         pix_width = CRTC_PIX_WIDTH_24BPP;
1285         dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
1286         dp_chain_mask = 0x8080;
1287     } else if (bpp <= 32) {
1288         bpp = 32;
1289         pix_width = CRTC_PIX_WIDTH_32BPP;
1290         dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
1291                        BYTE_ORDER_LSB_TO_MSB;
1292         dp_chain_mask = 0x8080;
1293     } else
1294         FAIL("invalid bpp");
1295 
1296     if (vxres*vyres*bpp/8 > info->total_vram)
1297         FAIL("not enough video RAM");
1298 
1299     if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
1300         FAIL("invalid vmode");
1301 
1302     /* output */
1303     crtc->vxres = vxres;
1304     crtc->vyres = vyres;
1305     crtc->xoffset = xoffset;
1306     crtc->yoffset = yoffset;
1307     crtc->bpp = bpp;
1308     crtc->h_tot_disp = h_total | (h_disp<<16);
1309     crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
1310                             ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) |
1311                             (h_sync_pol<<21);
1312     crtc->v_tot_disp = v_total | (v_disp<<16);
1313     crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
1314     crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
1315     crtc->gen_cntl = pix_width | c_sync | CRTC_EXT_DISP_EN | CRTC_ENABLE;
1316     if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID) ||
1317         ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07))) {
1318         /* Not VTB/GTB */
1319         /* FIXME: magic FIFO values */
1320         crtc->gen_cntl |= aty_ld_le32(CRTC_GEN_CNTL, info) & 0x000e0000;
1321     }
1322     crtc->dp_pix_width = dp_pix_width;
1323     crtc->dp_chain_mask = dp_chain_mask;
1324 
1325     return 0;
1326 }
1327 
1328 
1329 static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info, u32 bpp,
1330                                   u32 AccelMode)
1331 {
1332     u32 gModeReg, devSetupRegA, temp, mask;
1333 
1334     gModeReg = 0;
1335     devSetupRegA = 0;
1336 
1337     switch (bpp) {
1338         case 8:
1339             gModeReg = 0x83;
1340             devSetupRegA = 0x60 | 0x00 /*(info->mach64DAC8Bit ? 0x00 : 0x01) */;
1341             break;
1342         case 15:
1343             gModeReg = 0xA0;
1344             devSetupRegA = 0x60;
1345             break;
1346         case 16:
1347             gModeReg = 0xA1;
1348             devSetupRegA = 0x60;
1349             break;
1350         case 24:
1351             gModeReg = 0xC0;
1352             devSetupRegA = 0x60;
1353             break;
1354         case 32:
1355             gModeReg = 0xE3;
1356             devSetupRegA = 0x60;
1357             break;
1358     }
1359 
1360     if (!AccelMode) {
1361         gModeReg = 0x80;
1362         devSetupRegA = 0x61;
1363     }
1364 
1365     temp = aty_ld_8(DAC_CNTL, info);
1366     aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
1367 
1368     aty_st_8(DAC_REGS + 2, 0x1D, info);
1369     aty_st_8(DAC_REGS + 3, gModeReg, info);
1370     aty_st_8(DAC_REGS, 0x02, info);
1371 
1372     temp = aty_ld_8(DAC_CNTL, info);
1373     aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
1374 
1375     if (info->total_vram < MEM_SIZE_1M)
1376         mask = 0x04;
1377     else if (info->total_vram == MEM_SIZE_1M)
1378         mask = 0x08;
1379     else
1380         mask = 0x0C;
1381 
1382     /* The following assumes that the BIOS has correctly set R7 of the
1383      * Device Setup Register A at boot time.
1384      */
1385 #define A860_DELAY_L    0x80
1386 
1387     temp = aty_ld_8(DAC_REGS, info);
1388     aty_st_8(DAC_REGS, (devSetupRegA | mask) | (temp & A860_DELAY_L), info);
1389     temp = aty_ld_8(DAC_CNTL, info);
1390     aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)), info);
1391 
1392     return 0;
1393 }
1394 
1395 static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
1396                                  const struct pll_18818 *pll, u32 bpp)
1397 {
1398     u32 dotClock;
1399     int muxmode = 0;
1400     int DACMask = 0;
1401 
1402     dotClock = 100000000 / pll->period_in_ps;
1403 
1404     switch (bpp) {
1405         case 8:
1406             if (dotClock > 8000) {
1407                 DACMask = 0x24;
1408                 muxmode = 1;
1409             } else
1410                 DACMask = 0x04;
1411             break;
1412         case 15:
1413             DACMask = 0x16;
1414             break;
1415         case 16:
1416             DACMask = 0x36;
1417             break;
1418         case 24:
1419             DACMask = 0xE6;
1420             break;
1421         case 32:
1422             DACMask = 0xE6;
1423             break;
1424     }
1425 
1426     if (1 /* info->mach64DAC8Bit */)
1427         DACMask |= 0x02;
1428 
1429     aty_dac_waste4(info);
1430     aty_st_8(DAC_REGS + 2, DACMask, info);
1431 
1432     return muxmode;
1433 }
1434 
1435 void aty_dac_waste4(const struct fb_info_aty *info)
1436 {
1437   (void)aty_ld_8(DAC_REGS, info);
1438 
1439   (void)aty_ld_8(DAC_REGS + 2, info);
1440   (void)aty_ld_8(DAC_REGS + 2, info);
1441   (void)aty_ld_8(DAC_REGS + 2, info);
1442   (void)aty_ld_8(DAC_REGS + 2, info);
1443 }
1444 
1445 
1446 static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp)
1447 {
1448     static struct {
1449         u8 pixel_dly;
1450         u8 misc2_cntl;
1451         u8 pixel_rep;
1452         u8 pixel_cntl_index;
1453         u8 pixel_cntl_v1;
1454     } tab[3] = {
1455         { 0, 0x41, 0x03, 0x71, 0x45 },  /* 8 bpp */
1456         { 0, 0x45, 0x04, 0x0c, 0x01 },  /* 555 */
1457         { 0, 0x45, 0x06, 0x0e, 0x00 },  /* XRGB */
1458     };
1459     int i;
1460 
1461     switch (bpp) {
1462         case 8:
1463         default:
1464             i = 0;
1465             break;
1466         case 16:
1467             i = 1;
1468             break;
1469         case 32:
1470             i = 2;
1471             break;
1472     }
1473     aty_st_514(0x90, 0x00, info);               /* VRAM Mask Low */
1474     aty_st_514(0x04, tab[i].pixel_dly, info);   /* Horizontal Sync Control */
1475     aty_st_514(0x05, 0x00, info);               /* Power Management */
1476     aty_st_514(0x02, 0x01, info);               /* Misc Clock Control */
1477     aty_st_514(0x71, tab[i].misc2_cntl, info);  /* Misc Control 2 */
1478     aty_st_514(0x0a, tab[i].pixel_rep, info);   /* Pixel Format */
1479     aty_st_514(tab[i].pixel_cntl_index, tab[i].pixel_cntl_v1, info);
1480                         /* Misc Control 2 / 16 BPP Control / 32 BPP Control */
1481 }
1482 
1483 static int aty_crtc_to_var(const struct crtc *crtc,
1484                            struct fb_var_screeninfo *var)
1485 {
1486     u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
1487     u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
1488     u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
1489     u32 pix_width;
1490 
1491     /* input */
1492     h_total = crtc->h_tot_disp & 0x1ff;
1493     h_disp = (crtc->h_tot_disp>>16) & 0xff;
1494     h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
1495                   ((crtc->h_sync_strt_wid>>4) & 0x100);
1496     h_sync_dly = (crtc->h_sync_strt_wid>>8) & 0x7;
1497     h_sync_wid = (crtc->h_sync_strt_wid>>16) & 0x1f;
1498     h_sync_pol = (crtc->h_sync_strt_wid>>21) & 0x1;
1499     v_total = crtc->v_tot_disp & 0x7ff;
1500     v_disp = (crtc->v_tot_disp>>16) & 0x7ff;
1501     v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
1502     v_sync_wid = (crtc->v_sync_strt_wid>>16) & 0x1f;
1503     v_sync_pol = (crtc->v_sync_strt_wid>>21) & 0x1;
1504     c_sync = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
1505     pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
1506 
1507     /* convert */
1508     xres = (h_disp+1)*8;
1509     yres = v_disp+1;
1510     left = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;
1511     right = (h_sync_strt-h_disp)*8+h_sync_dly;
1512     hslen = h_sync_wid*8;
1513     upper = v_total-v_sync_strt-v_sync_wid;
1514     lower = v_sync_strt-v_disp;
1515     vslen = v_sync_wid;
1516     sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
1517            (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
1518            (c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
1519 
1520     switch (pix_width) {
1521 #if 0
1522         case CRTC_PIX_WIDTH_4BPP:
1523             bpp = 4;
1524             var->red.offset = 0;
1525             var->red.length = 8;
1526             var->green.offset = 0;
1527             var->green.length = 8;
1528             var->blue.offset = 0;
1529             var->blue.length = 8;
1530             var->transp.offset = 0;
1531             var->transp.length = 0;
1532             break;
1533 #endif
1534         case CRTC_PIX_WIDTH_8BPP:
1535             bpp = 8;
1536             var->red.offset = 0;
1537             var->red.length = 8;
1538             var->green.offset = 0;
1539             var->green.length = 8;
1540             var->blue.offset = 0;
1541             var->blue.length = 8;
1542             var->transp.offset = 0;
1543             var->transp.length = 0;
1544             break;
1545         case CRTC_PIX_WIDTH_15BPP:      /* RGB 555 */
1546             bpp = 16;
1547             var->red.offset = 10;
1548             var->red.length = 5;
1549             var->green.offset = 5;
1550             var->green.length = 5;
1551             var->blue.offset = 0;
1552             var->blue.length = 5;
1553             var->transp.offset = 0;
1554             var->transp.length = 0;
1555             break;
1556 #if 0
1557         case CRTC_PIX_WIDTH_16BPP:      /* RGB 565 */
1558             bpp = 16;
1559             var->red.offset = 11;
1560             var->red.length = 5;
1561             var->green.offset = 5;
1562             var->green.length = 6;
1563             var->blue.offset = 0;
1564             var->blue.length = 5;
1565             var->transp.offset = 0;
1566             var->transp.length = 0;
1567             break;
1568 #endif
1569         case CRTC_PIX_WIDTH_24BPP:      /* RGB 888 */
1570             bpp = 24;
1571             var->red.offset = 16;
1572             var->red.length = 8;
1573             var->green.offset = 8;
1574             var->green.length = 8;
1575             var->blue.offset = 0;
1576             var->blue.length = 8;
1577             var->transp.offset = 0;
1578             var->transp.length = 0;
1579             break;
1580         case CRTC_PIX_WIDTH_32BPP:      /* ARGB 8888 */
1581             bpp = 32;
1582             var->red.offset = 16;
1583             var->red.length = 8;
1584             var->green.offset = 8;
1585             var->green.length = 8;
1586             var->blue.offset = 0;
1587             var->blue.length = 8;
1588             var->transp.offset = 24;
1589             var->transp.length = 8;
1590             break;
1591         default:
1592             FAIL("Invalid pixel width");
1593     }
1594 
1595     /* output */
1596     var->xres = xres;
1597     var->yres = yres;
1598     var->xres_virtual = crtc->vxres;
1599     var->yres_virtual = crtc->vyres;
1600     var->bits_per_pixel = bpp;
1601     var->xoffset = crtc->xoffset;
1602     var->yoffset = crtc->yoffset;
1603     var->left_margin = left;
1604     var->right_margin = right;
1605     var->upper_margin = upper;
1606     var->lower_margin = lower;
1607     var->hsync_len = hslen;
1608     var->vsync_len = vslen;
1609     var->sync = sync;
1610     var->vmode = FB_VMODE_NONINTERLACED;
1611 
1612     return 0;
1613 }
1614 
1615 /* ------------------------------------------------------------------------- */
1616 
1617     /*
1618      *  PLL programming (Mach64 GX family)
1619      *
1620      *  FIXME: use function pointer tables instead of switch statements
1621      */
1622 
1623 static void aty_set_pll_gx(const struct fb_info_aty *info,
1624                            const struct pll_gx *pll)
1625 {
1626     switch (info->clk_type) {
1627         case CLK_ATI18818_1:
1628             aty_st_8(CLOCK_CNTL, pll->m, info);
1629             break;
1630         case CLK_IBMRGB514:
1631             aty_st_514(0x06, 0x02, info);       /* DAC Operation */
1632             aty_st_514(0x10, 0x01, info);       /* PLL Control 1 */
1633             aty_st_514(0x70, 0x01, info);       /* Misc Control 1 */
1634             aty_st_514(0x8f, 0x1f, info);       /* PLL Ref. Divider Input */
1635             aty_st_514(0x03, 0x00, info);       /* Sync Control */
1636             aty_st_514(0x05, 0x00, info);       /* Power Management */
1637             aty_st_514(0x20, pll->m, info);     /* F0 / M0 */
1638             aty_st_514(0x21, pll->n, info);     /* F1 / N0 */
1639             break;
1640     }
1641 }
1642 
1643 
1644 static int aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll)
1645 {
1646     u32 MHz100;         /* in 0.01 MHz */
1647     u32 program_bits;
1648     u32 post_divider;
1649 
1650     /* Calculate the programming word */
1651     MHz100 = 100000000 / period_in_ps;
1652 
1653     program_bits = -1;
1654     post_divider = 1;
1655 
1656     if (MHz100 > MAX_FREQ_2595) {
1657         MHz100 = MAX_FREQ_2595;
1658         return -EINVAL;
1659     } else if (MHz100 < ABS_MIN_FREQ_2595) {
1660         program_bits = 0;       /* MHz100 = 257 */
1661         return -EINVAL;
1662     } else {
1663         while (MHz100 < MIN_FREQ_2595) {
1664             MHz100 *= 2;
1665             post_divider *= 2;
1666         }
1667     }
1668     MHz100 *= 1000;
1669     MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
1670 
1671     MHz100 += 500;    /* + 0.5 round */
1672     MHz100 /= 1000;
1673 
1674     if (program_bits == -1) {
1675         program_bits = MHz100 - N_ADJ_2595;
1676         switch (post_divider) {
1677             case 1:
1678                 program_bits |= 0x0600;
1679                 break;
1680             case 2:
1681                 program_bits |= 0x0400;
1682                 break;
1683             case 4:
1684                 program_bits |= 0x0200;
1685                 break;
1686             case 8:
1687             default:
1688                 break;
1689         }
1690     }
1691 
1692     program_bits |= STOP_BITS_2595;
1693 
1694     pll->program_bits = program_bits;
1695     pll->locationAddr = 0;
1696     pll->post_divider = post_divider;
1697     pll->period_in_ps = period_in_ps;
1698 
1699     return 0;
1700 }
1701 
1702 static u32 aty_pll_18818_to_var(const struct pll_18818 *pll)
1703 {
1704     return(pll->period_in_ps);  /* default for now */
1705 }
1706 
1707 static void aty_set_pll18818(const struct fb_info_aty *info,
1708                              const struct pll_18818 *pll)
1709 {
1710     u32 program_bits;
1711     u32 locationAddr;
1712 
1713     u32 i;
1714 
1715     u8 old_clock_cntl;
1716     u8 old_crtc_ext_disp;
1717 
1718     old_clock_cntl = aty_ld_8(CLOCK_CNTL, info);
1719     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
1720 
1721     old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
1722     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
1723              info);
1724 
1725     mdelay(15); /* delay for 50 (15) ms */
1726 
1727     program_bits = pll->program_bits;
1728     locationAddr = pll->locationAddr;
1729 
1730     /* Program the clock chip */
1731     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);  /* Strobe = 0 */
1732     aty_StrobeClock(info);
1733     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 1, info);  /* Strobe = 0 */
1734     aty_StrobeClock(info);
1735 
1736     aty_ICS2595_put1bit(1, info);    /* Send start bits */
1737     aty_ICS2595_put1bit(0, info);    /* Start bit */
1738     aty_ICS2595_put1bit(0, info);    /* Read / ~Write */
1739 
1740     for (i = 0; i < 5; i++) {   /* Location 0..4 */
1741         aty_ICS2595_put1bit(locationAddr & 1, info);
1742         locationAddr >>= 1;
1743     }
1744 
1745     for (i = 0; i < 8 + 1 + 2 + 2; i++) {
1746         aty_ICS2595_put1bit(program_bits & 1, info);
1747         program_bits >>= 1;
1748     }
1749 
1750     udelay(1000); /* delay for 1 ms */
1751 
1752     (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
1753     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
1754     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, old_clock_cntl | CLOCK_STROBE,
1755              info);
1756 
1757     mdelay(50); /* delay for 50 (15) ms */
1758     aty_st_8(CLOCK_CNTL + info->clk_wr_offset,
1759              ((pll->locationAddr & 0x0F) | CLOCK_STROBE), info);
1760 
1761     return;
1762 }
1763 
1764 
1765 static int aty_var_to_pll_408(u32 period_in_ps, struct pll_18818 *pll)
1766 {
1767     u32 mhz100;         /* in 0.01 MHz */
1768     u32 program_bits;
1769     /* u32 post_divider; */
1770     u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
1771     u32 temp, tempB;
1772     u16 remainder, preRemainder;
1773     short divider = 0, tempA;
1774 
1775     /* Calculate the programming word */
1776     mhz100 = 100000000 / period_in_ps;
1777     mach64MinFreq = MIN_FREQ_2595;
1778     mach64MaxFreq = MAX_FREQ_2595;
1779     mach64RefFreq = REF_FREQ_2595;      /* 14.32 MHz */
1780 
1781     /* Calculate program word */
1782     if (mhz100 == 0)
1783         program_bits = 0xFF;
1784     else {
1785         if (mhz100 < mach64MinFreq)
1786             mhz100 = mach64MinFreq;
1787         if (mhz100 > mach64MaxFreq)
1788             mhz100 = mach64MaxFreq;
1789 
1790         while (mhz100 < (mach64MinFreq << 3)) {
1791             mhz100 <<= 1;
1792             divider += 0x40;
1793         }
1794 
1795         temp = (unsigned int)mhz100;
1796         temp = (unsigned int)(temp * (MIN_N_408 + 2));
1797         temp -= ((short)(mach64RefFreq << 1));
1798 
1799         tempA = MIN_N_408;
1800         preRemainder = 0xFFFF;
1801 
1802         do {
1803             tempB = temp;
1804             remainder = tempB % mach64RefFreq;
1805             tempB = tempB / mach64RefFreq;
1806             if (((tempB & 0xFFFF) <= 255) && (remainder <= preRemainder)) {
1807                 preRemainder = remainder;
1808                 divider &= ~0x3f;
1809                 divider |= tempA;
1810                 divider = (divider & 0x00FF) + ((tempB & 0xFF) << 8);
1811             }
1812             temp += mhz100;
1813             tempA++;
1814         } while(tempA <= 32);
1815 
1816         program_bits = divider;
1817     }
1818 
1819     pll->program_bits = program_bits;
1820     pll->locationAddr = 0;
1821     pll->post_divider = divider;        /* fuer nix */
1822     pll->period_in_ps = period_in_ps;
1823 
1824     return 0;
1825 }
1826 
1827 static u32 aty_pll_408_to_var(const struct pll_18818 *pll)
1828 {
1829     return(pll->period_in_ps);  /* default for now */
1830 }
1831 
1832 static void aty_set_pll_408(const struct fb_info_aty *info,
1833                             const struct pll_18818 *pll)
1834 {
1835     u32 program_bits;
1836     u32 locationAddr;
1837 
1838     u8 tmpA, tmpB, tmpC;
1839     char old_crtc_ext_disp;
1840 
1841     old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
1842     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
1843              info);
1844 
1845     program_bits = pll->program_bits;
1846     locationAddr = pll->locationAddr;
1847 
1848     /* Program clock */
1849     aty_dac_waste4(info);
1850     tmpB = aty_ld_8(DAC_REGS + 2, info) | 1;
1851     aty_dac_waste4(info);
1852     aty_st_8(DAC_REGS + 2, tmpB, info);
1853 
1854     tmpA = tmpB;
1855     tmpC = tmpA;
1856     tmpA |= 8;
1857     tmpB = 1;
1858 
1859     aty_st_8(DAC_REGS, tmpB, info);
1860     aty_st_8(DAC_REGS + 2, tmpA, info);
1861 
1862     udelay(400); /* delay for 400 us */
1863 
1864     locationAddr = (locationAddr << 2) + 0x40;
1865     tmpB = locationAddr;
1866     tmpA = program_bits >> 8;
1867 
1868     aty_st_8(DAC_REGS, tmpB, info);
1869     aty_st_8(DAC_REGS + 2, tmpA, info);
1870 
1871     tmpB = locationAddr + 1;
1872     tmpA = (u8)program_bits;
1873 
1874     aty_st_8(DAC_REGS, tmpB, info);
1875     aty_st_8(DAC_REGS + 2, tmpA, info);
1876 
1877     tmpB = locationAddr + 2;
1878     tmpA = 0x77;
1879 
1880     aty_st_8(DAC_REGS, tmpB, info);
1881     aty_st_8(DAC_REGS + 2, tmpA, info);
1882 
1883     udelay(400); /* delay for 400 us */
1884     tmpA = tmpC & (~(1 | 8));
1885     tmpB = 1;
1886 
1887     aty_st_8(DAC_REGS, tmpB, info);
1888     aty_st_8(DAC_REGS + 2, tmpA, info);
1889 
1890     (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
1891     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
1892 
1893     return;
1894 }
1895 
1896 
1897 static int aty_var_to_pll_1703(u32 period_in_ps, struct pll_18818 *pll)
1898 {
1899     u32 mhz100;                 /* in 0.01 MHz */
1900     u32 program_bits;
1901     /* u32 post_divider; */
1902     u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
1903     u32 temp, tempB;
1904     u16 remainder, preRemainder;
1905     short divider = 0, tempA;
1906 
1907     /* Calculate the programming word */
1908     mhz100 = 100000000 / period_in_ps;
1909     mach64MinFreq = MIN_FREQ_2595;
1910     mach64MaxFreq = MAX_FREQ_2595;
1911     mach64RefFreq = REF_FREQ_2595;      /* 14.32 MHz */
1912 
1913     /* Calculate program word */
1914     if (mhz100 == 0)
1915         program_bits = 0xE0;
1916     else {
1917         if (mhz100 < mach64MinFreq)
1918             mhz100 = mach64MinFreq;
1919         if (mhz100 > mach64MaxFreq)
1920             mhz100 = mach64MaxFreq;
1921 
1922         divider = 0;
1923         while (mhz100 < (mach64MinFreq << 3)) {
1924             mhz100 <<= 1;
1925             divider += 0x20;
1926         }
1927 
1928         temp = (unsigned int)(mhz100);
1929         temp = (unsigned int)(temp * (MIN_N_1703 + 2));
1930         temp -= (short)(mach64RefFreq << 1);
1931 
1932         tempA = MIN_N_1703;
1933         preRemainder = 0xffff;
1934 
1935         do {
1936             tempB = temp;
1937             remainder = tempB % mach64RefFreq;
1938             tempB = tempB / mach64RefFreq;
1939 
1940             if ((tempB & 0xffff) <= 127 && (remainder <= preRemainder)) {
1941                 preRemainder = remainder;
1942                 divider &= ~0x1f;
1943                 divider |= tempA;
1944                 divider = (divider & 0x00ff) + ((tempB & 0xff) << 8);
1945             }
1946 
1947             temp += mhz100;
1948             tempA++;
1949         } while (tempA <= (MIN_N_1703 << 1));
1950 
1951         program_bits = divider;
1952     }
1953 
1954       pll->program_bits = program_bits;
1955       pll->locationAddr = 0;
1956       pll->post_divider = divider;  /* fuer nix */
1957       pll->period_in_ps = period_in_ps;
1958 
1959       return 0;
1960 }
1961 
1962 static u32 aty_pll_1703_to_var(const struct pll_18818 *pll)
1963 {
1964     return(pll->period_in_ps);  /* default for now */
1965 }
1966 
1967 static void aty_set_pll_1703(const struct fb_info_aty *info,
1968                              const struct pll_18818 *pll)
1969 {
1970     u32 program_bits;
1971     u32 locationAddr;
1972 
1973     char old_crtc_ext_disp;
1974 
1975     old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
1976     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
1977              info);
1978 
1979     program_bits = pll->program_bits;
1980     locationAddr = pll->locationAddr;
1981 
1982     /* Program clock */
1983     aty_dac_waste4(info);
1984 
1985     (void)aty_ld_8(DAC_REGS + 2, info);
1986     aty_st_8(DAC_REGS+2, (locationAddr << 1) + 0x20, info);
1987     aty_st_8(DAC_REGS+2, 0, info);
1988     aty_st_8(DAC_REGS+2, (program_bits & 0xFF00) >> 8, info);
1989     aty_st_8(DAC_REGS+2, (program_bits & 0xFF), info);
1990 
1991     (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
1992     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
1993 
1994     return;
1995 }
1996 
1997 
1998 static int aty_var_to_pll_8398(u32 period_in_ps, struct pll_18818 *pll)
1999 {
2000 
2001     u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
2002 
2003     u32 mhz100;                         /* in 0.01 MHz */
2004     u32 program_bits;
2005     /* u32 post_divider; */
2006     u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
2007     u16 m, n, k=0, save_m, save_n, twoToKth;
2008 
2009     /* Calculate the programming word */
2010     mhz100 = 100000000 / period_in_ps;
2011     mach64MinFreq = MIN_FREQ_2595;
2012     mach64MaxFreq = MAX_FREQ_2595;
2013     mach64RefFreq = REF_FREQ_2595;      /* 14.32 MHz */
2014 
2015     save_m = 0;
2016     save_n = 0;
2017 
2018     /* Calculate program word */
2019     if (mhz100 == 0)
2020         program_bits = 0xE0;
2021     else
2022     {
2023         if (mhz100 < mach64MinFreq)
2024             mhz100 = mach64MinFreq;
2025         if (mhz100 > mach64MaxFreq)
2026             mhz100 = mach64MaxFreq;
2027 
2028         longMHz100 = mhz100 * 256 / 100;   /* 8 bit scale this */
2029 
2030         while (mhz100 < (mach64MinFreq << 3))
2031         {
2032             mhz100 <<= 1;
2033             k++;
2034         }
2035 
2036         twoToKth = 1 << k;
2037         diff = 0;
2038         preDiff = 0xFFFFFFFF;
2039 
2040         for (m = MIN_M; m <= MAX_M; m++)
2041         {
2042             for (n = MIN_N; n <= MAX_N; n++)
2043             {
2044                 tempA = (14.31818 * 65536);
2045                 tempA *= (n + 8);  /* 43..256 */
2046                 tempB = twoToKth * 256;
2047                 tempB *= (m + 2);  /* 4..32 */
2048                 fOut = tempA / tempB;  /* 8 bit scale */
2049 
2050                 if (longMHz100 > fOut)
2051                     diff = longMHz100 - fOut;
2052                 else
2053                     diff = fOut - longMHz100;
2054 
2055                 if (diff < preDiff)
2056                 {
2057                     save_m = m;
2058                     save_n = n;
2059                     preDiff = diff;
2060                 }
2061             }
2062         }
2063 
2064         program_bits = (k << 6) + (save_m) + (save_n << 8);
2065     }
2066 
2067     pll->program_bits = program_bits;
2068     pll->locationAddr = 0;
2069     pll->post_divider = 0;
2070     pll->period_in_ps = period_in_ps;
2071 
2072     return 0;
2073 }
2074 
2075 static u32 aty_pll_8398_to_var(const struct pll_18818 *pll)
2076 {
2077     return(pll->period_in_ps);  /* default for now */
2078 }
2079 
2080 static void aty_set_pll_8398(const struct fb_info_aty *info,
2081                              const struct pll_18818 *pll)
2082 {
2083     u32 program_bits;
2084     u32 locationAddr;
2085 
2086     char old_crtc_ext_disp;
2087     char tmp;
2088 
2089     old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
2090     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
2091              info);
2092 
2093     program_bits = pll->program_bits;
2094     locationAddr = pll->locationAddr;
2095 
2096     /* Program clock */
2097     tmp = aty_ld_8(DAC_CNTL, info);
2098     aty_st_8(DAC_CNTL, tmp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
2099 
2100     aty_st_8(DAC_REGS, locationAddr, info);
2101     aty_st_8(DAC_REGS+1, (program_bits & 0xff00) >> 8, info);
2102     aty_st_8(DAC_REGS+1, (program_bits & 0xff), info);
2103 
2104     tmp = aty_ld_8(DAC_CNTL, info);
2105     aty_st_8(DAC_CNTL, (tmp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
2106 
2107     (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
2108     aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
2109 
2110     return;
2111 }
2112 
2113 
2114 static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll)
2115 {
2116     /*
2117      *  FIXME: use real calculations instead of using fixed values from the old
2118      *         driver
2119      */
2120     static struct {
2121         u32 limit;      /* pixlock rounding limit (arbitrary) */
2122         u8 m;           /* (df<<6) | vco_div_count */
2123         u8 n;           /* ref_div_count */
2124     } RGB514_clocks[7] = {
2125         {  8000, (3<<6) | 20, 9 },      /*  7395 ps / 135.2273 MHz */
2126         { 10000, (1<<6) | 19, 3 },      /*  9977 ps / 100.2273 MHz */
2127         { 13000, (1<<6) |  2, 3 },      /* 12509 ps /  79.9432 MHz */
2128         { 14000, (2<<6) |  8, 7 },      /* 13394 ps /  74.6591 MHz */
2129         { 16000, (1<<6) | 44, 6 },      /* 15378 ps /  65.0284 MHz */
2130         { 25000, (1<<6) | 15, 5 },      /* 17460 ps /  57.2727 MHz */
2131         { 50000, (0<<6) | 53, 7 },      /* 33145 ps /  30.1705 MHz */
2132     };
2133     int i;
2134 
2135     for (i = 0; i < sizeof(RGB514_clocks)/sizeof(*RGB514_clocks); i++)
2136         if (vclk_per <= RGB514_clocks[i].limit) {
2137             pll->m = RGB514_clocks[i].m;
2138             pll->n = RGB514_clocks[i].n;
2139             return 0;
2140         }
2141     return -EINVAL;
2142 }
2143 
2144 
2145 static void aty_StrobeClock(const struct fb_info_aty *info)
2146 {
2147     u8 tmp;
2148 
2149     udelay(26);
2150 
2151     tmp = aty_ld_8(CLOCK_CNTL, info);
2152     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, tmp | CLOCK_STROBE, info);
2153 
2154     return;
2155 }
2156 
2157 
2158 static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info)
2159 {
2160     u8 tmp;
2161 
2162     data &= 0x01;
2163     tmp = aty_ld_8(CLOCK_CNTL, info);
2164     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x04) | (data << 2),
2165              info);
2166 
2167     tmp = aty_ld_8(CLOCK_CNTL, info);
2168     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (0 << 3), info);
2169 
2170     aty_StrobeClock(info);
2171 
2172     tmp = aty_ld_8(CLOCK_CNTL, info);
2173     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (1 << 3), info);
2174 
2175     aty_StrobeClock(info);
2176 
2177     return;
2178 }
2179 
2180 
2181 static u32 aty_pll_gx_to_var(const struct pll_gx *pll,
2182                              const struct fb_info_aty *info)
2183 {
2184     u8 df, vco_div_count, ref_div_count;
2185 
2186     df = pll->m >> 6;
2187     vco_div_count = pll->m & 0x3f;
2188     ref_div_count = pll->n;
2189 
2190     return ((info->ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
2191 }
2192 
2193 
2194     /*
2195      *  PLL programming (Mach64 CT family)
2196      */
2197 
2198 static void aty_set_pll_ct(const struct fb_info_aty *info,
2199                            const struct pll_ct *pll)
2200 {
2201     aty_st_pll(PLL_REF_DIV, pll->pll_ref_div, info);
2202     aty_st_pll(PLL_GEN_CNTL, pll->pll_gen_cntl, info);
2203     aty_st_pll(MCLK_FB_DIV, pll->mclk_fb_div, info);
2204     aty_st_pll(PLL_VCLK_CNTL, pll->pll_vclk_cntl, info);
2205     aty_st_pll(VCLK_POST_DIV, pll->vclk_post_div, info);
2206     aty_st_pll(VCLK0_FB_DIV, pll->vclk_fb_div, info);
2207     aty_st_pll(PLL_EXT_CNTL, pll->pll_ext_cntl, info);
2208 
2209     if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
2210           Gx == ET_CHIP_ID ||
2211           ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)))) {
2212         if (info->ram_type >= SDRAM)
2213             aty_st_pll(DLL_CNTL, 0xa6, info);
2214         else
2215             aty_st_pll(DLL_CNTL, 0xa0, info);
2216         aty_st_pll(VFC_CNTL, 0x1b, info);
2217         aty_st_le32(DSP_CONFIG, pll->dsp_config, info);
2218         aty_st_le32(DSP_ON_OFF, pll->dsp_on_off, info);
2219     }
2220 }
2221 
2222 static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
2223                       struct pll_ct *pll)
2224 {
2225     u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
2226     u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
2227 
2228     /* xclocks_per_row<<11 */
2229     xclks_per_row = (pll->mclk_fb_div*pll->vclk_post_div_real*64<<11)/
2230                     (pll->vclk_fb_div*pll->mclk_post_div_real*bpp);
2231     if (xclks_per_row < (1<<11))
2232         FAIL("Dotclock to high");
2233     if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == VT_CHIP_ID ||
2234         Gx == VU_CHIP_ID || Gx == GV_CHIP_ID || Gx == GW_CHIP_ID ||
2235         Gx == GZ_CHIP_ID) {
2236         fifo_size = 24;
2237         dsp_loop_latency = 0;
2238     } else {
2239         fifo_size = 32;
2240         dsp_loop_latency = 2;
2241     }
2242     dsp_precision = 0;
2243     y = (xclks_per_row*fifo_size)>>11;
2244     while (y) {
2245         y >>= 1;
2246         dsp_precision++;
2247     }
2248     dsp_precision -= 5;
2249     /* fifo_off<<6 */
2250     fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6);
2251 
2252     if (info->total_vram > 1*1024*1024) {
2253         if (info->ram_type >= SDRAM) {
2254             /* >1 MB SDRAM */
2255             dsp_loop_latency += 8;
2256             page_size = 8;
2257         } else {
2258             /* >1 MB DRAM */
2259             dsp_loop_latency += 6;
2260             page_size = 9;
2261         }
2262     } else {
2263         if (info->ram_type >= SDRAM) {
2264             /* <2 MB SDRAM */
2265             dsp_loop_latency += 9;
2266             page_size = 10;
2267         } else {
2268             /* <2 MB DRAM */
2269             dsp_loop_latency += 8;
2270             page_size = 10;
2271         }
2272     }
2273     /* fifo_on<<6 */
2274     if (xclks_per_row >= (page_size<<11))
2275         fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);
2276     else
2277         fifo_on = (3*page_size+2)<<6;
2278 
2279     dsp_xclks_per_row = xclks_per_row>>dsp_precision;
2280     dsp_on = fifo_on>>dsp_precision;
2281     dsp_off = fifo_off>>dsp_precision;
2282 
2283     pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
2284                       ((dsp_loop_latency & 0xf)<<16) |
2285                       ((dsp_precision & 7)<<20);
2286     pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff)<<16);
2287     return 0;
2288 }
2289 
2290 static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
2291                             struct pll_ct *pll)
2292 {
2293     u32 q, x;                   /* x is a workaround for sparc64-linux-gcc */
2294     x = x;                      /* x is a workaround for sparc64-linux-gcc */
2295 
2296     pll->pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
2297 
2298     /* FIXME: use the VTB/GTB /3 post divider if it's better suited */
2299     q = info->ref_clk_per*pll->pll_ref_div*4/info->mclk_per;    /* actually 8*q */
2300     if (q < 16*8 || q > 255*8)
2301         FAIL("mclk out of range");
2302     else if (q < 32*8)
2303         pll->mclk_post_div_real = 8;
2304     else if (q < 64*8)
2305         pll->mclk_post_div_real = 4;
2306     else if (q < 128*8)
2307         pll->mclk_post_div_real = 2;
2308     else
2309         pll->mclk_post_div_real = 1;
2310     pll->mclk_fb_div = q*pll->mclk_post_div_real/8;
2311 
2312     /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
2313     q = info->ref_clk_per*pll->pll_ref_div*4/vclk_per;  /* actually 8*q */
2314     if (q < 16*8 || q > 255*8)
2315         FAIL("vclk out of range");
2316     else if (q < 32*8)
2317         pll->vclk_post_div_real = 8;
2318     else if (q < 64*8)
2319         pll->vclk_post_div_real = 4;
2320     else if (q < 128*8)
2321         pll->vclk_post_div_real = 2;
2322     else
2323         pll->vclk_post_div_real = 1;
2324     pll->vclk_fb_div = q*pll->vclk_post_div_real/8;
2325     return 0;
2326 }
2327 
2328 static void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
2329 {
2330     u8 mpostdiv = 0;
2331     u8 vpostdiv = 0;
2332 
2333     if ((((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_CHIP_ID) ||
2334          (Gx == GV_CHIP_ID) || (Gx == GW_CHIP_ID) || (Gx == GZ_CHIP_ID) ||
2335          (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) ||
2336          (Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID) ||
2337          (Gx == VU_CHIP_ID)) && (info->ram_type >= SDRAM))
2338         pll->pll_gen_cntl = 0x04;
2339     else
2340         pll->pll_gen_cntl = 0x84;
2341 
2342     switch (pll->mclk_post_div_real) {
2343         case 1:
2344             mpostdiv = 0;
2345             break;
2346         case 2:
2347             mpostdiv = 1;
2348             break;
2349         case 3:
2350             mpostdiv = 4;
2351             break;
2352         case 4:
2353             mpostdiv = 2;
2354             break;
2355         case 8:
2356             mpostdiv = 3;
2357             break;
2358     }
2359     pll->pll_gen_cntl |= mpostdiv<<4;   /* mclk */
2360 
2361     if (Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48))
2362         pll->pll_ext_cntl = 0;
2363     else
2364         pll->pll_ext_cntl = mpostdiv;   /* xclk == mclk */
2365 
2366     switch (pll->vclk_post_div_real) {
2367         case 2:
2368             vpostdiv = 1;
2369             break;
2370         case 3:
2371             pll->pll_ext_cntl |= 0x10;
2372         case 1:
2373             vpostdiv = 0;
2374             break;
2375         case 6:
2376             pll->pll_ext_cntl |= 0x10;
2377         case 4:
2378             vpostdiv = 2;
2379             break;
2380         case 12:
2381             pll->pll_ext_cntl |= 0x10;
2382         case 8:
2383             vpostdiv = 3;
2384             break;
2385     }
2386 
2387     pll->pll_vclk_cntl = 0x03;  /* VCLK = PLL_VCLK/VCLKx_POST */
2388     pll->vclk_post_div = vpostdiv;
2389 }
2390 
2391 static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
2392                              u8 bpp, struct pll_ct *pll)
2393 {
2394     int err;
2395 
2396     if ((err = aty_valid_pll_ct(info, vclk_per, pll)))
2397         return err;
2398     if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
2399           Gx == ET_CHIP_ID ||
2400           ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)))) {
2401         if ((err = aty_dsp_gt(info, bpp, pll)))
2402             return err;
2403     }
2404     aty_calc_pll_ct(info, pll);
2405     return 0;
2406 }
2407 
2408 static u32 aty_pll_ct_to_var(const struct pll_ct *pll,
2409                              const struct fb_info_aty *info)
2410 {
2411     u32 ref_clk_per = info->ref_clk_per;
2412     u8 pll_ref_div = pll->pll_ref_div;
2413     u8 vclk_fb_div = pll->vclk_fb_div;
2414     u8 vclk_post_div = pll->vclk_post_div_real;
2415 
2416     return ref_clk_per*pll_ref_div*vclk_post_div/vclk_fb_div/2;
2417 }
2418 
2419 /* ------------------------------------------------------------------------- */
2420 
2421 static void atyfb_set_par(const struct atyfb_par *par,
2422                           struct fb_info_aty *info)
2423 {
2424     u32 i;
2425     int accelmode;
2426     int muxmode;
2427     u8 tmp;
2428 
2429     accelmode = par->accel_flags;  /* hack */
2430 
2431     info->current_par = *par;
2432 
2433     if (info->blitter_may_be_busy)
2434         wait_for_idle(info);
2435     tmp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
2436     aty_set_crtc(info, &par->crtc);
2437     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
2438                                         /* better call aty_StrobeClock ?? */
2439     aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);
2440 
2441     if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
2442         switch (info->dac_subtype) {
2443             case DAC_IBMRGB514:
2444                 aty_set_dac_514(info, par->crtc.bpp);
2445                 break;
2446             case DAC_ATI68860_B:
2447             case DAC_ATI68860_C:
2448                 muxmode = aty_set_dac_ATI68860_B(info, par->crtc.bpp,
2449                                                  accelmode);
2450                 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2451                 aty_st_le32(DAC_CNTL, 0x47052100, info);
2452                 break;
2453             case DAC_ATT20C408:
2454                 muxmode = aty_set_dac_ATT21C498(info, &par->pll.ics2595,
2455                                                 par->crtc.bpp);
2456                 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2457                 aty_st_le32(DAC_CNTL, 0x00072000, info);
2458                 break;
2459             case DAC_ATT21C498:
2460                 muxmode = aty_set_dac_ATT21C498(info, &par->pll.ics2595,
2461                                                 par->crtc.bpp);
2462                 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2463                 aty_st_le32(DAC_CNTL, 0x00072000, info);
2464                 break;
2465             default:
2466                 printk(" atyfb_set_par: DAC type not implemented yet!\n");
2467                 aty_st_le32(BUS_CNTL, 0x890e20f1, info);
2468                 aty_st_le32(DAC_CNTL, 0x47052100, info);
2469         /* new in 2.2.3p1 from Geert. ???????? */
2470         aty_st_le32(BUS_CNTL, 0x590e10ff, info);
2471         aty_st_le32(DAC_CNTL, 0x47012100, info);
2472                 break;
2473         }
2474 
2475         switch (info->clk_type) {
2476             case CLK_ATI18818_1:
2477                 aty_set_pll18818(info, &par->pll.ics2595);
2478                 break;
2479             case CLK_STG1703:
2480                 aty_set_pll_1703(info, &par->pll.ics2595);
2481                 break;
2482             case CLK_CH8398:
2483                 aty_set_pll_8398(info, &par->pll.ics2595);
2484                 break;
2485             case CLK_ATT20C408:
2486                 aty_set_pll_408(info, &par->pll.ics2595);
2487                 break;
2488             case CLK_IBMRGB514:
2489                 aty_set_pll_gx(info, &par->pll.gx);
2490                 break;
2491             default:
2492                 printk(" atyfb_set_par: CLK type not implemented yet!");
2493                 break;
2494         }
2495 
2496         /* Don't forget MEM_CNTL */
2497         i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;
2498         switch (par->crtc.bpp) {
2499             case 8:
2500                 i |= 0x02000000;
2501                 break;
2502             case 16:
2503                 i |= 0x03000000;
2504                 break;
2505             case 32:
2506                 i |= 0x06000000;
2507                 break;
2508         }
2509         aty_st_le32(MEM_CNTL, i, info);
2510 
2511     } else {
2512         aty_set_pll_ct(info, &par->pll.ct);
2513         i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;
2514         if (!(Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48)))
2515             i |= info->mem_refresh_rate << 20;
2516         switch (par->crtc.bpp) {
2517             case 8:
2518             case 24:
2519                 i |= 0x00000000;
2520                 break;
2521             case 16:
2522                 i |= 0x04000000;
2523                 break;
2524             case 32:
2525                 i |= 0x08000000;
2526                 break;
2527         }
2528         if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
2529             aty_st_le32(DAC_CNTL, 0x87010184, info);
2530             aty_st_le32(BUS_CNTL, 0x680000f9, info);
2531         } else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
2532             aty_st_le32(DAC_CNTL, 0x87010184, info);
2533             aty_st_le32(BUS_CNTL, 0x680000f9, info);
2534         }  else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
2535             aty_st_le32(DAC_CNTL, 0x80010102, info);
2536             aty_st_le32(BUS_CNTL, 0x7b33a040, info);
2537         } else {
2538             /* GT */
2539             aty_st_le32(DAC_CNTL, 0x86010102, info);
2540             aty_st_le32(BUS_CNTL, 0x7b23a040, info);
2541             aty_st_le32(EXT_MEM_CNTL,
2542                         aty_ld_le32(EXT_MEM_CNTL, info) | 0x5000001, info);
2543         }
2544         aty_st_le32(MEM_CNTL, i, info);
2545     }
2546     aty_st_8(DAC_MASK, 0xff, info);
2547 
2548     /* Initialize the graphics engine */
2549     if (par->accel_flags & FB_ACCELF_TEXT)
2550         init_engine(par, info);
2551 
2552 #ifdef CONFIG_FB_COMPAT_XPMAC
2553     if (!console_fb_info || console_fb_info == &info->fb_info) {
2554         struct fb_var_screeninfo var;
2555         int vmode, cmode;
2556         display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
2557         display_info.width = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
2558         display_info.depth = par->crtc.bpp;
2559         display_info.pitch = par->crtc.vxres*par->crtc.bpp/8;
2560         atyfb_encode_var(&var, par, info);
2561         if (mac_var_to_vmode(&var, &vmode, &cmode))
2562             display_info.mode = 0;
2563         else
2564             display_info.mode = vmode;
2565         strcpy(display_info.name, atyfb_name);
2566         display_info.fb_address = info->frame_buffer_phys;
2567         display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;
2568         display_info.cmap_data_address = info->ati_regbase_phys+0xc1;
2569         display_info.disp_reg_address = info->ati_regbase_phys;
2570     }
2571 #endif /* CONFIG_FB_COMPAT_XPMAC */
2572 }
2573 
2574 static int atyfb_decode_var(const struct fb_var_screeninfo *var,
2575                             struct atyfb_par *par,
2576                             const struct fb_info_aty *info)
2577 {
2578     int err;
2579 
2580     if ((err = aty_var_to_crtc(info, var, &par->crtc)))
2581         return err;
2582     if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
2583         switch (info->clk_type) {
2584             case CLK_ATI18818_1:
2585                 err = aty_var_to_pll_18818(var->pixclock, &par->pll.ics2595);
2586                 break;
2587             case CLK_STG1703:
2588                 err = aty_var_to_pll_1703(var->pixclock, &par->pll.ics2595);
2589                 break;
2590             case CLK_CH8398:
2591                 err = aty_var_to_pll_8398(var->pixclock, &par->pll.ics2595);
2592                 break;
2593             case CLK_ATT20C408:
2594                 err = aty_var_to_pll_408(var->pixclock, &par->pll.ics2595);
2595                 break;
2596             case CLK_IBMRGB514:
2597                 err = aty_var_to_pll_514(var->pixclock, &par->pll.gx);
2598                 break;
2599         }
2600     else
2601         err = aty_var_to_pll_ct(info, var->pixclock, par->crtc.bpp,
2602                                 &par->pll.ct);
2603     if (err)
2604         return err;
2605 
2606     if (var->accel_flags & FB_ACCELF_TEXT)
2607         par->accel_flags = FB_ACCELF_TEXT;
2608     else
2609         par->accel_flags = 0;
2610 
2611 #if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
2612     if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
2613         return -EINVAL;
2614 #endif
2615 
2616     return 0;
2617 }
2618 
2619 static int atyfb_encode_var(struct fb_var_screeninfo *var,
2620                             const struct atyfb_par *par,
2621                             const struct fb_info_aty *info)
2622 {
2623     int err;
2624 
2625     memset(var, 0, sizeof(struct fb_var_screeninfo));
2626 
2627     if ((err = aty_crtc_to_var(&par->crtc, var)))
2628         return err;
2629     if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
2630         switch (info->clk_type) {
2631             case CLK_ATI18818_1:
2632                 var->pixclock = aty_pll_18818_to_var(&par->pll.ics2595);
2633                 break;
2634             case CLK_STG1703:
2635                 var->pixclock = aty_pll_1703_to_var(&par->pll.ics2595);
2636                 break;
2637             case CLK_CH8398:
2638                 var->pixclock = aty_pll_8398_to_var(&par->pll.ics2595);
2639                 break;
2640             case CLK_ATT20C408:
2641                 var->pixclock = aty_pll_408_to_var(&par->pll.ics2595);
2642                 break;
2643             case CLK_IBMRGB514:
2644                 var->pixclock = aty_pll_gx_to_var(&par->pll.gx, info);
2645                 break;
2646         }
2647     else
2648         var->pixclock = aty_pll_ct_to_var(&par->pll.ct, info);
2649 
2650     var->height = -1;
2651     var->width = -1;
2652     var->accel_flags = par->accel_flags;
2653 
2654     return 0;
2655 }
2656 
2657 
2658 
2659 static void set_off_pitch(struct atyfb_par *par,
2660                           const struct fb_info_aty *info)
2661 {
2662     u32 xoffset = par->crtc.xoffset;
2663     u32 yoffset = par->crtc.yoffset;
2664     u32 vxres = par->crtc.vxres;
2665     u32 bpp = par->crtc.bpp;
2666 
2667     par->crtc.off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
2668     aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, info);
2669 }
2670 
2671 
2672     /*
2673      *  Open/Release the frame buffer device
2674      */
2675 
2676 static int atyfb_open(struct fb_info *info, int user)
2677 
2678 {
2679 #ifdef __sparc__
2680     struct fb_info_aty *fb = (struct fb_info_aty *)info;
2681 
2682     if (user) {
2683         fb->open++;
2684         fb->mmaped = 0;
2685         fb->vtconsole = -1;
2686     } else {
2687         fb->consolecnt++;
2688     }
2689 #endif
2690     return(0);
2691 }
2692 
2693 struct fb_var_screeninfo default_var = {
2694     /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
2695     640, 480, 640, 480, 0, 0, 8, 0,
2696     {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
2697     0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
2698     0, FB_VMODE_NONINTERLACED
2699 };
2700 
2701 static int atyfb_release(struct fb_info *info, int user)
2702 {
2703 #ifdef __sparc__
2704     struct fb_info_aty *fb = (struct fb_info_aty *)info;
2705 
2706     if (user) {
2707         fb->open--;
2708         udelay(1000);
2709         wait_for_idle(fb);
2710         if (!fb->open) {
2711                 int was_mmaped = fb->mmaped;
2712 
2713                 fb->mmaped = 0;
2714                 if (fb->vtconsole != -1)
2715                         vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
2716                 fb->vtconsole = -1;
2717 
2718                 if (was_mmaped) {
2719                         struct fb_var_screeninfo var;
2720 
2721                         /* Now reset the default display config, we have no
2722                          * idea what the program(s) which mmap'd the chip did
2723                          * to the configuration, nor whether it restored it
2724                          * correctly.
2725                          */
2726                         var = default_var;
2727                         if (noaccel)
2728                                 var.accel_flags &= ~FB_ACCELF_TEXT;
2729                         else
2730                                 var.accel_flags |= FB_ACCELF_TEXT;
2731                         if (var.yres == var.yres_virtual) {
2732                                 u32 vram = (fb->total_vram - (PAGE_SIZE << 2));
2733                                 var.yres_virtual = ((vram * 8) / var.bits_per_pixel) /
2734                                         var.xres_virtual;
2735                                 if (var.yres_virtual < var.yres)
2736                                         var.yres_virtual = var.yres;
2737                         }
2738                         atyfb_set_var(&var, -1, &fb->fb_info);
2739                 }
2740         }
2741     } else {
2742         fb->consolecnt--;
2743     }
2744 #endif
2745     return(0);
2746 }
2747 
2748 
2749 static int encode_fix(struct fb_fix_screeninfo *fix,
2750                       const struct atyfb_par *par,
2751                       const struct fb_info_aty *info)
2752 {
2753     memset(fix, 0, sizeof(struct fb_fix_screeninfo));
2754 
2755     strcpy(fix->id, atyfb_name);
2756     fix->smem_start = info->frame_buffer_phys;
2757     fix->smem_len = (u32)info->total_vram;
2758 
2759     /*
2760      *  Reg Block 0 (CT-compatible block) is at ati_regbase_phys
2761      *  Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
2762      */
2763     if (Gx == GX_CHIP_ID || Gx == CX_CHIP_ID) {
2764         fix->mmio_start = info->ati_regbase_phys;
2765         fix->mmio_len = 0x400;
2766         fix->accel = FB_ACCEL_ATI_MACH64GX;
2767     } else if (Gx == CT_CHIP_ID || Gx == ET_CHIP_ID) {
2768         fix->mmio_start = info->ati_regbase_phys;
2769         fix->mmio_len = 0x400;
2770         fix->accel = FB_ACCEL_ATI_MACH64CT;
2771     } else if (Gx == VT_CHIP_ID || Gx == VU_CHIP_ID || Gx == VV_CHIP_ID) {
2772         fix->mmio_start = info->ati_regbase_phys-0x400;
2773         fix->mmio_len = 0x800;
2774         fix->accel = FB_ACCEL_ATI_MACH64VT;
2775     } else {
2776         fix->mmio_start = info->ati_regbase_phys-0x400;
2777         fix->mmio_len = 0x800;
2778         fix->accel = FB_ACCEL_ATI_MACH64GT;
2779     }
2780     fix->type = FB_TYPE_PACKED_PIXELS;
2781     fix->type_aux = 0;
2782     fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
2783     fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
2784                                      : FB_VISUAL_DIRECTCOLOR;
2785     fix->ywrapstep = 0;
2786     fix->xpanstep = 8;
2787     fix->ypanstep = 1;
2788 
2789     return 0;
2790 }
2791 
2792 
2793     /*
2794      *  Get the Fixed Part of the Display
2795      */
2796 
2797 static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
2798                          struct fb_info *fb)
2799 {
2800     const struct fb_info_aty *info = (struct fb_info_aty *)fb;
2801     struct atyfb_par par;
2802 
2803     if (con == -1)
2804         par = info->default_par;
2805     else
2806         atyfb_decode_var(&fb_display[con].var, &par, info);
2807     encode_fix(fix, &par, info);
2808     return 0;
2809 }
2810 
2811 
2812     /*
2813      *  Get the User Defined Part of the Display
2814      */
2815 
2816 static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
2817                          struct fb_info *fb)
2818 {
2819     const struct fb_info_aty *info = (struct fb_info_aty *)fb;
2820 
2821     if (con == -1)
2822         atyfb_encode_var(var, &info->default_par, info);
2823     else
2824         *var = fb_display[con].var;
2825     return 0;
2826 }
2827 
2828 
2829 static void atyfb_set_dispsw(struct display *disp, struct fb_info_aty *info,
2830                              int bpp, int accel)
2831 {
2832             switch (bpp) {
2833 #ifdef FBCON_HAS_CFB8
2834                 case 8:
2835                     info->dispsw = accel ? fbcon_aty8 : fbcon_cfb8;
2836                     disp->dispsw = &info->dispsw;
2837                     break;
2838 #endif
2839 #ifdef FBCON_HAS_CFB16
2840                 case 16:
2841                     info->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
2842                     disp->dispsw = &info->dispsw;
2843                     disp->dispsw_data = info->fbcon_cmap.cfb16;
2844                     break;
2845 #endif
2846 #ifdef FBCON_HAS_CFB24
2847                 case 24:
2848                     info->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
2849                     disp->dispsw = &info->dispsw;
2850                     disp->dispsw_data = info->fbcon_cmap.cfb24;
2851                     break;
2852 #endif
2853 #ifdef FBCON_HAS_CFB32
2854                 case 32:
2855                     info->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
2856                     disp->dispsw = &info->dispsw;
2857                     disp->dispsw_data = info->fbcon_cmap.cfb32;
2858                     break;
2859 #endif
2860                 default:
2861                     disp->dispsw = &fbcon_dummy;
2862             }
2863             if (info->cursor) {
2864                 info->dispsw.cursor = atyfb_cursor;
2865                 info->dispsw.set_font = atyfb_set_font;
2866             }
2867 }
2868 
2869 
2870     /*
2871      *  Set the User Defined Part of the Display
2872      */
2873 
2874 static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
2875                          struct fb_info *fb)
2876 {
2877     struct fb_info_aty *info = (struct fb_info_aty *)fb;
2878     struct atyfb_par par;
2879     struct display *display;
2880     int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
2881     int activate = var->activate;
2882 
2883     if (con >= 0)
2884         display = &fb_display[con];
2885     else
2886         display = fb->disp;     /* used during initialization */
2887 
2888     if ((err = atyfb_decode_var(var, &par, info)))
2889         return err;
2890 
2891     atyfb_encode_var(var, &par, (struct fb_info_aty *)info);
2892 
2893     if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
2894         oldxres = display->var.xres;
2895         oldyres = display->var.yres;
2896         oldvxres = display->var.xres_virtual;
2897         oldvyres = display->var.yres_virtual;
2898         oldbpp = display->var.bits_per_pixel;
2899         oldaccel = display->var.accel_flags;
2900         display->var = *var;
2901         accel = var->accel_flags & FB_ACCELF_TEXT;
2902         if (oldxres != var->xres || oldyres != var->yres ||
2903             oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
2904             oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
2905             struct fb_fix_screeninfo fix;
2906 
2907             encode_fix(&fix, &par, info);
2908             display->screen_base = (char *)info->frame_buffer;
2909             display->visual = fix.visual;
2910             display->type = fix.type;
2911             display->type_aux = fix.type_aux;
2912             display->ypanstep = fix.ypanstep;
2913             display->ywrapstep = fix.ywrapstep;
2914             display->line_length = fix.line_length;
2915             display->can_soft_blank = 1;
2916             display->inverse = 0;
2917             if (accel)
2918                 display->scrollmode = (info->bus_type == PCI) ? SCROLL_YNOMOVE : 0;
2919             else
2920                 display->scrollmode = SCROLL_YREDRAW;
2921             if (info->fb_info.changevar)
2922                 (*info->fb_info.changevar)(con);
2923         }
2924         if (!info->fb_info.display_fg ||
2925             info->fb_info.display_fg->vc_num == con) {
2926             atyfb_set_par(&par, info);
2927             atyfb_set_dispsw(display, info, par.crtc.bpp, accel);
2928         }
2929         if (oldbpp != var->bits_per_pixel) {
2930             if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
2931                 return err;
2932             do_install_cmap(con, &info->fb_info);
2933         }
2934     }
2935 
2936     return 0;
2937 }
2938 
2939 
2940     /*
2941      *  Pan or Wrap the Display
2942      *
2943      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
2944      */
2945 
2946 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
2947                              struct fb_info *fb)
2948 {
2949     struct fb_info_aty *info = (struct fb_info_aty *)fb;
2950     u32 xres, yres, xoffset, yoffset;
2951     struct atyfb_par *par = &info->current_par;
2952 
2953     xres = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
2954     yres = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
2955     xoffset = (var->xoffset+7) & ~7;
2956     yoffset = var->yoffset;
2957     if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
2958         return -EINVAL;
2959     par->crtc.xoffset = xoffset;
2960     par->crtc.yoffset = yoffset;
2961     set_off_pitch(par, info);
2962     return 0;
2963 }
2964 
2965     /*
2966      *  Get the Colormap
2967      */
2968 
2969 static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
2970                           struct fb_info *info)
2971 {
2972     if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
2973         return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);
2974     else if (fb_display[con].cmap.len) /* non default colormap? */
2975         fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
2976     else {
2977         int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
2978         fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
2979     }
2980     return 0;
2981 }
2982 
2983     /*
2984      *  Set the Colormap
2985      */
2986 
2987 static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
2988                           struct fb_info *info)
2989 {
2990     int err;
2991     struct display *disp;
2992 
2993     if (con >= 0)
2994         disp = &fb_display[con];
2995     else
2996         disp = info->disp;
2997     if (!disp->cmap.len) {      /* no colormap allocated? */
2998         int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
2999         if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
3000             return err;
3001     }
3002     if (!info->display_fg || con == info->display_fg->vc_num)                   /* current console? */
3003         return fb_set_cmap(cmap, kspc, atyfb_setcolreg, info);
3004     else
3005         fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
3006     return 0;
3007 }
3008 
3009 
3010 #ifdef DEBUG
3011 #define ATYIO_CLKR              0x41545900      /* ATY\00 */
3012 #define ATYIO_CLKW              0x41545901      /* ATY\01 */
3013 
3014 struct atyclk {
3015     u32 ref_clk_per;
3016     u8 pll_ref_div;
3017     u8 mclk_fb_div;
3018     u8 mclk_post_div;           /* 1,2,3,4,8 */
3019     u8 vclk_fb_div;
3020     u8 vclk_post_div;           /* 1,2,3,4,6,8,12 */
3021     u32 dsp_xclks_per_row;      /* 0-16383 */
3022     u32 dsp_loop_latency;       /* 0-15 */
3023     u32 dsp_precision;          /* 0-7 */
3024     u32 dsp_on;                 /* 0-2047 */
3025     u32 dsp_off;                /* 0-2047 */
3026 };
3027 #endif
3028 
3029 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
3030                        u_long arg, int con, struct fb_info *info2)
3031 {
3032 #if defined(__sparc__) || defined(DEBUG)
3033     struct fb_info_aty *info = (struct fb_info_aty *)info2;
3034 #endif /* __sparc__ || DEBUG */
3035 #ifdef __sparc__
3036     struct fbtype fbtyp;
3037     struct display *disp;
3038 
3039     if (con >= 0)
3040         disp = &fb_display[con];
3041     else
3042         disp = info2->disp;
3043 #endif
3044 
3045     switch (cmd) {
3046 #ifdef __sparc__
3047     case FBIOGTYPE:
3048         fbtyp.fb_type = FBTYPE_PCI_GENERIC;
3049         fbtyp.fb_width = info->current_par.crtc.vxres;
3050         fbtyp.fb_height = info->current_par.crtc.vyres;
3051         fbtyp.fb_depth = info->current_par.crtc.bpp;
3052         fbtyp.fb_cmsize = disp->cmap.len;
3053         fbtyp.fb_size = info->total_vram;
3054         if (copy_to_user((struct fbtype *)arg, &fbtyp, sizeof(fbtyp)))
3055                 return -EFAULT;
3056         break;
3057 #endif /* __sparc__ */
3058 #ifdef DEBUG
3059     case ATYIO_CLKR:
3060         if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
3061             struct atyclk clk;
3062             struct pll_ct *pll = &info->current_par.pll.ct;
3063             u32 dsp_config = pll->dsp_config;
3064             u32 dsp_on_off = pll->dsp_on_off;
3065             clk.ref_clk_per = info->ref_clk_per;
3066             clk.pll_ref_div = pll->pll_ref_div;
3067             clk.mclk_fb_div = pll->mclk_fb_div;
3068             clk.mclk_post_div = pll->mclk_post_div_real;
3069             clk.vclk_fb_div = pll->vclk_fb_div;
3070             clk.vclk_post_div = pll->vclk_post_div_real;
3071             clk.dsp_xclks_per_row = dsp_config & 0x3fff;
3072             clk.dsp_loop_latency = (dsp_config>>16) & 0xf;
3073             clk.dsp_precision = (dsp_config>>20) & 7;
3074             clk.dsp_on = dsp_on_off & 0x7ff;
3075             clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
3076             if (copy_to_user((struct atyclk *)arg, &clk, sizeof(clk)))
3077                     return -EFAULT;
3078         } else
3079             return -EINVAL;
3080         break;
3081     case ATYIO_CLKW:
3082         if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
3083             struct atyclk clk;
3084             struct pll_ct *pll = &info->current_par.pll.ct;
3085             if (copy_from_user(&clk, (struct atyclk *)arg, sizeof(clk)))
3086                     return -EFAULT;
3087             info->ref_clk_per = clk.ref_clk_per;
3088             pll->pll_ref_div = clk.pll_ref_div;
3089             pll->mclk_fb_div = clk.mclk_fb_div;
3090             pll->mclk_post_div_real = clk.mclk_post_div;
3091             pll->vclk_fb_div = clk.vclk_fb_div;
3092             pll->vclk_post_div_real = clk.vclk_post_div;
3093             pll->dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
3094                               ((clk.dsp_loop_latency & 0xf)<<16) |
3095                               ((clk.dsp_precision & 7)<<20);
3096             pll->dsp_on_off = (clk.dsp_on & 0x7ff) |
3097                               ((clk.dsp_off & 0x7ff)<<16);
3098             aty_calc_pll_ct(info, pll);
3099             aty_set_pll_ct(info, pll);
3100         } else
3101             return -EINVAL;
3102         break;
3103 #endif /* DEBUG */
3104     default:
3105         return -EINVAL;
3106     }
3107     return 0;
3108 }
3109 
3110 static int atyfb_rasterimg(struct fb_info *info, int start)
3111 {
3112     struct fb_info_aty *fb = (struct fb_info_aty *)info;
3113 
3114     if (fb->blitter_may_be_busy)
3115         wait_for_idle(fb);
3116     return 0;
3117 }
3118 
3119 #ifdef __sparc__
3120 static int atyfb_mmap(struct fb_info *info, struct file *file,
3121                       struct vm_area_struct *vma)
3122 {
3123         struct fb_info_aty *fb = (struct fb_info_aty *)info;
3124         unsigned int size, page, map_size = 0;
3125         unsigned long map_offset = 0;
3126         unsigned long off;
3127         int i;
3128 
3129         if (!fb->mmap_map)
3130                 return -ENXIO;
3131 
3132         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
3133                 return -EINVAL;
3134 
3135         off = vma->vm_pgoff << PAGE_SHIFT;
3136         size = vma->vm_end - vma->vm_start;
3137 
3138         /* To stop the swapper from even considering these pages. */
3139         vma->vm_flags |= (VM_SHM | VM_LOCKED);
3140 
3141         if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||
3142             ((off == fb->total_vram) && (size == PAGE_SIZE)))
3143                 off += 0x8000000000000000UL;
3144 
3145         vma->vm_pgoff = off >> PAGE_SHIFT;      /* propagate off changes */
3146 
3147 #ifdef __sparc_v9__
3148         /* Align it as much as desirable */
3149         {
3150                 unsigned long j, align;
3151                 int max = -1;
3152 
3153                 map_offset = off + size;
3154                 for (i = 0; fb->mmap_map[i].size; i++) {
3155                         if (fb->mmap_map[i].voff < off)
3156                                 continue;
3157                         if (fb->mmap_map[i].voff >= map_offset)
3158                                 break;
3159                         if (max < 0 ||
3160                             fb->mmap_map[i].size > fb->mmap_map[max].size)
3161                                 max = i;
3162                 }
3163                 if (max >= 0) {
3164                         j = fb->mmap_map[max].size;
3165                         if (fb->mmap_map[max].voff + j > map_offset)
3166                                 j = map_offset - fb->mmap_map[max].voff;
3167                         for (align = 0x400000; align > PAGE_SIZE; align >>= 3)
3168                                 if (j >= align &&
3169                                     !(fb->mmap_map[max].poff & (align - 1)))
3170                                         break;
3171                         if (align > PAGE_SIZE) {
3172                                 j = align;
3173                                 align = j - ((vma->vm_start
3174                                               + fb->mmap_map[max].voff
3175                                               - off) & (j - 1));
3176                                 if (align != j) {
3177                                         struct vm_area_struct *vmm;
3178 
3179                                         vmm = find_vma(current->mm,
3180                                                        vma->vm_start);
3181                                         if (!vmm || vmm->vm_start
3182                                                     >= vma->vm_end + align) {
3183                                                 vma->vm_start += align;
3184                                                 vma->vm_end += align;
3185                                         }
3186                                 }
3187                         }
3188                 }
3189         }
3190 #endif
3191 
3192         /* Each page, see which map applies */
3193         for (page = 0; page < size; ) {
3194                 map_size = 0;
3195                 for (i = 0; fb->mmap_map[i].size; i++) {
3196                         unsigned long start = fb->mmap_map[i].voff;
3197                         unsigned long end = start + fb->mmap_map[i].size;
3198                         unsigned long offset = off + page;
3199 
3200                         if (start > offset)
3201                                 continue;
3202                         if (offset >= end)
3203                                 continue;
3204 
3205                         map_size = fb->mmap_map[i].size - (offset - start);
3206                         map_offset = fb->mmap_map[i].poff + (offset - start);
3207                         break;
3208                 }
3209                 if (!map_size) {
3210                         page += PAGE_SIZE;
3211                         continue;
3212                 }
3213                 if (page + map_size > size)
3214                         map_size = size - page;
3215 
3216                 pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
3217                 pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
3218 
3219                 if (remap_page_range(vma->vm_start + page, map_offset,
3220                                      map_size, vma->vm_page_prot))
3221                         return -EAGAIN;
3222 
3223                 page += map_size;
3224         }
3225 
3226         if (!map_size)
3227                 return -EINVAL;
3228 
3229         vma->vm_flags |= VM_IO;
3230 
3231         if (!fb->mmaped) {
3232                 int lastconsole = 0;
3233 
3234                 if (info->display_fg)
3235                         lastconsole = info->display_fg->vc_num;
3236                 fb->mmaped = 1;
3237                 if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
3238                         fb->vtconsole = lastconsole;
3239                         vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
3240                 }
3241         }
3242         return 0;
3243 }
3244 
3245 static struct {
3246         u32     yoffset;
3247         u8      r[2][256];
3248         u8      g[2][256];
3249         u8      b[2][256];
3250 } atyfb_save;
3251 
3252 static void atyfb_save_palette(struct fb_info *fb, int enter)
3253 {
3254         struct fb_info_aty *info = (struct fb_info_aty *)fb;
3255         int i, tmp, scale;
3256 
3257         for (i = 0; i < 256; i++) {
3258                 tmp = aty_ld_8(DAC_CNTL, info) & 0xfc;
3259                 if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
3260                     Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
3261                     Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
3262                     Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID)
3263                         tmp |= 0x2;
3264                 aty_st_8(DAC_CNTL, tmp, info);
3265                 aty_st_8(DAC_MASK, 0xff, info);
3266 
3267                 scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
3268                         (info->current_par.crtc.bpp == 16)) ? 3 : 0;
3269                 writeb(i << scale, &info->aty_cmap_regs->rindex);
3270 
3271                 atyfb_save.r[enter][i] = readb(&info->aty_cmap_regs->lut);
3272                 atyfb_save.g[enter][i] = readb(&info->aty_cmap_regs->lut);
3273                 atyfb_save.b[enter][i] = readb(&info->aty_cmap_regs->lut);
3274                 writeb(i << scale, &info->aty_cmap_regs->windex);
3275                 writeb(atyfb_save.r[1-enter][i], &info->aty_cmap_regs->lut);
3276                 writeb(atyfb_save.g[1-enter][i], &info->aty_cmap_regs->lut);
3277                 writeb(atyfb_save.b[1-enter][i], &info->aty_cmap_regs->lut);
3278         }
3279 }
3280 
3281 static void atyfb_palette(int enter)
3282 {
3283         struct fb_info_aty *info;
3284         struct atyfb_par *par;
3285         struct display *d;
3286         int i;
3287 
3288         for (i = 0; i < MAX_NR_CONSOLES; i++) {
3289                 d = &fb_display[i];
3290                 if (d->fb_info &&
3291                     d->fb_info->fbops == &atyfb_ops &&
3292                     d->fb_info->display_fg &&
3293                     d->fb_info->display_fg->vc_num == i) {
3294                         atyfb_save_palette(d->fb_info, enter);
3295                         info = (struct fb_info_aty *)d->fb_info;
3296                         par = &info->current_par;
3297                         if (enter) {
3298                                 atyfb_save.yoffset = par->crtc.yoffset;
3299                                 par->crtc.yoffset = 0;
3300                                 set_off_pitch(par, info);
3301                         } else {
3302                                 par->crtc.yoffset = atyfb_save.yoffset;
3303                                 set_off_pitch(par, info);
3304                         }
3305                         break;
3306                 }
3307         }
3308 }
3309 #endif /* __sparc__ */
3310 
3311     /*
3312      *  Initialisation
3313      */
3314 
3315 static int __init aty_init(struct fb_info_aty *info, const char *name)
3316 {
3317     u32 chip_id;
3318     u32 i;
3319     int j, k;
3320     struct fb_var_screeninfo var;
3321     struct display *disp;
3322     const char *chipname = NULL, *ramname = NULL, *xtal;
3323     int pll, mclk, gtb_memsize;
3324 #if defined(CONFIG_PPC)
3325     int sense;
3326 #endif
3327     u8 pll_ref_div;
3328 
3329     info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
3330     chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
3331     Gx = chip_id & CFG_CHIP_TYPE;
3332     Rev = (chip_id & CFG_CHIP_REV)>>24;
3333     for (j = 0; j < (sizeof(aty_features)/sizeof(*aty_features)); j++)
3334         if (aty_features[j].chip_type == Gx) {
3335             chipname = aty_features[j].name;
3336             info->dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
3337             break;
3338         }
3339     if (!chipname) {
3340         printk("atyfb: Unknown mach64 0x%04x\n", Gx);
3341         return 0;
3342     } else
3343         printk("atyfb: %s [0x%04x rev 0x%02x] ", chipname, Gx, Rev);
3344     if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
3345         info->bus_type = (aty_ld_le32(CONFIG_STAT0, info) >> 0) & 0x07;
3346         info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) >> 3) & 0x07;
3347         ramname = aty_gx_ram[info->ram_type];
3348         /* FIXME: clockchip/RAMDAC probing? */
3349 #ifdef CONFIG_ATARI
3350         info->clk_type = CLK_ATI18818_1;
3351         info->dac_type = (aty_ld_le32(CONFIG_STAT0, info) >> 9) & 0x07;
3352         if (info->dac_type == 0x07)
3353             info->dac_subtype = DAC_ATT20C408;
3354         else
3355             info->dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, info) & 0xF0) |
3356                                 info->dac_type;
3357 #else
3358         info->dac_type = DAC_IBMRGB514;
3359         info->dac_subtype = DAC_IBMRGB514;
3360         info->clk_type = CLK_IBMRGB514;
3361 #endif
3362         /* FIXME */
3363         pll = 135;
3364         mclk = 50;
3365     } else {
3366         info->bus_type = PCI;
3367         info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
3368         ramname = aty_ct_ram[info->ram_type];
3369         info->dac_type = DAC_INTERNAL;
3370         info->dac_subtype = DAC_INTERNAL;
3371         info->clk_type = CLK_INTERNAL;
3372         if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
3373             pll = 135;
3374             mclk = 60;
3375         } else {
3376             mclk = info->ram_type >= SDRAM ? 67 : 63;
3377             if ((Gx == VT_CHIP_ID) && (Rev == 0x08)) {
3378                 /* VTA3 */
3379                 pll = 170;
3380             } else if (((Gx == VT_CHIP_ID) && ((Rev == 0x40) ||
3381                                                (Rev == 0x48))) ||
3382                        ((Gx == VT_CHIP_ID) && ((Rev == 0x01) ||
3383                                                (Rev == 0x9a))) ||
3384                        Gx == VU_CHIP_ID) {
3385                 /* VTA4 or VTB */
3386                 pll = 200;
3387             } else if (Gx == VV_CHIP_ID) {
3388                 /* VT4 */
3389                 pll = 230;
3390                 mclk = 83;
3391             } else if (Gx == VT_CHIP_ID) {
3392                 /* other VT */
3393                 pll = 135;
3394                 mclk = 63;
3395             } else if ((Gx == GT_CHIP_ID) && (Rev & 0x01)) {
3396                 /* RAGE II */
3397                 pll = 170;
3398             } else if (((Gx == GT_CHIP_ID) && (Rev & 0x02)) ||
3399                        (Gx == GU_CHIP_ID)) {
3400                 /* RAGE II+ */
3401                 pll = 200;
3402             } else if (Gx == GV_CHIP_ID || Gx == GW_CHIP_ID ||
3403                        Gx == GZ_CHIP_ID) {
3404                 /* RAGE IIC */
3405                 pll = 230;
3406                 mclk = 83;
3407             } else if (Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
3408                        Gx == GI_CHIP_ID || Gx == GP_CHIP_ID ||
3409                        Gx == GQ_CHIP_ID || Gx == LB_CHIP_ID ||
3410                        Gx == LD_CHIP_ID ||
3411                        Gx == LI_CHIP_ID || Gx == LP_CHIP_ID) {
3412                 /* RAGE PRO or LT PRO */
3413                 pll = 230;
3414                 mclk = 100;
3415             } else if (Gx == LG_CHIP_ID) {
3416                 /* Rage LT */
3417                 pll = 230;
3418                 mclk = 63;
3419             } else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
3420                 /* Rage mobility M1 */
3421                 pll = 230;
3422                 mclk = 50;
3423             } else {
3424                 /* other RAGE */
3425                 pll = 135;
3426                 mclk = 63;
3427             }
3428         }
3429     }
3430 
3431     info->ref_clk_per = 1000000000000ULL/14318180;
3432     xtal = "14.31818";
3433     if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
3434           Gx == ET_CHIP_ID ||
3435           ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07))) &&
3436         (pll_ref_div = aty_ld_pll(PLL_REF_DIV, info))) {
3437         int diff1, diff2;
3438         diff1 = 510*14/pll_ref_div-pll;
3439         diff2 = 510*29/pll_ref_div-pll;
3440         if (diff1 < 0)
3441             diff1 = -diff1;
3442         if (diff2 < 0)
3443             diff2 = -diff2;
3444         if (diff2 < diff1) {
3445             info->ref_clk_per = 1000000000000ULL/29498928;
3446             xtal = "29.498928";
3447         }
3448     }
3449 
3450     i = aty_ld_le32(MEM_CNTL, info);
3451     gtb_memsize = !(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
3452                     Gx == ET_CHIP_ID ||
3453                     ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)));
3454     if (gtb_memsize)
3455         switch (i & 0xF) {      /* 0xF used instead of MEM_SIZE_ALIAS */
3456             case MEM_SIZE_512K:
3457                 info->total_vram = 0x80000;
3458                 break;
3459             case MEM_SIZE_1M:
3460                 info->total_vram = 0x100000;
3461                 break;
3462             case MEM_SIZE_2M_GTB:
3463                 info->total_vram = 0x200000;
3464                 break;
3465             case MEM_SIZE_4M_GTB:
3466                 info->total_vram = 0x400000;
3467                 break;
3468             case MEM_SIZE_6M_GTB:
3469                 info->total_vram = 0x600000;
3470                 break;
3471             case MEM_SIZE_8M_GTB:
3472                 info->total_vram = 0x800000;
3473                 break;
3474             default:
3475                 info->total_vram = 0x80000;
3476         }
3477     else
3478         switch (i & MEM_SIZE_ALIAS) {
3479             case MEM_SIZE_512K:
3480                 info->total_vram = 0x80000;
3481                 break;
3482             case MEM_SIZE_1M:
3483                 info->total_vram = 0x100000;
3484                 break;
3485             case MEM_SIZE_2M:
3486                 info->total_vram = 0x200000;
3487                 break;
3488             case MEM_SIZE_4M:
3489                 info->total_vram = 0x400000;
3490                 break;
3491             case MEM_SIZE_6M:
3492                 info->total_vram = 0x600000;
3493                 break;
3494             case MEM_SIZE_8M:
3495                 info->total_vram = 0x800000;
3496                 break;
3497             default:
3498                 info->total_vram = 0x80000;
3499         }
3500 
3501     if (Gx == GI_CHIP_ID) {
3502         if (aty_ld_le32(CONFIG_STAT1, info) & 0x40000000)
3503           info->total_vram += 0x400000;
3504     }
3505 
3506     if (default_vram) {
3507         info->total_vram = default_vram*1024;
3508         i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
3509         if (info->total_vram <= 0x80000)
3510             i |= MEM_SIZE_512K;
3511         else if (info->total_vram <= 0x100000)
3512             i |= MEM_SIZE_1M;
3513         else if (info->total_vram <= 0x200000)
3514             i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
3515         else if (info->total_vram <= 0x400000)
3516             i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
3517         else if (info->total_vram <= 0x600000)
3518             i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
3519         else
3520             i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
3521         aty_st_le32(MEM_CNTL, i, info);
3522     }
3523     if (default_pll)
3524         pll = default_pll;
3525     if (default_mclk)
3526         mclk = default_mclk;
3527 
3528     printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
3529            info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
3530            info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
3531 
3532     if (mclk < 44)
3533         info->mem_refresh_rate = 0;     /* 000 = 10 Mhz - 43 Mhz */
3534     else if (mclk < 50)
3535         info->mem_refresh_rate = 1;     /* 001 = 44 Mhz - 49 Mhz */
3536     else if (mclk < 55)
3537         info->mem_refresh_rate = 2;     /* 010 = 50 Mhz - 54 Mhz */
3538     else if (mclk < 66)
3539         info->mem_refresh_rate = 3;     /* 011 = 55 Mhz - 65 Mhz */
3540     else if (mclk < 75)
3541         info->mem_refresh_rate = 4;     /* 100 = 66 Mhz - 74 Mhz */
3542     else if (mclk < 80)
3543         info->mem_refresh_rate = 5;     /* 101 = 75 Mhz - 79 Mhz */
3544     else if (mclk < 100)
3545         info->mem_refresh_rate = 6;     /* 110 = 80 Mhz - 100 Mhz */
3546     else
3547         info->mem_refresh_rate = 7;     /* 111 = 100 Mhz and above */
3548     info->pll_per = 1000000/pll;
3549     info->mclk_per = 1000000/mclk;
3550 
3551 #ifdef DEBUG
3552     if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
3553         int i;
3554         printk("BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
3555                "DSP_CONFIG DSP_ON_OFF\n"
3556                "%08x %08x %08x %08x     %08x      %08x   %08x\n"
3557                "PLL",
3558                aty_ld_le32(BUS_CNTL, info), aty_ld_le32(DAC_CNTL, info),
3559                aty_ld_le32(MEM_CNTL, info), aty_ld_le32(EXT_MEM_CNTL, info),
3560                aty_ld_le32(CRTC_GEN_CNTL, info), aty_ld_le32(DSP_CONFIG, info),
3561                aty_ld_le32(DSP_ON_OFF, info));
3562         for (i = 0; i < 16; i++)
3563             printk(" %02x", aty_ld_pll(i, info));
3564         printk("\n");
3565     }
3566 #endif
3567 
3568     /*
3569      *  Last page of 8 MB (4 MB on ISA) aperture is MMIO
3570      *  FIXME: we should use the auxiliary aperture instead so we can acces the
3571      *  full 8 MB of video RAM on 8 MB boards
3572      */
3573     if (info->total_vram == 0x800000 ||
3574         (info->bus_type == ISA && info->total_vram == 0x400000))
3575             info->total_vram -= GUI_RESERVE;
3576 
3577     /* Clear the video memory */
3578     fb_memset((void *)info->frame_buffer, 0, info->total_vram);
3579 
3580     disp = &info->disp;
3581 
3582     strcpy(info->fb_info.modename, atyfb_name);
3583     info->fb_info.node = -1;
3584     info->fb_info.fbops = &atyfb_ops;
3585     info->fb_info.disp = disp;
3586     strcpy(info->fb_info.fontname, fontname);
3587     info->fb_info.changevar = NULL;
3588     info->fb_info.switch_con = &atyfbcon_switch;
3589     info->fb_info.updatevar = &atyfbcon_updatevar;
3590     info->fb_info.blank = &atyfbcon_blank;
3591     info->fb_info.flags = FBINFO_FLAG_DEFAULT;
3592 
3593 #ifdef CONFIG_PMAC_BACKLIGHT
3594     if (Gx == LI_CHIP_ID && machine_is_compatible("PowerBook1,1")) {
3595         /* these bits let the 101 powerbook wake up from sleep -- paulus */
3596         aty_st_lcd(LCD_POWER_MANAGEMENT, aty_ld_lcd(LCD_POWER_MANAGEMENT, info)
3597                 | (USE_F32KHZ | TRISTATE_MEM_EN), info);
3598     }
3599     if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID))
3600         register_backlight_controller(&aty_backlight_controller, info, "ati");
3601 #endif /* CONFIG_PMAC_BACKLIGHT */
3602 
3603 #ifdef MODULE
3604     var = default_var;
3605 #else /* !MODULE */
3606     memset(&var, 0, sizeof(var));
3607 #ifdef CONFIG_PPC
3608     if (_machine == _MACH_Pmac) {
3609             /*
3610              *  FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
3611              *         applies to all Mac video cards
3612              */
3613             if (mode_option) {
3614                 if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
3615                     var = default_var;
3616             } else {
3617 #ifdef CONFIG_NVRAM
3618                 if (default_vmode == VMODE_NVRAM) {
3619                     default_vmode = nvram_read_byte(NV_VMODE);
3620                     if (default_vmode <= 0 || default_vmode > VMODE_MAX)
3621                         default_vmode = VMODE_CHOOSE;
3622                 }
3623 #endif
3624                 if (default_vmode == VMODE_CHOOSE) {
3625                     if (Gx == LG_CHIP_ID || Gx == LI_CHIP_ID)
3626                         /* G3 PowerBook with 1024x768 LCD */
3627                         default_vmode = VMODE_1024_768_60;
3628                     else if (machine_is_compatible("iMac"))
3629                         default_vmode = VMODE_1024_768_75;
3630                     else if (machine_is_compatible("PowerBook2,1"))
3631                         /* iBook with 800x600 LCD */
3632                         default_vmode = VMODE_800_600_60;
3633                     else
3634                         default_vmode = VMODE_640_480_67;
3635                     sense = read_aty_sense(info);
3636                     printk(KERN_INFO "atyfb: monitor sense=%x, mode %d\n",
3637                            sense, mac_map_monitor_sense(sense));
3638                 }
3639                 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
3640                     default_vmode = VMODE_640_480_60;
3641 #ifdef CONFIG_NVRAM
3642                 if (default_cmode == CMODE_NVRAM)
3643                     default_cmode = nvram_read_byte(NV_CMODE);
3644 #endif
3645                 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
3646                     default_cmode = CMODE_8;
3647                 if (mac_vmode_to_var(default_vmode, default_cmode, &var))
3648                     var = default_var;
3649             }
3650     }
3651     else if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
3652         var = default_var;
3653 #else /* !CONFIG_PPC */
3654 #ifdef __sparc__
3655     if (mode_option) {
3656         if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
3657             var = default_var;
3658     } else
3659         var = default_var;
3660 #else
3661     if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
3662         var = default_var;
3663 #endif /* !__sparc__ */
3664 #endif /* !CONFIG_PPC */
3665 #endif /* !MODULE */
3666     if (noaccel)
3667         var.accel_flags &= ~FB_ACCELF_TEXT;
3668     else
3669         var.accel_flags |= FB_ACCELF_TEXT;
3670 
3671     if (var.yres == var.yres_virtual) {
3672         u32 vram = (info->total_vram - (PAGE_SIZE << 2));
3673         var.yres_virtual = ((vram * 8) / var.bits_per_pixel) / var.xres_virtual;
3674         if (var.yres_virtual < var.yres)
3675                 var.yres_virtual = var.yres;
3676     }
3677 
3678     if (atyfb_decode_var(&var, &info->default_par, info)) {
3679         printk("atyfb: can't set default video mode\n");
3680         return 0;
3681     }
3682 
3683 #ifdef __sparc__
3684     atyfb_save_palette(&info->fb_info, 0);
3685 #endif
3686     for (j = 0; j < 16; j++) {
3687         k = color_table[j];
3688         info->palette[j].red = default_red[k];
3689         info->palette[j].green = default_grn[k];
3690         info->palette[j].blue = default_blu[k];
3691     }
3692 
3693     if (Gx != GX_CHIP_ID && Gx != CX_CHIP_ID) {
3694         info->cursor = aty_init_cursor(info);
3695         if (info->cursor) {
3696             info->dispsw.cursor = atyfb_cursor;
3697             info->dispsw.set_font = atyfb_set_font;
3698         }
3699     }
3700 
3701     atyfb_set_var(&var, -1, &info->fb_info);
3702 
3703     if (register_framebuffer(&info->fb_info) < 0)
3704         return 0;
3705 
3706     info->next = fb_list;
3707     fb_list = info;
3708 
3709     printk("fb%d: %s frame buffer device on %s\n",
3710            GET_FB_IDX(info->fb_info.node), atyfb_name, name);
3711     return 1;
3712 }
3713 
3714 int __init atyfb_init(void)
3715 {
3716 #if defined(CONFIG_PCI)
3717     struct pci_dev *pdev = NULL;
3718     struct fb_info_aty *info;
3719     unsigned long addr, res_start, res_size;
3720     int i;
3721 #ifdef __sparc__
3722     extern void (*prom_palette) (int);
3723     extern int con_is_present(void);
3724     struct pcidev_cookie *pcp;
3725     char prop[128];
3726     int node, len, j;
3727     u32 mem, chip_id;
3728 
3729     /* Do not attach when we have a serial console. */
3730     if (!con_is_present())
3731         return -ENXIO;
3732 #else
3733     u16 tmp;
3734 #endif
3735 
3736     while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
3737         if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
3738             struct resource *rp;
3739 
3740             for (i = sizeof(aty_features)/sizeof(*aty_features)-1; i >= 0; i--)
3741                 if (pdev->device == aty_features[i].pci_id)
3742                     break;
3743             if (i < 0)
3744                 continue;
3745 
3746             info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
3747             if (!info) {
3748                 printk("atyfb_init: can't alloc fb_info_aty\n");
3749                 return -ENXIO;
3750             }
3751             memset(info, 0, sizeof(struct fb_info_aty));
3752 
3753             rp = &pdev->resource[0];
3754             if (rp->flags & IORESOURCE_IO)
3755                     rp = &pdev->resource[1];
3756             addr = rp->start;
3757             if (!addr)
3758                 continue;
3759 
3760             res_start = rp->start;
3761             res_size = rp->end-rp->start+1;
3762             if (!request_mem_region(res_start, res_size, "atyfb"))
3763                 continue;
3764 
3765 #ifdef __sparc__
3766             /*
3767              * Map memory-mapped registers.
3768              */
3769             info->ati_regbase = addr + 0x7ffc00UL;
3770             info->ati_regbase_phys = addr + 0x7ffc00UL;
3771 
3772             /*
3773              * Map in big-endian aperture.
3774              */
3775             info->frame_buffer = (unsigned long) addr + 0x800000UL;
3776             info->frame_buffer_phys = addr + 0x800000UL;
3777 
3778             /*
3779              * Figure mmap addresses from PCI config space.
3780              * Split Framebuffer in big- and little-endian halfs.
3781              */
3782             for (i = 0; i < 6 && pdev->resource[i].start; i++)
3783                 /* nothing */;
3784             j = i + 4;
3785 
3786             info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
3787             if (!info->mmap_map) {
3788                 printk("atyfb_init: can't alloc mmap_map\n");
3789                 kfree(info);
3790                 release_mem_region(res_start, res_size);
3791                 return -ENXIO;
3792             }
3793             memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
3794 
3795             for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
3796                 struct resource *rp = &pdev->resource[i];
3797                 int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
3798                 unsigned long base;
3799                 u32 size, pbase;
3800 
3801                 base = rp->start;
3802 
3803                 io = (rp->flags & IORESOURCE_IO);
3804 
3805                 size = rp->end - base + 1;
3806 
3807                 pci_read_config_dword(pdev, breg, &pbase);
3808 
3809                 if (io)
3810                         size &= ~1;
3811 
3812                 /*
3813                  * Map the framebuffer a second time, this time without
3814                  * the braindead _PAGE_IE setting. This is used by the
3815                  * fixed Xserver, but we need to maintain the old mapping
3816                  * to stay compatible with older ones...
3817                  */
3818                 if (base == addr) {
3819                     info->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
3820                     info->mmap_map[j].poff = base & PAGE_MASK;
3821                     info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3822                     info->mmap_map[j].prot_mask = _PAGE_CACHE;
3823                     info->mmap_map[j].prot_flag = _PAGE_E;
3824                     j++;
3825                 }
3826 
3827                 /*
3828                  * Here comes the old framebuffer mapping with _PAGE_IE
3829                  * set for the big endian half of the framebuffer...
3830                  */
3831                 if (base == addr) {
3832                     info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
3833                     info->mmap_map[j].poff = (base+0x800000) & PAGE_MASK;
3834                     info->mmap_map[j].size = 0x800000;
3835                     info->mmap_map[j].prot_mask = _PAGE_CACHE;
3836                     info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
3837                     size -= 0x800000;
3838                     j++;
3839                 }
3840 
3841                 info->mmap_map[j].voff = pbase & PAGE_MASK;
3842                 info->mmap_map[j].poff = base & PAGE_MASK;
3843                 info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
3844                 info->mmap_map[j].prot_mask = _PAGE_CACHE;
3845                 info->mmap_map[j].prot_flag = _PAGE_E;
3846                 j++;
3847             }
3848 
3849             /*
3850              * Fix PROMs idea of MEM_CNTL settings...
3851              */
3852             mem = aty_ld_le32(MEM_CNTL, info);
3853             chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
3854             if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) &&
3855                 !((chip_id >> 24) & 1)) {
3856                 switch (mem & 0x0f) {
3857                     case 3:
3858                         mem = (mem & ~(0x0f)) | 2;
3859                         break;
3860                     case 7:
3861                         mem = (mem & ~(0x0f)) | 3;
3862                         break;
3863                     case 9:
3864                         mem = (mem & ~(0x0f)) | 4;
3865                         break;
3866                     case 11:
3867                         mem = (mem & ~(0x0f)) | 5;
3868                         break;
3869                     default:
3870                         break;
3871                 }
3872                 if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM)
3873                         mem &= ~(0x00700000);
3874             }
3875             mem &= ~(0xcf80e000);       /* Turn off all undocumented bits. */
3876             aty_st_le32(MEM_CNTL, mem, info);
3877 
3878             /*
3879              * If this is the console device, we will set default video
3880              * settings to what the PROM left us with.
3881              */
3882             node = prom_getchild(prom_root_node);
3883             node = prom_searchsiblings(node, "aliases");
3884             if (node) {
3885                 len = prom_getproperty(node, "screen", prop, sizeof(prop));
3886                 if (len > 0) {
3887                     prop[len] = '\0';
3888                     node = prom_finddevice(prop);
3889                 } else {
3890                     node = 0;
3891                 }
3892             }
3893 
3894             pcp = pdev->sysdata;
3895             if (node == pcp->prom_node) {
3896 
3897                 struct fb_var_screeninfo *var = &default_var;
3898                 unsigned int N, P, Q, M, T;
3899                 u32 v_total, h_total;
3900                 struct crtc crtc;
3901                 u8 pll_regs[16];
3902                 u8 clock_cntl;
3903 
3904                 crtc.vxres = prom_getintdefault(node, "width", 1024);
3905                 crtc.vyres = prom_getintdefault(node, "height", 768);
3906                 crtc.bpp = prom_getintdefault(node, "depth", 8);
3907                 crtc.xoffset = crtc.yoffset = 0;
3908                 crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, info);
3909                 crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, info);
3910                 crtc.v_tot_disp = aty_ld_le32(CRTC_V_TOTAL_DISP, info);
3911                 crtc.v_sync_strt_wid = aty_ld_le32(CRTC_V_SYNC_STRT_WID, info);
3912                 crtc.gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, info);
3913                 aty_crtc_to_var(&crtc, var);
3914 
3915                 h_total = var->xres + var->right_margin +
3916                           var->hsync_len + var->left_margin;
3917                 v_total = var->yres + var->lower_margin +
3918                           var->vsync_len + var->upper_margin;
3919 
3920                 /*
3921                  * Read the PLL to figure actual Refresh Rate.
3922                  */
3923                 clock_cntl = aty_ld_8(CLOCK_CNTL, info);
3924                 /* printk("atyfb: CLOCK_CNTL: %02x\n", clock_cntl); */
3925                 for (i = 0; i < 16; i++)
3926                         pll_regs[i] = aty_ld_pll(i, info);
3927 
3928                 /*
3929                  * PLL Reference Devider M:
3930                  */
3931                 M = pll_regs[2];
3932 
3933                 /*
3934                  * PLL Feedback Devider N (Dependant on CLOCK_CNTL):
3935                  */
3936                 N = pll_regs[7 + (clock_cntl & 3)];
3937 
3938                 /*
3939                  * PLL Post Devider P (Dependant on CLOCK_CNTL):
3940                  */
3941                 P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1));
3942 
3943                 /*
3944                  * PLL Devider Q:
3945                  */
3946                 Q = N / P;
3947 
3948                 /*
3949                  * Target Frequency:
3950                  *
3951                  *      T * M
3952                  * Q = -------
3953                  *      2 * R
3954                  *
3955                  * where R is XTALIN (= 14318 kHz).
3956                  */
3957                 T = 2 * Q * 14318 / M;
3958 
3959                 default_var.pixclock = 1000000000 / T;
3960             }
3961 
3962 #else /* __sparc__ */
3963 
3964             info->ati_regbase_phys = 0x7ff000 + addr;
3965             info->ati_regbase = (unsigned long)
3966                                 ioremap(info->ati_regbase_phys, 0x1000);
3967 
3968             if(!info->ati_regbase) {
3969                     kfree(info);
3970                     release_mem_region(res_start, res_size);
3971                     return -ENOMEM;
3972             }
3973 
3974             info->ati_regbase_phys += 0xc00;
3975             info->ati_regbase += 0xc00;
3976 
3977             /*
3978              * Enable memory-space accesses using config-space
3979              * command register.
3980              */
3981             pci_read_config_word(pdev, PCI_COMMAND, &tmp);
3982             if (!(tmp & PCI_COMMAND_MEMORY)) {
3983                 tmp |= PCI_COMMAND_MEMORY;
3984                 pci_write_config_word(pdev, PCI_COMMAND, tmp);
3985             }
3986 
3987 #ifdef __BIG_ENDIAN
3988             /* Use the big-endian aperture */
3989             addr += 0x800000;
3990 #endif
3991 
3992             /* Map in frame buffer */
3993             info->frame_buffer_phys = addr;
3994             info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
3995 
3996             if(!info->frame_buffer) {
3997                     kfree(info);
3998                     release_mem_region(res_start, res_size);
3999                     return -ENXIO;
4000             }
4001 
4002 #endif /* __sparc__ */
4003 
4004             if (!aty_init(info, "PCI")) {
4005                 if (info->mmap_map)
4006                     kfree(info->mmap_map);
4007                 kfree(info);
4008                 release_mem_region(res_start, res_size);
4009                 return -ENXIO;
4010             }
4011 
4012 #ifdef __sparc__
4013             if (!prom_palette)
4014                 prom_palette = atyfb_palette;
4015 
4016             /*
4017              * Add /dev/fb mmap values.
4018              */
4019             info->mmap_map[0].voff = 0x8000000000000000UL;
4020             info->mmap_map[0].poff = info->frame_buffer & PAGE_MASK;
4021             info->mmap_map[0].size = info->total_vram;
4022             info->mmap_map[0].prot_mask = _PAGE_CACHE;
4023             info->mmap_map[0].prot_flag = _PAGE_E;
4024             info->mmap_map[1].voff = info->mmap_map[0].voff + info->total_vram;
4025             info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK;
4026             info->mmap_map[1].size = PAGE_SIZE;
4027             info->mmap_map[1].prot_mask = _PAGE_CACHE;
4028             info->mmap_map[1].prot_flag = _PAGE_E;
4029 #endif /* __sparc__ */
4030 
4031 #ifdef CONFIG_PMAC_PBOOK
4032             if (first_display == NULL)
4033                 pmu_register_sleep_notifier(&aty_sleep_notifier);
4034             info->next = first_display;
4035             first_display = info;
4036 #endif
4037 
4038 #ifdef CONFIG_FB_COMPAT_XPMAC
4039             if (!console_fb_info)
4040                 console_fb_info = &info->fb_info;
4041 #endif /* CONFIG_FB_COMPAT_XPMAC */
4042         }
4043     }
4044 
4045 #elif defined(CONFIG_ATARI)
4046   u32   clock_r;
4047     int m64_num;
4048     struct fb_info_aty *info;
4049 
4050     for (m64_num = 0; m64_num < mach64_count; m64_num++) {
4051         if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
4052             !phys_guiregbase[m64_num]) {
4053             printk(" phys_*[%d] parameters not set => returning early. \n",
4054                    m64_num);
4055             continue;
4056         }
4057 
4058         info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
4059         if (!info) {
4060             printk("atyfb_init: can't alloc fb_info_aty\n");
4061             return -ENOMEM;
4062         }
4063         memset(info, 0, sizeof(struct fb_info_aty));
4064 
4065         /*
4066          *  Map the video memory (physical address given) to somewhere in the
4067          *  kernel address space.
4068          */
4069         info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
4070         info->frame_buffer_phys = info->frame_buffer;  /* Fake! */
4071         info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
4072         info->ati_regbase_phys = info->ati_regbase;  /* Fake! */
4073 
4074         aty_st_le32(CLOCK_CNTL, 0x12345678, info);
4075         clock_r = aty_ld_le32(CLOCK_CNTL, info);
4076 
4077         switch (clock_r & 0x003F) {
4078             case 0x12:
4079                 info->clk_wr_offset = 3;  /*  */
4080                 break;
4081             case 0x34:
4082                 info->clk_wr_offset = 2;  /* Medusa ST-IO ISA Adapter etc. */
4083                 break;
4084             case 0x16:
4085                 info->clk_wr_offset = 1;  /*  */
4086                 break;
4087             case 0x38:
4088                 info->clk_wr_offset = 0;  /* Panther 1 ISA Adapter (Gerald) */
4089                 break;
4090         }
4091 
4092         if (!aty_init(info, "ISA bus")) {
4093             kfree(info);
4094             /* This is insufficient! kernel_map has added two large chunks!! */
4095             return -ENXIO;
4096         }
4097     }
4098 #endif /* CONFIG_ATARI */
4099     return 0;
4100 }
4101 
4102 #ifndef MODULE
4103 int __init atyfb_setup(char *options)
4104 {
4105     char *this_opt;
4106 
4107     if (!options || !*options)
4108         return 0;
4109 
4110     for (this_opt = strtok(options, ","); this_opt;
4111          this_opt = strtok(NULL, ",")) {
4112         if (!strncmp(this_opt, "font:", 5)) {
4113                 char *p;
4114                 int i;
4115 
4116                 p = this_opt + 5;
4117                 for (i = 0; i < sizeof(fontname) - 1; i++)
4118                         if (!*p || *p == ' ' || *p == ',')
4119                                 break;
4120                 memcpy(fontname, this_opt + 5, i);
4121                 fontname[i] = 0;
4122         } else if (!strncmp(this_opt, "noblink", 7)) {
4123                 curblink = 0;
4124         } else if (!strncmp(this_opt, "noaccel", 7)) {
4125                 noaccel = 1;
4126         } else if (!strncmp(this_opt, "vram:", 5))
4127                 default_vram = simple_strtoul(this_opt+5, NULL, 0);
4128         else if (!strncmp(this_opt, "pll:", 4))
4129                 default_pll = simple_strtoul(this_opt+4, NULL, 0);
4130         else if (!strncmp(this_opt, "mclk:", 5))
4131                 default_mclk = simple_strtoul(this_opt+5, NULL, 0);
4132 #ifdef CONFIG_PPC
4133         else if (!strncmp(this_opt, "vmode:", 6)) {
4134             unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
4135             if (vmode > 0 && vmode <= VMODE_MAX)
4136                 default_vmode = vmode;
4137         } else if (!strncmp(this_opt, "cmode:", 6)) {
4138             unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
4139             switch (cmode) {
4140                 case 0:
4141                 case 8:
4142                     default_cmode = CMODE_8;
4143                     break;
4144                 case 15:
4145                 case 16:
4146                     default_cmode = CMODE_16;
4147                     break;
4148                 case 24:
4149                 case 32:
4150                     default_cmode = CMODE_32;
4151                     break;
4152             }
4153         }
4154 #endif
4155 #ifdef CONFIG_ATARI
4156         /*
4157          * Why do we need this silly Mach64 argument?
4158          * We are already here because of mach64= so its redundant.
4159          */
4160         else if (MACH_IS_ATARI && (!strncmp(this_opt, "Mach64:", 7))) {
4161             static unsigned char m64_num;
4162             static char mach64_str[80];
4163             strncpy(mach64_str, this_opt+7, 80);
4164             if (!store_video_par(mach64_str, m64_num)) {
4165                 m64_num++;
4166                 mach64_count = m64_num;
4167             }
4168         }
4169 #endif
4170         else
4171             mode_option = this_opt;
4172     }
4173     return 0;
4174 }
4175 #endif /* !MODULE */
4176 
4177 #ifdef CONFIG_ATARI
4178 static int __init store_video_par(char *video_str, unsigned char m64_num)
4179 {
4180     char *p;
4181     unsigned long vmembase, size, guiregbase;
4182 
4183     printk("store_video_par() '%s' \n", video_str);
4184 
4185     if (!(p = strtoke(video_str, ";")) || !*p)
4186         goto mach64_invalid;
4187     vmembase = simple_strtoul(p, NULL, 0);
4188     if (!(p = strtoke(NULL, ";")) || !*p)
4189         goto mach64_invalid;
4190     size = simple_strtoul(p, NULL, 0);
4191     if (!(p = strtoke(NULL, ";")) || !*p)
4192         goto mach64_invalid;
4193     guiregbase = simple_strtoul(p, NULL, 0);
4194 
4195     phys_vmembase[m64_num] = vmembase;
4196     phys_size[m64_num] = size;
4197     phys_guiregbase[m64_num] = guiregbase;
4198     printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
4199            guiregbase);
4200     return 0;
4201 
4202 mach64_invalid:
4203     phys_vmembase[m64_num]   = 0;
4204     return -1;
4205 }
4206 
4207 static char __init *strtoke(char *s, const char *ct)
4208 {
4209     static char *ssave = NULL;
4210     char *sbegin, *send;
4211 
4212     sbegin  = s ? s : ssave;
4213     if (!sbegin)
4214         return NULL;
4215     if (*sbegin == '\0') {
4216         ssave = NULL;
4217         return NULL;
4218     }
4219     send = strpbrk(sbegin, ct);
4220     if (send && *send != '\0')
4221         *send++ = '\0';
4222     ssave = send;
4223     return sbegin;
4224 }
4225 #endif /* CONFIG_ATARI */
4226 
4227 static int atyfbcon_switch(int con, struct fb_info *fb)
4228 {
4229     struct fb_info_aty *info = (struct fb_info_aty *)fb;
4230     struct atyfb_par par;
4231 
4232     /* Do we have to save the colormap? */
4233     if (fb_display[currcon].cmap.len)
4234         fb_get_cmap(&fb_display[currcon].cmap, 1, atyfb_getcolreg, fb);
4235 
4236     /* Erase HW Cursor */
4237     if (info->cursor)
4238         atyfb_cursor(&fb_display[currcon], CM_ERASE,
4239                      info->cursor->pos.x, info->cursor->pos.y);
4240 
4241     currcon = con;
4242 
4243     atyfb_decode_var(&fb_display[con].var, &par, info);
4244     atyfb_set_par(&par, info);
4245     atyfb_set_dispsw(&fb_display[con], info, par.crtc.bpp,
4246                      par.accel_flags & FB_ACCELF_TEXT);
4247 
4248     /* Install new colormap */
4249     do_install_cmap(con, fb);
4250 
4251     /* Install hw cursor */
4252     if (info->cursor) {
4253         aty_set_cursor_color(info, cursor_pixel_map, cursor_color_map,
4254                              cursor_color_map, cursor_color_map);
4255         aty_set_cursor_shape(info);
4256     }
4257     return 1;
4258 }
4259 
4260     /*
4261      *  Blank the display.
4262      */
4263 
4264 static void atyfbcon_blank(int blank, struct fb_info *fb)
4265 {
4266     struct fb_info_aty *info = (struct fb_info_aty *)fb;
4267     u8 gen_cntl;
4268 
4269 #ifdef CONFIG_PMAC_BACKLIGHT
4270     if ((_machine == _MACH_Pmac) && blank)
4271         set_backlight_enable(0);
4272 #endif /* CONFIG_PMAC_BACKLIGHT */
4273 
4274     gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
4275     if (blank > 0)
4276         switch (blank-1) {
4277             case VESA_NO_BLANKING:
4278                 gen_cntl |= 0x40;
4279                 break;
4280             case VESA_VSYNC_SUSPEND:
4281                 gen_cntl |= 0x8;
4282                 break;
4283             case VESA_HSYNC_SUSPEND:
4284                 gen_cntl |= 0x4;
4285                 break;
4286             case VESA_POWERDOWN:
4287                 gen_cntl |= 0x4c;
4288                 break;
4289         }
4290     else
4291         gen_cntl &= ~(0x4c);
4292     aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
4293 
4294 #ifdef CONFIG_PMAC_BACKLIGHT
4295     if ((_machine == _MACH_Pmac) && !blank)
4296         set_backlight_enable(1);
4297 #endif /* CONFIG_PMAC_BACKLIGHT */
4298 }
4299 
4300 
4301     /*
4302      *  Read a single color register and split it into
4303      *  colors/transparent. Return != 0 for invalid regno.
4304      */
4305 
4306 static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
4307                            u_int *transp, struct fb_info *fb)
4308 {
4309     struct fb_info_aty *info = (struct fb_info_aty *)fb;
4310 
4311     if (regno > 255)
4312         return 1;
4313     *red = (info->palette[regno].red<<8) | info->palette[regno].red;
4314     *green = (info->palette[regno].green<<8) | info->palette[regno].green;
4315     *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
4316     *transp = 0;
4317     return 0;
4318 }
4319 
4320 
4321     /*
4322      *  Set a single color register. The values supplied are already
4323      *  rounded down to the hardware's capabilities (according to the
4324      *  entries in the var structure). Return != 0 for invalid regno.
4325      */
4326 
4327 static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
4328                            u_int transp, struct fb_info *fb)
4329 {
4330     struct fb_info_aty *info = (struct fb_info_aty *)fb;
4331     int i, scale;
4332 
4333     if (regno > 255)
4334         return 1;
4335     red >>= 8;
4336     green >>= 8;
4337     blue >>= 8;
4338     info->palette[regno].red = red;
4339     info->palette[regno].green = green;
4340     info->palette[regno].blue = blue;
4341     i = aty_ld_8(DAC_CNTL, info) & 0xfc;
4342     if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
4343         Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
4344         Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
4345         Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == LI_CHIP_ID)
4346         i |= 0x2;       /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
4347     aty_st_8(DAC_CNTL, i, info);
4348     aty_st_8(DAC_MASK, 0xff, info);
4349     scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
4350              (info->current_par.crtc.bpp == 16)) ? 3 : 0;
4351     writeb(regno << scale, &info->aty_cmap_regs->windex);
4352     writeb(red, &info->aty_cmap_regs->lut);
4353     writeb(green, &info->aty_cmap_regs->lut);
4354     writeb(blue, &info->aty_cmap_regs->lut);
4355     if (regno < 16)
4356         switch (info->current_par.crtc.bpp) {
4357 #ifdef FBCON_HAS_CFB16
4358             case 16:
4359                 info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
4360                                                 regno;
4361                 break;
4362 #endif
4363 #ifdef FBCON_HAS_CFB24
4364             case 24:
4365                 info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
4366                                                 regno;
4367                 break;
4368 #endif
4369 #ifdef FBCON_HAS_CFB32
4370             case 32:
4371                 i = (regno << 8) | regno;
4372                 info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
4373                 break;
4374 #endif
4375             }
4376     return 0;
4377 }
4378 
4379 
4380 static void do_install_cmap(int con, struct fb_info *info)
4381 {
4382     if (con != currcon)
4383         return;
4384     if (fb_display[con].cmap.len)
4385         fb_set_cmap(&fb_display[con].cmap, 1, atyfb_setcolreg, info);
4386     else {
4387         int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
4388         fb_set_cmap(fb_default_cmap(size), 1, atyfb_setcolreg, info);
4389     }
4390 }
4391 
4392 
4393     /*
4394      *  Accelerated functions
4395      */
4396 
4397 static inline void draw_rect(s16 x, s16 y, u16 width, u16 height,
4398                              struct fb_info_aty *info)
4399 {
4400     /* perform rectangle fill */
4401     wait_for_fifo(2, info);
4402     aty_st_le32(DST_Y_X, (x << 16) | y, info);
4403     aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, info);
4404     info->blitter_may_be_busy = 1;
4405 }
4406 
4407 static inline void aty_rectcopy(int srcx, int srcy, int dstx, int dsty,
4408                                 u_int width, u_int height,
4409                                 struct fb_info_aty *info)
4410 {
4411     u32 direction = DST_LAST_PEL;
4412     u32 pitch_value;
4413 
4414     if (!width || !height)
4415         return;
4416 
4417     pitch_value = info->current_par.crtc.vxres;
4418     if (info->current_par.crtc.bpp == 24) {
4419         /* In 24 bpp, the engine is in 8 bpp - this requires that all */
4420         /* horizontal coordinates and widths must be adjusted */
4421         pitch_value *= 3;
4422         srcx *= 3;
4423         dstx *= 3;
4424         width *= 3;
4425     }
4426 
4427     if (srcy < dsty) {
4428         dsty += height - 1;
4429         srcy += height - 1;
4430     } else
4431         direction |= DST_Y_TOP_TO_BOTTOM;
4432 
4433     if (srcx < dstx) {
4434         dstx += width - 1;
4435         srcx += width - 1;
4436     } else
4437         direction |= DST_X_LEFT_TO_RIGHT;
4438 
4439     wait_for_fifo(4, info);
4440     aty_st_le32(DP_SRC, FRGD_SRC_BLIT, info);
4441     aty_st_le32(SRC_Y_X, (srcx << 16) | srcy, info);
4442     aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | height, info);
4443     aty_st_le32(DST_CNTL, direction, info);
4444     draw_rect(dstx, dsty, width, height, info);
4445 }
4446 
4447 static inline void aty_rectfill(int dstx, int dsty, u_int width, u_int height,
4448                                 u_int color, struct fb_info_aty *info)
4449 {
4450     if (!width || !height)
4451         return;
4452 
4453     if (info->current_par.crtc.bpp == 24) {
4454         /* In 24 bpp, the engine is in 8 bpp - this requires that all */
4455         /* horizontal coordinates and widths must be adjusted */
4456         dstx *= 3;
4457         width *= 3;
4458     }
4459 
4460     wait_for_fifo(3, info);
4461     aty_st_le32(DP_FRGD_CLR, color, info);
4462     aty_st_le32(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
4463                 info);
4464     aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
4465                           DST_X_LEFT_TO_RIGHT, info);
4466     draw_rect(dstx, dsty, width, height, info);
4467 }
4468 
4469     /*
4470      *  Update the `var' structure (called by fbcon.c)
4471      */
4472 
4473 static int atyfbcon_updatevar(int con, struct fb_info *fb)
4474 {
4475     struct fb_info_aty *info = (struct fb_info_aty *)fb;
4476     struct atyfb_par *par = &info->current_par;
4477     struct display *p = &fb_display[con];
4478     struct vc_data *conp = p->conp;
4479     u32 yres, yoffset, sy, height;
4480 
4481     yres = ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1;
4482     yoffset = fb_display[con].var.yoffset;
4483 
4484     sy = (conp->vc_rows + p->yscroll) * fontheight(p);
4485     height = yres - conp->vc_rows * fontheight(p);
4486 
4487     if (height && (yoffset + yres > sy)) {
4488         u32 xres, xoffset;
4489         u32 bgx;
4490 
4491         xres = (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8;
4492         xoffset = fb_display[con].var.xoffset;
4493 
4494 
4495         bgx = attr_bgcol_ec(p, conp);
4496         bgx |= (bgx << 8);
4497         bgx |= (bgx << 16);
4498 
4499         if (sy + height > par->crtc.vyres) {
4500             wait_for_fifo(1, info);
4501             aty_st_le32(SC_BOTTOM, sy + height - 1, info);
4502         }
4503         aty_rectfill(xoffset, sy, xres, height, bgx, info);
4504     }
4505 
4506     if (info->cursor && (yoffset + yres <= sy))
4507         atyfb_cursor(p, CM_ERASE, info->cursor->pos.x, info->cursor->pos.y);
4508 
4509     info->current_par.crtc.yoffset = yoffset;
4510     set_off_pitch(&info->current_par, info);
4511     return 0;
4512 }
4513 
4514     /*
4515      *  Text console acceleration
4516      */
4517 
4518 static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
4519                             int height, int width)
4520 {
4521 #ifdef __sparc__
4522     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4523 
4524     if (fb->mmaped && (!fb->fb_info.display_fg
4525         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4526         return;
4527 #endif
4528 
4529     sx *= fontwidth(p);
4530     sy *= fontheight(p);
4531     dx *= fontwidth(p);
4532     dy *= fontheight(p);
4533     width *= fontwidth(p);
4534     height *= fontheight(p);
4535 
4536     aty_rectcopy(sx, sy, dx, dy, width, height,
4537                  (struct fb_info_aty *)p->fb_info);
4538 }
4539 
4540 static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
4541                             int sx, int height, int width)
4542 {
4543     u32 bgx;
4544 #ifdef __sparc__
4545     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4546 
4547     if (fb->mmaped && (!fb->fb_info.display_fg
4548         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4549         return;
4550 #endif
4551 
4552     bgx = attr_bgcol_ec(p, conp);
4553     bgx |= (bgx << 8);
4554     bgx |= (bgx << 16);
4555 
4556     sx *= fontwidth(p);
4557     sy *= fontheight(p);
4558     width *= fontwidth(p);
4559     height *= fontheight(p);
4560 
4561     aty_rectfill(sx, sy, width, height, bgx,
4562                  (struct fb_info_aty *)p->fb_info);
4563 }
4564 
4565 #ifdef FBCON_HAS_CFB8
4566 static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
4567                             int yy, int xx)
4568 {
4569     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4570 
4571 #ifdef __sparc__
4572     if (fb->mmaped && (!fb->fb_info.display_fg
4573         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4574         return;
4575 #endif
4576 
4577     if (fb->blitter_may_be_busy)
4578         wait_for_idle((struct fb_info_aty *)p->fb_info);
4579     fbcon_cfb8_putc(conp, p, c, yy, xx);
4580 }
4581 
4582 static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
4583                              const unsigned short *s, int count, int yy,
4584                              int xx)
4585 {
4586     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4587 
4588 #ifdef __sparc__
4589     if (fb->mmaped && (!fb->fb_info.display_fg
4590         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4591         return;
4592 #endif
4593 
4594     if (fb->blitter_may_be_busy)
4595         wait_for_idle((struct fb_info_aty *)p->fb_info);
4596     fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
4597 }
4598 
4599 static void fbcon_aty8_clear_margins(struct vc_data *conp, struct display *p,
4600                                      int bottom_only)
4601 {
4602     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4603 
4604 #ifdef __sparc__
4605     if (fb->mmaped && (!fb->fb_info.display_fg
4606         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4607         return;
4608 #endif
4609 
4610     if (fb->blitter_may_be_busy)
4611         wait_for_idle((struct fb_info_aty *)p->fb_info);
4612     fbcon_cfb8_clear_margins(conp, p, bottom_only);
4613 }
4614 
4615 static struct display_switch fbcon_aty8 = {
4616     setup:              fbcon_cfb8_setup,
4617     bmove:              fbcon_aty_bmove,
4618     clear:              fbcon_aty_clear,
4619     putc:               fbcon_aty8_putc,
4620     putcs:              fbcon_aty8_putcs,
4621     revc:               fbcon_cfb8_revc,
4622     clear_margins:      fbcon_aty8_clear_margins,
4623     fontwidthmask:      FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4624 };
4625 #endif
4626 
4627 #ifdef FBCON_HAS_CFB16
4628 static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c,
4629                              int yy, int xx)
4630 {
4631     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4632 
4633 #ifdef __sparc__
4634     if (fb->mmaped && (!fb->fb_info.display_fg
4635         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4636         return;
4637 #endif
4638 
4639     if (fb->blitter_may_be_busy)
4640         wait_for_idle((struct fb_info_aty *)p->fb_info);
4641     fbcon_cfb16_putc(conp, p, c, yy, xx);
4642 }
4643 
4644 static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
4645                               const unsigned short *s, int count, int yy,
4646                               int xx)
4647 {
4648     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4649 
4650 #ifdef __sparc__
4651     if (fb->mmaped && (!fb->fb_info.display_fg
4652         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4653         return;
4654 #endif
4655 
4656     if (fb->blitter_may_be_busy)
4657         wait_for_idle((struct fb_info_aty *)p->fb_info);
4658     fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
4659 }
4660 
4661 static void fbcon_aty16_clear_margins(struct vc_data *conp, struct display *p,
4662                                       int bottom_only)
4663 {
4664     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4665 
4666 #ifdef __sparc__
4667     if (fb->mmaped && (!fb->fb_info.display_fg
4668         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4669         return;
4670 #endif
4671 
4672     if (fb->blitter_may_be_busy)
4673         wait_for_idle((struct fb_info_aty *)p->fb_info);
4674     fbcon_cfb16_clear_margins(conp, p, bottom_only);
4675 }
4676 
4677 static struct display_switch fbcon_aty16 = {
4678     setup:              fbcon_cfb16_setup,
4679     bmove:              fbcon_aty_bmove,
4680     clear:              fbcon_aty_clear,
4681     putc:               fbcon_aty16_putc,
4682     putcs:              fbcon_aty16_putcs,
4683     revc:               fbcon_cfb16_revc,
4684     clear_margins:      fbcon_aty16_clear_margins,
4685     fontwidthmask:      FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4686 };
4687 #endif
4688 
4689 #ifdef FBCON_HAS_CFB24
4690 static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
4691                              int yy, int xx)
4692 {
4693     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4694 
4695 #ifdef __sparc__
4696     if (fb->mmaped && (!fb->fb_info.display_fg
4697         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4698         return;
4699 #endif
4700 
4701     if (fb->blitter_may_be_busy)
4702         wait_for_idle((struct fb_info_aty *)p->fb_info);
4703     fbcon_cfb24_putc(conp, p, c, yy, xx);
4704 }
4705 
4706 static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
4707                               const unsigned short *s, int count, int yy,
4708                               int xx)
4709 {
4710     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4711 
4712 #ifdef __sparc__
4713     if (fb->mmaped && (!fb->fb_info.display_fg
4714         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4715         return;
4716 #endif
4717 
4718     if (fb->blitter_may_be_busy)
4719         wait_for_idle((struct fb_info_aty *)p->fb_info);
4720     fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
4721 }
4722 
4723 static void fbcon_aty24_clear_margins(struct vc_data *conp, struct display *p,
4724                                       int bottom_only)
4725 {
4726     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4727 
4728 #ifdef __sparc__
4729     if (fb->mmaped && (!fb->fb_info.display_fg
4730         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4731         return;
4732 #endif
4733 
4734     if (fb->blitter_may_be_busy)
4735         wait_for_idle((struct fb_info_aty *)p->fb_info);
4736     fbcon_cfb24_clear_margins(conp, p, bottom_only);
4737 }
4738 
4739 static struct display_switch fbcon_aty24 = {
4740     setup:              fbcon_cfb24_setup,
4741     bmove:              fbcon_aty_bmove,
4742     clear:              fbcon_aty_clear,
4743     putc:               fbcon_aty24_putc,
4744     putcs:              fbcon_aty24_putcs,
4745     revc:               fbcon_cfb24_revc,
4746     clear_margins:      fbcon_aty24_clear_margins,
4747     fontwidthmask:      FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4748 };
4749 #endif
4750 
4751 #ifdef FBCON_HAS_CFB32
4752 static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
4753                              int yy, int xx)
4754 {
4755     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4756 
4757 #ifdef __sparc__
4758     if (fb->mmaped && (!fb->fb_info.display_fg
4759         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4760         return;
4761 #endif
4762 
4763     if (fb->blitter_may_be_busy)
4764         wait_for_idle((struct fb_info_aty *)p->fb_info);
4765     fbcon_cfb32_putc(conp, p, c, yy, xx);
4766 }
4767 
4768 static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
4769                               const unsigned short *s, int count, int yy,
4770                               int xx)
4771 {
4772     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4773 
4774 #ifdef __sparc__
4775     if (fb->mmaped && (!fb->fb_info.display_fg
4776         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4777         return;
4778 #endif
4779 
4780     if (fb->blitter_may_be_busy)
4781         wait_for_idle((struct fb_info_aty *)p->fb_info);
4782     fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
4783 }
4784 
4785 static void fbcon_aty32_clear_margins(struct vc_data *conp, struct display *p,
4786                                       int bottom_only)
4787 {
4788     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
4789 
4790 #ifdef __sparc__
4791     if (fb->mmaped && (!fb->fb_info.display_fg
4792         || fb->fb_info.display_fg->vc_num == fb->vtconsole))
4793         return;
4794 #endif
4795 
4796     if (fb->blitter_may_be_busy)
4797         wait_for_idle((struct fb_info_aty *)p->fb_info);
4798     fbcon_cfb32_clear_margins(conp, p, bottom_only);
4799 }
4800 
4801 static struct display_switch fbcon_aty32 = {
4802     setup:              fbcon_cfb32_setup,
4803     bmove:              fbcon_aty_bmove,
4804     clear:              fbcon_aty_clear,
4805     putc:               fbcon_aty32_putc,
4806     putcs:              fbcon_aty32_putcs,
4807     revc:               fbcon_cfb32_revc,
4808     clear_margins:      fbcon_aty32_clear_margins,
4809     fontwidthmask:      FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
4810 };
4811 #endif
4812 
4813 #ifdef CONFIG_PMAC_PBOOK
4814 
4815 /* Power management routines. Those are used for PowerBook sleep.
4816  *
4817  * It appears that Rage LT and Rage LT Pro have different power
4818  * management registers. There's is some confusion about which
4819  * chipID is a Rage LT or LT pro :(
4820  */
4821 static int
4822 aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
4823 {
4824         unsigned int pm;
4825         int timeout;
4826         
4827         pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4828         pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
4829         aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4830         pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4831         
4832         timeout = 200000;
4833         if (sleep) {
4834                 /* Sleep */
4835                 pm &= ~PWR_MGT_ON;
4836                 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4837                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4838                 udelay(10);
4839                 pm &= ~(PWR_BLON | AUTO_PWR_UP);
4840                 pm |= SUSPEND_NOW;
4841                 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4842                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4843                 udelay(10);
4844                 pm |= PWR_MGT_ON;
4845                 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4846                 do {
4847                         pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4848                         udelay(10);
4849                         if ((--timeout) == 0)
4850                                 break;
4851                 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
4852         } else {
4853                 /* Wakeup */
4854                 pm &= ~PWR_MGT_ON;
4855                 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4856                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4857                 udelay(10);
4858                 pm |=  (PWR_BLON | AUTO_PWR_UP);
4859                 pm &= ~SUSPEND_NOW;
4860                 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4861                 pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4862                 udelay(10);
4863                 pm |= PWR_MGT_ON;
4864                 aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
4865                 do {
4866                         pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
4867                         udelay(10);
4868                         if ((--timeout) == 0)
4869                                 break;
4870                 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
4871         }
4872         mdelay(500);
4873 
4874         return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
4875 }
4876 
4877 static int
4878 aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
4879 {
4880         unsigned int pm;
4881         int timeout;
4882         
4883         pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4884         pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
4885         aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4886         pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4887 
4888         timeout = 200;
4889         if (sleep) {
4890                 /* Sleep */
4891                 pm &= ~PWR_MGT_ON;
4892                 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4893                 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4894                 udelay(10);
4895                 pm &= ~(PWR_BLON | AUTO_PWR_UP);
4896                 pm |= SUSPEND_NOW;
4897                 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4898                 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4899                 udelay(10);
4900                 pm |= PWR_MGT_ON;
4901                 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4902                 do {
4903                         pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4904                         udelay(1000);
4905                         if ((--timeout) == 0)
4906                                 break;
4907                 } while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
4908         } else {
4909                 /* Wakeup */
4910                 pm &= ~PWR_MGT_ON;
4911                 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4912                 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4913                 udelay(10);
4914                 pm &= ~SUSPEND_NOW;
4915                 pm |= (PWR_BLON | AUTO_PWR_UP);
4916                 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4917                 pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
4918                 udelay(10);
4919                 pm |= PWR_MGT_ON;
4920                 aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
4921                 do {
4922                         pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);                    
4923                         udelay(1000);
4924                         if ((--timeout) == 0)
4925                                 break;
4926                 } while ((pm & PWR_MGT_STATUS_MASK) != 0);
4927         }
4928 
4929         return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
4930 }
4931 
4932 /*
4933  * Save the contents of the frame buffer when we go to sleep,
4934  * and restore it when we wake up again.
4935  */
4936 int
4937 aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
4938 {
4939         struct fb_info_aty *info;
4940         int result;
4941 
4942         result = PBOOK_SLEEP_OK;
4943 
4944         for (info = first_display; info != NULL; info = info->next) {
4945                 struct fb_fix_screeninfo fix;
4946                 int nb;
4947 
4948                 atyfb_get_fix(&fix, fg_console, (struct fb_info *)info);
4949                 nb = fb_display[fg_console].var.yres * fix.line_length;
4950 
4951                 switch (when) {
4952                 case PBOOK_SLEEP_REQUEST:
4953                         info->save_framebuffer = vmalloc(nb);
4954                         if (info->save_framebuffer == NULL)
4955                                 return PBOOK_SLEEP_REFUSE;
4956                         break;
4957                 case PBOOK_SLEEP_REJECT:
4958                         if (info->save_framebuffer) {
4959                                 vfree(info->save_framebuffer);
4960                                 info->save_framebuffer = 0;
4961                         }
4962                         break;
4963                 case PBOOK_SLEEP_NOW:
4964                         if (info->blitter_may_be_busy)
4965                                 wait_for_idle(info);
4966                         /* Stop accel engine (stop bus mastering) */
4967                         if (info->current_par.accel_flags & FB_ACCELF_TEXT)
4968                                 reset_engine(info);
4969 
4970                         /* Backup fb content */ 
4971                         if (info->save_framebuffer)
4972                                 memcpy_fromio(info->save_framebuffer,
4973                                        (void *)info->frame_buffer, nb);
4974 
4975                         /* Blank display and LCD */
4976                         atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
4977 
4978                         /* Set chip to "suspend" mode */
4979                         if (Gx == LG_CHIP_ID)
4980                                 result = aty_power_mgmt_LT(1, info);
4981                         else
4982                                 result = aty_power_mgmt_LTPro(1, info);
4983                         break;
4984                 case PBOOK_WAKE:
4985                         /* Wakeup chip */
4986                         if (Gx == LG_CHIP_ID)
4987                                 result = aty_power_mgmt_LT(0, info);
4988                         else
4989                                 result = aty_power_mgmt_LTPro(0, info);
4990 
4991                         /* Restore fb content */                        
4992                         if (info->save_framebuffer) {
4993                                 memcpy_toio((void *)info->frame_buffer,
4994                                        info->save_framebuffer, nb);
4995                                 vfree(info->save_framebuffer);
4996                                 info->save_framebuffer = 0;
4997                         }
4998                         /* Restore display */
4999                         atyfb_set_par(&info->current_par, info);
5000                         atyfbcon_blank(0, (struct fb_info *)info);
5001                         break;
5002                 }
5003         }
5004         return result;
5005 }
5006 #endif /* CONFIG_PMAC_PBOOK */
5007 
5008 #ifdef CONFIG_PMAC_BACKLIGHT
5009 static int backlight_conv[] = {
5010         0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
5011         0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
5012 };
5013 
5014 static int
5015 aty_set_backlight_enable(int on, int level, void* data)
5016 {
5017         struct fb_info_aty *info = (struct fb_info_aty *)data;
5018         unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, info);
5019         
5020         reg |= (BLMOD_EN | BIASMOD_EN);
5021         if (on && level > BACKLIGHT_OFF) {
5022                 reg &= ~BIAS_MOD_LEVEL_MASK;
5023                 reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
5024         } else {
5025                 reg &= ~BIAS_MOD_LEVEL_MASK;
5026                 reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
5027         }
5028         aty_st_lcd(LCD_MISC_CNTL, reg, info);
5029 
5030         return 0;
5031 }
5032 
5033 static int
5034 aty_set_backlight_level(int level, void* data)
5035 {
5036         return aty_set_backlight_enable(1, level, data);
5037 }
5038 
5039 #endif /* CONFIG_PMAC_BACKLIGHT */
5040 
5041 
5042 #ifdef MODULE
5043 int __init init_module(void)
5044 {
5045     atyfb_init();
5046     return fb_list ? 0 : -ENXIO;
5047 }
5048 
5049 void cleanup_module(void)
5050 {
5051     while (fb_list) {
5052         struct fb_info_aty *info = fb_list;
5053         fb_list = info->next;
5054 
5055         unregister_framebuffer(&info->fb_info);
5056 
5057 #ifndef __sparc__
5058         if (info->ati_regbase)
5059             iounmap((void *)info->ati_regbase);
5060         if (info->frame_buffer)
5061             iounmap((void *)info->frame_buffer);
5062 #ifdef __BIG_ENDIAN
5063         if (info->cursor && info->cursor->ram)
5064             iounmap(info->cursor->ram);
5065 #endif
5066 #endif
5067 
5068         if (info->cursor) {
5069             if (info->cursor->timer)
5070                 kfree(info->cursor->timer);
5071             kfree(info->cursor);
5072         }
5073 #ifdef __sparc__
5074         if (info->mmap_map)
5075             kfree(info->mmap_map);
5076 #endif
5077         kfree(info);
5078     }
5079 }
5080 
5081 #endif
5082 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.