⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atyfb_base.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  ATI Frame Buffer Device Driver Core * *	Copyright (C) 2004  Alex Kern <alex.kern@gmx.de> *	Copyright (C) 1997-2001  Geert Uytterhoeven *	Copyright (C) 1998  Bernd Harries *	Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be) * *  This driver supports the following ATI graphics chips: *    - ATI Mach64 * *  To do: add support for *    - ATI Rage128 (from aty128fb.c) *    - ATI Radeon (from radeonfb.c) * *  This driver is partly based on the PowerMac console driver: * *	Copyright (C) 1996 Paul Mackerras * *  and on the PowerMac ATI/mach64 display driver: * *	Copyright (C) 1997 Michael AK Tesch * *	      with work by Jon Howell *			   Harry AC Eaton *			   Anthony Tong <atong@uiuc.edu> * *  Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug. * *  This file is subject to the terms and conditions of the GNU General Public *  License. See the file COPYING in the main directory of this archive for *  more details. * *  Many thanks to Nitya from ATI devrel for support and patience ! *//******************************************************************************  TODO:    - cursor support on all cards and all ramdacs.    - cursor parameters controlable via ioctl()s.    - guess PLL and MCLK based on the original PLL register values initialized      by Open Firmware (if they are initialized). BIOS is done    (Anyone with Mac to help with this?)******************************************************************************/#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/slab.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/console.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/interrupt.h>#include <linux/spinlock.h>#include <linux/wait.h>#include <linux/backlight.h>#include <asm/io.h>#include <linux/uaccess.h>#include <video/mach64.h>#include "atyfb.h"#include "ati_ids.h"#ifdef __powerpc__#include <asm/machdep.h>#include <asm/prom.h>#include "../macmodes.h"#endif#ifdef __sparc__#include <asm/fbio.h>#include <asm/oplib.h>#include <asm/prom.h>#endif#ifdef CONFIG_ADB_PMU#include <linux/adb.h>#include <linux/pmu.h>#endif#ifdef CONFIG_BOOTX_TEXT#include <asm/btext.h>#endif#ifdef CONFIG_PMAC_BACKLIGHT#include <asm/backlight.h>#endif#ifdef CONFIG_MTRR#include <asm/mtrr.h>#endif/* * Debug flags. */#undef DEBUG/*#define DEBUG*//* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs *//*  - must be large enough to catch all GUI-Regs   *//*  - must be aligned to a PAGE boundary           */#define GUI_RESERVE	(1 * PAGE_SIZE)/* FIXME: remove the FAIL definition */#define FAIL(msg) do { \	if (!(var->activate & FB_ACTIVATE_TEST)) \		printk(KERN_CRIT "atyfb: " msg "\n"); \	return -EINVAL; \} while (0)#define FAIL_MAX(msg, x, _max_) do { \	if (x > _max_) { \		if (!(var->activate & FB_ACTIVATE_TEST)) \			printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \		return -EINVAL; \	} \} while (0)#ifdef DEBUG#define DPRINTK(fmt, args...)	printk(KERN_DEBUG "atyfb: " fmt, ## args)#else#define DPRINTK(fmt, args...)#endif#define PRINTKI(fmt, args...)	printk(KERN_INFO "atyfb: " fmt, ## args)#define PRINTKE(fmt, args...)	 printk(KERN_ERR "atyfb: " fmt, ## args)#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)static const u32 lt_lcd_regs[] = {	CNFG_PANEL_LG,	LCD_GEN_CNTL_LG,	DSTN_CONTROL_LG,	HFB_PITCH_ADDR_LG,	HORZ_STRETCHING_LG,	VERT_STRETCHING_LG,	0, /* EXT_VERT_STRETCH */	LT_GIO_LG,	POWER_MANAGEMENT_LG};void aty_st_lcd(int index, u32 val, const struct atyfb_par *par){	if (M64_HAS(LT_LCD_REGS)) {		aty_st_le32(lt_lcd_regs[index], val, par);	} else {		unsigned long temp;		/* write addr byte */		temp = aty_ld_le32(LCD_INDEX, par);		aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);		/* write the register value */		aty_st_le32(LCD_DATA, val, par);	}}u32 aty_ld_lcd(int index, const struct atyfb_par *par){	if (M64_HAS(LT_LCD_REGS)) {		return aty_ld_le32(lt_lcd_regs[index], par);	} else {		unsigned long temp;		/* write addr byte */		temp = aty_ld_le32(LCD_INDEX, par);		aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, par);		/* read the register value */		return aty_ld_le32(LCD_DATA, par);	}}#endif /* defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) */#ifdef CONFIG_FB_ATY_GENERIC_LCD/* * ATIReduceRatio -- * * Reduce a fraction by factoring out the largest common divider of the * fraction's numerator and denominator. */static void ATIReduceRatio(int *Numerator, int *Denominator){    int Multiplier, Divider, Remainder;    Multiplier = *Numerator;    Divider = *Denominator;    while ((Remainder = Multiplier % Divider))    {        Multiplier = Divider;        Divider = Remainder;    }    *Numerator /= Divider;    *Denominator /= Divider;}#endif    /*     *  The Hardware parameters for each card     */struct pci_mmap_map {	unsigned long voff;	unsigned long poff;	unsigned long size;	unsigned long prot_flag;	unsigned long prot_mask;};static struct fb_fix_screeninfo atyfb_fix __devinitdata = {	.id		= "ATY Mach64",	.type		= FB_TYPE_PACKED_PIXELS,	.visual		= FB_VISUAL_PSEUDOCOLOR,	.xpanstep	= 8,	.ypanstep	= 1,};    /*     *  Frame buffer device API     */static int atyfb_open(struct fb_info *info, int user);static int atyfb_release(struct fb_info *info, int user);static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);static int atyfb_set_par(struct fb_info *info);static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,	u_int transp, struct fb_info *info);static int atyfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);static int atyfb_blank(int blank, struct fb_info *info);static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg);#ifdef __sparc__static int atyfb_mmap(struct fb_info *info, struct vm_area_struct *vma);#endifstatic int atyfb_sync(struct fb_info *info);    /*     *  Internal routines     */static int aty_init(struct fb_info *info);#ifdef CONFIG_ATARIstatic int store_video_par(char *videopar, unsigned char m64_num);#endifstatic struct crtc saved_crtc;static union aty_pll saved_pll;static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc);static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *var);static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);#ifdef CONFIG_PPCstatic int read_aty_sense(const struct atyfb_par *par);#endif    /*     *  Interface used by the world     */static struct fb_var_screeninfo default_var = {	/* 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};static struct fb_videomode defmode = {	/* 640x480 @ 60 Hz, 31.5 kHz hsync */	NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,	0, FB_VMODE_NONINTERLACED};static struct fb_ops atyfb_ops = {	.owner		= THIS_MODULE,	.fb_open	= atyfb_open,	.fb_release	= atyfb_release,	.fb_check_var	= atyfb_check_var,	.fb_set_par	= atyfb_set_par,	.fb_setcolreg	= atyfb_setcolreg,	.fb_pan_display	= atyfb_pan_display,	.fb_blank	= atyfb_blank,	.fb_ioctl	= atyfb_ioctl,	.fb_fillrect	= atyfb_fillrect,	.fb_copyarea	= atyfb_copyarea,	.fb_imageblit	= atyfb_imageblit,#ifdef __sparc__	.fb_mmap	= atyfb_mmap,#endif	.fb_sync	= atyfb_sync,};static int noaccel;#ifdef CONFIG_MTRRstatic int nomtrr;#endifstatic int vram;static int pll;static int mclk;static int xclk;static int comp_sync __devinitdata = -1;static char *mode;#ifdef CONFIG_PMAC_BACKLIGHTstatic int backlight __devinitdata = 1;#elsestatic int backlight __devinitdata = 0;#endif#ifdef CONFIG_PPCstatic int default_vmode __devinitdata = VMODE_CHOOSE;static int default_cmode __devinitdata = CMODE_CHOOSE;module_param_named(vmode, default_vmode, int, 0);MODULE_PARM_DESC(vmode, "int: video mode for mac");module_param_named(cmode, default_cmode, int, 0);MODULE_PARM_DESC(cmode, "int: color mode for mac");#endif#ifdef CONFIG_ATARIstatic unsigned int mach64_count __devinitdata = 0;static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, };static unsigned long phys_size[FB_MAX] __devinitdata = { 0, };static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };#endif/* top -> down is an evolution of mach64 chipset, any corrections? */#define ATI_CHIP_88800GX   (M64F_GX)#define ATI_CHIP_88800CX   (M64F_GX)#define ATI_CHIP_264CT     (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)#define ATI_CHIP_264ET     (M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO)#define ATI_CHIP_264VT     (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO)#define ATI_CHIP_264GT     (M64F_GT | M64F_INTEGRATED               | M64F_MAGIC_FIFO | M64F_EXTRA_BRIGHT)#define ATI_CHIP_264VTB    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP)#define ATI_CHIP_264VT3    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)#define ATI_CHIP_264VT4    (M64F_VT | M64F_INTEGRATED               | M64F_GTB_DSP)/* FIXME what is this chip? */#define ATI_CHIP_264LT     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP)/* make sets shorter */#define ATI_MODERN_SET     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP | M64F_EXTRA_BRIGHT)#define ATI_CHIP_264GTB    (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)/*#define ATI_CHIP_264GTDVD  ?*/#define ATI_CHIP_264LTG    (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL)#define ATI_CHIP_264GT2C   (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE)#define ATI_CHIP_264GTPRO  (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)#define ATI_CHIP_264LTPRO  (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)#define ATI_CHIP_264XL     (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)#define ATI_CHIP_MOBILITY  (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS)static struct {	u16 pci_id;	const char *name;	int pll, mclk, xclk, ecp_max;	u32 features;} aty_chips[] __devinitdata = {#ifdef CONFIG_FB_ATY_GX	/* Mach64 GX */	{ PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },	{ PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },#endif /* CONFIG_FB_ATY_GX */#ifdef CONFIG_FB_ATY_CT	{ PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },	{ PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },	/* FIXME what is this chip? */	{ PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },	{ PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },	{ PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },	{ PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },	{ PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },	{ PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },	{ PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },	{ PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },	{ PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },	{ PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },	{ PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },	{ PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },	{ PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },	{ PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },	{ PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },	{ PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },	{ PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },	{ PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },	{ 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 },	{ PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },	{ PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },	{ PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },	{ PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },	{ PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },	{ PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },	{ PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },	{ PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },	{ PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },	{ PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },	{ PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },#endif /* CONFIG_FB_ATY_CT */};static int __devinit correct_chipset(struct atyfb_par *par){	u8 rev;	u16 type;	u32 chip_id;	const char *name;	int i;	for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)		if (par->pci_id == aty_chips[i].pci_id)			break;	if (i < 0)		return -ENODEV;	name = aty_chips[i].name;	par->pll_limits.pll_max = aty_chips[i].pll;	par->pll_limits.mclk = aty_chips[i].mclk;	par->pll_limits.xclk = aty_chips[i].xclk;	par->pll_limits.ecp_max = aty_chips[i].ecp_max;	par->features = aty_chips[i].features;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -