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