Linux Audio

Check our new training course

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