root/drivers/video/fbdev/aty/atyfb_base.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aty_st_lcd
  2. aty_ld_lcd
  3. ATIReduceRatio
  4. aty_fudge_framebuffer_len
  5. correct_chipset
  6. atyfb_get_pixclock
  7. read_aty_sense
  8. aty_get_crtc
  9. aty_set_crtc
  10. calc_line_length
  11. aty_var_to_crtc
  12. aty_crtc_to_var
  13. atyfb_set_par
  14. atyfb_check_var
  15. set_off_pitch
  16. atyfb_open
  17. aty_irq
  18. aty_enable_irq
  19. aty_disable_irq
  20. atyfb_release
  21. atyfb_pan_display
  22. aty_waitforvblank
  23. atyfb_ioctl
  24. atyfb_sync
  25. atyfb_mmap
  26. aty_power_mgmt
  27. atyfb_pci_suspend
  28. aty_resume_chip
  29. atyfb_pci_resume
  30. aty_bl_get_level_brightness
  31. aty_bl_update_status
  32. aty_bl_init
  33. aty_bl_exit
  34. aty_calc_mem_refresh
  35. atyfb_get_timings_from_lcd
  36. aty_init
  37. store_video_par
  38. atyfb_blank
  39. aty_st_pal
  40. atyfb_setcolreg
  41. atyfb_setup_sparc
  42. aty_init_lcd
  43. init_from_bios
  44. atyfb_setup_generic
  45. atyfb_pci_probe
  46. atyfb_atari_probe
  47. atyfb_remove
  48. atyfb_pci_remove
  49. atyfb_setup
  50. atyfb_reboot_notify
  51. atyfb_init
  52. atyfb_exit

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

/* [<][>][^][v][top][bottom][index][help] */