omap24xxfb.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,697 行 · 第 1/4 页

C
1,697
字号
	/* set the offset of the graphics window within the framebuffer */	dispc->gfx_ba0 = info->fix.smem_start 		+ var->yoffset*info->fix.line_length 		+ (var->xoffset*info->var.bits_per_pixel)/8;	dispc->gfx_ba1 = dispc->gfx_ba0;	dispc->gfx_row_inc = 1 + info->fix.line_length 		- (info->var.xres*info->var.bits_per_pixel)/8;	dispc->gfx_pixel_inc = 1;	if (oinfo->asleep)		return 0;	/* write our updated register values to the display controller */	dispc_reg_out(oinfo, DISPC_GFX_BA0, dispc->gfx_ba0);	dispc_reg_out(oinfo, DISPC_GFX_BA1, dispc->gfx_ba1);	dispc_reg_out(oinfo, DISPC_GFX_ROW_INC, dispc->gfx_row_inc);	dispc_reg_out(oinfo, DISPC_GFX_PIXEL_INC, dispc->gfx_pixel_inc);	/*	 * Inform the display controller that our register updates are complete.	 */	dispc_control = dispc->control & 		~(DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE);	dispc_control |= dispc_reg_in(oinfo, DISPC_CONTROL) 		& (DISPC_CONTROL_DIGITALENABLE | DISPC_CONTROL_LCDENABLE);	if (dispc_control & DISPC_CONTROL_DIGITALENABLE)		dispc_control |= DISPC_CONTROL_GODIGITAL;	if (dispc_control & DISPC_CONTROL_LCDENABLE)		dispc_control |= DISPC_CONTROL_GOLCD;	dispc_reg_out(oinfo, DISPC_CONTROL, dispc_control);	return 0;}/** *	  omap24xxfb_blank - NOT a required function. Blanks the display. *	  @blank_mode: the blank mode we want.  *	  @info: frame buffer structure that represents a single frame buffer * *	  Blank the screen if blank_mode != 0, else unblank. Return 0 if *	  blanking succeeded, != 0 if un-/blanking failed due to e.g. a  *	  video mode which doesn't support it. Implements VESA suspend *	  and powerdown modes on hardware that supports disabling hsync/vsync: *	  blank_mode == 2: suspend vsync *	  blank_mode == 3: suspend hsync *	  blank_mode == 4: powerdown * *	  Returns negative errno on error, or zero on success. * */static intomap24xxfb_blank(int blank_mode, struct fb_info *info){	struct omap24xxfb_info *oinfo = (struct omap24xxfb_info *) info->par;	if (oinfo->asleep)		return 0;	if (blank_mode) {		/* blank--disable display controller */		omap24xxfb_disable(oinfo, oinfo->timeout);	}	else {		/* unblank--enable display controller */		omap24xxfb_enable(oinfo, &oinfo->state, oinfo->timeout);	}	return 0;}/** *	omap24xxfb_sync - NOT a required function. Normally the accel engine  *			  for a graphics card take a specific amount of time. *			  Often we have to wait for the accelerator to finish *			  its operation before we can write to the framebuffer *			  so we can have consistent display output.  * *	@info: frame buffer structure that represents a single frame buffer */static intomap24xxfb_sync(struct fb_info *info){	return 0;}/** *	omap24xxfb_ioctl - handler for private ioctls. */static intomap24xxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 	unsigned long arg, struct fb_info *info){	struct omap24xxfb_info *oinfo = (struct omap24xxfb_info *) info->par;	switch (cmd) {		case FBIO_WAITFORVSYNC:			/* This ioctl accepts an integer argument to specify a 			 * display.  We only support one display, so we will 			 * simply ignore the argument.			 */			return omap24xxfb_wait_for_vsync(oinfo);	}	return -EINVAL;}	/*	 *  Frame buffer operations	 */static struct fb_ops omap24xxfb_ops = {	.owner		= THIS_MODULE,	.fb_check_var	= omap24xxfb_check_var,	.fb_set_par	= omap24xxfb_set_par,		.fb_setcolreg	= omap24xxfb_setcolreg,	.fb_blank	= omap24xxfb_blank,	.fb_pan_display	= omap24xxfb_pan_display,		.fb_fillrect	= cfb_fillrect, 	.fb_copyarea	= cfb_copyarea, 	.fb_imageblit	= cfb_imageblit,	.fb_cursor	= soft_cursor,	.fb_rotate	= NULL,	.fb_sync	= omap24xxfb_sync,	.fb_ioctl	= omap24xxfb_ioctl,};int __init omap24xxfb_setup(char *options){	/* no command-line options to parse for now */		return 0;}	/*	 *  Initialization	 */int __init omap24xxfb_init(void){	struct omap24xxfb_info *oinfo;	struct fb_info *info;#ifndef MODULE	{		char *option;				if (fb_get_options("omap24xxfb", &option)) {			return -ENODEV;		}		omap24xxfb_setup(option);	}#endif	oinfo = kmalloc(sizeof(struct omap24xxfb_info), GFP_KERNEL);	if (!oinfo) {		printk(KERN_ERR FB_NAME ": could not allocate memory\n");		return -ENODEV;	}	memset(oinfo, 0, sizeof(struct omap24xxfb_info));	saved_oinfo = oinfo;		/* set the period (in picoseconds) of the graphics timebase */	oinfo->gfx_clk_period = omap24xxfb_gfx_clk_period();	/* initialize the display resolution */	oinfo->display_xres = omap24xxfb_display_xres();	oinfo->display_yres = omap24xxfb_display_yres();		/* Set base addrs */	oinfo->fb_base_phys = omap24xxfb_fb_base();	oinfo->fb_size = omap24xxfb_fb_size();	oinfo->mmio_base_phys = DSS_REG_BASE;	/* A null base address indicates that the framebuffer memory should be 	 * dynamically allocated.	 */	if (!oinfo->fb_base_phys)		oinfo->alloc_fb_mem = 1;	/* request the mem regions */	if (!request_mem_region(oinfo->mmio_base_phys, DSS_REG_SIZE, FB_NAME))	{		printk(KERN_ERR FB_NAME ": cannot reserve MMIO region\n");		goto free_par;	}		if (!oinfo->alloc_fb_mem) {		if (!request_mem_region(oinfo->fb_base_phys, 					oinfo->fb_size, FB_NAME))		{			printk(KERN_ERR FB_NAME ": cannot reserve FB region\n");			goto release_mmio;		}	}	/* map the regions */	oinfo->mmio_base = 		(unsigned long) ioremap(oinfo->mmio_base_phys, DSS_REG_SIZE);	if (!oinfo->mmio_base) {		printk(KERN_ERR FB_NAME ": cannot map MMIO\n");		goto release_fb;	}	if (!oinfo->alloc_fb_mem) {		oinfo->fb_base = 			(unsigned long) ioremap(oinfo->fb_base_phys, 						oinfo->fb_size);		if (!oinfo->fb_base) {			printk(KERN_ERR FB_NAME ": cannot map framebuffer\n");			goto unmap_mmio;		}	}	else {		/* allocate coherent memory for the framebuffer */		oinfo->fb_base = (unsigned long) dma_alloc_coherent(NULL, 				oinfo->fb_size, &oinfo->fb_base_phys, 				GFP_KERNEL | GFP_DMA);		if (!oinfo->fb_base) {			printk(KERN_ERR FB_NAME ": cannot allocate "				"framebuffer\n");			goto unmap_mmio;		}	}	memset((void *)oinfo->fb_base, 0, oinfo->fb_size);	/* allocate coherent memory for the palette */	oinfo->palette = (u32 *) dma_alloc_coherent(NULL, sizeof(u32)*256, 				&oinfo->palette_phys, GFP_KERNEL | GFP_DMA);	if (!oinfo->palette) {		printk(KERN_ERR FB_NAME ": cannot allocate palette memory\n");		goto free_fb;	}	memset(oinfo->palette, 0, sizeof(u32)*256);	/* reset the display controller with a timeout of 200ms */#ifndef OMAP_24XX_VIRTIO	/* Right now there is a problem with softrest on virtio */	omap24xxfb_reset(oinfo, HZ/5);#endif	/* capture the initial state of the display controller */	omap24xxfb_save_state(oinfo, &oinfo->state);	/* initialize the fb_info structure */	info = &oinfo->info;	info->flags = FBINFO_DEFAULT;	info->fbops = &omap24xxfb_ops;	info->screen_base = (char *)(oinfo->fb_base);	info->currcon = -1;	info->pseudo_palette = oinfo->pseudo_palette;	info->par = oinfo;	/* Initialize variable screeninfo.	 * The variable screeninfo can be directly specified by the user 	 * via an ioctl.	 */	memcpy(&info->var, omap24xxfb_default_var(), sizeof(info->var));	info->var.activate = FB_ACTIVATE_NOW;	/* Initialize fixed screeninfo.	 * The fixed screeninfo cannot be directly specified by the user, but 	 * it may change to reflect changes to the var info.	 */	strlcpy(info->fix.id, FB_NAME, sizeof(info->fix.id));	info->fix.smem_start = oinfo->fb_base_phys;	info->fix.smem_len = oinfo->fb_size;	info->fix.type = FB_TYPE_PACKED_PIXELS;	info->fix.visual = ((var_to_depth(&info->var) <= 8) ? 				FB_VISUAL_PSEUDOCOLOR: FB_VISUAL_TRUECOLOR);	info->fix.xpanstep = 0;	info->fix.ypanstep = 0;	info->fix.ywrapstep = 0;	info->fix.line_length = 		(info->var.xres_virtual*info->var.bits_per_pixel)/8;	info->fix.type_aux = 0;	info->fix.mmio_start = oinfo->mmio_base_phys;	info->fix.mmio_len = DSS_REG_SIZE;	info->fix.accel = FB_ACCEL_NONE;	/* Allocate the color map to the maximum size.	 * Color depths greater than 8 bits are true color and use a 16-bit 	 * pseudo-palette instead of an actual palette, so the maximum color 	 * map size is 256 colors.	 */	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {		printk(KERN_ERR FB_NAME ": cannot allocate color map\n");		goto free_palette;	}	if (omap24xxfb_check_var(&info->var, info)) {		printk(KERN_ERR FB_NAME ": invalid default video mode\n");		goto dealloc_cmap;	}	/* initialize board-specific display controller registers */	omap24xxfb_change_mode(&info->var, &oinfo->state);		oinfo->hsync = horizontal_sync_freq(&oinfo->state, &info->var);	oinfo->vsync = vertical_sync_freq(&oinfo->state, &info->var);	if (oinfo->vsync > 0)		oinfo->timeout = ((HZ + oinfo->vsync - 1)/oinfo->vsync)*2;	else		oinfo->timeout = HZ/5;	/* 200ms default timeout */	/* initialize the vsync wait queue */	init_waitqueue_head(&oinfo->vsync_wait);	/* install our interrupt service routine */	if (request_irq(INT_DSS_IRQ, omap24xxfb_isr, SA_SHIRQ, FB_NAME, oinfo))	{		printk(KERN_ERR FB_NAME 			": could not install interrupt service routine\n");		goto dealloc_cmap;	}	if (register_framebuffer((struct fb_info *) oinfo) < 0) {		printk(KERN_ERR FB_NAME ": could not register framebuffer\n");		goto uninstall_isr;	}	printk(KERN_INFO FB_NAME ": fb%d frame buffer device\n", info->node);	printk(KERN_INFO FB_NAME 		": OMAP24xx display controller hardware rev %d.%d\n",		(oinfo->state.revision & DISPC_REVISION_MAJOR) 			>> DISPC_REVISION_MAJOR_SHIFT,		(oinfo->state.revision & DISPC_REVISION_MINOR) 			>> DISPC_REVISION_MINOR_SHIFT);	printk(KERN_INFO FB_NAME ": display mode %dx%dx%d", 		oinfo->display_xres, oinfo->display_yres, 		var_to_depth(&info->var));	if (oinfo->state.control & DISPC_CONTROL_LCDENABLE) {		printk(" hsync %dkHz vsync %dHz", 			oinfo->hsync/1000, oinfo->vsync);	}	printk("\n");	return 0;uninstall_isr:	free_irq(INT_DSS_IRQ, oinfo);dealloc_cmap:	fb_dealloc_cmap(&info->cmap);free_palette:	dma_free_coherent(NULL, sizeof(u32)*256, oinfo->palette, 				oinfo->palette_phys);free_fb:	if (!oinfo->alloc_fb_mem)		iounmap((void*)oinfo->fb_base);	else		dma_free_coherent(NULL, oinfo->fb_size, (void *)oinfo->fb_base, 					oinfo->fb_base_phys);unmap_mmio:	iounmap((void*)oinfo->mmio_base);release_fb:	if (!oinfo->alloc_fb_mem)		release_mem_region(oinfo->fb_base_phys, oinfo->fb_size);release_mmio:	release_mem_region(oinfo->mmio_base_phys, DSS_REG_SIZE);free_par:	kfree(oinfo);	saved_oinfo = NULL;	return -ENODEV;}	/*	 *  Cleanup	 */static void __exit omap24xxfb_cleanup(void){	struct omap24xxfb_info *oinfo = saved_oinfo;	if (!oinfo)		return;	unregister_framebuffer((struct fb_info *) oinfo);	/* uninstall isr */ 	free_irq(INT_DSS_IRQ, oinfo);	/* reset the video controller with a timeout of 200ms */#ifndef OMAP_24XX_VIRTIO	/* Right now there is a problem with softrest on virtio */	omap24xxfb_reset(oinfo, HZ/5);#endif	fb_dealloc_cmap(&oinfo->info.cmap);		dma_free_coherent(NULL, sizeof(u32)*256, oinfo->palette, 			  oinfo->palette_phys);	if (!oinfo->alloc_fb_mem)		iounmap((void*)oinfo->fb_base);	else		dma_free_coherent(NULL, oinfo->fb_size, 				(void *)oinfo->fb_base, oinfo->fb_base_phys);	iounmap((void*)oinfo->mmio_base);	if (!oinfo->alloc_fb_mem)		release_mem_region(oinfo->fb_base_phys, oinfo->fb_size);	release_mem_region(oinfo->mmio_base_phys, DSS_REG_SIZE);	kfree(oinfo);	saved_oinfo = NULL;}	/*	 *  Modularization	 */module_init(omap24xxfb_init);module_exit(omap24xxfb_cleanup);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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