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