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