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