cirrusfb.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,329 行 · 第 1/5 页

C
2,329
字号
/* * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets * * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com> * * Contributors (thanks, all!) * *	David Eger: *	Overhaul for Linux 2.6 * *      Jeff Rugen: *      Major contributions;  Motorola PowerStack (PPC and PCI) support, *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK. * *	Geert Uytterhoeven: *	Excellent code review. * *	Lars Hecking: *	Amiga updates and testing. * * Original cirrusfb author:  Frank Neumann * * Based on retz3fb.c and cirrusfb.c: *      Copyright (C) 1997 Jes Sorensen *      Copyright (C) 1996 Frank Neumann * *************************************************************** * * Format this code with GNU indent '-kr -i8 -pcs' options. * * 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. * */#define CIRRUSFB_VERSION "2.0-pre2"#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/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/selection.h>#include <asm/pgtable.h>#ifdef CONFIG_ZORRO#include <linux/zorro.h>#endif#ifdef CONFIG_PCI#include <linux/pci.h>#endif#ifdef CONFIG_AMIGA#include <asm/amigahw.h>#endif#ifdef CONFIG_PPC_PREP#include <asm/processor.h>#define isPReP (_machine == _MACH_prep)#else#define isPReP 0#endif#include "video/vga.h"#include "video/cirrus.h"/***************************************************************** * * debugging and utility macros * *//* enable debug output? *//* #define CIRRUSFB_DEBUG 1 *//* disable runtime assertions? *//* #define CIRRUSFB_NDEBUG *//* debug output */#ifdef CIRRUSFB_DEBUG#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)#else#define DPRINTK(fmt, args...)#endif/* debugging assertions */#ifndef CIRRUSFB_NDEBUG#define assert(expr) \        if(!(expr)) { \        printk( "Assertion failed! %s,%s,%s,line=%d\n",\        #expr,__FILE__,__FUNCTION__,__LINE__); \        }#else#define assert(expr)#endif#ifdef TRUE#undef TRUE#endif#ifdef FALSE#undef FALSE#endif#define TRUE  1#define FALSE 0#define MB_ (1024*1024)#define KB_ (1024)#define MAX_NUM_BOARDS 7/***************************************************************** * * chipset information * *//* board types */typedef enum {	BT_NONE = 0,	BT_SD64,	BT_PICCOLO,	BT_PICASSO,	BT_SPECTRUM,	BT_PICASSO4,	/* GD5446 */	BT_ALPINE,	/* GD543x/4x */	BT_GD5480,	BT_LAGUNA,	/* GD546x */} cirrusfb_board_t;/* * per-board-type information, used for enumerating and abstracting * chip-specific information * NOTE: MUST be in the same order as cirrusfb_board_t in order to * use direct indexing on this array * NOTE: '__initdata' cannot be used as some of this info * is required at runtime.  Maybe separate into an init-only and * a run-time table? */static const struct cirrusfb_board_info_rec {	char *name;		/* ASCII name of chipset */	long maxclock[5];		/* maximum video clock */	/* for  1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */	unsigned init_sr07 : 1;	/* init SR07 during init_vgachip() */	unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */	unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */	/* initial SR07 value, then for each mode */	unsigned char sr07;	unsigned char sr07_1bpp;	unsigned char sr07_1bpp_mux;	unsigned char sr07_8bpp;	unsigned char sr07_8bpp_mux;	unsigned char sr1f;	/* SR1F VGA initial register value */} cirrusfb_board_info[] = {	[BT_SD64] = {		.name			= "CL SD64",		.maxclock		= {			/* guess */			/* the SD64/P4 have a higher max. videoclock */			140000, 140000, 140000, 140000, 140000,		},		.init_sr07		= TRUE,		.init_sr1f		= TRUE,		.scrn_start_bit19	= TRUE,		.sr07			= 0xF0,		.sr07_1bpp		= 0xF0,		.sr07_8bpp		= 0xF1,		.sr1f			= 0x20	},	[BT_PICCOLO] = {		.name			= "CL Piccolo",		.maxclock		= {			/* guess */			90000, 90000, 90000, 90000, 90000		},		.init_sr07		= TRUE,		.init_sr1f		= TRUE,		.scrn_start_bit19	= FALSE,		.sr07			= 0x80,		.sr07_1bpp		= 0x80,		.sr07_8bpp		= 0x81,		.sr1f			= 0x22	},	[BT_PICASSO] = {		.name			= "CL Picasso",		.maxclock		= {			/* guess */			90000, 90000, 90000, 90000, 90000		},		.init_sr07		= TRUE,		.init_sr1f		= TRUE,		.scrn_start_bit19	= FALSE,		.sr07			= 0x20,		.sr07_1bpp		= 0x20,		.sr07_8bpp		= 0x21,		.sr1f			= 0x22	},	[BT_SPECTRUM] = {		.name			= "CL Spectrum",		.maxclock		= {			/* guess */			90000, 90000, 90000, 90000, 90000		},		.init_sr07		= TRUE,		.init_sr1f		= TRUE,		.scrn_start_bit19	= FALSE,		.sr07			= 0x80,		.sr07_1bpp		= 0x80,		.sr07_8bpp		= 0x81,		.sr1f			= 0x22	},	[BT_PICASSO4] = {		.name			= "CL Picasso4",		.maxclock		= {			135100, 135100, 85500, 85500, 0		},		.init_sr07		= TRUE,		.init_sr1f		= FALSE,		.scrn_start_bit19	= TRUE,		.sr07			= 0x20,		.sr07_1bpp		= 0x20,		.sr07_8bpp		= 0x21,		.sr1f			= 0	},	[BT_ALPINE] = {		.name			= "CL Alpine",		.maxclock		= {			/* for the GD5430.  GD5446 can do more... */			85500, 85500, 50000, 28500, 0		},		.init_sr07		= TRUE,		.init_sr1f		= TRUE,		.scrn_start_bit19	= TRUE,		.sr07			= 0xA0,		.sr07_1bpp		= 0xA1,		.sr07_1bpp_mux		= 0xA7,		.sr07_8bpp		= 0xA1,		.sr07_8bpp_mux		= 0xA7,		.sr1f			= 0x1C	},	[BT_GD5480] = {		.name			= "CL GD5480",		.maxclock		= {			135100, 200000, 200000, 135100, 135100		},		.init_sr07		= TRUE,		.init_sr1f		= TRUE,		.scrn_start_bit19	= TRUE,		.sr07			= 0x10,		.sr07_1bpp		= 0x11,		.sr07_8bpp		= 0x11,		.sr1f			= 0x1C	},	[BT_LAGUNA] = {		.name			= "CL Laguna",		.maxclock		= {			/* guess */			135100, 135100, 135100, 135100, 135100,		},		.init_sr07		= FALSE,		.init_sr1f		= FALSE,		.scrn_start_bit19	= TRUE,	}};#ifdef CONFIG_PCI#define CHIP(id, btype) \	{ PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }static struct pci_device_id cirrusfb_pci_table[] = {	CHIP( CIRRUS_5436,	BT_ALPINE ),	CHIP( CIRRUS_5434_8,	BT_ALPINE ),	CHIP( CIRRUS_5434_4,	BT_ALPINE ),	CHIP( CIRRUS_5430,	BT_ALPINE ), /* GD-5440 has identical id */	CHIP( CIRRUS_7543,	BT_ALPINE ),	CHIP( CIRRUS_7548,	BT_ALPINE ),	CHIP( CIRRUS_5480,	BT_GD5480 ), /* MacPicasso probably */	CHIP( CIRRUS_5446,	BT_PICASSO4 ), /* Picasso 4 is a GD5446 */	CHIP( CIRRUS_5462,	BT_LAGUNA ), /* CL Laguna */	CHIP( CIRRUS_5464,	BT_LAGUNA ), /* CL Laguna 3D */	CHIP( CIRRUS_5465,	BT_LAGUNA ), /* CL Laguna 3DA*/	{ 0, }};MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);#undef CHIP#endif /* CONFIG_PCI */#ifdef CONFIG_ZORROstatic const struct zorro_device_id cirrusfb_zorro_table[] = {	{		.id		= ZORRO_PROD_HELFRICH_SD64_RAM,		.driver_data	= BT_SD64,	}, {		.id		= ZORRO_PROD_HELFRICH_PICCOLO_RAM,		.driver_data	= BT_PICCOLO,	}, {		.id		= ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,		.driver_data	= BT_PICASSO,	}, {		.id		= ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,		.driver_data	= BT_SPECTRUM,	}, {		.id		= ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,		.driver_data	= BT_PICASSO4,	},	{ 0 }};static const struct {	zorro_id id2;	unsigned long size;} cirrusfb_zorro_table2[] = {	[BT_SD64] = {		.id2	= ZORRO_PROD_HELFRICH_SD64_REG,		.size	= 0x400000	},	[BT_PICCOLO] = {		.id2	= ZORRO_PROD_HELFRICH_PICCOLO_REG,		.size	= 0x200000	},	[BT_PICASSO] = {		.id2	= ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,		.size	= 0x200000	},	[BT_SPECTRUM] = {		.id2	= ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,		.size	= 0x200000	},	[BT_PICASSO4] = {		.id2	= 0,		.size	= 0x400000	}};#endif /* CONFIG_ZORRO */struct cirrusfb_regs {	__u32 line_length;	/* in BYTES! */	__u32 visual;	__u32 type;	long freq;	long nom;	long den;	long div;	long multiplexing;	long mclk;	long divMCLK;	long HorizRes;		/* The x resolution in pixel */	long HorizTotal;	long HorizDispEnd;	long HorizBlankStart;	long HorizBlankEnd;	long HorizSyncStart;	long HorizSyncEnd;	long VertRes;		/* the physical y resolution in scanlines */	long VertTotal;	long VertDispEnd;	long VertSyncStart;	long VertSyncEnd;	long VertBlankStart;	long VertBlankEnd;};#ifdef CIRRUSFB_DEBUGtypedef enum {        CRT,        SEQ} cirrusfb_dbg_reg_class_t;#endif                          /* CIRRUSFB_DEBUG *//* info about board */struct cirrusfb_info {	struct fb_info *info;	caddr_t fbmem;	caddr_t regbase;	caddr_t mem;	unsigned long size;	cirrusfb_board_t btype;	unsigned char SFR;	/* Shadow of special function register */	unsigned long fbmem_phys;	unsigned long fbregs_phys;	struct cirrusfb_regs currentmode;	int blank_mode;	u32	pseudo_palette[17];	struct { u8 red, green, blue, pad; } palette[256];#ifdef CONFIG_ZORRO	struct zorro_dev *zdev;#endif#ifdef CONFIG_PCI	struct pci_dev *pdev;#endif	void (*unmap)(struct cirrusfb_info *cinfo);};static unsigned cirrusfb_def_mode = 1;static int noaccel = 0;/* *    Predefined Video Modes */static const struct {	const char *name;	struct fb_var_screeninfo var;} cirrusfb_predefined[] = {	{		/* autodetect mode */		.name	= "Autodetect",	}, {		/* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */		.name	= "640x480",		.var	= {			.xres		= 640,			.yres		= 480,			.xres_virtual	= 640,			.yres_virtual	= 480,			.bits_per_pixel	= 8,			.red		= { .length = 8 },			.green		= { .length = 8 },			.blue		= { .length = 8 },			.width		= -1,			.height		= -1,			.pixclock	= 40000,			.left_margin	= 48,			.right_margin	= 16,			.upper_margin	= 32,			.lower_margin	= 8,			.hsync_len	= 96,			.vsync_len	= 4,			.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,			.vmode		= FB_VMODE_NONINTERLACED		 }	}, {		/* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */		.name	= "800x600",		.var	= {			.xres		= 800,			.yres		= 600,			.xres_virtual	= 800,			.yres_virtual	= 600,			.bits_per_pixel	= 8,

⌨️ 快捷键说明

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