rk3128 lcd 驱动调试记录

最近刚调试了基于rk3128平台的lcd驱动,顺便记录总结一下,有不足之处,望各位不吝赐教!


关于framebuffer(帧缓冲设备)的架构这里就不多罗嗦了,不会的可以网上百度,这个很多的


1.代码架构

       drivers/video/rockchip/transmitter/
                |_ rk32_mipi_dsi.c /* MIPI 驱动主体文件 */
                |_ rk32_mipi_dsi.h /* 寄存器以及结构体的定义 */
                |_ mipi_dsi.c /* 封装的函数指针接口函数, 供 lcd_mipi.c 调用, 函数的具体实现

       在 rk32_mipi_dsi.c 中 */
                |_ mipi_dsi.h /* mipi 协议相关的宏定义以及函数指针结构体定义 */

       drivers/video/rockchip/screen/
                |_ lcd_mipi.c /* 屏参 dtsi 文件的解析 */

由于rk3128平台使用了3.10以后的内核,所以采用了dts的形式来管理驱动,刚开始的时候会觉得顺手,用多了还是相当方便的


2.代码架构图

        无论是正常的开机流程以及休眠唤醒的流程,显示相关的模块都是要和 fb 以及
vop(lcdc)交互的。rk32_dsi_enable()和 rk32_dsi_disable()函数作为 MIPI 和 vop 之
间 的 交 互 的 总 入 口 函 数 。 另 外 还 有 一 对 rk32_mipi_power_up_DDR() 和
rk32_mipi_power_down_DDR()函数是单独供 ddr 变频的时候使用,
正常的开机以及休
眠唤醒流程不走这两个函数。开机流程图如下图所示:

rk3128 lcd 驱动调试记录_第1张图片

dsi_init() : 该函数主要实现 mipi host 和 phy 的上电以及初始化工作。

rk_mipi_screen_standby() : 屏的供电以及屏的初始化工作(屏初始化命令的发送)

dsi_enable_video_mode() : command 模式和 video 模式的切换,发送命令一般是在 command 模式下,正常数据传输是在 video 模下。

dsi_is_enable() : mipi host 的关闭与开启。


3.移植过程

      a.配置menuconfig

             rk3128 lcd 驱动调试记录_第2张图片


             rk3128 lcd 驱动调试记录_第3张图片


    b.添加关于lcd的dtsi文件(屏参文件)

         在kernel/arch/arm/boot/dts中随便一个其他mipi屏的dtsi文件参考其写法(3.10内核的新变化,也可以不用


           屏参文件包含四个部分:mipi host 配置、屏电源控制配置、屏初始化序列和屏参。

           b.1   mipi host的配置

                    disp_mipi_init: mipi_dsi_init{
                        compatible = "rockchip,mipi_dsi_init";
                        rockchip,screen_init    = <1>;
                        rockchip,dsi_lane        = <4>;
                        rockchip,dsi_hs_clk        = <310>;
                        rockchip,mipi_dsi_num    = <1>;
                     };

                            screen_init : 表示屏是否需要初始化,如果需要则置为 1.

                    dsi_lane : mipi 数据传输需要几条数据 lane,这个一般根据原理图和 mipi 屏的规格书来配置。这个指的是每个 mipi 的数据 lane 数。譬如如果是双 mipi,每个 mipi 为 4 lane。那么此处仍然设置为 4。

                    dsi_hs_clk : 屏 ddr clk,表示一条数据 lane 的传输速率,单位为 Mbits/s。有个大概的计算公式:100+H_total*V_total*fps*3*8/lanes。H_total,V_total 包括 active,bp,fp 和 sync-len 的和;fps 为帧率,刚调试一款屏时,fps 为 50 多帧就好,然后慢慢抬高;3 为一个像素点为 rgb 3 个字节;8 为 8 bits;lanes 为(dsi_lane*mipi_dsi_num) ;100 为实际的结果要比理论值大 100M 左右。上面计算得到的值只是大概值并非精确的值,但是对于一般的屏都适用,对于部分屏需要微调该值。

                    mipi_dsi_num : 单 mipi 还是双 mipi,也是根据原理图和屏幕规格书来配置的。如果是双 mipi 则置为 2。单 MIPI 的屏 SDK 代码默认设置的是 MIPI_TX,所以单 MIPI 是接MIPI_TX 这一路,双 MIPI 接法:MIPI_TX 这路接左屏,MIPI_TX/RX 这一路接右屏。

                b.2    屏电源的配置

                      &lcdc {
                                 status = "okay";

                                 backlight = <&backlight>;
                                 pinctrl-names = "default", "gpio";
                                 pinctrl-0 = <&lcdc0_lcdc>;
                                 pinctrl-1 = <&lcdc0_gpio>;

                                 rockchip,fb-win-map = ;
                                 power_ctr: power_ctr {
                                         rockchip,debug = <0>;
                                         lcd_cs: lcd_cs {
                                                 rockchip,power_type = ;
                                                 gpios = <&gpio1 GPIO_B4 GPIO_ACTIVE_HIGH>;
                                                 rockchip,delay = <10>;
                                         };

                                         lcd_rst:lcd_rst{
                                                 rockchip,power_type = ;
                                                 gpios = <&gpio0 GPIO_D0 GPIO_ACTIVE_LOW>;
                                                 rockchip,delay = <20>;
                                          };
        
                                          lcd_en:lcd_en {
                                                  rockchip,power_type = ;
                                                  gpios = <&gpio0 GPIO_B0 GPIO_ACTIVE_LOW>;
                                                  rockchip,delay = <20>;
                                           };
                                   };
                          };

                    电源配置的 gpios 需要根据原理图来配置 lcd_en 等各对应哪路 gpio

                b.3    屏的初始化序列

                         disp_mipi_init_cmds: screen-on-cmds {
                                  compatible = "rockchip,screen-on-cmds";
                                  rockchip,cmd_debug = <1>;

                                  rockchip,on-cmds1 {
                                          compatible = "rockchip,on-cmds";
                                          rockchip,cmd_type = ;
                                          rockchip,dsi_id = <0>;
                                          rockchip,cmd = <0x15 0x80 0xAC>;
                                          rockchip,cmd_delay = <0>;
                                  };

                                  rockchip,on-cmds2 {
                                          compatible = "rockchip,on-cmds";
                                          rockchip,cmd_type = ;
                                          rockchip,dsi_id = <0>;
                                          rockchip,cmd = <0x15 0x81 0xB8>;
                                          rockchip,cmd_delay = <0>;
                                  };

                                                    。

                                                    。

                                                   

                                 rockchip,on-cmds8 {
                                          compatible = "rockchip,on-cmds";
                                          rockchip,cmd_type = ;
                                          rockchip,dsi_id = <0>;
                                          rockchip,cmd = <0x05 0x11>;
                                          rockchip,cmd_delay = <10>;
                                   };

                                   rockchip,on-cmds9 {
                                           compatible = "rockchip,on-cmds";
                                           rockchip,cmd_type = ;
                                           rockchip,dsi_id = <0>;
                                           rockchip,cmd = <0x05 0x29>;
                                           rockchip,cmd_delay = <10>;
                                  };

                      };     

                            cmd_type : 命令是在 low power(LPDT)还是 high speed(HSDT)下发送。

                          dsi_id : 命令通过哪个 mipi 发送。0 表示在 mipi0 发送,1 表示在 mipi1 发送,2 表示双 mipi 同时发送。因为很少出现单独使用 mipi1 的情况,所以对于单 mipi,这个值默认是 0;对于双 mipi,这个值  是 2。

                     cmd : 初始化命令。格式:命令类型(如 0x05/0x15/0x39)+命令+参数。具体细节见 mipi 协议文档。
            

                    注:最后两条命令是mipi协议规定的,一定要加的0x11 Exit_sleep_mode,0x29:Set_display_on 表示告诉显示设备(屏)可以开始显示图像数据了。


                b.4   屏的参数

                          disp_timings: display-timings {
                                  native-mode = <&timing0>;
                                  compatible = "rockchip,display-timings";
                                  timing0: timing0 {
                                          screen-type = ;
                                          lvds-format = ;
                                          out-face    = ;
                                          clock-frequency = <51668640>;
                                          hactive = <1024>;
                                          vactive = <600>;
                                          hback-porch = <160>;
                                          hfront-porch = <160>;
                                          vback-porch = <23>;
                                          vfront-porch = <12>;
                                          hsync-len = <10>;
                                          vsync-len = <1>;
                                          hsync-active = <0>;
                                          vsync-active = <0>;
                                          de-active = <0>;
                                          pixelclk-active = <0>;
                                          swap-rb = <0>;
                                          swap-rg = <0>;
                                          swap-gb = <0>;
                                    };
                            };

                            screen-type : 屏幕类型,对于 mipi 屏来说有两种选择:单 mipi(SCREEN_MIPI);双 mipi(SCREEN_DUAL_MIPI);

                            lvds-format : lvds 数据格式。对于 mipi 来说是无效参数,不用配置

                            out-face : 屏幕接线格式
                           上述三个参数的取值在 include/dt-bindings/rkfb/rk_fb.h 中定义。

                           clock-frequency : dclk 频率,单位为 HZ,一般屏的规格书中有,如果没有可以通过公式计算:H*V(包括同步信号)*fps

                            Hactive : 水平有效像素

                            Vactive : 垂直有效像素

                           hback-porch/hfront-porch/hsync-len : 水平同步信号

                           vback-porch/vfront-porch/vsync-len : 垂直同步信号

                           hsync-active 、 vsync-active 、 de-active 、 pixelclk-active :分 别 为 hync,vsync,DEN,dclk 的极性控制。置 1 将对极性进行翻转。

                           swap-rb、swap-rg、swap-gb : 设 1 将对对应的颜色进行翻转。

                b.5    板级文件配置

                          屏参文件配置好以后,需要在板级文件中包含这个屏参文件:
                          #include "lcd-xxxxx-mipi.dtsi"

                          因为在芯片 dtsi 中默认是关闭的,所以需要在板级板级文件中开启 mipi host

                          &dsihost0 {
                                  status = "okay";
                          };

                          因为是单mipi,只要配置一个就可以了

4.调试遇到的问题与总结

        1.开机后lcd屏闪

           问题定位:修改代码,提高dclk到一个较高的频率;

           (1)若提高pclk后,屏闪现象消失

         现象分析:说明此现象是刷新频率较低引起的;

         解决方法:将dclk提高到一个合适的较高频率;

           (2) 若提高dclk后,屏闪现象仍然存在

         现象分析:说明此现象不是刷新频率较低引起的,这种情况是LCD极性设置不正确造成的;

            解决方法:在dtsi文件中修改LCD的极性;

         2.休眠唤醒只有背光亮,屏不亮

           问题定位:查看唤醒时的log,代码跑崩了,重新上电,屏是可以起来的,可能是唤醒屏时,en,rst的配置有问题

自己其实当时用一个很low的方法来获取rst,en脚的管脚号,在lcd_mipi.c中通过解析dtsi的那个文件的那个函数,获得了gpio号,

然后在用gpio_direction_output的方法设置管脚号(这也是我刚开始不习惯的原因),后来在rk_fb.c的文件中发现有现成的接口,做了修改,代码倒是崩溃了,但是屏还是不亮,通过log发现休眠唤醒时,居然没有走我的初始化序列,一看,发现少了0x11和0x29两条指令,加上后,问题解决

           解决方法修改获得pin脚号的方法,加上0x11和0x29命令
               

你可能感兴趣的:(android驱动调试)