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