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