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

📄 g400.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Matrox G200/G400/G450 chipset driver Based on the XFree86 driver.Tested only on a G450. TODO: SDRAM, reference frequency checking.*/#include <stdlib.h>#include <stdio.h>		#include <string.h>#include <unistd.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include "timing.h"#include "vgaregs.h"#include "interface.h"#include "accel.h"#include "vgapci.h"#define SKREG_SAVE(i) (VGA_TOTAL_REGS+i)#define G400_TOTAL_REGS (VGA_TOTAL_REGS + 0x50 + 9 + 12)static void __svgalib_outpal(int i, int r, int g, int b){    outb(PEL_IW,i);    outb(PEL_D,r);    outb(PEL_D,g);    outb(PEL_D,b);}enum { ID_G100 = 0, ID_G200, ID_G400, ID_G450 };static int g400_init(int, int, int);static void g400_unlock(void);static void g400_lock(void);void __svgalib_g400accel_init(AccelSpecs * accelspecs, int bpp, int width_in_pixels);static int g400_memory, id;static int g400_is_linear, g400_linear_base, g400_mmio_base;static int HasSDRAM;static CardSpecs *cardspecs;static int g400_inExt(int i) {    *(MMIO_POINTER + 0x1fde) = i;    return *(MMIO_POINTER + 0x1fdf);}static void g400_outExt(int i, int d) {    *(unsigned short *)(MMIO_POINTER + 0x1fde) = (d<<8) | i;}static int g400_inDAC(int i) {    *(MMIO_POINTER + 0x3c00) = i;    return *(MMIO_POINTER + 0x3c0a);}static void g400_outDAC(int i, int d) {    *(MMIO_POINTER + 0x3c00) = i;    *(MMIO_POINTER + 0x3c0a) = d;}static void g400_setpage(int page){	g400_outExt(4,page);}static int __svgalib_g400_inlinearmode(void){return g400_is_linear;}/* Fill in chipset specific mode information */static void g400_getmodeinfo(int mode, vga_modeinfo *modeinfo){    if(modeinfo->colors==16)return;    modeinfo->maxpixels = g400_memory*1024/modeinfo->bytesperpixel;    modeinfo->maxlogicalwidth = 8184;    modeinfo->startaddressrange = g400_memory * 1024 - 1;    modeinfo->haveblit = 0;    modeinfo->flags &= ~HAVE_RWPAGE;    if (modeinfo->bytesperpixel >= 1) {	if(g400_linear_base)modeinfo->flags |= CAPABLE_LINEAR;        if (__svgalib_g400_inlinearmode())	    modeinfo->flags |= IS_LINEAR;    }}/* Read and save chipset-specific registers */#define PCI_CONF_ADDR  0xcf8#define PCI_CONF_DATA  0xcfc static int g400_saveregs(unsigned char regs[]){   int i;    g400_unlock();		    outl (PCI_CONF_ADDR, 0x80010000 + 0x40);    *(unsigned int *)(regs + VGA_TOTAL_REGS + 0x50 + 9 + 0 )  = inl (PCI_CONF_DATA);    outl (PCI_CONF_ADDR, 0x80010000 + 0x50);    *(unsigned int *)(regs + VGA_TOTAL_REGS + 0x50 + 9 + 4 )  = inl (PCI_CONF_DATA);    outl (PCI_CONF_ADDR, 0x80010000 + 0x54);    *(unsigned int *)(regs + VGA_TOTAL_REGS + 0x50 + 9 + 8 )  = inl (PCI_CONF_DATA);    for(i=0;i<0x50;i++) regs[VGA_TOTAL_REGS + i]=g400_inDAC(i);    for(i=0;i<9;i++) regs[VGA_TOTAL_REGS + 0x50 + i]=g400_inExt(i);    return G400_TOTAL_REGS - VGA_TOTAL_REGS;}/* Set chipset-specific registers */static void g400_setregs(const unsigned char regs[], int mode){      int i;    g400_unlock();		    for(i=0;i<0x50;i++) {#if 0        if( (i> 0x03) && (i!=0x07) && (i!=0x0b) && (i!=0x0f) &&            (i< 0x13) && (i> 0x17) && (i!=0x1b) && (i!=0x1c) &&            (i< 0x1f) && (i> 0x29) && (i< 0x30) && (i> 0x37) &&            (i!=0x39) && (i!=0x3b) && (i!=0x3f) && (i!=0x41) &&            (i!=0x43) && (i!=0x47) && (i!=0x4b)             			 				)#endif            g400_outDAC(i,regs[VGA_TOTAL_REGS + i]);    }    outl (PCI_CONF_ADDR, 0x80010000 + 0x40);    outl(PCI_CONF_DATA, *(unsigned int *)(regs + VGA_TOTAL_REGS + 0x50 + 9 ));    outl (PCI_CONF_ADDR, 0x80010000 + 0x50);    outl(PCI_CONF_DATA, *(unsigned int *)(regs + VGA_TOTAL_REGS + 0x50 + 9 + 4 ));    outl (PCI_CONF_ADDR, 0x80010000 + 0x54);    outl(PCI_CONF_DATA, *(unsigned int *)(regs + VGA_TOTAL_REGS + 0x50 + 9 + 8 ));    for(i=0;i<9;i++) g400_outExt(i, regs[VGA_TOTAL_REGS + 0x50 + i]);}/* Return nonzero if mode is available */static int g400_modeavailable(int mode){    struct info *info;    ModeTiming *modetiming;    ModeInfo *modeinfo;    if (IS_IN_STANDARD_VGA_DRIVER(mode))	return __svgalib_vga_driverspecs.modeavailable(mode);    info = &__svgalib_infotable[mode];    if (g400_memory * 1024 < info->ydim * info->xbytes)	return 0;    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);    modetiming = malloc(sizeof(ModeTiming));    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {	free(modetiming);	free(modeinfo);	return 0;    }    free(modetiming);    free(modeinfo);    return SVGADRV;}#define MGA_MIN_VCO_FREQ    120000#define MGA_MAX_VCO_FREQ    250000#define MGA_MAX_PCLK_FREQ   250000#define MGA_MAX_MCLK_FREQ   100000#define MGA_REF_FREQ        27050.0#define MGA_ALT_REF_FREQ    14318.0#define MGA_FEED_DIV_MIN    8#define MGA_FEED_DIV_MAX    127#define MGA_IN_DIV_MIN      1#define MGA_IN_DIV_MAX      30#define MGA_ALT_IN_DIV_MAX      6#define MGA_POST_DIV_MIN    0#define MGA_POST_DIV_MAX    3static doubleMGACalcClock ( long f_out, long f_max, int *m, int *n, int *p, int *s ){	int best_m=0, best_n=0;	double f_pll, f_vco;	double m_err, calc_f, base_freq;        int mga_in_div_max;	static double ref = 0.0;	switch(id) {            case ID_G400:            case ID_G450:                ref = MGA_REF_FREQ;                mga_in_div_max = MGA_IN_DIV_MAX;                mga_in_div_max = MGA_ALT_IN_DIV_MAX; /* 31 should be allowed,                   					but does not work. */                break;            case ID_G200:                ref = MGA_ALT_REF_FREQ;                mga_in_div_max = MGA_ALT_IN_DIV_MAX;                break;            default:                ref = MGA_ALT_REF_FREQ;                mga_in_div_max = MGA_ALT_IN_DIV_MAX;                break;        }	/* Make sure that f_min <= f_out <= f_max */	if ( f_out < ( MGA_MIN_VCO_FREQ / 8))		f_out = MGA_MIN_VCO_FREQ / 8;	if ( f_out > f_max )		f_out = f_max;	/*	 * f_pll = f_vco /  (2^p)	 * Choose p so that MGA_MIN_VCO_FREQ   <= f_vco <= MGA_MAX_VCO_FREQ  	 * we don't have to bother checking for this maximum limit.	 */	f_vco = ( double ) f_out;	for ( *p = 0; *p < MGA_POST_DIV_MAX && f_vco < MGA_MIN_VCO_FREQ;								( *p )++ )		f_vco *= 2.0;	/* Initial value of calc_f for the loop */	calc_f = 0;	base_freq = ref / ( 1 << *p );	/* Initial amount of error for frequency maximum */	m_err = f_out;	/* Search for the different values of ( *m ) */	for ( *m = MGA_IN_DIV_MIN ;		*m < mga_in_div_max ; ( *m )++ )	{		/* see values of ( *n ) which we can't use */		for ( *n = MGA_FEED_DIV_MIN;			*n <= MGA_FEED_DIV_MAX; ( *n )++ )		{ 			calc_f = (base_freq * (*n)) / *m ;		/*		 * Pick the closest frequency.		 */			if (abs( calc_f - f_out ) < m_err ) {				m_err = abs(calc_f - f_out);				best_m = *m;				best_n = *n;			}		}	}		/* Now all the calculations can be completed */	f_vco = ref * best_n / best_m;	/* Adjustments for filtering pll feed back */        switch(id) {	    case ID_G450:		*s=0;		break;            case ID_G400: 	        if ( (50000.0 <= f_vco)	        && (f_vco < 110000.0) )		        *s = 0;		        if ( (110000.0 <= f_vco)	        && (f_vco < 170000.0) )		        *s = 1;		        if ( (170000.0 <= f_vco)	        && (f_vco < 240000.0) )		        *s = 2;		        if ( (240000.0 <= f_vco)	        && (f_vco < 310000.0) )		        *s = 3;	                break;            case ID_G200:	        if ( (50000.0 <= f_vco)	        && (f_vco < 100000.0) )		        *s = 0;		        if ( (100000.0 <= f_vco)	        && (f_vco < 140000.0) )		        *s = 1;		        if ( (140000.0 <= f_vco)	        && (f_vco < 180000.0) )		        *s = 2;		        if ( (180000.0 <= f_vco)	        && (f_vco < 250000.0) )		        *s = 3;	                break;        }	f_pll = f_vco / ( 1 << *p );	*m = best_m - 1;	*n = best_n - 1;	*p = ( 1 << *p ) - 1 ; 	return f_pll;}/* * MGASetPCLK - Set the pixel (PCLK) and loop (LCLK) clocks. * * PARAMETERS *   f_pll			IN	Pixel clock PLL frequencly in kHz. */static void MGASetPCLK( long f_out, unsigned char *initDAC ){	/* Pixel clock values */	int m, n, p, s;	/* The actual frequency output by the clock */	double f_pll;	long f_max;	/* Get the maximum pixel clock frequency from the BIOS,          * or from a reasonable default         */	if ( 0 )		f_max = (/*MGABios2.PclkMax+*/100) * 1000; /* [ajv - scale it] */	else		f_max = MGA_MAX_PCLK_FREQ;	/* Do the calculations for m, n, and p */	f_pll = MGACalcClock( f_out, f_max, &m, &n, &p , &s);	/* Values for the pixel clock PLL registers */	if((id == ID_G450) && (p==3))p=2;		initDAC[ 0x4c ] = ( m & 0x1f );	initDAC[ 0x4d ] = ( n & 0x7f );	initDAC[ 0x4e ] = ( (p & 0x07) | ((s & 0x3) << 3) );}static void g400_initializemode(unsigned char *moderegs,			    ModeTiming * modetiming, ModeInfo * modeinfo, int mode){ 	static unsigned char initDAC[] = {	/* 0x00: */	   0,    0,    0,    0,    0,    0, 0x00,    0,	/* 0x08: */	   0,    0,    0,    0,    0,    0,    0,    0,	/* 0x08: */	   0,    0,    0,    0,    0,    0,    0,    0,	/* 0x18: */	0x03,    0, 0x09, 0xFF, 0xBF, 0x20, 0x1F, 0x20,	/* 0x20: */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 0x28: */	0x00, 0x00, 0x00, 0x77, 0x04, 0x2D, 0x19, 0x40,	/* 0x30: */	0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,	/* 0x38: */	0x00, 0x93, 0x00, 0x77, 0x71, 0xDB, 0x02, 0x3A,	/* 0x40: */	   0,    0,    0,    0,    0,    0,    0,    0,	/* 0x48: */	   0,    0,    0,    0,    0,    0,    0,    0	};	int hd, hs, he, ht, vd, vs, ve, vt, wd;	int i;	int weight555 = 0;        int MGABppShft = 0;        __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);	switch(modeinfo->bitsPerPixel)	{	case 8:		initDAC[ 0x19 ] = 0;

⌨️ 快捷键说明

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