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