MTK LCM流程

LCM的设备模型是遵守设备总线驱动结构的

总线
platform虚拟总线,在该总线的设备和驱动通过name来匹配。

设备
设备定义在设备树 在/kernel-3.18/arch/arm/boot/dts/mt6735m.dtsi 或 bd6735m_35g_b_m0.dts

驱动
驱动文件出了MTK抽象出来的具体设备驱动文件外,这里指的是挂在platform上的驱动文件。kernel-3.18/drivers/misc/mediatek/video/common/mtkfb.c。
static const struct of_device_id mtkfb_of_ids[] = {
        {.compatible = "mediatek,mtkfb",},
        {}
};

const struct dev_pm_ops mtkfb_pm_ops = {
        .suspend = mtkfb_pm_suspend,
        .resume = mtkfb_pm_resume,
        .freeze = mtkfb_pm_freeze,
        .thaw = mtkfb_pm_resume,
        .poweroff = mtkfb_pm_suspend,
        .restore = mtkfb_pm_resume,
        .restore_noirq = mtkfb_pm_restore_noirq,
};

static struct platform_driver mtkfb_driver = {
        .driver = {
                .name = MTKFB_DRIVER,
#ifdef CONFIG_PM
                .pm = &mtkfb_pm_ops,
#endif
                .bus = &platform_bus_type,
                .probe = mtkfb_probe,
                .remove = mtkfb_remove,
                .suspend = mtkfb_suspend,
                .resume = mtkfb_resume,
                .shutdown = mtkfb_shutdown,
                .of_match_table = mtkfb_of_ids,
        },
};

注册驱动
int __init mtkfb_init(void)
{
        int r = 0;

MSG_FUNC_ENTER();

if (platform_driver_register(&mtkfb_driver)) {
                PRNERR("failed to register mtkfb driver\n");
                r = -ENODEV;
                goto exit;
        }
#if 0
#ifdef CONFIG_HAS_EARLYSUSPEND
        register_early_suspend(&mtkfb_early_suspend_handler);
#endif
#endif
        /* FIXME: find definition */
        PanelMaster_Init();

DBG_Init();
        mtkfb_ipo_init();
exit:
        MSG_FUNC_LEAVE();
        return r;
}

驱动的名字和设备匹配后,调用驱动的probe进行探测设备,
mtkfb_probe()有
/*mtkfb should parse lcm name from kernel boot command line */
primary_display_init(mtkfb_find_lcm_driver(),lcd_fps);        //加载定制化的驱动,其中mtkfb_find_lcm_driver()查找到对应驱动

char *mtkfb_find_lcm_driver(void)
{
#ifdef CONFIG_OF
   if( 1 == _parse_tag_videolfb()){
   
   }

#else

#endif
  return mtkfb_lcm_name;
}
再来看
int _parse_tag_videolfb(void)
{
        struct tag_videolfb *videolfb_tag = NULL;
        /* not necessary */
        /* DISPCHECK("[DT][videolfb]isvideofb_parse_done = %d\n",is_videofb_parse_done); */

if (is_videofb_parse_done)
                return 0;
#ifdef MTK_NO_DISP_IN_LK
        DISPCHECK("[DT][videolfb] zaikuo, workaround for LK not ready\n"); /* after LK ready, remove this code */
        return 1;
#endif

if (of_scan_flat_dt(fb_early_init_dt_get_chosen, NULL) > 0) {
                videolfb_tag = (struct tag_videolfb *)of_get_flat_dt_prop(video_node, "atag,videolfb", NULL);
                if (videolfb_tag) {
                        memset((void *)mtkfb_lcm_name, 0, sizeof(mtkfb_lcm_name));
                        strcpy((char *)mtkfb_lcm_name, videolfb_tag->lcmname);
                        mtkfb_lcm_name[strlen(videolfb_tag->lcmname)] = '\0';

lcd_fps = videolfb_tag->fps;
                        if (0 == lcd_fps)
                                lcd_fps = 6000;

islcmconnected = videolfb_tag->islcmfound;
                        vramsize = videolfb_tag->vram;
                        fb_base = videolfb_tag->fb_base;
                        is_videofb_parse_done = 1;
                        DISPPRINT("[DT][videolfb] lcmfound=%d, fps=%d, fb_base=%p, vram=%d, lcmname=%s\n",
                             islcmconnected, lcd_fps, (void *)fb_base, vramsize, mtkfb_lcm_name);
#if 0
                        DISPCHECK("[DT][videolfb] islcmfound = %d\n", islcmconnected);
                        DISPCHECK("[DT][videolfb] fps        = %d\n", lcd_fps);
                        DISPCHECK("[DT][videolfb] fb_base    = %p\n", (void *)fb_base);
                        DISPCHECK("[DT][videolfb] vram       = %d\n", vramsize);
                        DISPCHECK("[DT][videolfb] lcmname    = %s\n", mtkfb_lcm_name);
#endif
                        return 0;
                }

DISPCHECK("[DT][videolfb] videolfb_tag not found\n");
                return 1;
        }

DISPCHECK("[DT][videolfb] of_chosen not found\n");
        return 1;
}
从运行log中可以看到lcmname=jd9522_hd720_dsi_vdo_qc
[    0.477467] <0>.(0)[1:swapper/0][name:mtkfb&][DISP][DT][videolfb] lcmfound=1, fps=5764, fb_base=7f330000, vram=13172736, lcmname=jd9522_hd720_dsi_vdo_qc

回过来看
primary_display_init()  //kernel-3.18/drivers/misc/mediatek/video/mt6757/videox/primary_display.c
进入primary_display_init函数中,再执行disp_lcm_probe()函数。 
pgc->plcm=disp_lcm_probe(lcm_name,LCM_INTERFACE_NOTDEFFINE)
kernel-3.18/drivers/misc/mediatek/video/mt6757/videox/disp_lcm.c中
disp_lcm_probe()找到驱动jd9522_hd720_dsi_vdo_qc,并返回一个disp_lcm_handle指针,获得lcm参数。

下面是对LK代码中LCM驱动的选择流程分析
LK核心流程
kmain()依次执行
thread_init_early()
arch_early_init()
platform_early_init()
call_constructors()
bootstrap2()
然后Bootstrap2依次执行
platform_init()
app_init()
mt_boot_init()
boot_linux_from_storage()
boot_linux()
在platform_init()中
mt_disp_init((void *)g_fb_base);
在mt_disp_init()中调用
primay_display_init(NULL) //  类似kernel中操作,只是这个地方传入为NULL, 而kernel中传入的是lk传递过去lcm_name;
在primay_display_init()中也是执行,支持lcm_name为null。
pgc->plcm = disp_lcm_probe( lcm_name, LCM_INTERFACE_NOTDEFINED);

??
通过调用文件Mt_boot.c (app\mt_boot)中的int boot_linux_from_storage(void)函数中
ret = fdt_setprop(fdt, offset, "atag,videolfb", buf, ptr - buf);  
传递给kernel

mtk6737m的lk中lcm流程相关推荐

  1. (转)Android bootloader(LK)启动流程

    转自:http://blog.csdn.net/jmq_0000/article/details/7378348 LK是什么 LK 是 Little Kernel 它是 appsbl (Applica ...

  2. lk中内联调用的dsb()

    lk中内联调用的dsb() 比如lk的uart_dm_init()函数就调用了dsb() /* Configure the uart clock */clock_config_uart_dm(id); ...

  3. 关于企业信息化中审计流程“寻租”现象的探讨

    关于企业信息化中审计流程"寻租"现象的探讨 企业信息化,刚开始研究这个方向时,等着导师给出一个清晰概念,岂料导师给了个80年代国内某大型企业开展企业信息化的案例.感觉那段时间就是对 ...

  4. Python基础之:Python中的流程控制

    文章目录 简介 while语句 if 语句 for语句 Break Continue pass 简介 流程控制无非就是if else之类的控制语句,今天我们来看一下Python中的流程控制会有什么不太 ...

  5. 4、java中的流程控制(程序结构)

            说一下java的流程控制(程序结构),其实对于计算机而言,无非就那几类执行流程(程序结构),程序从头到尾依次执行每一行代码,这就是顺序结构:也可能在执行过程中遇到条件判断,造成程序运行 ...

  6. c if语句多个条件判断顺序_Java中的流程控制语句 (基础篇四)

    流程控制就是对事物次序的布置和安排,在程序中就是对代码执行次序的安排和控制 程序中的流程控制主要有三种:顺序流程.选择流程.循环流程. 顺序流程:比如打印输出的代码按照指定的顺序结构依次排序,打印的结 ...

  7. java中的四个跳转语句_Java中的流程控制语句 (基础篇四)

    流程控制就是对事物次序的布置和安排,在程序中就是对代码执行次序的安排和控制 程序中的流程控制主要有三种:顺序流程.选择流程.循环流程. 顺序流程:比如打印输出的代码按照指定的顺序结构依次排序,打印的结 ...

  8. python和控制流程_Python基础之:Python中的流程控制

    简介 流程控制无非就是if else之类的控制语句,今天我们来看一下Python中的流程控制会有什么不太一样的地方. while语句 python中的while语句和其他语言没有什么不一样,我使用wh ...

  9. 细数APDL中的流程控制命令

    作者:水哥ANSYS,获授权转载 一.概述 有过其他编程语言经验的同学都知道,流程控制类语言命令在编程中是必须掌握的一门技巧,这类命令能大幅提高我们的编程效率,增加程序可读性.类似地,在APDL中也有 ...

  10. 简易理解设计模式之:责任链模式——OA中请假流程示例

    介绍: 责任链模式属于行为型设计模式.它的定义为:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,只到有对象处理它为止. 类图: ...

最新文章

  1. 用java实现一个计算器程序_1.2第一个java程序——hello world
  2. Hbase数据存储架构
  3. 新疆电信IBSS系统集中联机热备份--案例
  4. 如何利用css使PNG图片透明
  5. 记录工作中常用的CSS3
  6. 思科isis路由的优先级_华为 路由双点双向引入
  7. 【树莓派】给树莓派安装中文输入法Fcitx及Google拼音输入法
  8. 基于MM2的跨IDC kafka热备多活方案
  9. HRBP与HRM的区别是什么?
  10. 测试linux和window下 jdk最大能使用多大内存
  11. with open as f用法_UE4精品教程 | C++Tuple元组的详细用法
  12. silverlight打开和保存文件
  13. linux显卡测试radeon,15款热门显卡对比:Radeon RX 6800系列在Linux 1440p环境下表现出色...
  14. w ndows 那个比较好用,DOS工具箱哪个好用?DOS工具箱盘点
  15. drcom宽带认证登录超时_drcom宽带认证客户端登录超时
  16. ASP.NET 氚云平台集成Dome
  17. 不积跬步无以至千里008
  18. 小米2023届秋招校招内推
  19. I 爆炸的符卡洋洋洒洒(牛客)01背包
  20. 【免费】傻瓜式一键内网穿透实现ssh连接远程局域网的电脑(利用免费frp服务器)

热门文章

  1. HDU - 6438 优先队列,+贪心。
  2. 新版《鹿鼎记》史上最低分!数据分析告诉你,韦小宝跟哪个老婆最亲
  3. 手机电源键失灵无法开机的有效土方法
  4. A*搜索 --算法竞赛专题解析(9)
  5. lmp+heartbeat+drbd
  6. 我们将迎来另一个 VR 寒冬吗?
  7. 【pyqt5学习】—— 滑动条Qslider、计数器QSpinBox学习
  8. csp-j/s组第一轮测试140题版本模拟试题及解析
  9. java应届生面试收集总结
  10. [USACO2019JAN]Sleepy Cow Sorting题解