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

📄 savagefb_driver.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* This function is used to debug, it prints out the contents of s3 regs */static void SavagePrintRegs(struct savagefb_par *par){	unsigned char i;	int vgaCRIndex = 0x3d4;	int vgaCRReg = 0x3d5;	printk(KERN_DEBUG "SR    x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE "	       "xF");	for (i = 0; i < 0x70; i++) {		if (!(i % 16))			printk(KERN_DEBUG "\nSR%xx ", i >> 4);		vga_out8(0x3c4, i, par);		printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par));	}	printk(KERN_DEBUG "\n\nCR    x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "	       "xD xE xF");	for (i = 0; i < 0xB7; i++) {		if (!(i % 16))			printk(KERN_DEBUG "\nCR%xx ", i >> 4);		vga_out8(vgaCRIndex, i, par);		printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par));	}	printk(KERN_DEBUG "\n\n");}#endif/* --------------------------------------------------------------------- */static void savage_get_default_par(struct savagefb_par *par, struct savage_reg *reg){	unsigned char cr3a, cr53, cr66;	vga_out16(0x3d4, 0x4838, par);	vga_out16(0x3d4, 0xa039, par);	vga_out16(0x3c4, 0x0608, par);	vga_out8(0x3d4, 0x66, par);	cr66 = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr66 | 0x80, par);	vga_out8(0x3d4, 0x3a, par);	cr3a = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr3a | 0x80, par);	vga_out8(0x3d4, 0x53, par);	cr53 = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr53 & 0x7f, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, cr66, par);	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, cr3a, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, cr66, par);	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, cr3a, par);	/* unlock extended seq regs */	vga_out8(0x3c4, 0x08, par);	reg->SR08 = vga_in8(0x3c5, par);	vga_out8(0x3c5, 0x06, par);	/* now save all the extended regs we need */	vga_out8(0x3d4, 0x31, par);	reg->CR31 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x32, par);	reg->CR32 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x34, par);	reg->CR34 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x36, par);	reg->CR36 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x3a, par);	reg->CR3A = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x40, par);	reg->CR40 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x42, par);	reg->CR42 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x45, par);	reg->CR45 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x50, par);	reg->CR50 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x51, par);	reg->CR51 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x53, par);	reg->CR53 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x58, par);	reg->CR58 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x60, par);	reg->CR60 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x66, par);	reg->CR66 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x67, par);	reg->CR67 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x68, par);	reg->CR68 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x69, par);	reg->CR69 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x6f, par);	reg->CR6F = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x33, par);	reg->CR33 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x86, par);	reg->CR86 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x88, par);	reg->CR88 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x90, par);	reg->CR90 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x91, par);	reg->CR91 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0xb0, par);	reg->CRB0 = vga_in8(0x3d5, par) | 0x80;	/* extended mode timing regs */	vga_out8(0x3d4, 0x3b, par);	reg->CR3B = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x3c, par);	reg->CR3C = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x43, par);	reg->CR43 = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x5d, par);	reg->CR5D = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x5e, par);	reg->CR5E = vga_in8(0x3d5, par);	vga_out8(0x3d4, 0x65, par);	reg->CR65 = vga_in8(0x3d5, par);	/* save seq extended regs for DCLK PLL programming */	vga_out8(0x3c4, 0x0e, par);	reg->SR0E = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x0f, par);	reg->SR0F = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x10, par);	reg->SR10 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x11, par);	reg->SR11 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x12, par);	reg->SR12 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x13, par);	reg->SR13 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x29, par);	reg->SR29 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x15, par);	reg->SR15 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x30, par);	reg->SR30 = vga_in8(0x3c5, par);	vga_out8(0x3c4, 0x18, par);	reg->SR18 = vga_in8(0x3c5, par);	/* Save flat panel expansion regsters. */	if (par->chip == S3_SAVAGE_MX) {		int i;		for (i = 0; i < 8; i++) {			vga_out8(0x3c4, 0x54+i, par);			reg->SR54[i] = vga_in8(0x3c5, par);		}	}	vga_out8(0x3d4, 0x66, par);	cr66 = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr66 | 0x80, par);	vga_out8(0x3d4, 0x3a, par);	cr3a = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr3a | 0x80, par);	/* now save MIU regs */	if (par->chip != S3_SAVAGE_MX) {		reg->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);		reg->MMPR1 = savage_in32(MIU_CONTROL_REG, par);		reg->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);		reg->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);	}	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, cr3a, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, cr66, par);}static void savage_set_default_par(struct savagefb_par *par,				struct savage_reg *reg){	unsigned char cr3a, cr53, cr66;	vga_out16(0x3d4, 0x4838, par);	vga_out16(0x3d4, 0xa039, par);	vga_out16(0x3c4, 0x0608, par);	vga_out8(0x3d4, 0x66, par);	cr66 = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr66 | 0x80, par);	vga_out8(0x3d4, 0x3a, par);	cr3a = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr3a | 0x80, par);	vga_out8(0x3d4, 0x53, par);	cr53 = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr53 & 0x7f, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, cr66, par);	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, cr3a, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, cr66, par);	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, cr3a, par);	/* unlock extended seq regs */	vga_out8(0x3c4, 0x08, par);	vga_out8(0x3c5, reg->SR08, par);	vga_out8(0x3c5, 0x06, par);	/* now restore all the extended regs we need */	vga_out8(0x3d4, 0x31, par);	vga_out8(0x3d5, reg->CR31, par);	vga_out8(0x3d4, 0x32, par);	vga_out8(0x3d5, reg->CR32, par);	vga_out8(0x3d4, 0x34, par);	vga_out8(0x3d5, reg->CR34, par);	vga_out8(0x3d4, 0x36, par);	vga_out8(0x3d5,reg->CR36, par);	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, reg->CR3A, par);	vga_out8(0x3d4, 0x40, par);	vga_out8(0x3d5, reg->CR40, par);	vga_out8(0x3d4, 0x42, par);	vga_out8(0x3d5, reg->CR42, par);	vga_out8(0x3d4, 0x45, par);	vga_out8(0x3d5, reg->CR45, par);	vga_out8(0x3d4, 0x50, par);	vga_out8(0x3d5, reg->CR50, par);	vga_out8(0x3d4, 0x51, par);	vga_out8(0x3d5, reg->CR51, par);	vga_out8(0x3d4, 0x53, par);	vga_out8(0x3d5, reg->CR53, par);	vga_out8(0x3d4, 0x58, par);	vga_out8(0x3d5, reg->CR58, par);	vga_out8(0x3d4, 0x60, par);	vga_out8(0x3d5, reg->CR60, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, reg->CR66, par);	vga_out8(0x3d4, 0x67, par);	vga_out8(0x3d5, reg->CR67, par);	vga_out8(0x3d4, 0x68, par);	vga_out8(0x3d5, reg->CR68, par);	vga_out8(0x3d4, 0x69, par);	vga_out8(0x3d5, reg->CR69, par);	vga_out8(0x3d4, 0x6f, par);	vga_out8(0x3d5, reg->CR6F, par);	vga_out8(0x3d4, 0x33, par);	vga_out8(0x3d5, reg->CR33, par);	vga_out8(0x3d4, 0x86, par);	vga_out8(0x3d5, reg->CR86, par);	vga_out8(0x3d4, 0x88, par);	vga_out8(0x3d5, reg->CR88, par);	vga_out8(0x3d4, 0x90, par);	vga_out8(0x3d5, reg->CR90, par);	vga_out8(0x3d4, 0x91, par);	vga_out8(0x3d5, reg->CR91, par);	vga_out8(0x3d4, 0xb0, par);	vga_out8(0x3d5, reg->CRB0, par);	/* extended mode timing regs */	vga_out8(0x3d4, 0x3b, par);	vga_out8(0x3d5, reg->CR3B, par);	vga_out8(0x3d4, 0x3c, par);	vga_out8(0x3d5, reg->CR3C, par);	vga_out8(0x3d4, 0x43, par);	vga_out8(0x3d5, reg->CR43, par);	vga_out8(0x3d4, 0x5d, par);	vga_out8(0x3d5, reg->CR5D, par);	vga_out8(0x3d4, 0x5e, par);	vga_out8(0x3d5, reg->CR5E, par);	vga_out8(0x3d4, 0x65, par);	vga_out8(0x3d5, reg->CR65, par);	/* save seq extended regs for DCLK PLL programming */	vga_out8(0x3c4, 0x0e, par);	vga_out8(0x3c5, reg->SR0E, par);	vga_out8(0x3c4, 0x0f, par);	vga_out8(0x3c5, reg->SR0F, par);	vga_out8(0x3c4, 0x10, par);	vga_out8(0x3c5, reg->SR10, par);	vga_out8(0x3c4, 0x11, par);	vga_out8(0x3c5, reg->SR11, par);	vga_out8(0x3c4, 0x12, par);	vga_out8(0x3c5, reg->SR12, par);	vga_out8(0x3c4, 0x13, par);	vga_out8(0x3c5, reg->SR13, par);	vga_out8(0x3c4, 0x29, par);	vga_out8(0x3c5, reg->SR29, par);	vga_out8(0x3c4, 0x15, par);	vga_out8(0x3c5, reg->SR15, par);	vga_out8(0x3c4, 0x30, par);	vga_out8(0x3c5, reg->SR30, par);	vga_out8(0x3c4, 0x18, par);	vga_out8(0x3c5, reg->SR18, par);	/* Save flat panel expansion regsters. */	if (par->chip == S3_SAVAGE_MX) {		int i;		for (i = 0; i < 8; i++) {			vga_out8(0x3c4, 0x54+i, par);			vga_out8(0x3c5, reg->SR54[i], par);		}	}	vga_out8(0x3d4, 0x66, par);	cr66 = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr66 | 0x80, par);	vga_out8(0x3d4, 0x3a, par);	cr3a = vga_in8(0x3d5, par);	vga_out8(0x3d5, cr3a | 0x80, par);	/* now save MIU regs */	if (par->chip != S3_SAVAGE_MX) {		savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par);		savage_out32(MIU_CONTROL_REG, reg->MMPR1, par);		savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par);		savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par);	}	vga_out8(0x3d4, 0x3a, par);	vga_out8(0x3d5, cr3a, par);	vga_out8(0x3d4, 0x66, par);	vga_out8(0x3d5, cr66, par);}static void savage_update_var(struct fb_var_screeninfo *var,			      const struct fb_videomode *modedb){	var->xres = var->xres_virtual = modedb->xres;	var->yres = modedb->yres;        if (var->yres_virtual < var->yres)	    var->yres_virtual = var->yres;        var->xoffset = var->yoffset = 0;        var->pixclock = modedb->pixclock;        var->left_margin = modedb->left_margin;        var->right_margin = modedb->right_margin;        var->upper_margin = modedb->upper_margin;        var->lower_margin = modedb->lower_margin;        var->hsync_len = modedb->hsync_len;        var->vsync_len = modedb->vsync_len;        var->sync = modedb->sync;        var->vmode = modedb->vmode;}static int savagefb_check_var(struct fb_var_screeninfo   *var,			      struct fb_info *info){	struct savagefb_par *par = info->par;	int memlen, vramlen, mode_valid = 0;	DBG("savagefb_check_var");	var->transp.offset = 0;	var->transp.length = 0;	switch (var->bits_per_pixel) {	case 8:		var->red.offset = var->green.offset =			var->blue.offset = 0;		var->red.length = var->green.length =			var->blue.length = var->bits_per_pixel;		break;	case 16:		var->red.offset = 11;		var->red.length = 5;		var->green.offset = 5;		var->green.length = 6;		var->blue.offset = 0;		var->blue.length = 5;		break;	case 32:		var->transp.offset = 24;		var->transp.length = 8;		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		break;	default:		return -EINVAL;	}	if (!info->monspecs.hfmax || !info->monspecs.vfmax ||	    !info->monspecs.dclkmax || !fb_validate_mode(var, info))		mode_valid = 1;	/* calculate modeline if supported by monitor */	if (!mode_valid && info->monspecs.gtf) {		if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))			mode_valid = 1;	}	if (!mode_valid) {		const struct fb_videomode *mode;		mode = fb_find_best_mode(var, &info->modelist);		if (mode) {			savage_update_var(var, mode);			mode_valid = 1;		}	}	if (!mode_valid && info->monspecs.modedb_len)		return -EINVAL;	/* Is the mode larger than the LCD panel? */	if (par->SavagePanelWidth &&	    (var->xres > par->SavagePanelWidth ||	     var->yres > par->SavagePanelHeight)) {		printk(KERN_INFO "Mode (%dx%d) larger than the LCD panel "		       "(%dx%d)\n", var->xres,  var->yres,		       par->SavagePanelWidth,		       par->SavagePanelHeight);		return -1;	}	if (var->yres_virtual < var->yres)		var->yres_virtual = var->yres;	if (var->xres_virtual < var->xres)		var->xres_virtual = var->xres;	vramlen = info->fix.smem_len;	memlen = var->xres_virtual * var->bits_per_pixel *		var->yres_virtual / 8;	if (memlen > vramlen) {		var->yres_virtual = vramlen * 8 /			(var->xres_virtual * var->bits_per_pixel);		memlen = var->xres_virtual * var->bits_per_pixel *			var->yres_virtual / 8;	}	/* we must round yres/xres down, we already rounded y/xres_virtual up	   if it was possible. We should return -EINVAL, but I disagree */	if (var->yres_virtual < var->yres)		var->yres = var->yres_virtual;	if (var->xres_virtual < var->xres)		var->xres = var->xres_virtual;	if (var->xoffset + var->xres > var->xres_virtual)		var->xoffset = var->xres_virtual - var->xres;	if (var->yoffset + var->yres > var->yres_virtual)		var->yoffset = var->yres_virtual - var->yres;	return 0;}static int savagefb_decode_var(struct fb_var_screeninfo   *var,			       struct savagefb_par        *par,			       struct savage_reg          *reg){	struct xtimings timings;	int width, dclk, i, j; /*, refresh; */	unsigned int m, n, r;	unsigned char tmp = 0;	unsigned int pixclock = var->pixclock;	DBG("savagefb_decode_var");	memset(&timings, 0, sizeof(timings));	if (!pixclock) pixclock = 10000;	/* 10ns = 100MHz */	timings.Clock = 1000000000 / pixclock;	if (timings.Clock < 1) timings.Clock = 1;	timings.dblscan = var->vmode & FB_VMODE_DOUBLE;	timings.interlaced = var->vmode & FB_VMODE_INTERLACED;	timings.HDisplay = var->xres;	timings.HSyncStart = timings.HDisplay + var->right_margin;	timings.HSyncEnd = timings.HSyncStart + var->hsync_len;	timings.HTotal = timings.HSyncEnd + var->left_margin;	timings.VDisplay = var->yres;	timings.VSyncStart = timings.VDisplay + var->lower_margin;	timings.VSyncEnd = timings.VSyncStart + var->vsync_len;	timings.VTotal = timings.VSyncEnd + var->upper_margin;	timings.sync = var->sync;	par->depth  = var->bits_per_pixel;	par->vwidth = var->xres_virtual;	if (var->bits_per_pixel == 16  &&  par->chip == S3_SAVAGE3D) {		timings.HDisplay *= 2;		timings.HSyncStart *= 2;		timings.HSyncEnd *= 2;		timings.HTotal *= 2;	}	/*	 * This will allocate the datastructure and initialize all of the	 * generic VGA registers.	 */	vgaHWInit(var, par, &timings, reg);

⌨️ 快捷键说明

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