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