mtk6737m的lk中lcm流程

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


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值