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