我是靠谱客的博主 开心抽屉,最近开发中收集的这篇文章主要介绍linux系统LCD驱动(二):mtk lcd驱动fb_info初始化,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这一篇博文承接上一篇博文“系统lcd驱动(-)”(https://blog.csdn.net/Ian22l/article/details/105927936),这篇博文讲的是mtk的lcd驱动一部分。
上一篇讲到在移植或者调试的时候需要填充fb_info对象信息并且进行register_framebuffer进行注册。那么mtk的lcd驱动便是实现这一部分的逻辑。首先从mtkfb_probe进行底层硬件lcd驱动的加载。如下:
代码路径:
drivers/misc/mediatek/video/xxx/videox/mtkfb.c(其中xxx代表某个具体平台,例如mt3561)

static int mtkfb_probe(struct platform_device *pdev)
{
	struct mtkfb_device *fbdev = NULL;
	struct fb_info *fbi;
	......
	......
	/*申请一块fb_info类型的内存*/
	fbi = framebuffer_alloc(sizeof(struct mtkfb_device), &(pdev->dev));
	if (!fbi) {
		DISPERR("unable to allocate memory for device infon");
		r = -ENOMEM;
		goto cleanup;
	}
	mtkfb_fbi = fbi;

	fbdev = (struct mtkfb_device *)fbi->par;
	fbdev->fb_info = fbi;
	fbdev->dev = &(pdev->dev);
	dev_set_drvdata(&(pdev->dev), fbdev);
	......
	......
	
	/*lcd控制器以及lcm模组的初始化*/
	primary_display_init(mtkfb_find_lcm_driver(), lcd_fps, is_lcm_inited);	
	......
	......
	
	/*初始化fb_info*/
	r = mtkfb_fbinfo_init(fbi);
	if (r) {
		DISPERR("mtkfb_fbinfo_init fail, r = %dn", r);
		goto cleanup;
	}
	
	......
	......
	
	/*注册fb_info结构体fbi*/
	r = register_framebuffer(fbi);
	if (r != 0) {
		DISPERR("register_framebuffer failedn");
		goto cleanup;
	}
	DISPMSG("register_framebuffer donen");
	
	......
	return r;
}

mtk的驱动其实可以分为两条线,一个是初始化fb_info结构体,另外一个是lcm模组的一些初始化。这里我们先说fb_info的初始化,后续会说lcm模组的初始化。

一:fb_info结构体的初始化以及注册
从上面的代码看出,fb_info结构体的初始化主要是通过mtkfb_fbinfo_init进行fb_info对象的填充,然后再通过r = register_framebuffer(fbi);进行注册。这正是我们上一篇博文的结尾所提到的内容。这里我们看下fb_info的初始化主要初始化的内容是什么。

mtkfb_fbinfo_init代码主要内容:

static int mtkfb_fbinfo_init(struct fb_info *info)
{
	struct mtkfb_device *fbdev = (struct mtkfb_device *)info->par;
	struct fb_var_screeninfo var;
	int r = 0;

	DISPFUNC();

	ASSERT(fbdev->fb_va_base);
	/*初始化操作集合*/
	info->fbops = &mtkfb_ops;
	info->flags = FBINFO_FLAG_DEFAULT;
	info->screen_base = (char *)fbdev->fb_va_base;
	info->screen_size = fbdev->fb_size_in_byte;
	info->pseudo_palette = fbdev->pseudo_palette;

	r = fb_alloc_cmap(&info->cmap, 32, 0);
	if (r != 0)
		DISPERR("unable to allocate color map memoryn");

	/* setup the initial video mode (RGB565) */

	memset(&var, 0, sizeof(var));

	/*初始化可变参数fb_var_screeninfo,例如分辨率*/
	var.xres = MTK_FB_XRES;
	var.yres = MTK_FB_YRES;
	var.xres_virtual = MTK_FB_XRESV;
	var.yres_virtual = MTK_FB_YRESV;
	DISPMSG(
		"mtkfb_fbinfo_init var.xres=%d,var.yres=%d,var.xres_virtual=%d,var.yres_virtual=%dn",
		var.xres, var.yres, var.xres_virtual, var.yres_virtual);
	/* use 32 bit framebuffer as default */
	var.bits_per_pixel = 32;

	var.transp.offset = 24;
	var.red.length = 8;
	
/*初始化颜色位域*/
#if 0
	var.red.offset = 16;
	var.red.length = 8;
	var.green.offset = 8;
	var.green.length = 8;
	var.blue.offset = 0;
	var.blue.length = 8;
#else
	var.red.offset = 0;
	var.red.length = 8;
	var.green.offset = 8;
	var.green.length = 8;
	var.blue.offset = 16;
	var.blue.length = 8;
#endif

	var.width = DISP_GetActiveWidth();
	var.height = DISP_GetActiveHeight();

	var.activate = FB_ACTIVATE_NOW;

	r = mtkfb_check_var(&var, info);
	if (r != 0)
		DISPERR("failed to mtkfb_check_varn");

	/*将已经初始化好的fb_var_screeninfo对象赋值给info中的var*/
	info->var = var;

	/*初始化fb_fix_screeninfo*/
	r = mtkfb_set_par(info);
	if (r != 0)
		DISPERR("failed to mtkfb_set_parn");

	MSG_FUNC_LEAVE();
	return r;
}

fb_info的初始化内核主要是对fb_var_screeninfo以及fb_fix_screeninfo,info->fbops的初始化。
(1)其中fb_var_screeninfo的初始化主要进行分辨率,颜色位域等初始化。

(2)nfo->fbops的初始化:

static struct fb_ops mtkfb_ops = {
	.owner = THIS_MODULE,
	.fb_open = mtkfb_open,
	.fb_release = mtkfb_release,
	.fb_setcolreg = mtkfb_setcolreg,
	.fb_pan_display = mtkfb_pan_display_proxy,
	.fb_fillrect = cfb_fillrect,
	.fb_copyarea = cfb_copyarea,
	.fb_imageblit = cfb_imageblit,
	.fb_cursor = mtkfb_soft_cursor,
	.fb_check_var = mtkfb_check_var,
	.fb_set_par = mtkfb_set_par,
	.fb_ioctl = mtkfb_ioctl,
#ifdef CONFIG_COMPAT
	.fb_compat_ioctl = mtkfb_compat_ioctl,
#endif
#if defined(CONFIG_PM_AUTOSLEEP)
	.fb_blank = mtkfb_blank,
#endif
};

(3)fb_fix_screeninfo初始化:

/* Switch to a new mode. The parameters for it has been check already by
 * mtkfb_check_var.
 */
static int mtkfb_set_par(struct fb_info *fbi)
{
	struct fb_var_screeninfo *var = &fbi->var;
	struct mtkfb_device *fbdev = (struct mtkfb_device *)fbi->par;
	struct fb_overlay_layer fb_layer;
	u32 bpp = var->bits_per_pixel;
	struct disp_session_input_config *session_input;
	struct disp_input_config *input;


	/* DISPFUNC(); */
	memset(&fb_layer, 0, sizeof(struct fb_overlay_layer));
	switch (bpp) {
	case 16:
		fb_layer.src_fmt = MTK_FB_FORMAT_RGB565;
		fb_layer.src_use_color_key = 1;
		fb_layer.src_color_key = 0xFF000000;
		break;

	case 24:
		fb_layer.src_use_color_key = 1;
		fb_layer.src_fmt = (var->blue.offset == 0) ?
		    MTK_FB_FORMAT_RGB888 : MTK_FB_FORMAT_BGR888;
		fb_layer.src_color_key = 0xFF000000;
		break;

	case 32:
		fb_layer.src_use_color_key = 0;
		DISPDBG("set_par,var->blue.offset=%dn", var->blue.offset);
		fb_layer.src_fmt = (var->blue.offset == 0) ?
		    MTK_FB_FORMAT_ARGB8888 : MTK_FB_FORMAT_BGRA8888;
		fb_layer.src_color_key = 0;
		break;

	default:
		fb_layer.src_fmt = MTK_FB_FORMAT_UNKNOWN;
		DISPWARN("[%s]unsupported bpp: %d", __func__, bpp);
		return -1;
	}

	//初始化fb_fix_screeninfo
	set_fb_fix(fbdev);

}
static void set_fb_fix(struct mtkfb_device *fbdev)
{
	struct fb_info *fbi = fbdev->fb_info;
	struct fb_fix_screeninfo *fix = &fbi->fix;
	struct fb_var_screeninfo *var = &fbi->var;
	struct fb_ops *fbops = fbi->fbops;

	strncpy(fix->id, MTKFB_DRIVER, sizeof(fix->id));
	fix->type = FB_TYPE_PACKED_PIXELS;

	switch (var->bits_per_pixel) {
	case 16:
	case 24:
	case 32:
		fix->visual = FB_VISUAL_TRUECOLOR;
		break;
	case 1:
	case 2:
	case 4:
	case 8:
		fix->visual = FB_VISUAL_PSEUDOCOLOR;
		break;
	default:
		DISPERR("set fb fix fail,bits per pixel=%dn",
			var->bits_per_pixel);
		return;
	}

	fix->accel = FB_ACCEL_NONE;
	fix->line_length = ALIGN_TO(var->xres_virtual, MTK_FB_ALIGNMENT) *
		var->bits_per_pixel / 8;
	fix->smem_len = fbdev->fb_size_in_byte;
	fix->smem_start = fbdev->fb_pa_base;

	fix->xpanstep = 0;
	fix->ypanstep = 1;

	fbops->fb_fillrect = cfb_fillrect;
	fbops->fb_copyarea = cfb_copyarea;
	fbops->fb_imageblit = cfb_imageblit;
}

最后

以上就是开心抽屉为你收集整理的linux系统LCD驱动(二):mtk lcd驱动fb_info初始化的全部内容,希望文章能够帮你解决linux系统LCD驱动(二):mtk lcd驱动fb_info初始化所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部