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