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

📄 stifb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * linux/drivers/video/stifb.c -  * Low level Frame buffer driver for HP workstations with  * STI (standard text interface) video firmware. * * Copyright (C) 2001-2006 Helge Deller <deller@gmx.de> * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de> *  * Based on: * - linux/drivers/video/artistfb.c -- Artist frame buffer driver *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> *   - based on skeletonfb, which was *	Created 28 Dec 1997 by Geert Uytterhoeven * - HP Xhp cfb-based X11 window driver for XFree86 *	(c)Copyright 1992 Hewlett-Packard Co. * *  *  The following graphics display devices (NGLE family) are supported by this driver: * *  HPA4070A	known as "HCRX", a 1280x1024 color device with 8 planes *  HPA4071A	known as "HCRX24", a 1280x1024 color device with 24 planes, *		optionally available with a hardware accelerator as HPA4071A_Z *  HPA1659A	known as "CRX", a 1280x1024 color device with 8 planes *  HPA1439A	known as "CRX24", a 1280x1024 color device with 24 planes, *		optionally available with a hardware accelerator. *  HPA1924A	known as "GRX", a 1280x1024 grayscale device with 8 planes *  HPA2269A	known as "Dual CRX", a 1280x1024 color device with 8 planes, *		implements support for two displays on a single graphics card. *  HP710C	internal graphics support optionally available on the HP9000s710 SPU, *		supports 1280x1024 color displays with 8 planes. *  HP710G	same as HP710C, 1280x1024 grayscale only *  HP710L	same as HP710C, 1024x768 color only *  HP712	internal graphics support on HP9000s712 SPU, supports 640x480,  *		1024x768 or 1280x1024 color displays on 8 planes (Artist) * * 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. *//* TODO: *	- 1bpp mode is completely untested *	- add support for h/w acceleration *	- add hardware cursor *	- automatically disable double buffering (e.g. on RDI precisionbook laptop) *//* on supported graphic devices you may: * #define FALLBACK_TO_1BPP to fall back to 1 bpp, or * #undef  FALLBACK_TO_1BPP to reject support for unsupported cards */#undef FALLBACK_TO_1BPP#undef DEBUG_STIFB_REGS		/* debug sti register accesses */#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/delay.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/ioport.h>#include <asm/grfioctl.h>	/* for HP-UX compatibility */#include <asm/uaccess.h>#include "sticore.h"/* REGION_BASE(fb_info, index) returns the virtual address for region <index> */#define REGION_BASE(fb_info, index) \	F_EXTEND(fb_info->sti->glob_cfg->region_ptrs[index])#define NGLEDEVDEPROM_CRT_REGION 1#define NR_PALETTE 256typedef struct {	__s32	video_config_reg;	__s32	misc_video_start;	__s32	horiz_timing_fmt;	__s32	serr_timing_fmt;	__s32	vert_timing_fmt;	__s32	horiz_state;	__s32	vert_state;	__s32	vtg_state_elements;	__s32	pipeline_delay;	__s32	misc_video_end;} video_setup_t;typedef struct {                  	__s16	sizeof_ngle_data;	__s16	x_size_visible;	    /* visible screen dim in pixels  */	__s16	y_size_visible;	__s16	pad2[15];	__s16	cursor_pipeline_delay;	__s16	video_interleaves;	__s32	pad3[11];} ngle_rom_t;struct stifb_info {	struct fb_info info;	unsigned int id;	ngle_rom_t ngle_rom;	struct sti_struct *sti;	int deviceSpecificConfig;	u32 pseudo_palette[16];};static int __initdata stifb_bpp_pref[MAX_STI_ROMS];/* ------------------- chipset specific functions -------------------------- *//* offsets to graphic-chip internal registers */#define REG_1		0x000118#define REG_2		0x000480#define REG_3		0x0004a0#define REG_4		0x000600#define REG_6		0x000800#define REG_8		0x000820#define REG_9		0x000a04#define REG_10		0x018000#define REG_11		0x018004#define REG_12		0x01800c#define REG_13		0x018018#define REG_14  	0x01801c#define REG_15		0x200000#define REG_15b0	0x200000#define REG_16b1	0x200005#define REG_16b3	0x200007#define REG_21		0x200218#define REG_22		0x0005a0#define REG_23		0x0005c0#define REG_26		0x200118#define REG_27		0x200308#define REG_32		0x21003c#define REG_33		0x210040#define REG_34		0x200008#define REG_35		0x018010#define REG_38		0x210020#define REG_39		0x210120#define REG_40		0x210130#define REG_42		0x210028#define REG_43		0x21002c#define REG_44		0x210030#define REG_45		0x210034#define READ_BYTE(fb,reg)		gsc_readb((fb)->info.fix.mmio_start + (reg))#define READ_WORD(fb,reg)		gsc_readl((fb)->info.fix.mmio_start + (reg))#ifndef DEBUG_STIFB_REGS# define  DEBUG_OFF()# define  DEBUG_ON()# define WRITE_BYTE(value,fb,reg)	gsc_writeb((value),(fb)->info.fix.mmio_start + (reg))# define WRITE_WORD(value,fb,reg)	gsc_writel((value),(fb)->info.fix.mmio_start + (reg))#else  static int debug_on = 1;# define  DEBUG_OFF() debug_on=0# define  DEBUG_ON()  debug_on=1# define WRITE_BYTE(value,fb,reg)	do { if (debug_on) \						printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \							__func__, reg, value, READ_BYTE(fb,reg)); 		  \					gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)# define WRITE_WORD(value,fb,reg)	do { if (debug_on) \						printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \							__func__, reg, value, READ_WORD(fb,reg)); 		  \					gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)#endif /* DEBUG_STIFB_REGS */#define ENABLE	1	/* for enabling/disabling screen */	#define DISABLE 0#define NGLE_LOCK(fb_info)	do { } while (0) #define NGLE_UNLOCK(fb_info)	do { } while (0)static voidSETUP_HW(struct stifb_info *fb){	char stat;	do {		stat = READ_BYTE(fb, REG_15b0);		if (!stat)	    		stat = READ_BYTE(fb, REG_15b0);	} while (stat);}static voidSETUP_FB(struct stifb_info *fb){		unsigned int reg10_value = 0;		SETUP_HW(fb);	switch (fb->id)	{		case CRT_ID_VISUALIZE_EG:		case S9000_ID_ARTIST:		case S9000_ID_A1659A:			reg10_value = 0x13601000;			break;		case S9000_ID_A1439A:			if (fb->info.var.bits_per_pixel == 32)										reg10_value = 0xBBA0A000;			else 				reg10_value = 0x13601000;			break;		case S9000_ID_HCRX:			if (fb->info.var.bits_per_pixel == 32)				reg10_value = 0xBBA0A000;			else									reg10_value = 0x13602000;			break;		case S9000_ID_TIMBER:		case CRX24_OVERLAY_PLANES:			reg10_value = 0x13602000;			break;	}	if (reg10_value)		WRITE_WORD(reg10_value, fb, REG_10);	WRITE_WORD(0x83000300, fb, REG_14);	SETUP_HW(fb);	WRITE_BYTE(1, fb, REG_16b1);}static voidSTART_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb){	SETUP_HW(fb);	WRITE_WORD(0xBBE0F000, fb, REG_10);	WRITE_WORD(0x03000300, fb, REG_14);	WRITE_WORD(~0, fb, REG_13);}static voidWRITE_IMAGE_COLOR(struct stifb_info *fb, int index, int color) {	SETUP_HW(fb);	WRITE_WORD(((0x100+index)<<2), fb, REG_3);	WRITE_WORD(color, fb, REG_4);}static voidFINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb) {			WRITE_WORD(0x400, fb, REG_2);	if (fb->info.var.bits_per_pixel == 32) {		WRITE_WORD(0x83000100, fb, REG_1);	} else {		if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)			WRITE_WORD(0x80000100, fb, REG_26);		else										WRITE_WORD(0x80000100, fb, REG_1);	}	SETUP_FB(fb);}static voidSETUP_RAMDAC(struct stifb_info *fb) {	SETUP_HW(fb);	WRITE_WORD(0x04000000, fb, 0x1020);	WRITE_WORD(0xff000000, fb, 0x1028);}static void CRX24_SETUP_RAMDAC(struct stifb_info *fb) {	SETUP_HW(fb);	WRITE_WORD(0x04000000, fb, 0x1000);	WRITE_WORD(0x02000000, fb, 0x1004);	WRITE_WORD(0xff000000, fb, 0x1008);	WRITE_WORD(0x05000000, fb, 0x1000);	WRITE_WORD(0x02000000, fb, 0x1004);	WRITE_WORD(0x03000000, fb, 0x1008);}#if 0static void HCRX_SETUP_RAMDAC(struct stifb_info *fb){	WRITE_WORD(0xffffffff, fb, REG_32);}#endifstatic void CRX24_SET_OVLY_MASK(struct stifb_info *fb){	SETUP_HW(fb);	WRITE_WORD(0x13a02000, fb, REG_11);	WRITE_WORD(0x03000300, fb, REG_14);	WRITE_WORD(0x000017f0, fb, REG_3);	WRITE_WORD(0xffffffff, fb, REG_13);	WRITE_WORD(0xffffffff, fb, REG_22);	WRITE_WORD(0x00000000, fb, REG_23);}static voidENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable){	unsigned int value = enable ? 0x43000000 : 0x03000000;        SETUP_HW(fb);        WRITE_WORD(0x06000000,	fb, 0x1030);        WRITE_WORD(value, 	fb, 0x1038);}static void CRX24_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable){	unsigned int value = enable ? 0x10000000 : 0x30000000;	SETUP_HW(fb);	WRITE_WORD(0x01000000,	fb, 0x1000);	WRITE_WORD(0x02000000,	fb, 0x1004);	WRITE_WORD(value,	fb, 0x1008);}static voidARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) {	u32 DregsMiscVideo = REG_21;	u32 DregsMiscCtl = REG_27;		SETUP_HW(fb);	if (enable) {	  WRITE_WORD(READ_WORD(fb, DregsMiscVideo) | 0x0A000000, fb, DregsMiscVideo);	  WRITE_WORD(READ_WORD(fb, DregsMiscCtl)   | 0x00800000, fb, DregsMiscCtl);	} else {	  WRITE_WORD(READ_WORD(fb, DregsMiscVideo) & ~0x0A000000, fb, DregsMiscVideo);	  WRITE_WORD(READ_WORD(fb, DregsMiscCtl)   & ~0x00800000, fb, DregsMiscCtl);	}}#define GET_ROMTABLE_INDEX(fb) \	(READ_BYTE(fb, REG_16b3) - 1)#define HYPER_CONFIG_PLANES_24 0x00000100	#define IS_24_DEVICE(fb) \	(fb->deviceSpecificConfig & HYPER_CONFIG_PLANES_24)#define IS_888_DEVICE(fb) \	(!(IS_24_DEVICE(fb)))#define GET_FIFO_SLOTS(fb, cnt, numslots)	\{	while (cnt < numslots) 			\		cnt = READ_WORD(fb, REG_34);	\	cnt -= numslots;			\}#define	    IndexedDcd	0	/* Pixel data is indexed (pseudo) color */#define	    Otc04	2	/* Pixels in each longword transfer (4) */#define	    Otc32	5	/* Pixels in each longword transfer (32) */#define	    Ots08	3	/* Each pixel is size (8)d transfer (1) */#define	    OtsIndirect	6	/* Each bit goes through FG/BG color(8) */#define	    AddrLong	5	/* FB address is Long aligned (pixel) */#define	    BINovly	0x2	/* 8 bit overlay */#define	    BINapp0I	0x0	/* Application Buffer 0, Indexed */#define	    BINapp1I	0x1	/* Application Buffer 1, Indexed */#define	    BINapp0F8	0xa	/* Application Buffer 0, Fractional 8-8-8 */#define	    BINattr	0xd	/* Attribute Bitmap */#define	    RopSrc 	0x3#define	    BitmapExtent08  3	/* Each write hits ( 8) bits in depth */#define	    BitmapExtent32  5	/* Each write hits (32) bits in depth */#define	    DataDynamic	    0	/* Data register reloaded by direct access */#define	    MaskDynamic	    1	/* Mask register reloaded by direct access */#define	    MaskOtc	    0	/* Mask contains Object Count valid bits */#define MaskAddrOffset(offset) (offset)#define StaticReg(en) (en)#define BGx(en) (en)#define FGx(en) (en)#define BAJustPoint(offset) (offset)#define BAIndexBase(base) (base)#define BA(F,C,S,A,J,B,I) \	(((F)<<31)|((C)<<27)|((S)<<24)|((A)<<21)|((J)<<16)|((B)<<12)|(I))#define IBOvals(R,M,X,S,D,L,B,F) \	(((R)<<8)|((M)<<16)|((X)<<24)|((S)<<29)|((D)<<28)|((L)<<31)|((B)<<1)|(F))#define NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb, val) \	WRITE_WORD(val, fb, REG_14)#define NGLE_QUICK_SET_DST_BM_ACCESS(fb, val) \	WRITE_WORD(val, fb, REG_11)#define NGLE_QUICK_SET_CTL_PLN_REG(fb, val) \	WRITE_WORD(val, fb, REG_12)#define NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, plnmsk32) \	WRITE_WORD(plnmsk32, fb, REG_13)#define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, fg32) \	WRITE_WORD(fg32, fb, REG_35)#define NGLE_SET_TRANSFERDATA(fb, val) \	WRITE_WORD(val, fb, REG_8)#define NGLE_SET_DSTXY(fb, val) \	WRITE_WORD(val, fb, REG_6)#define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) (		\	(u32) (fbaddrbase) +					\	    (	(unsigned int)  ( (y) << 13      ) |		\		(unsigned int)  ( (x) << 2       )	)	\	)#define NGLE_BINC_SET_DSTADDR(fb, addr) \	WRITE_WORD(addr, fb, REG_3)#define NGLE_BINC_SET_SRCADDR(fb, addr) \	WRITE_WORD(addr, fb, REG_2)#define NGLE_BINC_SET_DSTMASK(fb, mask) \	WRITE_WORD(mask, fb, REG_22)#define NGLE_BINC_WRITE32(fb, data32) \	WRITE_WORD(data32, fb, REG_23)#define START_COLORMAPLOAD(fb, cmapBltCtlData32) \	WRITE_WORD((cmapBltCtlData32), fb, REG_38)#define SET_LENXY_START_RECFILL(fb, lenxy) \	WRITE_WORD(lenxy, fb, REG_9)static voidHYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable){	u32 DregsHypMiscVideo = REG_33;	unsigned int value;	SETUP_HW(fb);	value = READ_WORD(fb, DregsHypMiscVideo);	if (enable)		value |= 0x0A000000;	else		value &= ~0x0A000000;	WRITE_WORD(value, fb, DregsHypMiscVideo);}/* BufferNumbers used by SETUP_ATTR_ACCESS() */#define BUFF0_CMAP0	0x00001e02#define BUFF1_CMAP0	0x02001e02#define BUFF1_CMAP3	0x0c001e02#define ARTIST_CMAP0	0x00000102#define HYPER_CMAP8	0x00000100#define HYPER_CMAP24	0x00000800static voidSETUP_ATTR_ACCESS(struct stifb_info *fb, unsigned BufferNumber){	SETUP_HW(fb);	WRITE_WORD(0x2EA0D000, fb, REG_11);	WRITE_WORD(0x23000302, fb, REG_14);	WRITE_WORD(BufferNumber, fb, REG_12);	WRITE_WORD(0xffffffff, fb, REG_8);}static voidSET_ATTR_SIZE(struct stifb_info *fb, int width, int height) {	/* REG_6 seems to have special values when run on a 	   RDI precisionbook parisc laptop (INTERNAL_EG_DX1024 or	   INTERNAL_EG_X1024).  The values are:		0x2f0: internal (LCD) & external display enabled		0x2a0: external display only		0x000: zero on standard artist graphic cards

⌨️ 快捷键说明

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