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