学习交流加

  • 个人qq:
    1126137994
  • 个人微信:
    liu1126137994
  • 学习交流资源分享qq群:
    962535112

今天记录一下项目中的关于LVDS显示屏的驱动程序的分析与移植。因为驱动源码厂家已经提供好,我们需要做的就是读懂驱动程序的代码,以及平台层的匹配过程,以及如何在uboot中获取lvds参数,来匹配你的具体显示屏的参数。

首先我们来大致分析一下驱动程序的重要的结构部分:

1.mxc_ipuv3_fb.c 是imx6具体显示模块平台核心的驱动,最终用于把fb_info结构体注册到
framebuffer驱动核心层中。
2.mxc_dispdrv.c 通用注册handle接口,用于统一管理imx6显示模块的各种接口,
比如lvds,lcd,hdmi等显示接口。
3.ldb.c是LVDS 驱动的具体实现过程。

分析:
mxc_ipuv3_fb.c中
在mxc_ipuv3_fb.c文件中初始化mxcfb_init函数注册mxcfb_driver结构体,
当mxcfb_driver结构体成员驱动name与平台设备层中name匹配相同时调用mxcfb_probe初始化函数。
imx6具体显示模块平台核心的驱动的工作主要是在mxcfb_probe里完成。

以下是将重要的函数抽出来分析,并不是具体的代码程序。具体的代码程序见最后的分析。

mxcfb_probe
	mxcfb_init_fbinfo
		framebuffer_alloc
	mxcfb_option_setup
		fb_get_options(根据uboot传进来的参数,比较是否匹配,获取分辨率,bpp等参数)
	mxcfb_dispdrv_init
		mxc_dispdrv_gethandle
			if (!strcmp(entry->drv->name, name) && (entry->drv->init)) //如果uboot传进来的参数名字
			与ldb_driver里注册的名字匹配时,就会进入就会执行ldb.c文件里的ldb_disp_init函数
			entry->drv->init  //mxc_dispdrv.c 调用对应driver的init函数,这里就是ldb driver对应的init了。
	mxcfb_register
		register_framebuffer

entry->drv->init是如何调用ldb_disp_init?当ldb.c中ldb_grv结构体中的name与uboot传进来的名字
	相匹配,就会调用.init,
	
		static struct mxc_dispdrv_driver ldb_drv = {
	.name 	= DISPDRV_LDB,
	.init 	= ldb_disp_init,
	.deinit	= ldb_disp_deinit,
	.setup = ldb_disp_setup,
};

ldb.c中ldb_probe()
第三步调用mxcfb_dispdrv_init函数,它会调用在mxc_dispdrv.c文件的mxc_dispdrv_gethandle函数;
根据uboot传到内核的显示设备name(ldb),在dispdrv_list链表中匹配获取对应的driver handle;
这里是获取的是ldb的handle,它的注册是ldb_probe()里的mxc_dispdrv_register函数的,它将自己
添加到dispdrv_list。通过entry->drv->init函数,当从uboot获取的显示设备名字和ldb driver里
注册的名字match匹配时,就会执行ldb.c文件里的ldb_disp_init函数(具体见另一个文档,告诉你
如何实现参数匹配),然后通过结构体fb_videomode[]来设置屏幕的分辨率、刷新频率、上下左右
页边距、行扫描脉宽、场扫描脉宽等参数。ldb_disp_init函数是LVDS驱动具体实现函数。

ldb_disp_init
	ret = fb_find_mode(具体硬件参数的匹配过程,分析见另一篇文章链接为:)
	return ret

上面大致框架分析好后,一定要看一下具体硬件的参数匹配过程,见上面链接(链接:iMX6开发板移植Linux系统之LVDS显示屏驱动程序分析之LVDS参数的匹配过程分析),然后就是如何设置我的参数,来匹配我的开发板了:

首先在这个结构体中,需要知道具体的参数:

/* include/linux/fb.h */
 struct fb_videomode {  
2.     const char *name;  “LDB-WSVGA”    /* 名字 */  
3.     u32 refresh;        60    /* 刷新频率 */  
4.     u32 xres;           1024  //行像素  
5.     u32 yres;           768   //列像素  
6.     u32 pixclock;       19528(14065) //时钟频率,单位ps,14430  
7.     u32 left_margin;    140   // HBPD(horizontal back porch):80  
8.     u32 right_margin;   160   // HFPD(horizontal front porth):48  
9.     u32 upper_margin;   20    // VBPD(vertical back porch),15  
10.    u32 lower_margin;   12    // VFBD(vertical front porch),2  
11.    u32 hsync_len;      20    // HSPW(horizontal sync pulse width):32  
12.    u32 vsync_len;      3     // VSPW(vertical sync pulse width):47  
13.    u32 sync;           0 
14.    u32 vmode;          
15.    u32 flag;  
16.};  

我们的参数为:

整屏刷新频率 60M
屏幕分辨率 1024*768
时钟频率 14065
left_margin 40(单位像素)
right_margin 40(单位像素)
upper_margin 10(单位像素)
lower_margin 3(单位像素)
行扫描脉宽 hsync_len 80(单位像素时间)
场扫描脉宽vsync_len 10(单位像素时间)

在i.mx6中,关于lvds液晶屏的这个结构体参数(系统lvds接口支持的lcd时序参数都在此了)所属文件为:driver/video/mxc/ldb.c

static struct fb_videomode ldb_modedb[] = {
	{
	 "LDB-WXGA", 60, 1280, 800, 14065,
	 40, 40,
	 10, 3,
	 80, 10,
	 0,
	 FB_VMODE_NONINTERLACED,
	 FB_MODE_IS_DETAILED,},
	{
	 "LDB-XGA", 60, 1024, 768, 15385,
	 220, 40,
	 21, 7,
	 60, 10,
	 0,
	 FB_VMODE_NONINTERLACED,
	 FB_MODE_IS_DETAILED,},
	{"LDB-WSVGA", 60, 1024, 600, 19528,
	 140, 160,
	 20, 12,
	 20, 3,
	 0,
	 FB_VMODE_NONINTERLACED,
	 FB_MODE_IS_DETAILED,},
	{"LDB-WSVGA480", 60, 1024, 480, 23000,
	 140, 160,
	 20, 12,
	 20, 3,
	 0,
	 FB_VMODE_NONINTERLACED,
	 FB_MODE_IS_DETAILED,},
	{
	 "LDB-1080P60", 60, 1920, 1080, 7692,
	 100, 40,
	 30, 3,
	 10, 2,
	 0,
	 FB_VMODE_NONINTERLACED,
	 FB_MODE_IS_DETAILED,},
	{
	 "LDB-QXGA", 30, 2048, 1536, 9746,
	 5, 150,
	 9, 3,
	 5, 1,
	 0,
	 FB_VMODE_NONINTERLACED,
	 FB_MODE_IS_DETAILED,},
	 
};

我们选用"LDB-WSVGA"这个结构体里的内容作为我们的参数,将参数修改好适合我们的的参数。

经过后来做实验,发现启动后显示屏显示的有问题,显示的不完全,经过后来的搜索,我在uboot启动后,输入参数,来覆盖上面的结构体参数,屏幕显示就正常了。具体原因没有分析,以后有时间再做具体分析。
uboot启动后输入的具体参数为:

setenv bootargs_mmc 'setenv bootargs ${bootargs} ip=off root=/dev/mmcblk0p1 rootwait rw video=mxcfb0:dev=ldb,LDB-WSVGA,if=RGB24,bpp=32 video=mxcfb1:off video=mxcfb2:off ldb=sin0 fbmem=28M fb0base=0x27b00000 '

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。