[go: nahoru, domu]

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