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