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