QUALCOMM MDM9X15 LCD初始化流程

先来看一下 board-9615.c 文件


MACHINE_START(MSM9615_CDP, "QCT MSM9615 CDP")
.map_io = msm9615_map_io,
.init_irq = msm9615_init_irq,
.handle_irq = gic_handle_irq,
.timer = &msm_timer,
.init_machine = msm9615_cdp_init,    // 在这个函数里面调用 mdm9615_init_fb
.reserve = msm9615_reserve,
#ifdef CONFIG_FB_MSM
.init_early = mdm9615_allocate_memory_regions,   // 在这个函数里面allocate frambuffer 空间
#endif
MACHINE_END


static void __init msm9615_cdp_init(void)
{
msm9615_common_init();
#ifdef CONFIG_FB_MSM
mdm9615_init_fb();
#endif
}


static void __init mdm9615_allocate_memory_regions(void)
{
mdm9615_allocate_fb_region();  // 这个函数定义在 board-9615-display.c 文件里
}


kernel启动时  在 start_kernel函数中调用 setup_arch(&command_line)函数, 在setup_arch函数中调用
mdm9615_allocate_memory_regions,从而分配了 frambuffer的空间。

start_kernel----->setup_arch------> mdesc->init_early(即 mdm9615_allocate_memory_regions)


设备初始化时调用 mdm9615_init_fb()
mdm9615_init_fb()函数定义在 board-9615-display.c 文件中


void __init mdm9615_init_fb(void)
{
platform_device_register(&msm_fb_device);

#if 0 //Modified by BroadMobi
platform_device_register(&ebi2_epson_s1d_panel_device);
#else
platform_device_register(&ebi2_sh1106_panel_device);
#endif


msm_fb_register_device("ebi2_lcd", &ebi2_lcdc_pdata);
}
该函数依次向platform总线添加 msm_fb设备 ,ebi2_sh1106设备 , ebi2_lcd设备


下面来看看LCD驱动初始化流程吧,从这个sh1106 oled屏初始化开始看起。


static int __init sh1106_init(void)
{
int ret;
struct msm_panel_info *pinfo;


ret = platform_driver_register(&this_driver); // 注册ebi2_sh1106驱动, 在probe函数中获得 platform_data
if (!ret) { // 若驱动注册成功, 填充panel_info
pinfo = &sh1106_panel_data.panel_info;
pinfo->xres = PANEL_WIDTH;
pinfo->yres = PANEL_HEIGHT;
MSM_FB_SINGLE_MODE_PANEL(pinfo);
pinfo->type = EBI2_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0x821000;  //EBI2 cfg0寄存器配置, 读写等待时间
pinfo->bpp = 16;
pinfo->fb_num = 2;
pinfo->lcd.vsync_enable = FALSE;


ret = platform_device_register(&this_device); // register ebi2_sh1106 device again, probe function will be called again
if (ret)
platform_driver_unregister(&this_driver);
}


return ret;
}


首先注册ebi2_sh1106驱动,在probe函数中获得platform_data。若注册成功,填充panel_info结构体(分辨率,类型,bpp等),然后再次
注册ebi2_sh1106设备,probe函数中的 msm_fb_add_device(pdev)函数将被调用,这个函数定义在 msm_fb.c 文件中。


msm_fb_add_device()函数主要功能: 

创建 ebi2_lcd 平台设备, 并将 ebi2_sh1106 设备的 platform_data (sh1106_panel_data)传递给 ebi2_lcd 平台设备的 platform_data。 创建一个 fb_info 结构体,填充 mfd(msm_fb_data_type),分别将 mfd 和 fbi 放到 mfd_list

和 fbi_list 的全局数组中,最后向系统注册 EBI2_LCD 平台设备。



EBI2_LCD 平台设备再次注册, EBI2_LCD 平台驱动的probe函数也将被再次调用, 现在来看看 ebi2_lcd.c中的probe函数
再次调用 ebi2_lcd_probe函数,主要实现下面功能:
1. 从 platform_device结构体中获得 mfd (msm_fb_data_type)结构体;
2. 创建 mdp platform_device结构体,将从 ebi2_sh1106 设备获得的 platform_data (sh1106_panel_data)再次传递给 mdp 平台设备;
3. 设置mdp platform_device 的platform_data(msm_fb_panel_data)的 on/off接口,并将EBI2_LCD platform_device结构体赋值给msm_fb_panel_data中的next指针,即mdp platform_device 是 EBI2_LCD (LCDC)的父节点;
4. 设置 EBI2_CHIP_SELECT_CFG0 寄存器的 6-7位 0x01 ,即设置 EBI2_CS(4)为 LCD device connected, 设置 EBI2_LCD_CFG0寄存器(调整各种信号的时间长度,需要多调试,否则可能因时序问题出现各种bug, 图像偏移,字符扭曲等现象);
5. 获得读写屏寄存器的 cmd_port ,data_port 地址
6. 注册 mdp 平台设备



mdp 平台设备注册,系统必然会调用到该设备驱动的probe函数, 在 ebi2_host.c文件中

ebi2_host_probe()函数实现下面功能:
1. 创建 msm_fb 平台设备, 并将从 ebi2_sh1106 设备一路传递过来的 platform_data (sh1106_panel_data)赋值给msm_fb 的 platform_data
2. 初始化 msm_fb 的 on/off函数接口, 并将 mdp 的 platform device结构体赋值给 msm_fb platform_data (sh1106_panel_data)的 next, 即  msm_fb device 是  mdp device的父节点
3. 再次注册   msm_fb device 到系统中



msm_fb device 被再次注册, msm_fb driver中的probe函数迟早也会被再调用一次
在 msm_fb_probe 函数中,调用 msm_fb_register(mfd)函数,该函数会对前面讲到的fb_info结构体进行填充,
设置fb_var_screen和fb_fix_screen结构体的显示参数,包括图像显示格式、可见分辨率、虚拟分辨率、红绿蓝
色域的偏移、帧率、虚拟基地址等等一些参数,并将高通平台自带的fb_ops接口填充到fb_info结构体里面,然后
调用register_framebuffer来创建fb0 device。至此,fb0的建立已经完成,应用层可以对fb0节点的控制来操

作framebuffer缓冲区。



从头看来发现整个LCD驱动的流程都是通过相应的platform_device中的id 和probe函数控制从底到上的顺序 来初始化各个功能模块

 ebi2_sh1106(具体的屏驱动)--->EBI2_LCD(LCDC)--->mdp--->msm_fb

通过这种方法可以控制驱动注册的先后顺序,值得学习。













                    
                    





























  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值