我所理解的高通平台Lcd驱动框架

帧缓冲(framebuffer)是 Linux 系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关系物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。对于帧缓冲设备而言,只要在显示缓冲区中与显示点对应的区域写入颜色值,对应的颜色会自动在屏幕上显示。帧缓冲为标准字符设备,主设备号为29,对应于/dev/fbn。lcd驱动就是属于帧缓冲设备驱动

LCD分类:

LCD按材料分有:STN(超扭曲阵列),TFT(薄膜晶体管),LTPS(低温晶体多晶硅), OLED(有机发光二极管)等。LCD的接口种类有:TTL RGB(数字RGB颜色接口),i80(又称MCU接口),LVDS(低压差分信号), RSDS(低摆幅差分信号),EDP(嵌入式显示接口),MIPI DSI(MIPI标准显示接口)等

LK:

  • aboot_init()
  • target_display_init()
  • gcdb_display_init()
  • oem_panel_select():选择使用的屏
  • dsi_panel_init():初始化 panel 参数
  • msm_display_init()
    • pdata->power_func 开启电源
    • pdata->pll_clk_func 使能时钟
    • msm_fb_alloc 为帧缓冲器(frame buffer)分配内存。
    • display_image_on_screen() 从splash分区获取lk logo图片,如果splash分区没有满足要求的数据,就显示默认的logo。
    • msm_display_config() dsi发送初始化命令
    • msm_display_on()  使能DSI VIDEO,用初始化命令来初始化panel
    • pdata->bl_func(1) 开启背光

kernel:

一般的执行顺序是:  MDP probe →  DSI probe → FB probe
  • MDP驱动:是高通内部的显示控制芯片。主要对使用的硬件资源进行初始化:时钟,中断,iommu,总线,DMA等。同时注册一些接口供fb设备使用。
  • DSI驱动:传输协议层设备。解析模组厂商提供的panel的dtsi文件,从哪个文件中能够获取到panel的mode,分辨率,还有Driver IC的初始化command;
  • FB驱动:显卡的驱动设备。实现Linux Framebuffer的注册和为上层用户提供访问控制接口。FB驱动在 mdss_fb.c 中完成
MDP驱动层
  • module_init(mdp3_driver_init) ----> platform_driver_register(&mdp3_driver)  然后根据 dsi 设备树文件里的mdss_mdp: qcom,mdss_mdp@1a00000 {compatible = "qcom,mdss_mdp3", 跟 mdp3_driver 的mdp3_dt_match[] = {  { .compatible = "qcom,mdss_mdp3",}}匹配
  • mdp3_probe()。匹配成功,则执行 probe函数。
    • mdp3_res->mdss_util = mdss_get_util_intf() 以及接下来关于 mdp3_res->mdss_util 执行全局变量 mdss_util 的初始化,fb注册时会用到。
    • mdss_fb_register_mdp_instance(&mdp3_interface):将mdp3_interface赋值给全局变量mdp_instance,用fb注册时初始化mdp等操作
    • mdp3_res->mdss_util->mdp_probe_done = true:标志mdp已经执行probe,dsi probe会检测

DSI驱动层

  • module_init(msm_dsi_v2_driver_init) ----> platform_driver_register(&msm_dsi_v2_driver),用哪个dsi驱动,是根据dsi设备树文件里的mdss_dsi0: compatible = "qcom,msm-dsi-v2"。然后再跟msm_dsi_v2_driver结构体里的driver.name = "msm_dsi_v2"进行匹配驱动。在kernel/drivers/video/msm/mdss/dsi_host_v2.c
  • msm_dsi_probe ()。如果匹配成功,则执行 msm_dsi_v2_driver 里的 .probe = msm_dsi_probe ,msm_dsi_probe 函数。(LCD 初始化信息 : 遍历设备树,寻找fb设备节点。初始化lcd屏幕,注册LCD屏幕。)
    • platform_set_drvdata (pdev, ctrl_pdata)。将 ctrl_pdata 的数据传递给 pdev 。
    • platform_get_resource ()。从设备中获取内存、中断资源
    • mdss_get_util_intf ():获得全局变量mdp_instance,在mdp probe时注册
    • of_platform_populate (pdev->dev.of_node, NULL, NULL, &pdev->dev); 将设备树数据填充给 platform_device
    • dsi_get_panel_cfg ()。 dsi 里的 MDSS_DSI0 在 MDSS_MDP 数组里面选定具体那个LCD 配置。再根据 MDSS_MDP 选定的 lcd 配置里  获取具体名字 qcom,mdss-dsi-panel-name = “xxxx” 的配置项。
    • dsi_find_panel_of_node ()。 通过上面获取的panel name找到dsi panel节点。
    • mdss_dsi_panel_init ()。 初始化节点里 lcd 的 panel 参数。
    • dsi_ctrl_config_init()。获得调节电源的数据,解析gpio、phy设置
    • msm_dsi_io_init()。时钟和regulator的初始化
    • dsi_register_interface()。注册 dsi 接口
    • msm_dsi_ctrl_init()。初始化控制器
    • msm_dsi_irq_init()。初始化中断
    • dsi_panel_device_register_v2()。注册panel_device设备节点,确认是视频还是命令模式,并且注册 dsi_event_handler 来与 mdp层、fb层进行通信。 

FB驱动的注册

  • module_init(mdss_fb_init)---------->> 调用 platform_driver_register(&mdss_fb_driver)。平台设备是 fb0 所以用的是 dsi 中 mdss_mdb: mdi_fb0 :compatible = "qcom,mdss_fb" 跟mdss_fb_driver 结构体里面的 driver.name = "mdss_fb" 进行匹配驱动。在kernel/drivers/video/msm/mdss/mdss_fb.c
  • mdss_fb_probe()。如果匹配成功,则执行 mdss_fb_driver 里的 .probe = mdss_fb_probe 函数。
    • dev_get_platdata(&pdev->dev) 。 获取 mdss_panel_data 结构信息。
    • mdss_fb_register() :fb_info 结构体进行填充,完成fb的注册,从mfd中取出屏信息放到fbi中,进行fb注册,并包含fb给用户空间的的操作函数
      • register_framebuffer(struct fb_info *fb_info):注册 fb设备(在函数同文件中,即:kernel\drivers\video\fbmem.c中 module_init(fbmem_init) ----> fbmem_init ----> register_chrdev()创建了一个字符设备,证明 lcd 驱动 就是一个字符设备驱动),这个就是核心层的接口,应用层可以对fb0节点的控制来操作framebuffer缓冲区
        • struct fb_info *fb_info。注册framebuffer时需要用到fb_info结构体,fb_info结构体又包含了 fb_ops 、fb_var_screeninfo和fb_fix_screeninfo结构体
          • fb_ops 结构体中的fb_read、fb_write用于应用层对framebuffer的读写操作,fb_mmap用于应用进程和framebuffer之间的内存映射,fb_ioctl用于应用层对framebuffer进行的一些控制操作,fb_check_var和fb_set_par分别用于获取和设置framebuffer的显示参数
          • fb_var_screeninfo 记录用户可修改的显示控制参数,包括屏幕分辨率和每个像素点的比特数。
          • fb_fix_screeninfo 中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址、长度。
      • mfd->mdp.init_fnc(mfd):调用MDP的接口:init_fnc = mdp3_init
        • mdp3_init
          • mdp3_ctrl_init 注册控制函数
    • led_classdev_register(&pdev->dev, &backlight_led) 。注册背光灯设备

猜你喜欢

转载自blog.csdn.net/weixin_42432281/article/details/113246959