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

📄 pvr2fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	var->xres_virtual = par->vxres;	var->yres_virtual = par->vyres;	var->xoffset = par->xoffset;	var->yoffset = par->yoffset;	var->bits_per_pixel = par->bpp;	set_color_bitfields(var);	var->activate = FB_ACTIVATE_NOW;	var->height = -1;	var->width = -1;	var->pixclock = par->pixclock;	if (par->is_doublescan)		var->vmode = FB_VMODE_DOUBLE;	if (par->is_interlaced)		var->vmode |= FB_VMODE_INTERLACED;	else		var->vmode |= FB_VMODE_NONINTERLACED;	var->right_margin = par->borderstop_h - (par->diwstart_h + par->xres);	var->left_margin = par->diwstart_h - par->borderstart_h;	var->hsync_len = par->borderstart_h + (par->hsync_total - par->borderstop_h);	var->upper_margin = par->diwstart_v - par->borderstart_v;	var->lower_margin = par->borderstop_v - (par->diwstart_v + par->yres);	var->vsync_len = par->borderstart_v + (par->vsync_total - par->borderstop_v);	if (video_output != VO_VGA)		var->sync = FB_SYNC_BROADCAST;	if (par->vmode & FB_VMODE_YWRAP)		var->vmode |= FB_VMODE_YWRAP;		return 0;}static void pvr2_get_par(struct pvr2fb_par *par){	*par = currentpar;}/* Setup the new videomode in hardware */static void pvr2_set_var(struct fb_var_screeninfo *var){	do_vmode_pan = 0;	do_vmode_full = 0;	pvr2_decode_var(var, &currentpar);	do_vmode_full = 1;}/*  * Pan or wrap the display * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag in `var'. */static void pvr2_pan_var(struct fb_var_screeninfo *var){	struct pvr2fb_par *par = &currentpar;	par->xoffset = var->xoffset;	par->yoffset = var->yoffset;	if (var->vmode & FB_VMODE_YWRAP)		par->vmode |= FB_VMODE_YWRAP;	else		par->vmode &= ~FB_VMODE_YWRAP;	do_vmode_pan = 0;	pvr2_update_par();	do_vmode_pan = 1;}static int pvr2_update_par(void){	struct pvr2fb_par *par = &currentpar;	u_long move;	move = get_line_length(par->xoffset, par->bpp);	if (par->yoffset) {		par->disp_start += (par->next_line * par->yoffset) + move;	} else		par->disp_start += move;	return 0;}static void pvr2_update_display(void){	struct pvr2fb_par *par = &currentpar;	/* Update the start address of the display image */	ctrl_outl(par->disp_start, DISP_DIWADDRL);	ctrl_outl(par->disp_start +		  get_line_length(par->xoffset + par->xres, par->bpp),	          DISP_DIWADDRS);}/*  * Initialize the video mode.  Currently, the 16bpp and 24bpp modes aren't * very stable.  It's probably due to the fact that a lot of the 2D video * registers are still undocumented. */static void pvr2_init_display(void){	struct pvr2fb_par *par = &currentpar;	u_short diw_height, diw_width, diw_modulo = 1;	u_short bytesperpixel = par->bpp / 8;	/* hsync and vsync totals */	ctrl_outl((par->vsync_total << 16) | par->hsync_total, DISP_SYNCSIZE);	/* column height, modulo, row width */	/* since we're "panning" within vram, we need to offset things based	 * on the offset from the virtual x start to our real gfx. */	if (video_output != VO_VGA && par->is_interlaced)		diw_modulo += par->next_line / 4;	diw_height = (par->is_interlaced ? par->yres / 2 : par->yres);	diw_width = get_line_length(par->xres, par->bpp) / 4;	ctrl_outl((diw_modulo << 20) | (--diw_height << 10) | --diw_width,	          DISP_DIWSIZE);	/* display address, long and short fields */	ctrl_outl(par->disp_start, DISP_DIWADDRL);	ctrl_outl(par->disp_start +	          get_line_length(par->xoffset + par->xres, par->bpp),	          DISP_DIWADDRS);	/* border horizontal, border vertical, border color */	ctrl_outl((par->borderstart_h << 16) | par->borderstop_h, DISP_BRDRHORZ);	ctrl_outl((par->borderstart_v << 16) | par->borderstop_v, DISP_BRDRVERT);	ctrl_outl(0, DISP_BRDRCOLR);	/* display window start position */	ctrl_outl(par->diwstart_h, DISP_DIWHSTRT);	ctrl_outl((par->diwstart_v << 16) | par->diwstart_v, DISP_DIWVSTRT);		/* misc. settings */	ctrl_outl((0x16 << 16) | par->is_lowres, DISP_DIWCONF);	/* clock doubler (for VGA), scan doubler, display enable */	ctrl_outl(((video_output == VO_VGA) << 23) | 	          (par->is_doublescan << 1) | 1, DISP_DIWMODE);	/* bits per pixel */	ctrl_outl(ctrl_inl(DISP_DIWMODE) | (--bytesperpixel << 2), DISP_DIWMODE);	/* video enable, color sync, interlace, 	 * hsync and vsync polarity (currently unused) */	ctrl_outl(0x100 | ((par->is_interlaced /*|4*/) << 4), DISP_SYNCCONF);}/* Simulate blanking by making the border cover the entire screen */#define BLANK_BIT (1<<3)static void pvr2_do_blank(void){	u_long diwconf;	diwconf = ctrl_inl(DISP_DIWCONF);	if (do_blank > 0)		ctrl_outl(diwconf | BLANK_BIT, DISP_DIWCONF);	else		ctrl_outl(diwconf & ~BLANK_BIT, DISP_DIWCONF);	is_blanked = do_blank > 0 ? do_blank : 0;}static void pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp){	if (do_vmode_pan || do_vmode_full)		pvr2_update_display();	if (do_vmode_full)		pvr2_init_display();	if (do_vmode_pan)		do_vmode_pan = 0;	if (do_blank) {		pvr2_do_blank();		do_blank = 0;	}	if (do_vmode_full) {		do_vmode_full = 0;	}}/* * Determine the cable type and initialize the cable output format.  Don't do * anything if the cable type has been overidden (via "cable:XX"). */#define PCTRA 0xff80002c#define PDTRA 0xff800030#define VOUTC 0xa0702c00static int pvr2_init_cable(void){	if (cable_type < 0) {		ctrl_outl((ctrl_inl(PCTRA) & 0xfff0ffff) | 0x000a0000, 	                  PCTRA);		cable_type = (ctrl_inw(PDTRA) >> 8) & 3;	}	/* Now select the output format (either composite or other) */	/* XXX: Save the previous val first, as this reg is also AICA	  related */	if (cable_type == CT_COMPOSITE)		ctrl_outl(3 << 8, VOUTC);	else		ctrl_outl(0, VOUTC);	return cable_type;}int __init pvr2fb_init(void){	struct fb_var_screeninfo var;	u_long modememused;	if (!MACH_DREAMCAST)		return -ENXIO;	/* Make a guess at the monitor based on the attached cable */	if (pvr2_init_cable() == CT_VGA) {		fb_info.monspecs.hfmin = 30000;		fb_info.monspecs.hfmax = 70000;		fb_info.monspecs.vfmin = 60;		fb_info.monspecs.vfmax = 60;	}	else { /* Not VGA, using a TV (taken from acornfb) */		fb_info.monspecs.hfmin = 15469;		fb_info.monspecs.hfmax = 15781;		fb_info.monspecs.vfmin = 49;		fb_info.monspecs.vfmax = 51;	}	/* XXX: This needs to pull default video output via BIOS or other means */	if (video_output < 0) {		if (cable_type == CT_VGA)			video_output = VO_VGA;		else			video_output = VO_NTSC;	}		strcpy(fb_info.modename, pvr2fb_name);	fb_info.changevar = NULL;	fb_info.node = -1;	fb_info.fbops = &pvr2fb_ops;	fb_info.disp = &disp;	fb_info.switch_con = &pvr2fbcon_switch;	fb_info.updatevar = &pvr2fbcon_updatevar;	fb_info.blank = &pvr2fbcon_blank;	fb_info.flags = FBINFO_FLAG_DEFAULT;	memset(&var, 0, sizeof(var));	if (video_output == VO_VGA)		defmode = DEFMODE_VGA;	if (!fb_find_mode(&var, &fb_info, mode_option, pvr2_modedb,	                  NUM_TOTAL_MODES, &pvr2_modedb[defmode], 16)) {		return -EINVAL;	}	if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0,	                "pvr2 VBL handler", &currentpar)) {		DPRINTK("couldn't register VBL int\n");		return -EBUSY;	}#ifdef CONFIG_MTRR	if (enable_mtrr) {		mtrr_handle = mtrr_add(videomemory, videomemorysize, MTRR_TYPE_WRCOMB, 1);		printk("pvr2fb: MTRR turned on\n");	}#endif	pvr2fb_set_var(&var, -1, &fb_info);	if (register_framebuffer(&fb_info) < 0)		return -EINVAL;	modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);	modememused *= var.yres_virtual;	printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",	       GET_FB_IDX(fb_info.node), fb_info.modename, modememused>>10,	       videomemorysize>>10);	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", 	       GET_FB_IDX(fb_info.node), var.xres, var.yres, var.bits_per_pixel, 	       get_line_length(var.xres, var.bits_per_pixel),	       (char *)pvr2_get_param(cables, NULL, cable_type, 3),	       (char *)pvr2_get_param(outputs, NULL, video_output, 3));	return 0;}static void __exit pvr2fb_exit(void){#ifdef CONFIG_MTRR	if (enable_mtrr) {		mtrr_del(mtrr_handle, videomemory, videomemorysize);		printk("pvr2fb: MTRR turned off\n");	}#endif	unregister_framebuffer(&fb_info);}static int __init pvr2_get_param(const struct pvr2_params *p, const char *s,                                   int val, int size){	int i;	for (i = 0 ; i < size ; i++ ) {		if (s != NULL) {			if (!strnicmp(p[i].name, s, strlen(s)))				return p[i].val;		} else {			if (p[i].val == val)				return (int)p[i].name;		}	}	return -1;}/* * Parse command arguments.  Supported arguments are: *    inverse                             Use inverse color maps *    nomtrr                              Disable MTRR usage *    font:<fontname>                     Specify console font *    cable:composite|rgb|vga             Override the video cable type *    output:NTSC|PAL|VGA                 Override the video output format * *    <xres>x<yres>[-<bpp>][@<refresh>]   or, *    <name>[-<bpp>][@<refresh>]          Startup using this video mode */#ifndef MODULEint __init pvr2fb_setup(char *options){	char *this_opt;	char cable_arg[80];	char output_arg[80];	fb_info.fontname[0] = '\0';	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ","))) {		if (!*this_opt)			continue;		if (!strcmp(this_opt, "inverse")) {			pvr2fb_inverse = 1;			fb_invert_cmaps();		} else if (!strncmp(this_opt, "font:", 5))			strcpy(fb_info.fontname, this_opt + 5);		else if (!strncmp(this_opt, "cable:", 6))			strcpy(cable_arg, this_opt + 6);		else if (!strncmp(this_opt, "output:", 7))			strcpy(output_arg, this_opt + 7);#ifdef CONFIG_MTRR		else if (!strncmp(this_opt, "nomtrr", 6))			enable_mtrr = 0;#endif		else			mode_option = this_opt;	}	if (*cable_arg)		cable_type = pvr2_get_param(cables, cable_arg, 0, 3);	if (*output_arg)		video_output = pvr2_get_param(outputs, output_arg, 0, 3);	return 0;}#endif#ifdef MODULEMODULE_LICENSE("GPL");module_init(pvr2fb_init);#endifmodule_exit(pvr2fb_exit);

⌨️ 快捷键说明

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