LCD Mipi 調試方法及問題彙總

調試流程

1. 設置 dts 中的參數 並 配置管腳

仿造平臺的其他 lcd-*-mipi.dtsi 編寫 lcd-xxx-mipi.dtsi 後 需要在 主 dts 文件中包含這個 dtsi

#include “lcd-xxx-mipi.dtsi“
  • 1

先看屏的手冊

裏面的關鍵信息有 分辨率(540×960) 接口(2條lanes)

## MIPI Host配置
disp_mipi_init: mipi_dsi_init{
        compatible = "rockchip,mipi_dsi_init";

        /* 是否要在 dtsi 中初始化 1 0 */
        rockchip,screen_init    = <1>;

        /* 要幾條數據 lane ,根據原理圖和 mipi 規格書*/
        rockchip,dsi_lane       = <2>;

        /* ddr clk 一條 lane 的傳輸速率 Mbits/s  */
        /* 100 + H_total×V_total×fps×3(一個rgb爲3字節)×8(8bits)/lanes  */
        /* 這裏的 total 指的是 sync + front + back + active */
        /* 比如 H_total = Hsync + HFP(hfront-proch)  + HBP(hback-porch) + Hactive  */
        rockchip,dsi_hs_clk     = <1000>;

        /* 單mipi 還是雙 mipi*/
        rockchip,mipi_dsi_num   = <1>;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

看原理圖,完成管腳的配置

可以看到,我這裏只用到了 LCD_RST,沒有用到 LCD_EN (是 VCC_LCD),說明是默認使能的,也沒有 LCD_CS
所以進行如下配置

## 屏電源控制配置
disp_mipi_power_ctr: mipi_power_ctr {
        compatible = "rockchip,mipi_power_ctr";
        mipi_lcd_rst:mipi_lcd_rst{
                compatible = "rockchip,lcd_rst";
                rockchip,gpios = <&gpio2 GPIO_B7 GPIO_ACTIVE_LOW>;
                rockchip,delay = <100>;
        };
        /*
        // 配置 lcd_en GPIO 哪一路 ,有可能沒有 LCD_EN 那麼就是 VCC 常供電
        mipi_lcd_en:mipi_lcd_en {
                compatible = "rockchip,lcd_en";
                rockchip,gpios = <&gpio0 GPIO_C1 GPIO_ACTIVE_HIGH>;
                rockchip,delay = <100>;
        };
        */
        //還可能有片選 cs
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

根據屏的規格書 完成 timings 配置
垂直方向的信息:

重要的參數有 垂直同步信號 VFP VBP VS 對應填充到屏參中的 Vfront-proch Vback-proch Vsync-len
同樣
水平方向的信息:

要注意的是, HS HBP HFP 雖然最小值是 5,但是不能設置的這麼低
因爲後面還有兩條要求,HBLK = HS + HBP + HFP >= 24 且 HS + HBP > 19
所以最初設置 HS = HBP = HFP = 10

// lcd-xxx-mipi.dtsi 中的 屏參
disp_timings: display-timings {
        native-mode = <&timing0>;
        compatible = "rockchip,display-timings";
        timing0: timing0 {
            screen-type = <SCREEN_MIPI>;        //單mipi SCREEN_MIPI 雙mipi SCREEN_DUAL_MIPI
            lvds-format = <LVDS_8BIT_2>;        //不用配置
            out-face    = <OUT_P888>;       //屏的接線格式 
            //配置顏色,可爲OUT_P888(24位)、OUT_P666(18位)或者OUT_P565(16位)
            clock-frequency = <120000000>;      //dclk頻率,看規格書,或者 H×V×fps
            hactive = <540>;            //水平有效像素
            vactive = <960>;            //垂直有效像素
            hback-porch = <80>;         //水平同步信號
            hfront-porch = <81>;            //水平同步信號
            vback-porch = <21>;
            vfront-porch = <21>;            
            hsync-len = <10>;           //水平同步信號
            vsync-len = <3>;
            hsync-active = <0>;         //hync 極性控制 置 1 反轉極性
            vsync-active = <0>;
            de-active = <0>;            //DEN 極性控制
            pixelclk-active = <0>;          //dclk 極性控制
            swap-rb = <0>;              //設 1 反轉顏色
            swap-rg = <0>;
            swap-gb = <0>;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

2. 背光部分

在 rk3288-tb_8846.dts 中還需要打開 mipi 相關的通道 並 配置背光相關的信息。
首先根據這顆背光 IC 的 datasheet

我們瞭解到 EN 拉高時背光使能,拉低時背光禁能; FB 接受反饋信號,動態控制背光亮度

我們知道這顆背光芯片有兩種調光方式
一是 EN 輸入 PWM 信號進行調光
二是 EN 使能後,通過 FB 獲得反饋信號進行調光。
根據我們的原理圖


BL_EN 是普通的 GPIO ,LCDC_BL 是支持 PWM 輸出的管腳,所以得知我們硬件採用的是第二種調光方式

backlight {
        compatible = "pwm-backlight";
        pwms = <&pwm0 0 25000>;     //在這裏配置採用的是 pwm0 還是 pwm1
        brightness-levels = <255 254 253 252 251 250 249 248 247 246 245 244 243 242 241 240
             239 238 237 236 235 234 233 232 231 230 229 228 227 226 225 224 223 222 221 220
             219 218 217 216 215 214 213 212 211 210 209 208 207 206 205 204 203 202 201 200
             199 198 197 196 195 194 193 192 191 190 189 188 187 186 185 184 183 182 181 180
             179 178 177 176 175 174 173 172 171 170 169 168 167 166 165 164 163 162 161 160
             159 158 157 156 155 154 153 152 151 150 149 148 147 146 145 144 143 142 141 140
             139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120
             119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100
             99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70
             69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
             39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
             9 8 7 6 5 4 3 2 1 0>;
        default-brightness-level = <200>;
        enable-gpios = <&gpio7 GPIO_A2 GPIO_ACTIVE_HIGH>;   //BL_EN 背光使能管腳
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3. LCD 初始化序列 cmds

最後如果有初始化序列的,打開之前的 screen-init = < 1 > ,並且填充初始化序列

## 屏初始化序列
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 = <LPDT>;     //命令是在 low power(LPDT)還是 high speed(HSDT)下發送
                rockchip,dsi_id = <2>;          //選擇通過哪個mipi發送 0==》單mipi0  1==》mipi1 2==》雙mipi0+1
                rockchip,cmd = <0x05 0x01>;     //初始化命令
                    //第一個字節 DSI 數據類型; 第二個字節爲 LCD 的 CMD; 後面爲指令內容
                rockchip,cmd_delay = <0>;
        };
        */
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

值得一講的是 cmd,一般屏廠或者FAE都會給出初始化序列。
比如這裏我拿到的是 MTK 平臺的 LCD 初始化代碼:

data_array[0]=0x00043902;
data_array[1]=0x8983FFB9; 
dsi_set_cmdq(&data_array, 2, 1); 
MDELAY(10);
  • 1
  • 2
  • 3
  • 4

分析得知
array[0] 中 04 代表要傳輸的字節數,3902 代表傳輸的是長包數據
//MTK平臺 3900 代表不傳值 3905 表示傳一個數據 3902 表示傳多個數據
array[1] 中的參數全部爲傳輸的參數,而且正確的傳參數據爲 B9 FF 83 89
所以移植到 RK 平臺就是:

rockchip,on-cmds1 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = <LPDT>;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x39 0xB9 0xFF 0x83 0x89>;
                            //0x39 爲 DSI 數據類型、  0xB9 爲LCD CMD、後面爲參數
                            rockchip,cmd_delay = <10>;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

我們根據 這塊 lcd 的 規格書,也能夠驗證結果初始化命令參數的正確性:

DSI 協議中 ,0x29 和 0x39 區別:在 Mipi 協議中,它倆都表示 長包(Long Packet)數據類型。
但是 Mipi DSI 的 Spec 中寫着兩者的區別 0x29 屬於 Generic long write ,0x39 屬於 DCS long write。
DCS 系的讀寫命令,可帶參數,常用於 LCD 初始化參數命令。
Generic 系讀寫命令,是協議規範外的命令,通常是一些 IC 定製的,只要確保主機和外設同意這些數據格式即可,通常和 DCS 通用。

另外值得一說的是大部分初始化代碼的最後一般都是 exit_sleep 和 display_on。

rockchip,on-cmds15 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = <LPDT>;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x05 dcs_exit_sleep_mode>;
                            rockchip,cmd_delay = <120>;
                    };
                    rockchip,on-cmds16 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = <LPDT>;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x05 dcs_set_display_on>;
                            rockchip,cmd_delay = <100>;
                    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

這裏 dcs_exit_sleep_mode dcs_set_display_on 在 drivers/video/rockchip/transmitter/mipi_dsi.h 中有定義

#define dcs_set_display_on  0x29
#define dcs_exit_sleep_mode 0x11
  • 1
  • 2

所以表示的 0x05 0x11 表示的含義爲,短包傳輸 發送 exit_sleep_mode 命令
這兩個命令後的延時*相當重要*!!務必確認好。

4. 打開 config

根據 RK 手冊中的要求
make menuconfig
打開三個宏

這裏也可以順手把 LVDS 的相關代碼給關掉

5. 檢查電壓

先不要接上屏,編譯完代碼燒錄後開機。
檢查原理圖上各個供電管腳的電壓(DVDD、IOVDD 是否爲 3.3V,VDD_LCDA 是否爲 5-10V,VDD_LCDK 是否爲 0V),確認電壓正常後,關機,上屏,結合 開機log 看能否正常開機。

6. 調試順序

6.1 背光有沒有亮

背光沒亮的話確認一下接上屏的時候,量一量 VDD_LCDA 的電壓爲多少(串聯電路大概能到 20V+)
沒有就去檢查背光電路供電電壓和 backlight 相關的配置

6.2 開機 以及 從休眠狀態喚醒 都沒有顯示內容

之所以這樣說是因爲可能存在 休眠喚醒 能顯示,但 開機 無法顯示的情況
如果兩種情況都沒有顯示,那麼很有可能是 cmds 或者 timing 仍然有問題
1. 用示波器量波形看 DCLKP 的頻率爲多少,是否爲 clock-frequency 中設置的(可能實際的會略低一點)
2. 量 RST 是否有一個 低-高 的變化,沒有則是 rst 設置的觸發方式可能反了
3. 在 RST 高低高後會開始傳輸數據,量 lanes 是否有數據輸出。抓取數據需要專門的儀器,我們用示波器大致看看有沒有數據輸出就夠了。

我在調試的時候就發現 lane 一直爲低電平,沒有數據傳輸,然後採取量 RST 發現喚醒屏後待到屏幕快滅了 RST 纔會被拉高。跟代碼發現 RK 平臺的實現是

!你設置的觸發電平
你設置的觸發電平
  • 1
  • 2

但是我設置的觸發電平是 低電平有效 ACTIVE_LOW

!ACTIVE_LOW
ACTIVE_LOW
  • 1
  • 2

即先高再低,所以是錯的,改爲 ACTIVE_HIGH 後正常。
但是雖然填的是 ACTIVE_HIGH ,但是應該還是屬於低電平有效的,這裏是 RK 平臺 driver 的實現有問題。
修改後 lane 有數據傳遞了。

但是有數據傳遞仍然怎麼樣都沒有顯示。
這時候有極大可能是 cmds 有問題。
下面着重講一下我 cmds 碰到的問題。

6.3 我碰到的 cmds 問題

我當時拿到 MTK 平臺參數的時候,有的參數超過了 32個字節(有個有36個字節,有個有39個字節),完成 dtsi 中 cmds 編寫後
燒錄,板子跑飛,空指針異常。
發現傳遞 這個超長 參數的時候有內存溢出情況。
於是跟代碼發現 dcs_cmd.cmds 的大小爲 int cmds[32],所以擅自想當然的將包拆成了 39 = 28+11,還將其中的延時設置爲 0 。
這樣當然是不行的。但是一切都是基於這個拆了包的 cmds 來調,走了不少彎路。
後來一切的其他參數都確定沒問題了。
於是去聯繫原廠的工程師,說平臺參數大小有限制,諮詢拆包是否可行。他們說建議修改 cmds[32] 改成了 cmds[400] 。
修改後發現屏幕終於點亮了。
終於點亮了。
點亮了。

問題集錦

RK 手冊中已經有相當一部分很有參考價值的了。
這裏的一部分是自己碰到的,有的是查資料時候收集到覺得很有意義的,都放這裏了。

1. 我調試中碰到的問題

  1. 在點亮屏後剛開始有開機 logo 閃爍,向右偏移了近半個屏幕的長度,等問題。
    重新確認 clock-frequence 後發現少打了一個 0 。
    修改後解決了 閃爍,大偏移 的問題。
  2. 最初偏移還是有點大,如下圖。

    稍微降低 hs_clk ,由 504 降低到 496 解決。
  3. 垂直方向會顯示多一點內容,如下圖。

    調整 VFP 後解決,將 VFP 增大爲 15 。
  4. 下面會有黑邊,如下圖。

    稍微增大 VBP 後解決,將 VBP 增大爲 15。
  5. 開機 android 最左邊會被裁剪一部分,如下圖。

    增大 HBP 後解決,將 HBP 由 10 增加到 30。
    至此屏幕已完美顯示。

2. 其他一些雜散的需要確認的內容

是否有framebuffer輸出,要是改動了display這塊的clk很有可能沒有buffer輸出的,可以通過cat /dev/graphyics/fb0查看有沒有輸出字符。(我是通過google 插件 vysor 直接連接開發板看有沒有內容顯示,windows 平臺也可以用 total control 軟件來看)

3. 參數爲 8 字節、16字節 傳輸會異常?錯,可以正常傳輸。

看到一篇文章中說,數據 cmds 爲 8 字節 和 16 字節 的時候,寫命令和數據的函數要注意變化。
然後在調試的時候發現 如果 參數爲這兩種情況的時候, 傳輸模式會自動由 LP 模式 變成 HS 模式。但這只是個意外
跟蹤代碼後發現,其實是可以正常傳輸的,我這只是個意外而已:
http://blog.csdn.net/dearsq/article/details/52369879

4. 顯示偏移、圖像位置偏差

timing 中的參數設置有誤。優先確認。
看着圖像調節前掃、回掃進行左右上下移動

5. 白屏

隨機出現白屏有可能是靜電問題,把LCD拿到頭髮上擦幾下,如果很容易出現白屏那肯定就是靜電問題了。另外一個在有Backend IC的情況下,也有可能bypass沒處理好。
結束開機logo至android動畫出現之間出現閃屏或者閃白光的情況。原因:在這個時間點kernel會會對屏再次初始化,我們可以軟件上屏蔽第一次初始化動作從而解決。

6. 屏在進出睡眠或者顯示過程中白屏

喚醒屏幕閃白光問題,說白了是背光早亮了,很有可能是下序列mdelay太久,改小點就沒有這個問題了。根本原因屏幕初始化序列下慢了。
sleep out(0x11)和 display on(0x29)之間需要 mdelay(120ms)左右。

7. 花屏

說明 lcd 初始化成功,但是沒有 rgb 刷過來。
timing 中的參數設置有誤。優先確認 pclk。
花屏 還可能是總線速度有問題。
開機就花屏最簡單的解決方式是,在 Init 結束的地方加一個刷黑屏的功能。也可以在睡眠函數里加延時函數。

8. 屏幕閃爍

  1. pclk 有問題
    在最開始的時候,我的 pclk 漏了一個 0 ,爲之前的 1/10 此時就有圖像閃爍問題。
  2. proch 有問題
    在調試完後,我嘗試將 proch 增加到極限,發現會出現圖像閃爍的問題。

9. 屏幕抖動

測時序,延時不足

10. 屏幕閃動

通過調節電壓來穩定,一般調節的電壓爲VRL、VRH、VDV和VCM

11. 喚醒閃屏問題

這是由於每次重新RST下序列過程delay久了導致,適當減少delay時間

12. 屏幕喚醒顯示灰色底面

寄存器沒有使能外部升壓電路

13. 水波紋

通常都是rgb interface polarity導致,需要調整pclk hsync vsync de極性使之符合平臺極性

14. 調節對比度

VRL、VRH、VDV和VCM,這些電壓也可以用來調節亮暗(對比度)
也可以通過調節Gamma值來實現,要調節的對象爲 PRP、PRN、VRP、VRN 等

15. 確認有沒有 framebuffer 輸出

要是改動了display這塊的clk很有可能沒有buffer輸出的,可以通過cat /dev/graphyics/fb0 查看有沒有輸出字符
如果有說明是 mipi 還沒有調通,如果沒有說明是 fb 有問題

16. 圖像顏色不正常

可能時鐘型號極性反了
可能 VCOM 調節不正常
進行 GAMMA 校正

感謝

這段時間基本上把有些 Mipi 移植和 RK 平臺 LCD 移植的文章看遍了。以下文章很有幫助。本文的問題集錦部分有一部分是將以下文章中的內容蒐羅過來的:
android lcd調試 高通平臺lcd調試深入分析總結(mipi和rgb接口)
firefly rk3288 的 wiki 百科
Mipi DSI 協議介紹
Mipi 調試經驗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章