高通LCD之MDP code简析

    xiaoxiao2021-03-25  87

    LCD相关code所在目录:

            kernel/drvier/video/msm/mdss/ 

    软件驱动主要分为三部分:

            MDP 驱动

            DSI 控制器驱动

            FrameBuffer驱动

    执行probe 的先后顺序:

           MDP probe →  DSI probe → FB probe

    1、MDP  probe 

          主要是对 使用的硬件资源进行初始化,同时在fb 设备中注册mdp 的使用接口,

           mdss_fb_register_mdp_instance(&mdp5);

             struct msm_mdp_interface mdp5 = {

                      .init_fnc =mdss_mdp_overlay_init,

                     .fb_mem_get_iommu_domain =mdss_fb_mem_get_iommu_domain,

                     .panel_register_done =mdss_panel_register_done,

                     .fb_stride =mdss_mdp_fb_stride,

                     .check_dsi_status =mdss_check_dsi_ctrl_status,

             };

         这些注册函数会在fb 初始化的时候调用。

    2、DSI  probe  

           解析模组厂提供的panel 的dtsi 文件,从那个文件中能获取到panel 的mode ,分辨率,刷新率,还有 Driver IC 的初始化 command;

           这些command 对于 video mode 和 command mode 是不一样的,在command mode 的时候还需要知道TE 相关的信息。

    3、Framebuffer  probe 

           从DSI 的数据结构中获取到panel 的相关信息,对MDP 做初始化。

            if (mfd->mdp.init_fnc) {

                    rc= mfd->mdp.init_fnc(mfd);

                    if(rc) {

                            pr_err("init_fncfailed\n");

                            returnrc;

                    }

            }

           init_fnc 就是 MDP probe 注册的  mdss_mdp_overlay_init,

           在 mdss_mdp_overlay_init 中,首先是对mdp interface 注册回调函数,

                mdp5_interface->on_fnc =mdss_mdp_overlay_on;

                mdp5_interface->off_fnc =mdss_mdp_overlay_off;

                mdp5_interface->release_fnc =__mdss_mdp_overlay_release_all;

                mdp5_interface->do_histogram =NULL;

                mdp5_interface->cursor_update =mdss_mdp_hw_cursor_update;

                mdp5_interface->dma_fnc =mdss_mdp_overlay_pan_display;

                mdp5_interface->ioctl_handler =mdss_mdp_overlay_ioctl_handler;

                mdp5_interface->panel_register_done= mdss_panel_register_done;

                mdp5_interface->kickoff_fnc =mdss_mdp_overlay_kickoff;

                mdp5_interface->get_sync_fnc =mdss_mdp_rotator_sync_pt_get;

                mdp5_interface->splash_init_fnc =mdss_mdp_splash_init;

                mdp5_interface->configure_panel =mdss_mdp_update_panel_info;

            如果连续显示被打开,则会调用mdss_mdp_overlay_handoff函数,

           此时,mdp5_data->ctl 还没有被初始化,所以调用__mdss_mdp_overlay_ctl_init 函数,在这个函数中会执行mdss_mdp_ctl_init,

           在这函数中,会根据panel 的 type 类   型,注册不同的控制函数,

           struct mdss_mdp_ctl*mdss_mdp_ctl_init(struct mdss_panel_data *pdata,

                                                structmsm_fb_data_type *mfd)

          {                                               

                  …...........

                case MIPI_VIDEO_PANEL:

                          ctl->is_video_mode = true;

                          if (pdata->panel_info.pdest ==DISPLAY_1)

                                     ctl->intf_num =MDSS_MDP_INTF1;

                          else

                                    ctl->intf_num = MDSS_MDP_INTF2;

                          ctl->intf_type =MDSS_INTF_DSI;

                          ctl->opmode =MDSS_MDP_CTL_OP_VIDEO_MODE;

                          ctl->start_fnc =mdss_mdp_video_start;

                         break;

                case MIPI_CMD_PANEL:

                         if (pdata->panel_info.pdest ==DISPLAY_1)

                                    ctl->intf_num =MDSS_MDP_INTF1;

                        else

                                   ctl->intf_num =MDSS_MDP_INTF2;

                                   ctl->intf_type =MDSS_INTF_DSI;

                                   ctl->opmode =MDSS_MDP_CTL_OP_CMD_MODE;

                                   ctl->start_fnc =mdss_mdp_cmd_start;

                        break;

                        …..........

             }

             在这里我们看出start_fuc根据不同的type注册的函数不同,所以在probe 的时候,不同的DSI mode 在初始化时注册的函数也不同,

             当我们在显示过程中要对DSI mode 做切换的时候,需要从初始化的注册函数开始进行重新配置。

             在__mdss_mdp_overlay_ctl_init 函数中,还会对vsync_handler进行注册,以及Mixer 的malloc 内存分配等工作。

             在这之后还要初始化MDP 所需要的clk,以及必要的成员进行初始化。

             在对MDP 初始化完成之后,还要对lcd使用的背光进行注册。

             if(!lcd_backlight_registered) {

                     backlight_led.brightness =mfd->panel_info->brightness_max;

                     backlight_led.max_brightness =mfd->panel_info->brightness_max;

                     if(led_classdev_register(&pdev->dev, &backlight_led))

                               pr_err("led_classdev_registerfailed\n");

                    else

                              lcd_backlight_registered= 1;

              }

             当开机动画的服务起来的时候,会取调用fb_open函数,打开fb设备,在这个函数中将__mdss_fb_display_thread添加到内核线程,

             同时发送FB_BLANK_UNBLANK亮屏的命令。至此,第一次使用fb驱动时,panel 已经被点亮。

    转载请注明原文地址: https://ju.6miu.com/read-13042.html

    最新回复(0)