高通LCD之MDP code简析

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 已经被点亮。


 


你可能感兴趣的:(Android之LCD开发)