File Index
Files and directories
Sign in
FILE

atyfb_base.c

File preview with syntax highlighting.

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