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

📄 sis_main.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 5 页
字号:
static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,                           unsigned transp, struct fb_info *fb_info){	if (regno >= ivideo.video_cmap_len)		return 1;	sis_palette[regno].red = red;	sis_palette[regno].green = green;	sis_palette[regno].blue = blue;	switch (ivideo.video_bpp) {#ifdef FBCON_HAS_CFB8	case 8:	        outSISREG(SISDACA, regno);		outSISREG(SISDACD, (red >> 10));		outSISREG(SISDACD, (green >> 10));		outSISREG(SISDACD, (blue >> 10));		if (ivideo.disp_state & DISPTYPE_DISP2) {		        outSISREG(SISDAC2A, regno);			outSISREG(SISDAC2D, (red >> 8));			outSISREG(SISDAC2D, (green >> 8));			outSISREG(SISDAC2D, (blue >> 8));		}		break;#endif#ifdef FBCON_HAS_CFB16	case 15:	case 16:		sis_fbcon_cmap.cfb16[regno] =		    ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);		break;#endif#ifdef FBCON_HAS_CFB24	case 24:		red >>= 8;		green >>= 8;		blue >>= 8;		sis_fbcon_cmap.cfb24[regno] = (red << 16) | (green << 8) | (blue);		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		red >>= 8;		green >>= 8;		blue >>= 8;		sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);		break;#endif	}	return 0;}static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,		      struct fb_info *info){	unsigned int htotal =		var->left_margin + var->xres + var->right_margin +		var->hsync_len;	unsigned int vtotal = 0; /* TW */	/*	var->upper_margin + var->yres + var->lower_margin +		var->vsync_len;     */	double drate = 0, hrate = 0;	int found_mode = 0;	int old_mode;	TWDEBUG("Inside do_set_var");	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {		vtotal = var->upper_margin + var->yres + var->lower_margin +		         var->vsync_len;   /* TW */		vtotal <<= 1;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {		vtotal = var->upper_margin + var->yres + var->lower_margin +		         var->vsync_len;   /* TW */		vtotal <<= 2;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +		         var->vsync_len;   /* TW */		/* var->yres <<= 1; */ /* TW */	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +		         var->vsync_len;	if(!(htotal) || !(vtotal)) {		DPRINTK("sisfb: Invalid 'var' information\n");		return -EINVAL;	}	drate = 1E12 / var->pixclock;	hrate = drate / htotal;	ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */	if((var->xres == 1024) && (var->yres == 600)) ivideo.refresh_rate = 60;	printk("sisfb: Change mode to %dx%dx%d-%dHz\n",		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);	old_mode = sisfb_mode_idx;	sisfb_mode_idx = 0;	while( (sisbios_mode[sisfb_mode_idx].mode_no != 0) &&	       (sisbios_mode[sisfb_mode_idx].xres <= var->xres) ) {		if( (sisbios_mode[sisfb_mode_idx].xres == var->xres) &&		    (sisbios_mode[sisfb_mode_idx].yres == var->yres) &&		    (sisbios_mode[sisfb_mode_idx].bpp == var->bits_per_pixel)) {			sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;			found_mode = 1;			break;		}		sisfb_mode_idx++;	}	if(found_mode)		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);	else		sisfb_mode_idx = -1;       	if(sisfb_mode_idx < 0) {		printk("sisfb: Mode %dx%dx%d not supported\n", var->xres,		       var->yres, var->bits_per_pixel);		sisfb_mode_idx = old_mode;		return -EINVAL;	}	if(sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;		ivideo.refresh_rate = 60;	}#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {#else	if(isactive) {#endif		sisfb_pre_setmode();		if(SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {			printk("sisfb: Setting mode[0x%x] failed\n", sisfb_mode_no);			return -EINVAL;		}		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);		sisfb_post_setmode();		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n",			sisbios_mode[sisfb_mode_idx].xres,			sisbios_mode[sisfb_mode_idx].yres,			sisbios_mode[sisfb_mode_idx].bpp,			ivideo.refresh_rate);		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;		ivideo.org_x = ivideo.org_y = 0;		ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);		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 accel depth %d", ivideo.video_bpp);			break;    		}	}	TWDEBUG("End of do_set_var");	return 0;}/* ------ Internal functions only for 2.4 series ------- */#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)static void sisfb_set_disp(int con, struct fb_var_screeninfo *var,                           struct fb_info *info){	struct fb_fix_screeninfo fix;	long   flags;	struct display *display;	struct display_switch *sw;	if(con >= 0)		display = &fb_display[con];	else		display = &sis_disp;	sisfb_get_fix(&fix, con, 0);#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)	display->screen_base = ivideo.video_vbase;#endif	display->visual = fix.visual;	display->type = fix.type;	display->type_aux = fix.type_aux;	display->ypanstep = fix.ypanstep;	display->ywrapstep = fix.ywrapstep;	display->line_length = fix.line_length;	display->next_line = fix.line_length;	display->can_soft_blank = 0;	display->inverse = sisfb_inverse;	display->var = *var;	save_flags(flags);	switch (ivideo.video_bpp) {#ifdef FBCON_HAS_CFB8	   case 8:#ifdef SISFBACCEL		sw = sisfb_accel ? &fbcon_sis8 : &fbcon_cfb8;#else		sw = &fbcon_cfb8;#endif		break;#endif#ifdef FBCON_HAS_CFB16	   case 15:	   case 16:#ifdef SISFBACCEL		sw = sisfb_accel ? &fbcon_sis16 : &fbcon_cfb16;#else		sw = &fbcon_cfb16;#endif		display->dispsw_data = sis_fbcon_cmap.cfb16;		break;#endif#ifdef FBCON_HAS_CFB24	   case 24:		sw = &fbcon_cfb24;		display->dispsw_data = sis_fbcon_cmap.cfb24;		break;#endif#ifdef FBCON_HAS_CFB32	   case 32:#ifdef SISFBACCEL		sw = sisfb_accel ? &fbcon_sis32 : &fbcon_cfb32;#else		sw = &fbcon_cfb32;#endif		display->dispsw_data = sis_fbcon_cmap.cfb32;		break;#endif	   default:		sw = &fbcon_dummy;		return;	}	memcpy(&sisfb_sw, sw, sizeof(*sw));	display->dispsw = &sisfb_sw;	restore_flags(flags);#ifdef SISFB_PAN        if(sisfb_ypan) {  	    /* display->scrollmode = SCROLL_YPAN; - not defined */	} else {	    display->scrollmode = SCROLL_YREDRAW;	    sisfb_sw.bmove = fbcon_redraw_bmove;	}#else	display->scrollmode = SCROLL_YREDRAW;	sisfb_sw.bmove = fbcon_redraw_bmove;#endif}static void sisfb_do_install_cmap(int con, struct fb_info *info){#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)	if (con != info->currcon)		return;        if (fb_display[con].cmap.len)                fb_set_cmap(&fb_display[con].cmap, 1, info);        else		fb_set_cmap(fb_default_cmap(ivideo.video_cmap_len), 1, info);#else        if (con != currcon)		return;        if (fb_display[con].cmap.len)		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);        else		fb_set_cmap(fb_default_cmap(ivideo.video_cmap_len), 1,			    sisfb_setcolreg, info);#endif}#endif/* ------ functions for all series ------ */#ifdef SISFB_PANstatic void sisfb_pan_var(struct fb_var_screeninfo *var){	unsigned int base;	TWDEBUG("Inside pan_var");        base = var->yoffset * var->xres_virtual + var->xoffset;        /* calculate base bpp dep. */        switch(var->bits_per_pixel) {        case 16:        	base >>= 1;        	break;	case 32:            	break;	case 8:        default:        	base >>= 2;            	break;        }		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(sisvga_engine == SIS_315_VGA) {		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);	}        if(ivideo.disp_state & DISPTYPE_DISP2) {		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);        	outSISIDXREG(SISPART1, 0x06, (base & 0xFF));        	outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));        	outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));		if(sisvga_engine == SIS_315_VGA) {			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);		}        }	TWDEBUG("End of pan_var");}#endifstatic void sisfb_crtc_to_var(struct fb_var_screeninfo *var){	u16 VRE, VBE, VRS, VBS, VDE, VT;	u16 HRE, HBE, HRS, HBS, HDE, HT;	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;	int A, B, C, D, E, F, temp;	double hrate, drate;	TWDEBUG("Inside crtc_to_var");	inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);	if (sr_data & SIS_INTERLACED_MODE)		var->vmode = FB_VMODE_INTERLACED;	else		var->vmode = FB_VMODE_NONINTERLACED;	switch ((sr_data & 0x1C) >> 2) {	   case SIS_8BPP_COLOR_MODE:		var->bits_per_pixel = 8;		break;	   case SIS_16BPP_COLOR_MODE:		var->bits_per_pixel = 16;		break;	   case SIS_32BPP_COLOR_MODE:		var->bits_per_pixel = 32;		break;	}	switch (var->bits_per_pixel) {	   case 8:		var->red.length = 6;		var->green.length = 6;		var->blue.length = 6;		ivideo.video_cmap_len = 256;		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;		ivideo.video_cmap_len = 16;		break;	   case 24:		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 = 0;		var->transp.length = 0;		ivideo.video_cmap_len = 16;		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;		ivideo.video_cmap_len = 16;		break;	}	inSISIDXREG(SISSR, 0x0A, sr_data);        inSISIDXREG(SISCR, 0x06, cr_data);        inSISIDXREG(SISCR, 0x07, cr_data2);	VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |	     ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) << 10);	A = VT + 2;	inSISIDXREG(SISCR, 0x12, cr_data);	VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |	      ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);	E = VDE + 1;	inSISIDXREG(SISCR, 0x10, cr_data);	VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |	      ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);	F = VRS + 1 - E;	inSISIDXREG(SISCR, 0x15, cr_data);	inSISIDXREG(SISCR, 0x09, cr_data3);	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);	inSISIDXREG(SISCR, 0x16, cr_data);	VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);	temp = VBE - ((E - 1) & 511);	B = (temp > 0) ? temp : (temp + 512);	inSISIDXREG(SISCR, 0x11, cr_data);	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);	temp = VRE - ((E + F - 1) & 31);	C = (temp > 0) ? temp : (temp + 32);	D = B - F - C;        var->yres = E;#ifndef SISFB_PAN	var->yres_virtual = E;#endif	/* TW: We have to report the physical dimension to the console! */	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {		var->yres <<= 1;#ifndef SISFB_PAN		var->yres_virtual <<= 1;#endif	}	/* TW end */	var->upper_margin = D;	var->lower_margin = F;	var->vsync_len = C;	inSISIDXREG(SISSR, 0x0b, sr_data);	inSISIDXREG(SISCR, 0x00, cr_data);	HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);	A = HT + 5;	inSISIDXREG(SISCR, 0x01, cr_data);	HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);	E = HDE + 1;	inSISIDXREG(SISCR, 0x04, cr_data);	HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);	F = HRS - E - 3;	inSISIDXREG(SISCR, 0x02, cr_data);	HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);	inSISIDXREG(SISSR, 0x0c, sr_data);	inSISIDXREG(SISCR, 0x03, cr_data);	inSISIDXREG(SISCR, 0x15, cr_data2);	HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |	      ((u16) (sr_data & 0x03) << 6);	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);	temp = HBE - ((E - 1) & 255);	B = (temp > 0) ? temp : (temp + 256);	temp = HRE - ((E + F + 3) & 63);	C = (temp > 0) ? temp : (temp + 64);	D = B - F - C;

⌨️ 快捷键说明

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