atyfb_base.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,413 行 · 第 1/5 页

C
2,413
字号
/* *  ATI Frame Buffer Device Driver Core * *	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> * *  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 the BIOS or Open Firmware (if they are initialized).						(Anyone to help with this?)******************************************************************************/#include <linux/config.h>#include <linux/module.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/selection.h>#include <linux/console.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/vt_kern.h>#include <linux/kd.h>#include <asm/io.h>#include <asm/uaccess.h>#include <video/mach64.h>#include "atyfb.h"#ifdef __powerpc__#include <asm/prom.h>#include "../macmodes.h"#endif#ifdef __sparc__#include <asm/pbm.h>#include <asm/fbio.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/* * Debug flags. */#undef 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(x) do { printk(x "\n"); return -EINVAL; } while (0)    /*     *  The Hardware parameters for each card     */struct aty_cmap_regs {	u8 windex;	u8 lut;	u8 mask;	u8 rindex;	u8 cntl;};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 __initdata = {	.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 inode *inode, struct file *file, u_int cmd,		       u_long arg, struct fb_info *info);extern void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);extern void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);extern void atyfb_imageblit(struct fb_info *info, const struct fb_image *image);#ifdef __sparc__static int atyfb_mmap(struct fb_info *info, struct file *file,		      struct vm_area_struct *vma);#endifstatic int atyfb_sync(struct fb_info *info);    /*     *  Internal routines     */static int aty_init(struct fb_info *info, const char *name);#ifdef CONFIG_ATARIstatic int store_video_par(char *videopar, unsigned char m64_num);#endifstatic 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     */int atyfb_init(void);#ifndef MODULEint atyfb_setup(char *);#endifstatic 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,	.fb_cursor	= soft_cursor,#ifdef __sparc__	.fb_mmap	= atyfb_mmap,#endif	.fb_sync	= atyfb_sync,};static char curblink __initdata = 1;static char noaccel __initdata = 0;static u32 default_vram __initdata = 0;static int default_pll __initdata = 0;static int default_mclk __initdata = 0;#ifndef MODULEstatic char *mode_option __initdata = NULL;#endif#ifdef CONFIG_PPCstatic int default_vmode __initdata = VMODE_CHOOSE;static int default_cmode __initdata = CMODE_CHOOSE;#endif#ifdef CONFIG_ATARIstatic unsigned int mach64_count __initdata = 0;static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };static unsigned long phys_size[FB_MAX] __initdata = { 0, };static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };#endif#ifdef CONFIG_FB_ATY_GXstatic char m64n_gx[] __initdata = "mach64GX (ATI888GX00)";static char m64n_cx[] __initdata = "mach64CX (ATI888CX00)";#endif /* CONFIG_FB_ATY_GX */#ifdef CONFIG_FB_ATY_CTstatic char m64n_ct[] __initdata = "mach64CT (ATI264CT)";static char m64n_et[] __initdata = "mach64ET (ATI264ET)";static char m64n_vta3[] __initdata = "mach64VTA3 (ATI264VT)";static char m64n_vta4[] __initdata = "mach64VTA4 (ATI264VT)";static char m64n_vtb[] __initdata = "mach64VTB (ATI264VTB)";static char m64n_vt4[] __initdata = "mach64VT4 (ATI264VT4)";static char m64n_gt[] __initdata = "3D RAGE (GT)";static char m64n_gtb[] __initdata = "3D RAGE II+ (GTB)";static char m64n_iic_p[] __initdata = "3D RAGE IIC (PCI)";static char m64n_iic_a[] __initdata = "3D RAGE IIC (AGP)";static char m64n_lt[] __initdata = "3D RAGE LT";static char m64n_ltg[] __initdata = "3D RAGE LT-G";static char m64n_gtc_ba[] __initdata = "3D RAGE PRO (BGA, AGP)";static char m64n_gtc_ba1[] __initdata = "3D RAGE PRO (BGA, AGP, 1x only)";static char m64n_gtc_bp[] __initdata = "3D RAGE PRO (BGA, PCI)";static char m64n_gtc_pp[] __initdata = "3D RAGE PRO (PQFP, PCI)";static char m64n_gtc_ppl[] __initdata =    "3D RAGE PRO (PQFP, PCI, limited 3D)";static char m64n_xl[] __initdata = "3D RAGE (XL)";static char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";#endif /* CONFIG_FB_ATY_CT */static struct {	u16 pci_id, chip_type;	u8 rev_mask, rev_val;	const char *name;	int pll, mclk;	u32 features;} aty_chips[] __initdata = {#ifdef CONFIG_FB_ATY_GX	/* Mach64 GX */	{	0x4758, 0x00d7, 0x00, 0x00, m64n_gx, 135, 50, M64F_GX}, {	0x4358, 0x0057, 0x00, 0x00, m64n_cx, 135, 50, M64F_GX},#endif				/* CONFIG_FB_ATY_GX */#ifdef CONFIG_FB_ATY_CT	    /* Mach64 CT */	{	0x4354, 0x4354, 0x00, 0x00, m64n_ct, 135, 60,		    M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |		    M64F_MAGIC_FIFO}, {	0x4554, 0x4554, 0x00, 0x00, m64n_et, 135, 60,		    M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |		    M64F_MAGIC_FIFO},	    /* Mach64 VT */	{	0x5654, 0x5654, 0xc7, 0x00, m64n_vta3, 170, 67,		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |		    M64F_MAGIC_FIFO | M64F_FIFO_24}, {	0x5654, 0x5654, 0xc7, 0x40, m64n_vta4, 200, 67,		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |		    M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV}, {	0x5654, 0x5654, 0x00, 0x00, m64n_vtb, 200, 67,		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |		    M64F_GTB_DSP | M64F_FIFO_24}, {	0x5655, 0x5655, 0x00, 0x00, m64n_vtb, 200, 67,		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |		    M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL}, {	0x5656, 0x5656, 0x00, 0x00, m64n_vt4, 230, 83,		    M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP},	    /* Mach64 GT (3D RAGE) */	{	0x4754, 0x4754, 0x07, 0x00, m64n_gt, 135, 63,		    M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO |		    M64F_FIFO_24 | M64F_EXTRA_BRIGHT}, {	0x4754, 0x4754, 0x07, 0x01, m64n_gt, 170, 67,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4754, 0x4754, 0x07, 0x02, m64n_gt, 200, 67,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4755, 0x4755, 0x00, 0x00, m64n_gtb, 200, 67,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4756, 0x4756, 0x00, 0x00, m64n_iic_p, 230, 83,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4757, 0x4757, 0x00, 0x00, m64n_iic_a, 230, 83,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x475a, 0x475a, 0x00, 0x00, m64n_iic_a, 230, 83,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT},	    /* Mach64 LT */	{	0x4c54, 0x4c54, 0x00, 0x00, m64n_lt, 135, 63,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP}, {	0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg, 230, 63,		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |		    M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT |		    M64F_LT_SLEEP | M64F_G3_PB_1024x768},	    /* Mach64 GTC (3D RAGE PRO) */	{	0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE}, {	0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT}, {	0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT},	    /* 3D RAGE XL */	{	0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |		    M64F_EXTRA_BRIGHT | M64F_XL_DLL},	    /* Mach64 LT PRO */	{	0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP}, {	0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP}, {	0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_EXTRA_BRIGHT |		    M64F_G3_PB_1_1 | M64F_G3_PB_1024x768}, {	0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p, 230, 100,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP},	    /* 3D RAGE Mobility */	{	0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_MOBIL_BUS}, {	0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50,		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |		    M64F_GTB_DSP | M64F_MOBIL_BUS},#endif				/* CONFIG_FB_ATY_CT */};static char ram_dram[] __initdata = "DRAM";#ifdef CONFIG_FB_ATY_GXstatic char ram_vram[] __initdata = "VRAM";#endif /* CONFIG_FB_ATY_GX */#ifdef CONFIG_FB_ATY_CTstatic char ram_edo[] __initdata = "EDO";static char ram_sdram[] __initdata = "SDRAM";static char ram_sgram[] __initdata = "SGRAM";static char ram_wram[] __initdata = "WRAM";static char ram_off[] __initdata = "OFF";#endif /* CONFIG_FB_ATY_CT */static char ram_resv[] __initdata = "RESV";static u32 pseudo_palette[17];#ifdef CONFIG_FB_ATY_GXstatic char *aty_gx_ram[8] __initdata = {	ram_dram, ram_vram, ram_vram, ram_dram,	ram_dram, ram_vram, ram_vram, ram_resv};#endif				/* CONFIG_FB_ATY_GX */#ifdef CONFIG_FB_ATY_CTstatic char *aty_ct_ram[8] __initdata = {	ram_off, ram_dram, ram_edo, ram_edo,	ram_sdram, ram_sgram, ram_wram, ram_resv};#endif				/* CONFIG_FB_ATY_CT */#if defined(CONFIG_PPC)    /*     *  Apple monitor sense     */static int __init read_aty_sense(const struct atyfb_par *par){	int sense, i;	aty_st_le32(GP_IO, 0x31003100, par);	/* drive outputs high */	__delay(200);	aty_st_le32(GP_IO, 0, par);	/* turn off outputs */	__delay(2000);	i = aty_ld_le32(GP_IO, par);	/* get primary sense value */	sense = ((i & 0x3000) >> 3) | (i & 0x100);	/* drive each sense line low in turn and collect the other 2 */	aty_st_le32(GP_IO, 0x20000000, par);	/* drive A low */	__delay(2000);	i = aty_ld_le32(GP_IO, par);	sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);	aty_st_le32(GP_IO, 0x20002000, par);	/* drive A high again */	__delay(200);	aty_st_le32(GP_IO, 0x10000000, par);	/* drive B low */	__delay(2000);	i = aty_ld_le32(GP_IO, par);	sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);	aty_st_le32(GP_IO, 0x10001000, par);	/* drive B high again */	__delay(200);	aty_st_le32(GP_IO, 0x01000000, par);	/* drive C low */	__delay(2000);	sense |= (aty_ld_le32(GP_IO, par) & 0x3000) >> 12;	aty_st_le32(GP_IO, 0, par);	/* turn off outputs */	return sense;}#endif				/* defined(CONFIG_PPC) */#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_PMAC_BACKLIGHT)static void aty_st_lcd(int index, u32 val, const struct atyfb_par *par){	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);}static u32 aty_ld_lcd(int index, const struct atyfb_par *par){	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 */

⌨️ 快捷键说明

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