📄 radeon_base.c
字号:
/* * drivers/video/aty/radeon_base.c * * framebuffer driver for ATI Radeon chipset video boards * * Copyright 2003 Ben. Herrenschmidt <benh@kernel.crashing.org> * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org> * * i2c bits from Luca Tettamanti <kronos@kronoz.cjb.net> * * Special thanks to ATI DevRel team for their hardware donations. * * ...Insert GPL boilerplate here... * * Significant portions of this driver apdated from XFree86 Radeon * driver which has the following copyright notice: * * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. * * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation on the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * XFree86 driver authors: * * Kevin E. Martin <martin@xfree86.org> * Rickard E. Faith <faith@valinux.com> * Alan Hourihane <alanh@fairlite.demon.co.uk> * */#define RADEON_VERSION "0.2.0"#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/delay.h>#include <linux/time.h>#include <linux/fb.h>#include <linux/ioport.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/vmalloc.h>#include <linux/device.h>#include <asm/io.h>#include <asm/uaccess.h>#ifdef CONFIG_PPC_OF#include <asm/pci-bridge.h>#include "../macmodes.h"#ifdef CONFIG_PMAC_BACKLIGHT#include <asm/backlight.h>#endif#ifdef CONFIG_BOOTX_TEXT#include <asm/btext.h>#endif#endif /* CONFIG_PPC_OF */#ifdef CONFIG_MTRR#include <asm/mtrr.h>#endif#include <video/radeon.h>#include <linux/radeonfb.h>#include "../edid.h" // MOVE THAT TO include/video#include "ati_ids.h"#include "radeonfb.h" #define MAX_MAPPED_VRAM (2048*2048*4)#define MIN_MAPPED_VRAM (1024*768*1)#define CHIP_DEF(id, family, flags) \ { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }static struct pci_device_id radeonfb_pci_table[] = { /* Mobility M6 */ CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), /* Radeon VE/7000 */ CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RN50, RV100, CHIP_HAS_CRTC2), /* Radeon IGP320M (U1) */ CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), /* Radeon IGP320 (A3) */ CHIP_DEF(PCI_CHIP_RS100_4136, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP), /* IGP330M/340M/350M (U2) */ CHIP_DEF(PCI_CHIP_RS200_4337, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), /* IGP330/340/350 (A4) */ CHIP_DEF(PCI_CHIP_RS200_4137, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), /* Mobility 7000 IGP */ CHIP_DEF(PCI_CHIP_RS250_4437, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), /* 7000 IGP (A4+) */ CHIP_DEF(PCI_CHIP_RS250_4237, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), /* 8500 AIW */ CHIP_DEF(PCI_CHIP_R200_BB, R200, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R200_BC, R200, CHIP_HAS_CRTC2), /* 8700/8800 */ CHIP_DEF(PCI_CHIP_R200_QH, R200, CHIP_HAS_CRTC2), /* 8500 */ CHIP_DEF(PCI_CHIP_R200_QL, R200, CHIP_HAS_CRTC2), /* 9100 */ CHIP_DEF(PCI_CHIP_R200_QM, R200, CHIP_HAS_CRTC2), /* Mobility M7 */ CHIP_DEF(PCI_CHIP_RADEON_LW, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RADEON_LX, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), /* 7500 */ CHIP_DEF(PCI_CHIP_RV200_QW, RV200, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV200_QX, RV200, CHIP_HAS_CRTC2), /* Mobility M9 */ CHIP_DEF(PCI_CHIP_RV250_Ld, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV250_Le, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV250_Lf, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV250_Lg, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), /* 9000/Pro */ CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2), /* Mobility 9100 IGP (U3) */ CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), /* 9100 IGP (A5) */ CHIP_DEF(PCI_CHIP_RS300_5834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), CHIP_DEF(PCI_CHIP_RS350_7834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), /* Mobility 9200 (M9+) */ CHIP_DEF(PCI_CHIP_RV280_5C61, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV280_5C63, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), /* 9200 */ CHIP_DEF(PCI_CHIP_RV280_5960, RV280, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV280_5961, RV280, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV280_5962, RV280, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV280_5964, RV280, CHIP_HAS_CRTC2), /* 9500 */ CHIP_DEF(PCI_CHIP_R300_AD, R300, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R300_AE, R300, CHIP_HAS_CRTC2), /* 9600TX / FireGL Z1 */ CHIP_DEF(PCI_CHIP_R300_AF, R300, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R300_AG, R300, CHIP_HAS_CRTC2), /* 9700/9500/Pro/FireGL X1 */ CHIP_DEF(PCI_CHIP_R300_ND, R300, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R300_NE, R300, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R300_NF, R300, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R300_NG, R300, CHIP_HAS_CRTC2), /* Mobility M10/M11 */ CHIP_DEF(PCI_CHIP_RV350_NP, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV350_NQ, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV350_NR, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV350_NS, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV350_NT, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV350_NV, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), /* 9600/FireGL T2 */ CHIP_DEF(PCI_CHIP_RV350_AP, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AQ, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV360_AR, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AS, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AT, RV350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV350_AV, RV350, CHIP_HAS_CRTC2), /* 9800/Pro/FileGL X2 */ CHIP_DEF(PCI_CHIP_R350_AH, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_AI, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_AJ, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_AK, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_NH, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_NI, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R360_NJ, R350, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R350_NK, R350, CHIP_HAS_CRTC2), /* Newer stuff */ CHIP_DEF(PCI_CHIP_RV380_3E50, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV380_3E54, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV380_3150, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV380_3154, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV370_5B60, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV370_5B62, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV370_5B64, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV370_5B65, RV380, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV370_5460, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RV370_5464, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_R420_JH, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JI, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JJ, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JK, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JL, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JM, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R420_JN, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_R420_JP, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UH, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UI, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UJ, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UK, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UQ, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UR, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_UT, R420, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_R423_5D57, R420, CHIP_HAS_CRTC2), /* Original Radeon/7200 */ CHIP_DEF(PCI_CHIP_RADEON_QD, RADEON, 0), CHIP_DEF(PCI_CHIP_RADEON_QE, RADEON, 0), CHIP_DEF(PCI_CHIP_RADEON_QF, RADEON, 0), CHIP_DEF(PCI_CHIP_RADEON_QG, RADEON, 0), { 0, }};MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);typedef struct { u16 reg; u32 val;} reg_val;/* these common regs are cleared before mode setting so they do not * interfere with anything */static reg_val common_regs[] = { { OVR_CLR, 0 }, { OVR_WID_LEFT_RIGHT, 0 }, { OVR_WID_TOP_BOTTOM, 0 }, { OV0_SCALE_CNTL, 0 }, { SUBPIC_CNTL, 0 }, { VIPH_CONTROL, 0 }, { I2C_CNTL_1, 0 }, { GEN_INT_CNTL, 0 }, { CAP0_TRIG_CNTL, 0 }, { CAP1_TRIG_CNTL, 0 },};/* * globals */ static char *mode_option;static char *monitor_layout;static int noaccel = 0;static int default_dynclk = -2;static int nomodeset = 0;static int ignore_edid = 0;static int mirror = 0;static int panel_yres = 0;static int force_dfp = 0;static int force_measure_pll = 0;#ifdef CONFIG_MTRRstatic int nomtrr = 0;#endif/* * prototypes */#ifdef CONFIG_PPC_OF#ifdef CONFIG_PMAC_BACKLIGHTstatic int radeon_set_backlight_enable(int on, int level, void *data);static int radeon_set_backlight_level(int level, void *data);static struct backlight_controller radeon_backlight_controller = { radeon_set_backlight_enable, radeon_set_backlight_level};#endif /* CONFIG_PMAC_BACKLIGHT */#endif /* CONFIG_PPC_OF */static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev){ if (!rinfo->bios_seg) return; pci_unmap_rom(dev, rinfo->bios_seg);}static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev){ void __iomem *rom; u16 dptr; u8 rom_type; size_t rom_size; /* If this is a primary card, there is a shadow copy of the * ROM somewhere in the first meg. We will just ignore the copy * and use the ROM directly. */ /* Fix from ATI for problem with Radeon hardware not leaving ROM enabled */ unsigned int temp; temp = INREG(MPP_TB_CONFIG); temp &= 0x00ffffffu; temp |= 0x04 << 24; OUTREG(MPP_TB_CONFIG, temp); temp = INREG(MPP_TB_CONFIG); rom = pci_map_rom(dev, &rom_size); if (!rom) { printk(KERN_ERR "radeonfb (%s): ROM failed to map\n", pci_name(rinfo->pdev)); return -ENOMEM; } rinfo->bios_seg = rom; /* Very simple test to make sure it appeared */ if (BIOS_IN16(0) != 0xaa55) { printk(KERN_DEBUG "radeonfb (%s): Invalid ROM signature %x " "should be 0xaa55\n", pci_name(rinfo->pdev), BIOS_IN16(0)); goto failed; } /* Look for the PCI data to check the ROM type */ dptr = BIOS_IN16(0x18); /* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM * for now, until I've verified this works everywhere. The goal here is more * to phase out Open Firmware images. * * Currently, we only look at the first PCI data, we could iteratre and deal with * them all, and we should use fb_bios_start relative to start of image and not * relative start of ROM, but so far, I never found a dual-image ATI card * * typedef struct { * u32 signature; + 0x00 * u16 vendor; + 0x04 * u16 device; + 0x06 * u16 reserved_1; + 0x08 * u16 dlen; + 0x0a * u8 drevision; + 0x0c * u8 class_hi; + 0x0d * u16 class_lo; + 0x0e * u16 ilen; + 0x10 * u16 irevision; + 0x12 * u8 type; + 0x14 * u8 indicator; + 0x15 * u16 reserved_2; + 0x16 * } pci_data_t; */ if (BIOS_IN32(dptr) != (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) { printk(KERN_WARNING "radeonfb (%s): PCI DATA signature in ROM" "incorrect: %08x\n", pci_name(rinfo->pdev), BIOS_IN32(dptr)); goto anyway; } rom_type = BIOS_IN8(dptr + 0x14); switch(rom_type) { case 0: printk(KERN_INFO "radeonfb: Found Intel x86 BIOS ROM Image\n"); break; case 1: printk(KERN_INFO "radeonfb: Found Open Firmware ROM Image\n"); goto failed; case 2: printk(KERN_INFO "radeonfb: Found HP PA-RISC ROM Image\n"); goto failed; default: printk(KERN_INFO "radeonfb: Found unknown type %d ROM Image\n", rom_type); goto failed; } anyway: /* Locate the flat panel infos, do some sanity checking !!! */ rinfo->fp_bios_start = BIOS_IN16(0x48); return 0; failed: rinfo->bios_seg = NULL; radeon_unmap_ROM(rinfo, dev); return -ENXIO;}#ifdef CONFIG_X86static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo){ /* I simplified this code as we used to miss the signatures in * a lot of case. It's now closer to XFree, we just don't check * for signatures at all... Something better will have to be done * if we end up having conflicts */ u32 segstart; void __iomem *rom_base = NULL; for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) { rom_base = ioremap(segstart, 0x10000); if (rom_base == NULL) return -ENOMEM; if (readb(rom_base) == 0x55 && readb(rom_base + 1) == 0xaa) break; iounmap(rom_base); rom_base = NULL; } if (rom_base == NULL) return -ENXIO; /* Locate the flat panel infos, do some sanity checking !!! */ rinfo->bios_seg = rom_base; rinfo->fp_bios_start = BIOS_IN16(0x48); return 0;}#endif#ifdef CONFIG_PPC_OF/* * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device * tree. Hopefully, ATI OF driver is kind enough to fill these */static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -