mtk-drm commit送显流程(二)

drm_atomic_helper_commit

前面讲完drm_atomic_commit函数先调用drm_atomic_check_only检查完参数的合法性;最后调用config->funcs->atomic_commit,此函数是drm驱动初始化drm_mode_config时创建的。可以由SOC厂商实现,也可以使用drm-core中的helper函数:drm_atomic_helper_commit

为了方便我们更好的理解atomic_commit函数,先得搞清楚drm_atomic_helper_commit这个函数的流程。

int drm_atomic_helper_commit(struct drm_device *dev,

struct drm_atomic_state *state,

bool nonblock)

{

    ......

    INIT_WORK(&state->commit_work, commit_work);

    ret = drm_atomic_helper_prepare_planes(dev, state);

    ......

    if (!nonblock) {

        ret = drm_atomic_helper_wait_for_fences(dev, state, true);

    }

    ret = drm_atomic_helper_swap_state(state, true);

    ......

    if (nonblock)

        queue_work(system_unbound_wq, &state->commit_work);

    else

        commit_tail(state);

    return 0;

}

1)初始化state->commit_work这个工作队列;

2)交换state,把刷新的state赋值给各个组件的state,并将上一次刷新的state保存;

3)根据nonblock标志决定如何调用commit_tail;如果nonblock被置位,则启动commit_work(commit_work中也是调用commit_tail函数);否则直接调用commit_tail函数;

commit_tail函数的流程如下:

static void commit_tail(struct drm_atomic_state *old_state)

{

    ......

    drm_atomic_helper_wait_for_fences(dev, old_state, false);

    drm_atomic_helper_wait_for_dependencies(old_state);

    ......

    if (funcs && funcs->atomic_commit_tail)

        funcs->atomic_commit_tail(old_state);

    else

        drm_atomic_helper_commit_tail(old_state);

    ......

}

commit_tail函数主要是进行一些fence等事件的判断(fence的内容我们现在先不关注,后面会专门去拆解这一部分),然后调用:drm_atomic_helper_commit_tail,这个函数才是刷图需要关注的重点。

函数重要的调用流程已经用红色序号标出,drm_atomic_helper_commit_modeset_disables函数流程比较复杂,下图有一个思维导图。

1)如果mode发生改变(其实就是state->mode_changed,state->active_changed,state->connectors_changed状态被置位),就会关掉crtc和encoder;SOC厂商需要根据硬件行为实现对应的hook函数,比如关掉显示和TCON等;

2)crtc_set_mode函数,如果active被置位,则调用crtc->helper_private->mode_set_nofbencoder->helper_private->atomic_mode_set函数,来将对应的mode配置到硬件,这些回调函数都需要SOC厂商来实现。

一句话总结:如果只是mode发生了变化,就先关crtc和encoder,再配置mode到crtc和encoder;如果只是状态发生变化,则只关掉crtc和encoder。

接下来还有一个重磅函数:drm_atomic_helper_commit_planes,大部分的硬件行为都是在这个函数配置的。其中,plane->helper_private->atomic_update函数根据plane_state中图像位置,大小和fb的显存地址信息等,作为layer的参数更新到硬件;crtc->helper_private->atomic_flush(crtc, old_crtc_state)更新除了layer的其他相关内容。这2个回调函数都会用到之前保存在state里面的信息。

接下来调用drm_atomic_helper_commit_modeset_enables函数,函数会把之前关闭的crtc和encoder打开,也就是配置硬件来打开显示和TCON,一并打开encoder。

drm_atomic_helper_commit_hw_done:上报hw_done事件,通知硬件配置已经完成。

drm_atomic_helper_wait_for_vblanks:等待vblank事件,硬件更新完成之后,会等到下一个vsync中断到来后才会生效,vblank事件会在vsync中断处理函数中上报;drm中默认等待50ms。由于接触的都是dsi_vdo的屏幕,vsync中断其实就是DSI模块中FRAME_DONE_INT_FLAG这个中断。

到这里,drm_atomic_helper_commit函数流程就结束了,下面来看mtk的实现。

mtk_atomic_commit

static int mtk_atomic_commit(struct drm_device *drm,

struct drm_atomic_state *state, bool async)

{

    ret = drm_atomic_helper_prepare_planes(drm, state);

    ret = drm_atomic_helper_swap_state(state, 0);

    if (async)

        mtk_atomic_schedule(private, state);

    else

        mtk_atomic_complete(private, state);

}

mtk的实现流程跟drm_atomic_helper_commit基本一致。async跟nonblock是同一个参数,最后都会调用到:mtk_atomic_complete

static void mtk_atomic_complete(struct mtk_drm_private *private,

struct drm_atomic_state *state)

{

    mtk_atomic_wait_for_fences(state);

    drm_atomic_helper_commit_modeset_disables(drm, state);

    drm_atomic_helper_commit_modeset_enables(drm, state);



    mtk_set_first_config(drm, state);

    mtk_drm_enable_trig(drm, state);

    mtk_atomic_disp_rsz_roi(drm, state);

    mtk_atomic_calculate_plane_enabled_number(drm, state);

    mtk_atomic_check_plane_sec_state(drm, state);

    mtk_atomic_mml(drm, state);

    if (!mtk_atomic_skip_plane_update(private, state))

        drm_atomic_helper_commit_planes(drm, state, DRM_PLANE_COMMIT_ACTIVE_ONLY);

    if (!mtk_drm_helper_get_opt(private->helper_opt, MTK_DRM_OPT_COMMIT_NO_WAIT_VBLANK))

        drm_atomic_helper_wait_for_vblanks(drm, state);

}

mtk对比drm_atomic_helper_commit函数,新增了不少客制化的东西,由于缺乏相应的文档和理解,目前对这一部分存疑。估计后续要搞清楚mtk实现的那一套disp_ddp的东西,这里就先过吧。

mtk_drm_enable_trig:更新trigger位???

mtk_atomic_disp_rsz_roi:???

mtk_atomic_mml:???

前面已经提到了,drm_atomic_helper_commit_planes会调用:plane->helper_private->atomic_update去更新layer信息到硬件。

最后会调用:crtc->helper_private->atomic_flush做善后的处理,mtk对此的实现也就是:mtk_drm_crtc_atomic_flush(这个函数完全看不懂???)。

写到这里,atomic_commit流程基本是写完了。给人的感觉是,从分析到mtk实现的drm_mode_config->func->atomic_config开始,代码中全是充斥着ddp和cmdq相关的内容,这一块如果不了解disp中相关的IP,这一块是完全看不懂。我们是终端设备的工程师,芯片厂mtk对这一块的资料是少之又少,这部分等后面有机会再补坑了。

后续的计划是:

1)vblank的流程;

2)fence的处理;

3)研究一下mtk_ddp的东西;

4)研究一下mtk DSI的东西;

5)还可以写一点mtk lcm的移植流程;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值