diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/aty |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/video/aty')
-rw-r--r-- | drivers/video/aty/Makefile | 15 | ||||
-rw-r--r-- | drivers/video/aty/ati_ids.h | 211 | ||||
-rw-r--r-- | drivers/video/aty/aty128fb.c | 2485 | ||||
-rw-r--r-- | drivers/video/aty/atyfb.h | 359 | ||||
-rw-r--r-- | drivers/video/aty/atyfb_base.c | 3720 | ||||
-rw-r--r-- | drivers/video/aty/mach64_accel.c | 433 | ||||
-rw-r--r-- | drivers/video/aty/mach64_ct.c | 619 | ||||
-rw-r--r-- | drivers/video/aty/mach64_cursor.c | 226 | ||||
-rw-r--r-- | drivers/video/aty/mach64_gx.c | 912 | ||||
-rw-r--r-- | drivers/video/aty/radeon_accel.c | 316 | ||||
-rw-r--r-- | drivers/video/aty/radeon_base.c | 2587 | ||||
-rw-r--r-- | drivers/video/aty/radeon_i2c.c | 265 | ||||
-rw-r--r-- | drivers/video/aty/radeon_monitor.c | 1010 | ||||
-rw-r--r-- | drivers/video/aty/radeon_pm.c | 2801 | ||||
-rw-r--r-- | drivers/video/aty/radeonfb.h | 625 | ||||
-rw-r--r-- | drivers/video/aty/xlinit.c | 354 |
16 files changed, 16938 insertions, 0 deletions
diff --git a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile new file mode 100644 index 00000000000..9dec96249ff --- /dev/null +++ b/drivers/video/aty/Makefile @@ -0,0 +1,15 @@ +obj-$(CONFIG_FB_ATY) += atyfb.o +obj-$(CONFIG_FB_ATY128) += aty128fb.o +obj-$(CONFIG_FB_RADEON) += radeonfb.o + +atyfb-y := atyfb_base.o mach64_accel.o mach64_cursor.o +atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o +atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o +atyfb-$(CONFIG_FB_ATY_XL_INIT) += xlinit.o + +atyfb-objs := $(atyfb-y) + +radeonfb-y := radeon_base.o radeon_pm.o radeon_monitor.o radeon_accel.o +radeonfb-$(CONFIG_FB_RADEON_I2C) += radeon_i2c.o +radeonfb-objs := $(radeonfb-y) + diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h new file mode 100644 index 00000000000..13321c689cf --- /dev/null +++ b/drivers/video/aty/ati_ids.h @@ -0,0 +1,211 @@ +/* + * ATI PCI IDs from XFree86, kept here to make sync'ing with + * XFree much simpler. Currently, this list is only used by + * radeonfb + */ + +#define PCI_CHIP_RV380_3150 0x3150 +#define PCI_CHIP_RV380_3151 0x3151 +#define PCI_CHIP_RV380_3152 0x3152 +#define PCI_CHIP_RV380_3153 0x3153 +#define PCI_CHIP_RV380_3154 0x3154 +#define PCI_CHIP_RV380_3156 0x3156 +#define PCI_CHIP_RV380_3E50 0x3E50 +#define PCI_CHIP_RV380_3E51 0x3E51 +#define PCI_CHIP_RV380_3E52 0x3E52 +#define PCI_CHIP_RV380_3E53 0x3E53 +#define PCI_CHIP_RV380_3E54 0x3E54 +#define PCI_CHIP_RV380_3E56 0x3E56 +#define PCI_CHIP_RS100_4136 0x4136 +#define PCI_CHIP_RS200_4137 0x4137 +#define PCI_CHIP_R300_AD 0x4144 +#define PCI_CHIP_R300_AE 0x4145 +#define PCI_CHIP_R300_AF 0x4146 +#define PCI_CHIP_R300_AG 0x4147 +#define PCI_CHIP_R350_AH 0x4148 +#define PCI_CHIP_R350_AI 0x4149 +#define PCI_CHIP_R350_AJ 0x414A +#define PCI_CHIP_R350_AK 0x414B +#define PCI_CHIP_RV350_AP 0x4150 +#define PCI_CHIP_RV350_AQ 0x4151 +#define PCI_CHIP_RV360_AR 0x4152 +#define PCI_CHIP_RV350_AS 0x4153 +#define PCI_CHIP_RV350_AT 0x4154 +#define PCI_CHIP_RV350_AV 0x4156 +#define PCI_CHIP_MACH32 0x4158 +#define PCI_CHIP_RS250_4237 0x4237 +#define PCI_CHIP_R200_BB 0x4242 +#define PCI_CHIP_R200_BC 0x4243 +#define PCI_CHIP_RS100_4336 0x4336 +#define PCI_CHIP_RS200_4337 0x4337 +#define PCI_CHIP_MACH64CT 0x4354 +#define PCI_CHIP_MACH64CX 0x4358 +#define PCI_CHIP_RS250_4437 0x4437 +#define PCI_CHIP_MACH64ET 0x4554 +#define PCI_CHIP_MACH64GB 0x4742 +#define PCI_CHIP_MACH64GD 0x4744 +#define PCI_CHIP_MACH64GI 0x4749 +#define PCI_CHIP_MACH64GL 0x474C +#define PCI_CHIP_MACH64GM 0x474D +#define PCI_CHIP_MACH64GN 0x474E +#define PCI_CHIP_MACH64GO 0x474F +#define PCI_CHIP_MACH64GP 0x4750 +#define PCI_CHIP_MACH64GQ 0x4751 +#define PCI_CHIP_MACH64GR 0x4752 +#define PCI_CHIP_MACH64GS 0x4753 +#define PCI_CHIP_MACH64GT 0x4754 +#define PCI_CHIP_MACH64GU 0x4755 +#define PCI_CHIP_MACH64GV 0x4756 +#define PCI_CHIP_MACH64GW 0x4757 +#define PCI_CHIP_MACH64GX 0x4758 +#define PCI_CHIP_MACH64GY 0x4759 +#define PCI_CHIP_MACH64GZ 0x475A +#define PCI_CHIP_RV250_Id 0x4964 +#define PCI_CHIP_RV250_Ie 0x4965 +#define PCI_CHIP_RV250_If 0x4966 +#define PCI_CHIP_RV250_Ig 0x4967 +#define PCI_CHIP_R420_JH 0x4A48 +#define PCI_CHIP_R420_JI 0x4A49 +#define PCI_CHIP_R420_JJ 0x4A4A +#define PCI_CHIP_R420_JK 0x4A4B +#define PCI_CHIP_R420_JL 0x4A4C +#define PCI_CHIP_R420_JM 0x4A4D +#define PCI_CHIP_R420_JN 0x4A4E +#define PCI_CHIP_R420_JP 0x4A50 +#define PCI_CHIP_MACH64LB 0x4C42 +#define PCI_CHIP_MACH64LD 0x4C44 +#define PCI_CHIP_RAGE128LE 0x4C45 +#define PCI_CHIP_RAGE128LF 0x4C46 +#define PCI_CHIP_MACH64LG 0x4C47 +#define PCI_CHIP_MACH64LI 0x4C49 +#define PCI_CHIP_MACH64LM 0x4C4D +#define PCI_CHIP_MACH64LN 0x4C4E +#define PCI_CHIP_MACH64LP 0x4C50 +#define PCI_CHIP_MACH64LQ 0x4C51 +#define PCI_CHIP_MACH64LR 0x4C52 +#define PCI_CHIP_MACH64LS 0x4C53 +#define PCI_CHIP_MACH64LT 0x4C54 +#define PCI_CHIP_RADEON_LW 0x4C57 +#define PCI_CHIP_RADEON_LX 0x4C58 +#define PCI_CHIP_RADEON_LY 0x4C59 +#define PCI_CHIP_RADEON_LZ 0x4C5A +#define PCI_CHIP_RV250_Ld 0x4C64 +#define PCI_CHIP_RV250_Le 0x4C65 +#define PCI_CHIP_RV250_Lf 0x4C66 +#define PCI_CHIP_RV250_Lg 0x4C67 +#define PCI_CHIP_RV250_Ln 0x4C6E +#define PCI_CHIP_RAGE128MF 0x4D46 +#define PCI_CHIP_RAGE128ML 0x4D4C +#define PCI_CHIP_R300_ND 0x4E44 +#define PCI_CHIP_R300_NE 0x4E45 +#define PCI_CHIP_R300_NF 0x4E46 +#define PCI_CHIP_R300_NG 0x4E47 +#define PCI_CHIP_R350_NH 0x4E48 +#define PCI_CHIP_R350_NI 0x4E49 +#define PCI_CHIP_R360_NJ 0x4E4A +#define PCI_CHIP_R350_NK 0x4E4B +#define PCI_CHIP_RV350_NP 0x4E50 +#define PCI_CHIP_RV350_NQ 0x4E51 +#define PCI_CHIP_RV350_NR 0x4E52 +#define PCI_CHIP_RV350_NS 0x4E53 +#define PCI_CHIP_RV350_NT 0x4E54 +#define PCI_CHIP_RV350_NV 0x4E56 +#define PCI_CHIP_RAGE128PA 0x5041 +#define PCI_CHIP_RAGE128PB 0x5042 +#define PCI_CHIP_RAGE128PC 0x5043 +#define PCI_CHIP_RAGE128PD 0x5044 +#define PCI_CHIP_RAGE128PE 0x5045 +#define PCI_CHIP_RAGE128PF 0x5046 +#define PCI_CHIP_RAGE128PG 0x5047 +#define PCI_CHIP_RAGE128PH 0x5048 +#define PCI_CHIP_RAGE128PI 0x5049 +#define PCI_CHIP_RAGE128PJ 0x504A +#define PCI_CHIP_RAGE128PK 0x504B +#define PCI_CHIP_RAGE128PL 0x504C +#define PCI_CHIP_RAGE128PM 0x504D +#define PCI_CHIP_RAGE128PN 0x504E +#define PCI_CHIP_RAGE128PO 0x504F +#define PCI_CHIP_RAGE128PP 0x5050 +#define PCI_CHIP_RAGE128PQ 0x5051 +#define PCI_CHIP_RAGE128PR 0x5052 +#define PCI_CHIP_RAGE128PS 0x5053 +#define PCI_CHIP_RAGE128PT 0x5054 +#define PCI_CHIP_RAGE128PU 0x5055 +#define PCI_CHIP_RAGE128PV 0x5056 +#define PCI_CHIP_RAGE128PW 0x5057 +#define PCI_CHIP_RAGE128PX 0x5058 +#define PCI_CHIP_RADEON_QD 0x5144 +#define PCI_CHIP_RADEON_QE 0x5145 +#define PCI_CHIP_RADEON_QF 0x5146 +#define PCI_CHIP_RADEON_QG 0x5147 +#define PCI_CHIP_R200_QH 0x5148 +#define PCI_CHIP_R200_QI 0x5149 +#define PCI_CHIP_R200_QJ 0x514A +#define PCI_CHIP_R200_QK 0x514B +#define PCI_CHIP_R200_QL 0x514C +#define PCI_CHIP_R200_QM 0x514D +#define PCI_CHIP_R200_QN 0x514E +#define PCI_CHIP_R200_QO 0x514F +#define PCI_CHIP_RV200_QW 0x5157 +#define PCI_CHIP_RV200_QX 0x5158 +#define PCI_CHIP_RV100_QY 0x5159 +#define PCI_CHIP_RV100_QZ 0x515A +#define PCI_CHIP_RAGE128RE 0x5245 +#define PCI_CHIP_RAGE128RF 0x5246 +#define PCI_CHIP_RAGE128RG 0x5247 +#define PCI_CHIP_RAGE128RK 0x524B +#define PCI_CHIP_RAGE128RL 0x524C +#define PCI_CHIP_RAGE128SE 0x5345 +#define PCI_CHIP_RAGE128SF 0x5346 +#define PCI_CHIP_RAGE128SG 0x5347 +#define PCI_CHIP_RAGE128SH 0x5348 +#define PCI_CHIP_RAGE128SK 0x534B +#define PCI_CHIP_RAGE128SL 0x534C +#define PCI_CHIP_RAGE128SM 0x534D +#define PCI_CHIP_RAGE128SN 0x534E +#define PCI_CHIP_RAGE128TF 0x5446 +#define PCI_CHIP_RAGE128TL 0x544C +#define PCI_CHIP_RAGE128TR 0x5452 +#define PCI_CHIP_RAGE128TS 0x5453 +#define PCI_CHIP_RAGE128TT 0x5454 +#define PCI_CHIP_RAGE128TU 0x5455 +#define PCI_CHIP_RV370_5460 0x5460 +#define PCI_CHIP_RV370_5461 0x5461 +#define PCI_CHIP_RV370_5462 0x5462 +#define PCI_CHIP_RV370_5463 0x5463 +#define PCI_CHIP_RV370_5464 0x5464 +#define PCI_CHIP_RV370_5465 0x5465 +#define PCI_CHIP_RV370_5466 0x5466 +#define PCI_CHIP_RV370_5467 0x5467 +#define PCI_CHIP_R423_UH 0x5548 +#define PCI_CHIP_R423_UI 0x5549 +#define PCI_CHIP_R423_UJ 0x554A +#define PCI_CHIP_R423_UK 0x554B +#define PCI_CHIP_R423_UQ 0x5551 +#define PCI_CHIP_R423_UR 0x5552 +#define PCI_CHIP_R423_UT 0x5554 +#define PCI_CHIP_MACH64VT 0x5654 +#define PCI_CHIP_MACH64VU 0x5655 +#define PCI_CHIP_MACH64VV 0x5656 +#define PCI_CHIP_RS300_5834 0x5834 +#define PCI_CHIP_RS300_5835 0x5835 +#define PCI_CHIP_RS300_5836 0x5836 +#define PCI_CHIP_RS300_5837 0x5837 +#define PCI_CHIP_RV370_5B60 0x5B60 +#define PCI_CHIP_RV370_5B61 0x5B61 +#define PCI_CHIP_RV370_5B62 0x5B62 +#define PCI_CHIP_RV370_5B63 0x5B63 +#define PCI_CHIP_RV370_5B64 0x5B64 +#define PCI_CHIP_RV370_5B65 0x5B65 +#define PCI_CHIP_RV370_5B66 0x5B66 +#define PCI_CHIP_RV370_5B67 0x5B67 +#define PCI_CHIP_RV280_5960 0x5960 +#define PCI_CHIP_RV280_5961 0x5961 +#define PCI_CHIP_RV280_5962 0x5962 +#define PCI_CHIP_RV280_5964 0x5964 +#define PCI_CHIP_RV280_5C61 0x5C61 +#define PCI_CHIP_RV280_5C63 0x5C63 +#define PCI_CHIP_R423_5D57 0x5D57 +#define PCI_CHIP_RS350_7834 0x7834 +#define PCI_CHIP_RS350_7835 0x7835 + diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c new file mode 100644 index 00000000000..8a4ba3bb987 --- /dev/null +++ b/drivers/video/aty/aty128fb.c @@ -0,0 +1,2485 @@ +/* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $ + * linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128 + * + * Copyright (C) 1999-2003, Brad Douglas <brad@neruo.com> + * Copyright (C) 1999, Anthony Tong <atong@uiuc.edu> + * + * Ani Joshi / Jeff Garzik + * - Code cleanup + * + * Michel Danzer <michdaen@iiic.ethz.ch> + * - 15/16 bit cleanup + * - fix panning + * + * Benjamin Herrenschmidt + * - pmac-specific PM stuff + * - various fixes & cleanups + * + * Andreas Hundt <andi@convergence.de> + * - FB_ACTIVATE fixes + * + * Paul Mackerras <paulus@samba.org> + * - Convert to new framebuffer API, + * fix colormap setting at 16 bits/pixel (565) + * + * Paul Mundt + * - PCI hotplug + * + * Jon Smirl <jonsmirl@yahoo.com> + * - PCI ID update + * - replace ROM BIOS search + * + * Based off of Geert's atyfb.c and vfb.c. + * + * TODO: + * - monitor sensing (DDC) + * - virtual display + * - other platform support (only ppc/x86 supported) + * - hardware cursor support + * + * Please cc: your patches to brad@neruo.com. + */ + +/* + * A special note of gratitude to ATI's devrel for providing documentation, + * example code and hardware. Thanks Nitya. -atong and brad + */ + + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <asm/uaccess.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/console.h> +#include <asm/io.h> + +#ifdef CONFIG_PPC_PMAC +#include <asm/pmac_feature.h> +#include <asm/prom.h> +#include <asm/pci-bridge.h> +#include "../macmodes.h" +#endif + +#ifdef CONFIG_PMAC_BACKLIGHT +#include <asm/backlight.h> +#endif + +#ifdef CONFIG_BOOTX_TEXT +#include <asm/btext.h> +#endif /* CONFIG_BOOTX_TEXT */ + +#ifdef CONFIG_MTRR +#include <asm/mtrr.h> +#endif + +#include <video/aty128.h> + +/* Debug flag */ +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt, args...) printk(KERN_DEBUG "aty128fb: %s " fmt, __FUNCTION__, ##args); +#else +#define DBG(fmt, args...) +#endif + +#ifndef CONFIG_PPC_PMAC +/* default mode */ +static struct fb_var_screeninfo default_var __initdata = { + /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ + 640, 480, 640, 480, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2, + 0, FB_VMODE_NONINTERLACED +}; + +#else /* CONFIG_PPC_PMAC */ +/* default to 1024x768 at 75Hz on PPC - this will work + * on the iMac, the usual 640x480 @ 60Hz doesn't. */ +static struct fb_var_screeninfo default_var = { + /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */ + 1024, 768, 1024, 768, 0, 0, 8, 0, + {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, + 0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED +}; +#endif /* CONFIG_PPC_PMAC */ + +/* default modedb mode */ +/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ +static struct fb_videomode defaultmode __initdata = { + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39722, + .left_margin = 48, + .right_margin = 16, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED +}; + +/* Chip generations */ +enum { + rage_128, + rage_128_pci, + rage_128_pro, + rage_128_pro_pci, + rage_M3, + rage_M3_pci, + rage_M4, + rage_128_ultra, +}; + +/* Must match above enum */ +static const char *r128_family[] __devinitdata = { + "AGP", + "PCI", + "PRO AGP", + "PRO PCI", + "M3 AGP", + "M3 PCI", + "M4 AGP", + "Ultra AGP", +}; + +/* + * PCI driver prototypes + */ +static int aty128_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +static void aty128_remove(struct pci_dev *pdev); +static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state); +static int aty128_pci_resume(struct pci_dev *pdev); +static int aty128_do_resume(struct pci_dev *pdev); + +/* supported Rage128 chipsets */ +static struct pci_device_id aty128_pci_tbl[] = { + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_MF, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_ML, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PA, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PB, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PC, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PD, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PG, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PH, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PI, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PJ, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PK, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PL, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PM, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PN, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PO, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PQ, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PS, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PU, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PV, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PW, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PX, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RG, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SF, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SG, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SH, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SK, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SL, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SM, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SN, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TF, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TL, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TR, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TS, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra }, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TU, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, aty128_pci_tbl); + +static struct pci_driver aty128fb_driver = { + .name = "aty128fb", + .id_table = aty128_pci_tbl, + .probe = aty128_probe, + .remove = __devexit_p(aty128_remove), + .suspend = aty128_pci_suspend, + .resume = aty128_pci_resume, +}; + +/* packed BIOS settings */ +#ifndef CONFIG_PPC +typedef struct { + u8 clock_chip_type; + u8 struct_size; + u8 accelerator_entry; + u8 VGA_entry; + u16 VGA_table_offset; + u16 POST_table_offset; + u16 XCLK; + u16 MCLK; + u8 num_PLL_blocks; + u8 size_PLL_blocks; + u16 PCLK_ref_freq; + u16 PCLK_ref_divider; + u32 PCLK_min_freq; + u32 PCLK_max_freq; + u16 MCLK_ref_freq; + u16 MCLK_ref_divider; + u32 MCLK_min_freq; + u32 MCLK_max_freq; + u16 XCLK_ref_freq; + u16 XCLK_ref_divider; + u32 XCLK_min_freq; + u32 XCLK_max_freq; +} __attribute__ ((packed)) PLL_BLOCK; +#endif /* !CONFIG_PPC */ + +/* onboard memory information */ +struct aty128_meminfo { + u8 ML; + u8 MB; + u8 Trcd; + u8 Trp; + u8 Twr; + u8 CL; + u8 Tr2w; + u8 LoopLatency; + u8 DspOn; + u8 Rloop; + const char *name; +}; + +/* various memory configurations */ +static const struct aty128_meminfo sdr_128 = + { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" }; +static const struct aty128_meminfo sdr_64 = + { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" }; +static const struct aty128_meminfo sdr_sgram = + { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" }; +static const struct aty128_meminfo ddr_sgram = + { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" }; + +static struct fb_fix_screeninfo aty128fb_fix __initdata = { + .id = "ATY Rage128", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_PSEUDOCOLOR, + .xpanstep = 8, + .ypanstep = 1, + .mmio_len = 0x2000, + .accel = FB_ACCEL_ATI_RAGE128, +}; + +static char *mode_option __initdata = NULL; + +#ifdef CONFIG_PPC_PMAC +static int default_vmode __initdata = VMODE_1024_768_60; +static int default_cmode __initdata = CMODE_8; +#endif + +#ifdef CONFIG_PMAC_PBOOK +static int default_crt_on __initdata = 0; +static int default_lcd_on __initdata = 1; +#endif + +#ifdef CONFIG_MTRR +static int mtrr = 1; +#endif + +/* PLL constants */ +struct aty128_constants { + u32 ref_clk; + u32 ppll_min; + u32 ppll_max; + u32 ref_divider; + u32 xclk; + u32 fifo_width; + u32 fifo_depth; +}; + +struct aty128_crtc { + u32 gen_cntl; + u32 h_total, h_sync_strt_wid; + u32 v_total, v_sync_strt_wid; + u32 pitch; + u32 offset, offset_cntl; + u32 xoffset, yoffset; + u32 vxres, vyres; + u32 depth, bpp; +}; + +struct aty128_pll { + u32 post_divider; + u32 feedback_divider; + u32 vclk; +}; + +struct aty128_ddafifo { + u32 dda_config; + u32 dda_on_off; +}; + +/* register values for a specific mode */ +struct aty128fb_par { + struct aty128_crtc crtc; + struct aty128_pll pll; + struct aty128_ddafifo fifo_reg; + u32 accel_flags; + struct aty128_constants constants; /* PLL and others */ + void __iomem *regbase; /* remapped mmio */ + u32 vram_size; /* onboard video ram */ + int chip_gen; + const struct aty128_meminfo *mem; /* onboard mem info */ +#ifdef CONFIG_MTRR + struct { int vram; int vram_valid; } mtrr; +#endif + int blitter_may_be_busy; + int fifo_slots; /* free slots in FIFO (64 max) */ + + int pm_reg; + int crt_on, lcd_on; + struct pci_dev *pdev; + struct fb_info *next; + int asleep; + int lock_blank; + + u8 red[32]; /* see aty128fb_setcolreg */ + u8 green[64]; + u8 blue[32]; + u32 pseudo_palette[16]; /* used for TRUECOLOR */ +}; + + +#define round_div(n, d) ((n+(d/2))/d) + +static int aty128fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info); +static int aty128fb_set_par(struct fb_info *info); +static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info); +static int aty128fb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *fb); +static int aty128fb_blank(int blank, struct fb_info *fb); +static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd, + u_long arg, struct fb_info *info); +static int aty128fb_sync(struct fb_info *info); + + /* + * Internal routines + */ + +static int aty128_encode_var(struct fb_var_screeninfo *var, + const struct aty128fb_par *par); +static int aty128_decode_var(struct fb_var_screeninfo *var, + struct aty128fb_par *par); +#if 0 +static void __init aty128_get_pllinfo(struct aty128fb_par *par, + void __iomem *bios); +static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); +#endif +static void aty128_timings(struct aty128fb_par *par); +static void aty128_init_engine(struct aty128fb_par *par); +static void aty128_reset_engine(const struct aty128fb_par *par); +static void aty128_flush_pixel_cache(const struct aty128fb_par *par); +static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par); +static void wait_for_fifo(u16 entries, struct aty128fb_par *par); +static void wait_for_idle(struct aty128fb_par *par); +static u32 depth_to_dst(u32 depth); + +#define BIOS_IN8(v) (readb(bios + (v))) +#define BIOS_IN16(v) (readb(bios + (v)) | \ + (readb(bios + (v) + 1) << 8)) +#define BIOS_IN32(v) (readb(bios + (v)) | \ + (readb(bios + (v) + 1) << 8) | \ + (readb(bios + (v) + 2) << 16) | \ + (readb(bios + (v) + 3) << 24)) + + +static struct fb_ops aty128fb_ops = { + .owner = THIS_MODULE, + .fb_check_var = aty128fb_check_var, + .fb_set_par = aty128fb_set_par, + .fb_setcolreg = aty128fb_setcolreg, + .fb_pan_display = aty128fb_pan_display, + .fb_blank = aty128fb_blank, + .fb_ioctl = aty128fb_ioctl, + .fb_sync = aty128fb_sync, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = soft_cursor, +}; + +#ifdef CONFIG_PMAC_BACKLIGHT +static int aty128_set_backlight_enable(int on, int level, void* data); +static int aty128_set_backlight_level(int level, void* data); + +static struct backlight_controller aty128_backlight_controller = { + aty128_set_backlight_enable, + aty128_set_backlight_level +}; +#endif /* CONFIG_PMAC_BACKLIGHT */ + + /* + * Functions to read from/write to the mmio registers + * - endian conversions may possibly be avoided by + * using the other register aperture. TODO. + */ +static inline u32 _aty_ld_le32(volatile unsigned int regindex, + const struct aty128fb_par *par) +{ + return readl (par->regbase + regindex); +} + +static inline void _aty_st_le32(volatile unsigned int regindex, u32 val, + const struct aty128fb_par *par) +{ + writel (val, par->regbase + regindex); +} + +static inline u8 _aty_ld_8(unsigned int regindex, + const struct aty128fb_par *par) +{ + return readb (par->regbase + regindex); +} + +static inline void _aty_st_8(unsigned int regindex, u8 val, + const struct aty128fb_par *par) +{ + writeb (val, par->regbase + regindex); +} + +#define aty_ld_le32(regindex) _aty_ld_le32(regindex, par) +#define aty_st_le32(regindex, val) _aty_st_le32(regindex, val, par) +#define aty_ld_8(regindex) _aty_ld_8(regindex, par) +#define aty_st_8(regindex, val) _aty_st_8(regindex, val, par) + + /* + * Functions to read from/write to the pll registers + */ + +#define aty_ld_pll(pll_index) _aty_ld_pll(pll_index, par) +#define aty_st_pll(pll_index, val) _aty_st_pll(pll_index, val, par) + + +static u32 _aty_ld_pll(unsigned int pll_index, + const struct aty128fb_par *par) +{ + aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x3F); + return aty_ld_le32(CLOCK_CNTL_DATA); +} + + +static void _aty_st_pll(unsigned int pll_index, u32 val, + const struct aty128fb_par *par) +{ + aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x3F) | PLL_WR_EN); + aty_st_le32(CLOCK_CNTL_DATA, val); +} + + +/* return true when the PLL has completed an atomic update */ +static int aty_pll_readupdate(const struct aty128fb_par *par) +{ + return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); +} + + +static void aty_pll_wait_readupdate(const struct aty128fb_par *par) +{ + unsigned long timeout = jiffies + HZ/100; // should be more than enough + int reset = 1; + + while (time_before(jiffies, timeout)) + if (aty_pll_readupdate(par)) { + reset = 0; + break; + } + + if (reset) /* reset engine?? */ + printk(KERN_DEBUG "aty128fb: PLL write timeout!\n"); +} + + +/* tell PLL to update */ +static void aty_pll_writeupdate(const struct aty128fb_par *par) +{ + aty_pll_wait_readupdate(par); + + aty_st_pll(PPLL_REF_DIV, + aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W); +} + + +/* write to the scratch register to test r/w functionality */ +static int __init register_test(const struct aty128fb_par *par) +{ + u32 val; + int flag = 0; + + val = aty_ld_le32(BIOS_0_SCRATCH); + + aty_st_le32(BIOS_0_SCRATCH, 0x55555555); + if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) { + aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA); + + if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA) + flag = 1; + } + + aty_st_le32(BIOS_0_SCRATCH, val); // restore value + return flag; +} + + +/* + * Accelerator engine functions + */ +static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par) +{ + int i; + + for (;;) { + for (i = 0; i < 2000000; i++) { + par->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff; + if (par->fifo_slots >= entries) + return; + } + aty128_reset_engine(par); + } +} + + +static void wait_for_idle(struct aty128fb_par *par) +{ + int i; + + do_wait_for_fifo(64, par); + + for (;;) { + for (i = 0; i < 2000000; i++) { + if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) { + aty128_flush_pixel_cache(par); + par->blitter_may_be_busy = 0; + return; + } + } + aty128_reset_engine(par); + } +} + + +static void wait_for_fifo(u16 entries, struct aty128fb_par *par) +{ + if (par->fifo_slots < entries) + do_wait_for_fifo(64, par); + par->fifo_slots -= entries; +} + + +static void aty128_flush_pixel_cache(const struct aty128fb_par *par) +{ + int i; + u32 tmp; + + tmp = aty_ld_le32(PC_NGUI_CTLSTAT); + tmp &= ~(0x00ff); + tmp |= 0x00ff; + aty_st_le32(PC_NGUI_CTLSTAT, tmp); + + for (i = 0; i < 2000000; i++) + if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY)) + break; +} + + +static void aty128_reset_engine(const struct aty128fb_par *par) +{ + u32 gen_reset_cntl, clock_cntl_index, mclk_cntl; + + aty128_flush_pixel_cache(par); + + clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX); + mclk_cntl = aty_ld_pll(MCLK_CNTL); + + aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000); + + gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL); + aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI); + aty_ld_le32(GEN_RESET_CNTL); + aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI)); + aty_ld_le32(GEN_RESET_CNTL); + + aty_st_pll(MCLK_CNTL, mclk_cntl); + aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index); + aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl); + + /* use old pio mode */ + aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4); + + DBG("engine reset"); +} + + +static void aty128_init_engine(struct aty128fb_par *par) +{ + u32 pitch_value; + + wait_for_idle(par); + + /* 3D scaler not spoken here */ + wait_for_fifo(1, par); + aty_st_le32(SCALE_3D_CNTL, 0x00000000); + + aty128_reset_engine(par); + + pitch_value = par->crtc.pitch; + if (par->crtc.bpp == 24) { + pitch_value = pitch_value * 3; + } + + wait_for_fifo(4, par); + /* setup engine offset registers */ + aty_st_le32(DEFAULT_OFFSET, 0x00000000); + + /* setup engine pitch registers */ + aty_st_le32(DEFAULT_PITCH, pitch_value); + + /* set the default scissor register to max dimensions */ + aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF); + + /* set the drawing controls registers */ + aty_st_le32(DP_GUI_MASTER_CNTL, + GMC_SRC_PITCH_OFFSET_DEFAULT | + GMC_DST_PITCH_OFFSET_DEFAULT | + GMC_SRC_CLIP_DEFAULT | |