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

📄 sis_main.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if(ivideo->sisvga_engine == SIS_300_VGA) {			if((ivideo->vbflags2 & VB2_30xB) &&			   (!(ivideo->vbflags2 & VB2_30xBDH))) {				setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);			}		} else if(ivideo->sisvga_engine == SIS_315_VGA) {			if((ivideo->vbflags2 & VB2_30xB) &&			   (!(ivideo->vbflags2 & VB2_30xBDH))) {				setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);			}		}	} else if(ivideo->currentvbflags & CRT2_VGA) {		if(ivideo->vbflags2 & VB2_30xB) {			setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);		}	}	return 0;}/* ------------- Callbacks from init.c/init301.c  -------------- */#ifdef CONFIG_FB_SIS_300unsigned intsisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg){   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;   u32 val = 0;   pci_read_config_dword(ivideo->nbridge, reg, &val);   return (unsigned int)val;}voidsisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg, unsigned int val){   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;   pci_write_config_dword(ivideo->nbridge, reg, (u32)val);}unsigned intsisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg){   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;   u32 val = 0;   if(!ivideo->lpcdev) return 0;   pci_read_config_dword(ivideo->lpcdev, reg, &val);   return (unsigned int)val;}#endif#ifdef CONFIG_FB_SIS_315voidsisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg, unsigned char val){   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;   pci_write_config_byte(ivideo->nbridge, reg, (u8)val);}unsigned intsisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg){   struct sis_video_info *ivideo = (struct sis_video_info *)SiS_Pr->ivideo;   u16 val = 0;   if(!ivideo->lpcdev) return 0;   pci_read_config_word(ivideo->lpcdev, reg, &val);   return (unsigned int)val;}#endif/* ----------- FBDev related routines for all series ----------- */static intsisfb_get_cmap_len(const struct fb_var_screeninfo *var){	return (var->bits_per_pixel == 8) ? 256 : 16;}static voidsisfb_set_vparms(struct sis_video_info *ivideo){	switch(ivideo->video_bpp) {	case 8:		ivideo->DstColor = 0x0000;		ivideo->SiS310_AccelDepth = 0x00000000;		ivideo->video_cmap_len = 256;		break;	case 16:		ivideo->DstColor = 0x8000;		ivideo->SiS310_AccelDepth = 0x00010000;		ivideo->video_cmap_len = 16;		break;	case 32:		ivideo->DstColor = 0xC000;		ivideo->SiS310_AccelDepth = 0x00020000;		ivideo->video_cmap_len = 16;		break;	default:		ivideo->video_cmap_len = 16;		printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);		ivideo->accel = 0;	}}static intsisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	int maxyres = ivideo->sisfb_mem / (var->xres_virtual * (var->bits_per_pixel >> 3));	if(maxyres > 32767) maxyres = 32767;	return maxyres;}static voidsisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	ivideo->video_linelength = var->xres_virtual * (var->bits_per_pixel >> 3);	ivideo->scrnpitchCRT1 = ivideo->video_linelength;	if(!(ivideo->currentvbflags & CRT1_LCDA)) {		if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {			ivideo->scrnpitchCRT1 <<= 1;		}	}}static voidsisfb_set_pitch(struct sis_video_info *ivideo){	bool isslavemode = false;	unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;	unsigned short HDisplay2 = ivideo->video_linelength >> 3;	if(sisfb_bridgeisslave(ivideo)) isslavemode = true;	/* We need to set pitch for CRT1 if bridge is in slave mode, too */	if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {		outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));		setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));	}	/* We must not set the pitch for CRT2 if bridge is in slave mode */	if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {		orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);		outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));		setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));	}}static voidsisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	ivideo->video_cmap_len = sisfb_get_cmap_len(var);	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 = 6;		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;		var->transp.offset = 0;		var->transp.length = 0;		break;	case 32:		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.offset = 24;		var->transp.length = 8;		break;	}}static intsisfb_set_mode(struct sis_video_info *ivideo, int clrscrn){	unsigned short modeno = ivideo->mode_no;	/* >=2.6.12's fbcon clears the screen anyway */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)	if(!clrscrn) modeno |= 0x80;#else	modeno |= 0x80;#endif	outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);	sisfb_pre_setmode(ivideo);	if(!SiSSetMode(&ivideo->SiS_Pr, modeno)) {		printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);		return -EINVAL;	}	outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);	sisfb_post_setmode(ivideo);	return 0;}static intsisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	unsigned int htotal = 0, vtotal = 0;	unsigned int drate = 0, hrate = 0;	int found_mode = 0, ret;	int old_mode;	u32 pixclock;	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;	pixclock = var->pixclock;	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {		vtotal += var->yres;		vtotal <<= 1;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {		vtotal += var->yres;		vtotal <<= 2;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {		vtotal += var->yres;		vtotal <<= 1;	} else 	vtotal += var->yres;	if(!(htotal) || !(vtotal)) {		DPRINTK("sisfb: Invalid 'var' information\n");		return -EINVAL;	}	if(pixclock && htotal && vtotal) {		drate = 1000000000 / pixclock;		hrate = (drate * 1000) / htotal;		ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);	} else {		ivideo->refresh_rate = 60;	}	old_mode = ivideo->sisfb_mode_idx;	ivideo->sisfb_mode_idx = 0;	while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) &&	       (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) {		if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) &&		    (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) &&		    (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) {			ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];			found_mode = 1;			break;		}		ivideo->sisfb_mode_idx++;	}	if(found_mode) {		ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,				ivideo->sisfb_mode_idx, ivideo->currentvbflags);	} else {		ivideo->sisfb_mode_idx = -1;	}       	if(ivideo->sisfb_mode_idx < 0) {		printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,		       var->yres, var->bits_per_pixel);		ivideo->sisfb_mode_idx = old_mode;		return -EINVAL;	}	ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];	if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {		ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;		ivideo->refresh_rate = 60;	}	if(isactive) {		/* If acceleration to be used? Need to know		 * before pre/post_set_mode()		 */		ivideo->accel = 0;#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)#ifdef STUPID_ACCELF_TEXT_SHIT		if(var->accel_flags & FB_ACCELF_TEXT) {			info->flags &= ~FBINFO_HWACCEL_DISABLED;		} else {			info->flags |= FBINFO_HWACCEL_DISABLED;		}#endif		if(!(info->flags & FBINFO_HWACCEL_DISABLED)) ivideo->accel = -1;#else		if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;#endif		if((ret = sisfb_set_mode(ivideo, 1))) {			return ret;		}		ivideo->video_bpp    = sisbios_mode[ivideo->sisfb_mode_idx].bpp;		ivideo->video_width  = sisbios_mode[ivideo->sisfb_mode_idx].xres;		ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;		sisfb_calc_pitch(ivideo, var);		sisfb_set_pitch(ivideo);		sisfb_set_vparms(ivideo);		ivideo->current_width = ivideo->video_width;		ivideo->current_height = ivideo->video_height;		ivideo->current_bpp = ivideo->video_bpp;		ivideo->current_htotal = htotal;		ivideo->current_vtotal = vtotal;		ivideo->current_linelength = ivideo->video_linelength;		ivideo->current_pixclock = var->pixclock;		ivideo->current_refresh_rate = ivideo->refresh_rate;		ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;	}	return 0;}static voidsisfb_set_base_CRT1(struct sis_video_info *ivideo, unsigned int base){	outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);	outSISIDXREG(SISCR, 0x0D, base & 0xFF);	outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);	outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);	if(ivideo->sisvga_engine == SIS_315_VGA) {		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);	}}static voidsisfb_set_base_CRT2(struct sis_video_info *ivideo, unsigned int base){	if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {		orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);		outSISIDXREG(SISPART1, 0x06, (base & 0xFF));		outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));		outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));		if(ivideo->sisvga_engine == SIS_315_VGA) {			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);		}	}}static intsisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	if(var->xoffset > (var->xres_virtual - var->xres)) {		return -EINVAL;	}	if(var->yoffset > (var->yres_virtual - var->yres)) {		return -EINVAL;	}	ivideo->current_base = (var->yoffset * var->xres_virtual) + var->xoffset;	/* calculate base bpp dep. */	switch(var->bits_per_pixel) {	case 32:		break;	case 16:		ivideo->current_base >>= 1;		break;	case 8:	default:		ivideo->current_base >>= 2;		break;	}	ivideo->current_base += (ivideo->video_offset >> 2);	sisfb_set_base_CRT1(ivideo, ivideo->current_base);	sisfb_set_base_CRT2(ivideo, ivideo->current_base);	return 0;}static intsisfb_open(struct fb_info *info, int user){	return 0;}static intsisfb_release(struct fb_info *info, int user){	return 0;}static intsisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,		unsigned transp, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	if(regno >= sisfb_get_cmap_len(&info->var))		return 1;	switch(info->var.bits_per_pixel) {	case 8:		outSISREG(SISDACA, regno);		outSISREG(SISDACD, (red >> 10));		outSISREG(SISDACD, (green >> 10));		outSISREG(SISDACD, (blue >> 10));		if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {			outSISREG(SISDAC2A, regno);			outSISREG(SISDAC2D, (red >> 8));			outSISREG(SISDAC2D, (green >> 8));			outSISREG(SISDAC2D, (blue >> 8));		}		break;	case 16:		if (regno >= 16)			break;		((u32 *)(info->pseudo_palette))[regno] =				(red & 0xf800)          |				((green & 0xfc00) >> 5) |				((blue & 0xf800) >> 11);		break;	case 32:		if (regno >= 16)			break;		red >>= 8;		green >>= 8;		blue >>= 8;		((u32 *)(info->pseudo_palette))[regno] =				(red << 16) | (green << 8) | (blue);		break;	}	return 0;}static intsisfb_set_par(struct fb_info *info){	int err;	if((err = sisfb_do_set_var(&info->var, 1, info)))		return err;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)	sisfb_get_fix(&info->fix, info->currcon, info);#else	sisfb_get_fix(&info->fix, -1, info);#endif	return 0;}static intsisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	unsigned int htotal = 0, vtotal = 0, myrateindex = 0;	unsigned int drate = 0, hrate = 0, maxyres;	int found_mode = 0;	int refresh_rate, search_idx, tidx;	bool recalc_clock = false;	u32 pixclock;	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;

⌨️ 快捷键说明

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