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

📄 sstfb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		fb_set_cmap(			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),			1, sstfb_setcolreg, info);}static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,                           u_int *transp, struct fb_info *info){	f_ddprintk("sstfb_getcolreg\n");	if (regno >= 16) return 1;	*red    = palette[regno].red;	*green  = palette[regno].green;	*blue   = palette[regno].blue;	*transp = palette[regno].transp;	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",	            regno,*red, *green, *blue, *transp);	return 0;}static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,                           u_int transp, struct fb_info *info){	u32 col;	f_ddprintk("sstfb_setcolreg\n");	f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",	            regno, red, green, blue, transp);	if (regno >= 16) return 1;	palette[regno].red   = red;	palette[regno].green = green;	palette[regno].blue  = blue;	red    >>= (16 - disp.var.red.length);	green  >>= (16 - disp.var.green.length);	blue   >>= (16 - disp.var.blue.length);	transp >>= (16 - disp.var.transp.length);	col = (red << disp.var.red.offset)		| (green << disp.var.green.offset)		| (blue  << disp.var.blue.offset)		| (transp << disp.var.transp.offset);	switch(disp.var.bits_per_pixel) {#ifdef FBCON_HAS_CFB16	case 16:		fbcon_cmap.cfb16[regno]=(u16)col;		break;#endif#ifdef EN_24_32_BPP#ifdef FBCON_HAS_CFB24	case 24:		fbcon_cmap.cfb32[regno]=col;		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		fbcon_cmap.cfb32[regno]=col;		break;#endif#endif	default:		eprintk("bug line %d: bad depth '%u'\n",__LINE__,			disp.var.bits_per_pixel);		break;	}	f_dddprintk("bpp: %d . encoded color: %#x\n",	            disp.var.bits_per_pixel, col);	return 0;}/* set par according to var ( checks var ) */static int sstfb_decode_var (const struct fb_var_screeninfo *var,                             struct sstfb_par *par,                             const struct sstfb_info *sst_info){	int real_length;	f_dprintk("sstfb_decode_var\n");	/* Check var validity */	if ((var->xres > 1024) || (!var->xres) || (!var->xres)) {		eprintk ("Unsupported resolution %dx%d\n",		         var->xres, var->yres);		return -EINVAL;	}	if ((var->vmode & FB_VMODE_MASK) !=  FB_VMODE_NONINTERLACED) {		eprintk("Interlace non supported %#x\n",			(var->vmode & FB_VMODE_MASK));		return -EINVAL;	}	memset(par, 0, sizeof(par));	par->xDim       = var->xres;	par->hSyncOn    = var->hsync_len;	par->hSyncOff   = var->xres + var->right_margin + var->left_margin;	par->hBackPorch = var->left_margin;	par->yDim       = var->yres;	par->vSyncOn    = var->vsync_len;	par->vSyncOff   = var->yres + var->lower_margin + var->upper_margin;	par->vBackPorch = var->upper_margin;	switch (var->bits_per_pixel) {	case 0 ... 16 :		par->bpp = 16;		break;#ifdef EN_24_32_BPP	case 17 ... 24 :		par->bpp = 24;		break;	case 25 ... 32 :		par->bpp = 32;		break;#endif	default :		eprintk ("Unsupported bpp %d\n", par->bpp);		return -EINVAL;		break;	}	if (sst_info->is_voodoo2) {		/* voodoo2 has 32 pixel wide tiles , BUT stange things		 happen with odd number of tiles */		par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;	} else {		/* voodoo1 has 64 pixels wide tiles. */		par->tiles_in_X= (par->xDim + 63 ) / 64;	}	/*	 *  mem check	 */	/* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/	/* FIXME: i don't like this... looks wrong*/	real_length = par->tiles_in_X  * (sst_info->is_voodoo2 ? 32 : 64 )	              * ((par->bpp == 16) ? 2 : 4);/*shoud this function change var ? for instance with yvirt > yres  ?*/	if ((real_length * var->yres) > fb_info.video.len) {		eprintk ("Not enough video memory\n");		return -ENOMEM;	}	par->freq = PS2KHZ(var->pixclock);		/* TODO add checks for timings */	return 0;}/* sets var according to par (basicaly, sets sane values) */static int sstfb_encode_var (struct fb_var_screeninfo *var,                             const struct sstfb_par *par,                             const struct sstfb_info *sst_info){	memset(var,0,sizeof(struct fb_var_screeninfo));	var->xres           = par->xDim;	var->yres           = par->yDim;	var->xres_virtual   = par->xDim;	var->yres_virtual   = par->yDim;	var->bits_per_pixel = par->bpp;	/* {x|y}offset = 0 ; sync=0 */	var->height         = -1;	var->width          = -1;	var->pixclock       = KHZ2PS(par->freq);	var->left_margin    = par->hBackPorch;	var->right_margin   = par->hSyncOff - par->xDim - par->hBackPorch;	var->upper_margin   = par->vBackPorch;	var->lower_margin   = par->vSyncOff - par->yDim - par->vBackPorch;	var->hsync_len      = par->hSyncOn;	var->vsync_len      = par->vSyncOn;	var->vmode          = FB_VMODE_NONINTERLACED;	/*	 * correct the color bit fields	 */	/* var->{red|green|blue}.msb_right    = 0; */	switch (par->bpp) {	case 16:	/* RGB 565  LfbMode 0 */		var->red.length    = 5;		var->green.length  = 6;		var->blue.length   = 5;		var->transp.length = 0;		var->red.offset    = 11;		var->green.offset  = 5;		var->blue.offset   = 0;		var->transp.offset = 0;		break;#ifdef EN_24_32_BPP	case 24:	/* RGB 888 LfbMode 4 */	case 32:	/* ARGB 8888 LfbMode 5 */		var->red.length    = 8;		var->green.length  = 8;		var->blue.length   = 8;		var->transp.length = 0;		var->red.offset    = 16;		var->green.offset  = 8;		var->blue.offset   = 0;		var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */		break;#endif	default:		eprintk ("bug line %d: bad depth '%u'\n", __LINE__, par->bpp);		break;	}	return 0;}/* * Frame buffer API */static int sstfb_open(struct fb_info *info, int user){	f_dprintk("sstfb_open(user: %d)\n",user);	MOD_INC_USE_COUNT;	return 0;}static int sstfb_release(struct fb_info *info, int user){	f_dprintk("sstfb_release(user: %d)\n",user);	MOD_DEC_USE_COUNT;	return 0;}static int sstfb_get_fix(struct fb_fix_screeninfo *fix,                         int con, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	struct fb_var_screeninfo *var;	f_dprintk("sstfb_get_fix(con: %d)\n",con);	if (con == -1)		var = &sstfb_default;	else		var = &fb_display[con].var;	strcpy(fix->id, sst_info->info.modename);	/* lfb phys address = membase + 4Mb */	fix->smem_start  = sst_info->video.base;	fix->smem_len    = sst_info->video.len;	fix->type        = FB_TYPE_PACKED_PIXELS;	fix->visual      = FB_VISUAL_TRUECOLOR;	/*	 *   According to the specs, the linelength must be of 1024 *pixels*.	 * and the 24bpp mode is in fact a 32 bpp mode.	 */	fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ;	return 0;#undef sst_info}static int sstfb_get_var(struct fb_var_screeninfo *var,                         int con, struct fb_info *info){	f_dprintk("sstfb_get_var(con: %d)\n",con);	if (con == -1)		*var = sstfb_default;	else		*var = fb_display[con].var;	print_var(var, "var");	return 0; }static int sstfb_set_var(struct fb_var_screeninfo *var,                         int con, struct fb_info *info){#define sst_info	((struct sstfb_info *) info)		struct sstfb_par par;		struct display *display;	int err;	int old_bpp,old_xres,old_yres;	f_dprintk("sstfb_set_var(con: %d)\n",con);	f_ddprintk("xres yres vxres vyres bpp activate\n");	f_ddprintk("%-4d %-4d %-5d %-5d %-3d %#-8x\n",		 var->xres,var->yres,var->xres_virtual,var->yres_virtual,		 var->bits_per_pixel,var->activate);	if (con < 0)		display = &disp;	else		display = &fb_display[con];	err = sstfb_decode_var(var, &par, sst_info);	if (err)		return err;	sstfb_encode_var (var, &par, sst_info);		switch (var->activate & FB_ACTIVATE_MASK) {		case FB_ACTIVATE_TEST:			return 0;		case FB_ACTIVATE_NXTOPEN:		case FB_ACTIVATE_NOW:			break;		default:			return -EINVAL;	}	old_xres = display->var.xres;	old_yres = display->var.yres;	old_bpp  = display->var.bits_per_pixel;	display->var = *var;	if ((old_xres != var->xres) || (old_yres != var->yres)	    || (old_bpp != var->bits_per_pixel)) {		/* 2-3  lignes redondantes avec get_fix */		display->screen_base = (char *) sst_info->video.vbase;		display->visual = FB_VISUAL_TRUECOLOR;		display->type = FB_TYPE_PACKED_PIXELS;		display->type_aux = 0;		display->ypanstep = 0;		display->ywrapstep = 0;		display->line_length = (var->bits_per_pixel==16) ? 2048 : 4096;		display->inverse = 0;		switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB16		case 16:			display->dispsw = &fbcon_cfb16;			display->dispsw_data = fbcon_cmap.cfb16;			break;#endif#ifdef EN_24_32_BPP#if defined (FBCON_HAS_CFB24) || defined (FBCON_HAS_CFB32 )		case 24: /*24bpp non packed <=> 32 bpp */		case 32:			display->dispsw = &fbcon_cfb32;			display->dispsw_data = fbcon_cmap.cfb32;			break;#endif#endif		default:			display->dispsw = &fbcon_dummy;			break;		}		display->scrollmode = SCROLL_YREDRAW;		if (sst_info->info.changevar) {			v_dprintk("fb_info.changevar(con: %d)\n", con);			(*sst_info->info.changevar)(con);			v_dprintk("fb_info.changevar: done \n");		} else {			v_dprintk("fb_info.changevar() == NULL . \n");		}	}	if ((con <0) || (con==currcon)) {		sstfb_set_par (&par, sst_info);	}	print_var(var, "var");	print_var(&display->var, "&display->var");	if (old_bpp != var->bits_per_pixel) {	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))		return err;	    sstfb_install_cmap(con, info);	}	return 0;#undef sst_info}static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,                          int con, struct fb_info *info){	struct display *d = (con<0) ? info->disp : fb_display + con;	f_dprintk("sstfb_set_cmap\n");	f_ddprintk("con: %d, currcon: %d, d->cmap.len %d\n",		 con, currcon, d->cmap.len);	if (d->cmap.len != 16 ) {	/* or test if cmap.len == 0 ? */		int err;		err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */		if (err) return err;	}	if (con == currcon) {		return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info);	} else {		fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);	}	return 0;}static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,                          int con, struct fb_info *info){	f_dprintk("sstfb_get_cmap\n");	f_ddprintk("con %d, curcon %d, cmap.len %d\n",		 con, currcon, fb_display[con].cmap.len);	/* FIXME: check if con = -1 ? cf sstfb_set_cmap...  */	if (con == currcon)		return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info);	else if (fb_display[con].cmap.len)		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(			fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),			cmap, kspc ? 0 : 2);	return 0;}/* TODO */static int sstfb_pan_display(struct fb_var_screeninfo *var,                             int con, struct fb_info *info){	f_dprintk("sstfb_pan_display\n");	return -EINVAL;}static int sstfb_ioctl(struct inode *inode, struct file *file,                       u_int cmd, u_long arg, int con,                       struct fb_info *info){#define sst_info	((struct sstfb_info *) info)	#if (SST_DEBUG_IOCTL >0)	int i;	u_long p;	u32 tmp;	u32 fbiinit0;	struct pci_dev * sst_dev = sst_info->dev;#endif	f_dprintk("sstfb_ioctl(%x)\n", cmd);#if (SST_DEBUG_IOCTL >0)	switch (cmd) {#  if (SST_DEBUG_VAR >0)/* tmp ioctl : dumps fb_display[0-5] */	case _IO('F', 0xdb):		/* 0x46db */		f_dprintk("dumping fb_display[0-5].var\n");		for (i = 0 ; i< 6 ; i++) {			print_var(&fb_display[i].var, "var(%d)", i);		}		return 0;#  endif /* (SST_DEBUG_VAR >0) *//* fills the lfb up to *(u32*)arg */	case _IOW('F', 0xdc, u32):	/* 0x46dc */		if (*(u32*)arg > 0x400000 )			*(u32*) arg = 0x400000;		f_dprintk("filling %#x \n", *(u32*)arg);		for (p = 0 ; p < *(u32*)arg; p+=2)			writew( p >> 6 , sst_info->video.vbase + p);		return 0;/* change VGA pass_through */	case _IOW('F', 0xdd, u32):	/* 0x46dd */		f_dprintk("switch VGA pass-through\n");		pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);		pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,				       tmp | PCI_EN_INIT_WR );		fbiinit0 = sst_read (FBIINIT0);		if (* (u32*)arg) {			sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);			iprintk ( "Disabling VGA pass-through\n");		} else {			sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);			iprintk ( "Enabling VGA pass-through\n");		}		pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);		return 0;	case _IO('F', 0xde):		/* 0x46de */		f_dprintk("test color display\n");		f_ddprintk("currcon: %d, bpp %d\n",			  currcon, fb_display[currcon].var.bits_per_pixel);		memset_io(sst_info->video.vbase, 0, sst_info->video.len);	switch (fb_display[currcon].var.bits_per_pixel) {/* FIXME broken : if we call this ioctl from a tty not bound to the fb, we use its depth and not the current one ... */	       	case 16:			sstfb_test16(sst_info);			break;#  ifdef EN_24_32_BPP		case 24:		case 32:			sstfb_test32(sst_info);			break;#  endif		default:			dprintk("bug line %d: bad depth '%u'\n", __LINE__,			        fb_display[currcon].var.bits_per_pixel);			}		return 0;	}#endif /* (SST_DEBUG_IOCTL >0) */	return -EINVAL;#undef sst_info}/* * Low level routines *//* get lfb size */static int sst_get_memsize(u_long *memsize){	u32 fbbase_virt = fb_info.video.vbase;	f_dprintk("sst_get_memsize\n");	/* force memsize */	if ((mem >= 1 ) &&  (mem <= 4)) {		*memsize = (mem * 0x100000);		iprintk("supplied memsize: %#lx\n", *memsize);		return 1;	}	writel (0xdeadbeef, fbbase_virt);	writel (0xdeadbeef, fbbase_virt+0x100000);	writel (0xdeadbeef, fbbase_virt+0x200000);	f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",	           readl(fbbase_virt), readl(fbbase_virt + 0x100000),	           readl(fbbase_virt + 0x200000));

⌨️ 快捷键说明

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