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

📄 omap_fb.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	int output_dev = omap2_disp_get_output_dev(OMAP2_GRAPHICS);	int count = 200;	timeout = jiffies + timeout;	while (!omap2_disp_reg_sync_done(output_dev) &&			time_before(jiffies, timeout) && count) {		if (busy_wait || in_interrupt()) {			udelay(100);			count--;		}		else {			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(1);			if (fb_suspend_data.suspended)				return;		}	}	if (!omap2_disp_reg_sync_done(output_dev)) {		printk(KERN_WARNING "timeout waiting for display controller "				"to save registers\n");	}}/** fbops functions*//* *	omap24xxfb_check_var - Validates a var passed in. *	@var: frame buffer variable screen structure *	@info: frame buffer structure that represents a single frame buffer * *	Returns negative errno on error, or zero on success.  The var info on *	exit may be different than the var info on entry. * *	This function accepts any bits-per-pixel value in the range 0 to 32 *	(0 to 8 for monochrome displays).  If the specified number of *	bits-per-pixel isn't supported, then the next greater number of *	bits-per-pixel will be substituted.  This function differentiates *	between color depths of 12 and 16 (which both have 16 bits-per-pixel) *	by checking to see if the sum of the lengths of the RGB fields is 12, *	in which case the color depth is assumed to be 12.  Except for *	differentiating between 12-bit and 16-bit color depths, the values *	passed in var->red, var->green, and var->blue are ignored and replaced *	with the correct values for the specified color depth. * *	The xres/yres variables in the var screeninfo specify the size of the *	graphics window.  The graphics window size must not be larger than the *	physical display size nor larger than the size of the framebuffer. *	The xres_virtual/yres_virtual values in the var screeninfo specify the *	size of the framebuffer in memory. The framebuffer must not be smaller *	than the size of the graphics window.  The display must not be smaller *	than the graphics window.  The display size depends on whether the *	framebuffer is displayed on LCD or a TV. The xoffset/yoffset variables *	in the var screeninfo specify the offset of the graphics window within *	the framebuffer.  There is no means for the user to specify the offset *	of the graphics window on the display, so that offset will always be *	zero unless the board-specific mode changing function implements some *	other behavior, such as centering. */static intomap24xxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	const struct omap24xxfb_info *oinfo =		(const struct omap24xxfb_info *) info->par;	struct fb_var_screeninfo v;	u32 hbp, hfp, hsw, vbp, vfp, vsw;	u32 display_xres, display_yres;	int output_dev;	omap2_disp_get_dss();	output_dev = omap2_disp_get_output_dev(OMAP2_GRAPHICS);	DBGENTER;	memcpy(&v, var, sizeof(v));	omap2_disp_put_dss();        return 0;	/* do board-specific checks on the var */	if (omap24xxfb_check_mode(oinfo, &v)){		omap2_disp_put_dss();		return -EINVAL;	}	switch (v.bits_per_pixel) {		case 0 ... 1:			v.bits_per_pixel = 1;			break;		case 2:			v.bits_per_pixel = 2;			break;		case 3 ... 4:			v.bits_per_pixel = 4;			break;		case 5 ... 8:			v.bits_per_pixel = 8;			break;		case 9 ... 16:			if (v.grayscale) {				omap2_disp_put_dss();				return -EINVAL;			}			v.bits_per_pixel = 16;			break;		case 17 ... 32:			if (v.grayscale) {				omap2_disp_put_dss();				return -EINVAL;			}			v.bits_per_pixel = 32;			break;		default:			omap2_disp_put_dss();			return -EINVAL;	}	switch (var_to_depth(&v)) {		case 1:			v.red.offset = v.green.offset = v.blue.offset = 0;			v.red.length = v.green.length = v.blue.length = 1;			v.transp.offset = v.transp.length = 0;			break;		case 2:			v.red.offset = v.green.offset = v.blue.offset = 0;			v.red.length = v.green.length = v.blue.length = 2;			v.transp.offset = v.transp.length = 0;			break;		case 4:			v.red.offset = v.green.offset = v.blue.offset = 0;			v.red.length = v.green.length = v.blue.length = 4;			v.transp.offset = v.transp.length = 0;			break;		case 8:			v.red.offset = v.green.offset = v.blue.offset = 0;			v.red.length = v.green.length = v.blue.length = 8;			v.transp.offset = v.transp.length = 0;			break;		case 12:			v.red.offset = 8;			v.green.offset = 4;			v.blue.offset = 0;			v.red.length = v.green.length = v.blue.length = 4;			v.transp.offset = v.transp.length = 0;			break;		case 16:			v.red.offset = 11;			v.green.offset = 5;			v.blue.offset = 0;			v.red.length = 5;			v.green.length = 6;			v.blue.length = 5;			v.transp.offset = v.transp.length = 0;			break;		case 24:			v.red.offset = 16;			v.green.offset = 8;			v.blue.offset = 0;			v.red.length = v.blue.length = v.green.length = 8;			v.transp.offset = v.transp.length = 0;			break;		case 32:			v.red.offset = 24;			v.green.offset = 16;			v.blue.offset = 8;			v.red.length = v.blue.length = v.green.length = 8;			v.transp.offset = 0;			v.transp.length = 8;			break;		default:			omap2_disp_put_dss();			return -EINVAL;	}	omap2_disp_get_panel_size(output_dev, &display_xres, &display_yres);	if (display_xres > MAX_PIXELS_PER_LINE ||			display_yres > MAX_LINES) {		omap2_disp_put_dss();		return -EINVAL;	}	if (display_xres == 0 || display_yres == 0) {		omap2_disp_put_dss();		return -EINVAL;	}	if (v.xres_virtual < v.xres || v.yres_virtual < v.yres) {		omap2_disp_put_dss();		return -EINVAL;	}	if (!oinfo->rotation_support) {		if (display_xres < v.xres || display_yres < v.yres) {			omap2_disp_put_dss();			return -EINVAL;		}	} else {		switch(v.rotate) {			case 0:			case 180:			default:				if (display_xres < v.xres ||						display_yres < v.yres) {					omap2_disp_put_dss();					return -EINVAL;				}				break;			case 90:			case 270:				if (display_xres < v.yres ||						display_yres < v.xres) {					omap2_disp_put_dss();					return -EINVAL;				}				break;		}	}	if (v.xoffset > v.xres_virtual - v.xres) {		omap2_disp_put_dss();				return -EINVAL;	}	if (v.yoffset > v.yres_virtual - v.yres) {		omap2_disp_put_dss();		return -EINVAL;	}	if ((v.bits_per_pixel < 8) && (((v.xres_virtual % 8) != 0)			|| ((v.xres % 8) != 0) || ((v.xoffset % 8) != 0)))	{		omap2_disp_put_dss();		return -EINVAL;	}	/* check if we have enough video memory to support this framebuffer */	if (((!oinfo->rotation_support) &&			(((v.xres_virtual*v.yres_virtual*v.bits_per_pixel)/8)			 > info->fix.smem_len))			||	((oinfo->rotation_support) &&		 (((MAX_PIXELS_PER_LINE*v.yres_virtual*v.bits_per_pixel)/8)		  > info->fix.smem_len)))	{		omap2_disp_put_dss();		return -EINVAL;	}	/* calculate horizontal timing parameters in pixclocks */	hbp = (v.left_margin > 0) ? (v.left_margin - 1) : 0;	if (hbp > 255)		hbp = 255;	hfp = (v.right_margin > 0) ? (v.right_margin - 1) : 0;	if (hfp > 255)		hfp = 255;	hsw = (v.hsync_len > 0) ? (v.hsync_len - 1) : 0;	if (hsw > 63)		hsw = 63;	v.left_margin = hbp + 1;	v.right_margin = hfp + 1;	v.hsync_len = hsw + 1;	/* calculate vertical timing parameters in line clocks */	vbp = v.upper_margin;	if (vbp > 255)		vbp = 255;	vfp = v.lower_margin;	if (vfp > 255)		vfp = 255;	vsw = (v.vsync_len > 0) ? (v.vsync_len - 1) : v.vsync_len;	if (vsw > 63)		vsw = 63;	v.upper_margin = vbp;	v.lower_margin = vfp;	v.vsync_len = vsw + 1;	v.red.msb_right = v.green.msb_right = v.blue.msb_right		= v.transp.msb_right = 0;	v.nonstd = 0;	v.accel_flags = 0;	memcpy(var, &v, sizeof(v));	omap2_disp_put_dss();	DBGLEAVE;	return 0;}/* Calculates the Graphics pipleline DMA parameters */static intomap24xxfb_set_dma_params(const struct fb_var_screeninfo *var,			  const struct fb_fix_screeninfo *fix,			  int rotation, int mirroring){	int context = 0;	u32 view_address_base;	u32 start, total_width, img_width;	u32 row_inc, pix_inc;	u32 xoffset, yoffset;	if ((rotation > 0) && (rotation % 90 != 0))		return -EINVAL;	if (!mirroring) {		if (rotation < 0) {			view_address_base = fix->smem_start;			start = view_address_base				+ var->yoffset*fix->line_length				+ (var->xoffset*var->bits_per_pixel)/8;			total_width = fix->line_length;			img_width = (var->xres *					var->bits_per_pixel)/8;		}		else {			view_address_base = SMS_ROT_VIRT_BASE(context, 0);			switch (rotation) {			/* to the user, xres and yres are interchanged between			   0/180 deg and 90/270 deg, but the DMA still has to 			   use the panel's dimension and orientation. */				case 0:				case 180:				default:					xoffset = var->xoffset;					if (rotation == 180)						xoffset += var->xres_virtual - var->xres;					start = view_address_base						+ var->yoffset*fix->line_length						+ (xoffset*var->bits_per_pixel)/8;					total_width = fix->line_length;					img_width = (var->xres *							var->bits_per_pixel)/8;					break;				case 90:				case 270:					yoffset = var->yoffset;					if (rotation == 90)						yoffset += var->yres_virtual - var->yres;					start = view_address_base						+ var->xoffset*fix->line_length						+ (yoffset*var->bits_per_pixel)/8;					total_width = fix->line_length;					img_width = (var->yres *							var->bits_per_pixel)/8;					break;			}		}		pix_inc = 1;		row_inc = 1 + total_width - img_width;		omap2_disp_set_dma_params(OMAP2_GRAPHICS, OMAP2_OUTPUT_LCD,				start, start, row_inc, pix_inc);		omap2_disp_set_dma_params(OMAP2_GRAPHICS, OMAP2_OUTPUT_TV,				start, (start + total_width),				(row_inc + total_width), pix_inc);	}	else {	/* mirroring */		if (rotation < 0) {			view_address_base = fix->smem_start;			img_width = (var->xres *					var->bits_per_pixel)/8;			start = view_address_base				+ var->yoffset*fix->line_length				+ (var->xoffset*var->bits_per_pixel)/8				+ (var->xres - 1) * var->bits_per_pixel/8;			total_width = fix->line_length;			pix_inc = - 2 * (var->bits_per_pixel/8) + 1;			row_inc = total_width				+ (var->xres - 2) * var->bits_per_pixel/8 + 1;			omap2_disp_set_dma_params(OMAP2_GRAPHICS,					OMAP2_OUTPUT_LCD,					start, start,					row_inc,					pix_inc);			omap2_disp_set_dma_params(OMAP2_GRAPHICS,					OMAP2_OUTPUT_TV,					start, (start + total_width),					(row_inc + total_width),					pix_inc);		}		else {			view_address_base = SMS_ROT_VIRT_BASE(context, 0);			switch (rotation) {				case 0:				case 180:				default:					xoffset = var->xoffset;					if (rotation == 0) {						xoffset += var->xres_virtual - var->xres;					}					start = view_address_base						+ (var->yres - var->yoffset - 1) * fix->line_length						- (xoffset*var->bits_per_pixel)/8;					total_width = fix->line_length;					img_width = (var->xres *							var->bits_per_pixel)/8;					break;				case 90:				case 270:					yoffset = var->yoffset;					if (rotation == 270) {						yoffset += var->yres_virtual - var->yres;					}					start = view_address_base						+ (var->xres - var->xoffset - 1) * fix->line_length						+ (yoffset*var->bits_per_pixel)/8;					total_width = fix->line_length;					img_width = (var->yres *							var->bits_per_pixel)/8;					break;			}			pix_inc = 1;			row_inc = - (total_width + img_width) + 1;			omap2_disp_set_dma_params(OMAP2_GRAPHICS,					OMAP2_OUTPUT_LCD,					start, start,					row_inc,					pix_inc);			omap2_disp_set_dma_params(OMAP2_GRAPHICS,					OMAP2_OUTPUT_TV,					start, (start - total_width),					(row_inc - total_width),					pix_inc);		}	}	return 0;}/* *	omap24xxfb_set_par - Alters the hardware state. *	@info: frame buffer structure that represents a single frame buffer * *	Using the fb_var_screeninfo in fb_info we set the resolution of *	this particular framebuffer. This function alters the par AND the *	fb_fix_screeninfo stored in fb_info. It does not alter var in *	fb_info since we are using that data. This means we depend on the *	data in var inside fb_info to be supported by the hardware. *	omap24xxfb_check_var is always called before omap24xxfb_set_par to *	ensure this. * */static intomap24xxfb_set_par(struct fb_info *info){	struct omap24xxfb_info *oinfo = (struct omap24xxfb_info *) info->par;	struct fb_var_screeninfo *var = &info->var;	u32 clkdiv, hbp, hfp, hsw, vbp, vfp, vsw;	int ret = 0;	DBGENTER;	if (oinfo->asleep)		return 0;	omap2_disp_get_dss();	/* update the fix screeninfo */	if (oinfo->rotation_support) {		oinfo->rotation_deg = var->rotate;		info->fix.line_length = MAX_PIXELS_PER_LINE *			var->bits_per_pixel / 8;	}	else		info->fix.line_length =			(var->xres_virtual*var->bits_per_pixel)/8;	info->fix.visual = ((var_to_depth(var) <= 8) ?			FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR);	/* Graphics window parameters */	if ((oinfo->rotation_support) &&		((oinfo->rotation_deg == 90) || (oinfo->rotation_deg == 270))) {		omap2_disp_config_gfxlayer(var->yres, var->xres,				var_to_depth(var));	} else {		omap2_disp_config_gfxlayer(var->xres, var->yres,				var_to_depth(var));	}	omap2_disp_set_gfx_palette(oinfo->palette_phys);	/* Rotation */	if (oinfo->rotation_support) {		int width = 0, height = 0;		if ((var->rotate == 90) || (var->rotate == 270)) {			width = var->xres_virtual;			height = var->yres_virtual;		} else {			width = var->yres_virtual;			height = var->xres_virtual;		}		omap2_disp_set_vrfb(0, oinfo->fb_base_phys,				width, height, var->bits_per_pixel/8);		if(omap24xxfb_mirroring){			info->fix.smem_start =  				oinfo->sms_rot_phy[omap_rot_mirror_index(oinfo->rotation_deg)];			info->screen_base = 				(char *)(oinfo->sms_rot_virt[omap_rot_mirror_index(oinfo->rotation_deg)]);		} else {

⌨️ 快捷键说明

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