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