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

📄 matroxfb_g450.c

📁 上传linux-jx2410的源代码
💻 C
字号:
/* * * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450. * * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz> * * Version: 1.51 2001/01/19 * * See matroxfb_base.c for contributors. * */#include "matroxfb_g450.h"#include "matroxfb_misc.h"#include "matroxfb_DAC1064.h"#include <linux/matroxfb.h>#include <asm/uaccess.h>static int matroxfb_g450_get_reg(WPMINFO int reg) {	int val;	unsigned long flags;	matroxfb_DAC_lock_irqsave(flags);	val = matroxfb_DAC_in(PMINFO reg);	matroxfb_DAC_unlock_irqrestore(flags);	return val;}static int matroxfb_g450_set_reg(WPMINFO int reg, int val) {	unsigned long flags;	matroxfb_DAC_lock_irqsave(flags);	matroxfb_DAC_out(PMINFO reg, val);	matroxfb_DAC_unlock_irqrestore(flags);	return 0;}static const struct matrox_pll_features maven_pll = {	110000,	27000,	4, 127,	2, 31,	3};static const struct matrox_pll_features g550_pll = {	135000,	27000,	4, 127,	0, 9,	3};static void DAC1064_calcclock(unsigned int freq, unsigned int fmax,		unsigned int* in, unsigned int* feed, unsigned int* post,		unsigned int timmings) {	unsigned int fvco;	unsigned int p;	switch (timmings) {		default:			fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p);			/* 0 => 100 ... 275 MHz		           1 => 243 ... 367 MHz		           2 => 320 ... 475 MHz		           3 => 453 ... 556 MHz		           4 => 540 ... 594 MHz		           5 => 588 ... 621 MHz		           6 => 626 ... 637 MHz		           7 => 631 ... 642 MHz		           As you can see, never choose frequency > 621 MHz, there is unavailable gap...		           Just to be sure, currently driver uses 110 ... 500 MHz range.		         */			if (fvco <= 260000)				;			else if (fvco <= 350000)				p |= 0x08;			else if (fvco <= 460000)				p |= 0x10;			else if (fvco <= 550000)				p |= 0x18;			else if (fvco <= 590000)				p |= 0x20;			else				p |= 0x28;			break;		case 1:			fvco = matroxfb_PLL_calcclock(&g550_pll, freq, fmax, in, feed, &p);			/* p |= 0x00; */			break;	}	*post = p;	return;}static inline int matroxfb_g450_compute_timming(struct matroxfb_g450_info* m2info,		struct my_timming* mt,		struct mavenregs* m) {	unsigned int a, b, c;	DAC1064_calcclock(mt->pixclock, 300000, &a, &b, &c, m2info->timmings);	m->regs[0x80] = a;	m->regs[0x81] = b;	m->regs[0x82] = c;	printk(KERN_DEBUG "PLL: %02X %02X %02X\n", a, b, c);	return 0;}static inline int matroxfb_g450_program_timming(struct matroxfb_g450_info* m2info, const struct mavenregs* m) {	MINFO_FROM(m2info->primary_dev);	matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2M, m->regs[0x81]);	matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2N, m->regs[0x80]);	matroxfb_g450_set_reg(PMINFO M1064_XPIXPLL2P, m->regs[0x82]);	return 0;}/******************************************************/static int matroxfb_g450_compute(void* md, struct my_timming* mt, struct matrox_hw_state* mr) {	return matroxfb_g450_compute_timming(md, mt, &mr->maven);}static int matroxfb_g450_program(void* md, const struct matrox_hw_state* mr) {	return matroxfb_g450_program_timming(md, &mr->maven);}static int matroxfb_g450_start(void* md) {	return 0;}static void matroxfb_g450_incuse(void* md) {	MOD_INC_USE_COUNT;}static void matroxfb_g450_decuse(void* md) {	MOD_DEC_USE_COUNT;}static int matroxfb_g450_set_mode(void* md, u_int32_t arg) {	if (arg == MATROXFB_OUTPUT_MODE_MONITOR) {		return 1;	}	return -EINVAL;}static int matroxfb_g450_get_mode(void* md, u_int32_t* arg) {	*arg = MATROXFB_OUTPUT_MODE_MONITOR;	return 0;}static struct matrox_altout matroxfb_g450_altout = {	matroxfb_g450_compute,	matroxfb_g450_program,	matroxfb_g450_start,	matroxfb_g450_incuse,	matroxfb_g450_decuse,	matroxfb_g450_set_mode,	matroxfb_g450_get_mode};static int matroxfb_g450_connect(struct matroxfb_g450_info* m2info) {	MINFO_FROM(m2info->primary_dev);	down_write(&ACCESS_FBINFO(altout.lock));	ACCESS_FBINFO(altout.device) = m2info;	ACCESS_FBINFO(altout.output) = &matroxfb_g450_altout;	up_write(&ACCESS_FBINFO(altout.lock));	ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;	matroxfb_switch(ACCESS_FBINFO(currcon), (struct fb_info*)MINFO);		return 0;}static void matroxfb_g450_shutdown(struct matroxfb_g450_info* m2info) {	MINFO_FROM(m2info->primary_dev);		if (MINFO) {		ACCESS_FBINFO(output.all) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;		ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;		ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;		down_write(&ACCESS_FBINFO(altout.lock));		ACCESS_FBINFO(altout.device) = NULL;		ACCESS_FBINFO(altout.output) = NULL;		up_write(&ACCESS_FBINFO(altout.lock));		m2info->primary_dev = NULL;	}}/* we do not have __setup() yet */static void* matroxfb_g450_probe(struct matrox_fb_info* minfo) {	struct matroxfb_g450_info* m2info;	/* hardware is not G450 incapable... */	if (!ACCESS_FBINFO(devflags.g450dac))		return NULL;	m2info = (struct matroxfb_g450_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);	if (!m2info) {		printk(KERN_ERR "matroxfb_g450: Not enough memory for G450 DAC control structs\n");		return NULL;	}	memset(m2info, 0, sizeof(*m2info));	m2info->primary_dev = MINFO;	if (ACCESS_FBINFO(devflags.g550dac)) {		m2info->timmings = 1;	} else {		m2info->timmings = 0;	}	if (matroxfb_g450_connect(m2info)) {		kfree(m2info);		printk(KERN_ERR "matroxfb_g450: G450 DAC failed to initialize\n");		return NULL;	}	return m2info;}static void matroxfb_g450_remove(struct matrox_fb_info* minfo, void* g450) {	matroxfb_g450_shutdown(g450);	kfree(g450);}static struct matroxfb_driver g450 = {		name:	"Matrox G450 output #2",		probe:	matroxfb_g450_probe,		remove:	matroxfb_g450_remove };static int matroxfb_g450_init(void) {	matroxfb_register_driver(&g450);	return 0;}static void matroxfb_g450_exit(void) {	matroxfb_unregister_driver(&g450);}MODULE_AUTHOR("(c) 2000-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");MODULE_DESCRIPTION("Matrox G450 secondary output driver");MODULE_LICENSE("GPL");module_init(matroxfb_g450_init);module_exit(matroxfb_g450_exit);

⌨️ 快捷键说明

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