cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

atyfb_base.c (111388B)


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