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

📄 matroxfb_base.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400 * * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz> * * Portions Copyright (c) 2001 Matrox Graphics Inc. * * Version: 1.64 2002/06/10 * * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org> * * Contributors: "menion?" <menion@mindless.com> *                     Betatesting, fixes, ideas * *               "Kurt Garloff" <garloff@suse.de> *                     Betatesting, fixes, ideas, videomodes, videomodes timmings * *               "Tom Rini" <trini@kernel.crashing.org> *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas * *               "Bibek Sahu" <scorpio@dodds.net> *                     Access device through readb|w|l and write b|w|l *                     Extensive debugging stuff * *               "Daniel Haun" <haund@usa.net> *                     Testing, hardware cursor fixes * *               "Scott Wood" <sawst46+@pitt.edu> *                     Fixes * *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de> *                     Betatesting * *               "Kelly French" <targon@hazmat.com> *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es> *                     Betatesting, bug reporting * *               "Pablo Bianucci" <pbian@pccp.com.ar> *                     Fixes, ideas, betatesting * *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es> *                     Fixes, enhandcements, ideas, betatesting * *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp> *                     PPC betatesting, PPC support, backward compatibility * *               "Paul Womar" <Paul@pwomar.demon.co.uk> *               "Owen Waller" <O.Waller@ee.qub.ac.uk> *                     PPC betatesting * *               "Thomas Pornin" <pornin@bolet.ens.fr> *                     Alpha betatesting * *               "Pieter van Leuven" <pvl@iae.nl> *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de> *                     G100 testing * *               "H. Peter Arvin" <hpa@transmeta.com> *                     Ideas * *               "Cort Dougan" <cort@cs.nmt.edu> *                     CHRP fixes and PReP cleanup * *               "Mark Vojkovich" <mvojkovi@ucsd.edu> *                     G400 support * *               "Samuel Hocevar" <sam@via.ecp.fr> *                     Fixes * *               "Anton Altaparmakov" <AntonA@bigfoot.com> *                     G400 MAX/non-MAX distinction * *               "Ken Aaker" <kdaaker@rchland.vnet.ibm.com> *                     memtype extension (needed for GXT130P RS/6000 adapter) * *               "Uns Lider" <unslider@miranda.org> *                     G100 PLNWT fixes * *               "Denis Zaitsev" <zzz@cd-club.ru> *                     Fixes * *               "Mike Pieper" <mike@pieper-family.de> *                     TVOut enhandcements, V4L2 control interface. * *               "Diego Biurrun" <diego@biurrun.de> *                     DFP testing * * (following author is not in any relation with this code, but his code *  is included in this driver) * * Based on framebuffer driver for VBE 2.0 compliant graphic boards *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de> * * (following author is not in any relation with this code, but his ideas *  were used when writting this driver) * *		 FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk> * *//* make checkconfig does not check included files... */#include <linux/config.h>#include "matroxfb_base.h"#include "matroxfb_misc.h"#include "matroxfb_accel.h"#include "matroxfb_DAC1064.h"#include "matroxfb_Ti3026.h"#include "matroxfb_maven.h"#include "matroxfb_crtc2.h"#include "matroxfb_g450.h"#include <linux/matroxfb.h>#include <asm/uaccess.h>#ifdef CONFIG_PPCunsigned char nvram_read_byte(int);static int default_vmode = VMODE_NVRAM;static int default_cmode = CMODE_NVRAM;#endifstatic void matroxfb_unregister_device(struct matrox_fb_info* minfo);/* --------------------------------------------------------------------- *//* * card parameters *//* --------------------------------------------------------------------- */static struct fb_var_screeninfo vesafb_defined = {	640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/	0,0,		/* virtual -> visible no offset */	8,		/* depth -> load bits_per_pixel */	0,		/* greyscale ? */	{0,0,0},	/* R */	{0,0,0},	/* G */	{0,0,0},	/* B */	{0,0,0},	/* transparency */	0,		/* standard pixel format */	FB_ACTIVATE_NOW,	-1,-1,	FB_ACCELF_TEXT,	/* accel flags */	39721L,48L,16L,33L,10L,	96L,2L,~0,	/* No sync info */	FB_VMODE_NONINTERLACED,	{0,0,0,0,0,0}};/* --------------------------------------------------------------------- */static void matroxfb_crtc1_panpos(WPMINFO2) {	if (ACCESS_FBINFO(crtc1.panpos) >= 0) {		unsigned long flags;		int panpos;				matroxfb_DAC_lock_irqsave(flags);		panpos = ACCESS_FBINFO(crtc1.panpos);		if (panpos >= 0) {			unsigned int extvga_reg;						ACCESS_FBINFO(crtc1.panpos) = -1; /* No update pending anymore */			extvga_reg = mga_inb(M_EXTVGA_INDEX);			mga_setr(M_EXTVGA_INDEX, 0x00, panpos);			if (extvga_reg != 0x00) {				mga_outb(M_EXTVGA_INDEX, extvga_reg);			}		}		matroxfb_DAC_unlock_irqrestore(flags);	}}static void matrox_irq(int irq, void *dev_id, struct pt_regs *fp){	u_int32_t status;	int handled = 0;	MINFO_FROM(dev_id);	status = mga_inl(M_STATUS);	if (status & 0x20) {		mga_outl(M_ICLEAR, 0x20);		ACCESS_FBINFO(crtc1.vsync.cnt)++;		matroxfb_crtc1_panpos(PMINFO2);		wake_up_interruptible(&ACCESS_FBINFO(crtc1.vsync.wait));		handled = 1;	}	if (status & 0x200) {		mga_outl(M_ICLEAR, 0x200);		ACCESS_FBINFO(crtc2.vsync.cnt)++;		wake_up_interruptible(&ACCESS_FBINFO(crtc2.vsync.wait));		handled = 1;	}	return;}int matroxfb_enable_irq(WPMINFO int reenable) {	u_int32_t bm;		if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)		bm = 0x220;	else		bm = 0x020;	if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) {		if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq,				SA_SHIRQ, "matroxfb", MINFO)) {			clear_bit(0, &ACCESS_FBINFO(irq_flags));			return -EINVAL;		}		/* Clear any pending field interrupts */		mga_outl(M_ICLEAR, bm);		mga_outl(M_IEN, mga_inl(M_IEN) | bm);	} else if (reenable) {		u_int32_t ien;				ien = mga_inl(M_IEN);		if ((ien & bm) != bm) {			printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien);			mga_outl(M_IEN, ien | bm);		}	}	return 0;}static void matroxfb_disable_irq(WPMINFO2) {	if (test_and_clear_bit(0, &ACCESS_FBINFO(irq_flags))) {		/* Flush pending pan-at-vbl request... */		matroxfb_crtc1_panpos(PMINFO2);		if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)			mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220);		else			mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20);		free_irq(ACCESS_FBINFO(pcidev)->irq, MINFO);	}}#ifndef wait_event_interruptible_timeout#define __wait_event_interruptible_timeout(wq, condition, ret)		\do {									\	wait_queue_t __wait;						\	init_waitqueue_entry(&__wait, current);				\									\	add_wait_queue(&wq, &__wait);					\	for (;;) {							\		set_current_state(TASK_INTERRUPTIBLE);			\		if (condition)						\			break;						\		if (!signal_pending(current)) {				\			ret = schedule_timeout(ret);			\			if (!ret)					\				break;					\			continue;					\		}							\		ret = -ERESTARTSYS;					\		break;							\	}								\	current->state = TASK_RUNNING;					\	remove_wait_queue(&wq, &__wait);				\} while (0)#define wait_event_interruptible_timeout(wq, condition, timeout)	\({									\	long __ret = timeout;						\	if (!(condition))						\		__wait_event_interruptible_timeout(wq, condition, __ret); \	__ret;								\})#endifint matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {	wait_queue_t __wait;	struct matrox_vsync *vs;	unsigned int cnt;	int ret;	switch (crtc) {		case 0:			vs = &ACCESS_FBINFO(crtc1.vsync);			break;		case 1:			if (ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG400) {				return -ENODEV;			}			vs = &ACCESS_FBINFO(crtc2.vsync);			break;		default:			return -ENODEV;	}	ret = matroxfb_enable_irq(PMINFO 0);	if (ret) {		return ret;	}        init_waitqueue_entry(&__wait, current);	cnt = vs->cnt;	ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10);	if (ret < 0) {		return ret;	}	if (ret == 0) {		matroxfb_enable_irq(PMINFO 1);		return -ETIMEDOUT;	}	return 0;}/* --------------------------------------------------------------------- */static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {	unsigned int pos;	unsigned short p0, p1, p2;#ifdef CONFIG_FB_MATROX_32MB	unsigned int p3;#endif	struct display *disp;	int vbl;	unsigned long flags;	CRITFLAGS	DBG("matrox_pan_var")	if (ACCESS_FBINFO(dead))		return;	disp = ACCESS_FBINFO(currcon_display);	if (disp->type == FB_TYPE_TEXT) {		pos = var->yoffset / fontheight(disp) * disp->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(disp)?fontwidth(disp):8);	} else {		pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;		pos += ACCESS_FBINFO(curr.ydstorg.chunks);	}	p0 = ACCESS_FBINFO(hw).CRTC[0x0D] = pos & 0xFF;	p1 = ACCESS_FBINFO(hw).CRTC[0x0C] = (pos & 0xFF00) >> 8;	p2 = ACCESS_FBINFO(hw).CRTCEXT[0] = (ACCESS_FBINFO(hw).CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);#ifdef CONFIG_FB_MATROX_32MB	p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21;#endif	/* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */	vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(PMINFO 0) == 0);	CRITBEGIN	matroxfb_DAC_lock_irqsave(flags);	mga_setr(M_CRTC_INDEX, 0x0D, p0);	mga_setr(M_CRTC_INDEX, 0x0C, p1);#ifdef CONFIG_FB_MATROX_32MB	if (ACCESS_FBINFO(devflags.support32MB))		mga_setr(M_EXTVGA_INDEX, 0x08, p3);#endif	if (vbl) {		ACCESS_FBINFO(crtc1.panpos) = p2;	} else {		/* Abort any pending change */		ACCESS_FBINFO(crtc1.panpos) = -1;		mga_setr(M_EXTVGA_INDEX, 0x00, p2);	}	matroxfb_DAC_unlock_irqrestore(flags);	CRITEND}static void matroxfb_remove(WPMINFO int dummy) {	/* Currently we are holding big kernel lock on all dead & usecount updates.	 * Destroy everything after all users release it. Especially do not unregister	 * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check	 * for device unplugged when in use.	 * In future we should point mmio.vbase & video.vbase somewhere where we can	 * write data without causing too much damage...	 */	ACCESS_FBINFO(dead) = 1;	if (ACCESS_FBINFO(usecount)) {		/* destroy it later */		return;	}	matroxfb_unregister_device(MINFO);	unregister_framebuffer(&ACCESS_FBINFO(fbcon));	matroxfb_g450_shutdown(PMINFO2);	del_timer_sync(&ACCESS_FBINFO(cursor.timer));#ifdef CONFIG_MTRR	if (ACCESS_FBINFO(mtrr.vram_valid))		mtrr_del(ACCESS_FBINFO(mtrr.vram), ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len));#endif	mga_iounmap(ACCESS_FBINFO(mmio.vbase));	mga_iounmap(ACCESS_FBINFO(video.vbase));	release_mem_region(ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len_maximum));	release_mem_region(ACCESS_FBINFO(mmio.base), 16384);#ifdef CONFIG_FB_MATROX_MULTIHEAD	kfree(ACCESS_FBINFO(fbcon.disp));	kfree(minfo);#endif}	/*	 * Open/Release the frame buffer device	 */static int matroxfb_open(struct fb_info *info, int user){	MINFO_FROM_INFO(info);		DBG_LOOP(__FUNCTION__)  	if (ACCESS_FBINFO(dead)) { 		return -ENXIO; 	} 	ACCESS_FBINFO(usecount)++;	if (user) {		ACCESS_FBINFO(userusecount)++;	}	return 0;}static int matroxfb_release(struct fb_info *info, int user){	MINFO_FROM_INFO(info);		DBG_LOOP(__FUNCTION__)	if (user) {		if (0 == --ACCESS_FBINFO(userusecount)) {			matroxfb_disable_irq(PMINFO2);		}	}	if (!(--ACCESS_FBINFO(usecount)) && ACCESS_FBINFO(dead)) {		matroxfb_remove(PMINFO 0);	}	return 0;}static int matroxfb_pan_display(struct fb_var_screeninfo *var, int con,		struct fb_info* info) {	struct display* dsp;	MINFO_FROM_INFO(info);	DBG("matroxfb_pan_display")	if (con < 0) {

⌨️ 快捷键说明

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