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