[Android6.0][RK3399] Mipi LCD 通用移植調試流程

[Android6.0][RK3399] Mipi LCD 通用移植調試流程。

其實之前有寫過一篇關於 =RK3288 平臺 LCD 調試流程的博客 。不過是 RK3288 Android5.1 平臺的。
雖然實際上 Mipi 部分代碼實在是大同小異。但是距上次那篇文章到現在也已經不知不覺整整一年瞭,這一年 Mipi LCD 確實也調瞭不少。
索性再次重新梳理一下,也許會有別樣的收獲吧。
沒有看過那篇文章的同學也不需要再看瞭,這篇文章會更加全面的描述和分析調試流程。
這次文章以 RM72014 這顆 Driver IC 為例,從 RK Mipi LCD 代碼分析 到 屏的公式計算 再到實踐中的問題都會涉及,調試為主,分析為輔,比較冗長,大傢可以挑選自己需要的部分來看。
隨著我碰到的情況更多,本文也將不斷更新。
也歡迎大傢留言分享交流自己碰到的情況和解決方案。

本文地址:https://blog.csdn.net/dearsq/article/details/77341120
作者 Younix,歡迎轉載,轉載請著名出處,謝謝。

一、扣出屏 datasheet 中的關鍵信息

首先我們要找屏廠索取詳細版的屏的規格書,扣出其中的關鍵信息。
屏 Spec 的目錄大概如下:

其中我們最需要關註的是
General Specification
Power on/off sequence 上電下電時序
Timing 屏參

1. General Specification

提煉出來關鍵信息是
Hactive = 800 ,水平分辨率
Vactive = 1280 ,垂直分辨率
Lanes = 4 ,Mipi data 信號線通道數

2. Power on/off sequence

這個在屏點不亮的時候需要首先確認,這個我們後面會說。
我們在調屏的時候可以先把這個截圖保存到自己的筆記中,就不需要每次都去翻 datasheet 瞭。

3. Timing

關鍵信息提煉出來:
Hactive = 800
HFP = 24
HBP = 132
Hsync = 4

Vactive = 1280
VFP = 8
VBP = 8
VSync = 4

Pixel Clock Frequency(Pclk)= 74.88MHZ

這裡我們詳細說一下各個參數的含義,這個對我們後續調屏會非常有幫助。
另外根據以上的信息,我們還能計算出 Mipi Dsi Clock 。
DCLK = 100 + H_total×V_total × fps × 3 × 8 / lanes_nums
total 這裡指的是 sync + front + back + active
比如 H_total = Hsync + HFP(hfront-proch) + HBP(hback-porch) + Hactive
fps 指的是幀率,一般我們按照 60 幀來計算
3 × 8 代表一個 RGB 為 3 個字節,每個字節 8 bit
lanes 代表 mipi data 通道數

所以對於我這個屏
DCLK
= 100Mbps + H_Total × V_Total x fps x 3 x 8 / lanes_nums
= 100 + ( 800 + 21 + 132 + 4 ) x ( 1280 + 8 + 8 + 4 ) x 60 幀 x 3 字節 x 8 bit / 4 lanes
= 100Mbps + 449Mbps = 549 Mbps

重點看下面這張圖,

二、根據屏參 和 硬件設計填寫 dts

RK LCD 這部分的去耦合性已經做的很好瞭。
我們僅僅隻需要填寫 dts ,驅動會自動解析 dts ,
管腳控制部分會自動申請分配操縱 GPIO,屏初始化代碼(init cmds)和屏參(timing)將被自動封裝成 mipi dsi 命令進行發送。

2.1 創建屏的 dtsi 文件

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

&rk_screen {
  /* 8inch LCD Mipi */
  #include 
};

根據前面我們獲取到的屏參信息開始編寫 dtsi

2.1.1 Mipi Host

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

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

        /* 要幾條數據 lane*/
        rockchip,dsi_lane       = <4>;

        /* ddr clk 一條 lane 的傳輸速率 Mbits/s */
        /* 前面我們已經算得為 549 */
        rockchip,dsi_hs_clk     = <549>;

        /* 單mipi 還是雙 mipi*/
        rockchip,mipi_dsi_num   = <1>;
};

2.1.2 Timing

disp_timings: display-timings {
        native-mode = <&timing0>;
        compatible = "rockchip,display-timings";
        timing0: timing0 {
            screen-type = ;     //單mipi SCREEN_MIPI 雙mipi SCREEN_DUAL_MIPI
            lvds-format = ;     //不用配置
            out-face    = ;        //屏的接線格式 
                                             //配置顏色,可為OUT_P888(24位)、OUT_P666(18位)或者OUT_P565(16位)
            clock-frequency = <74488000>;   //dclk頻率,看規格書,或者 H×V×fps
            hactive = <800>;                 //水平有效像素
            vactive = <1280>;                //垂直有效像素
            hback-porch = <132>;              //水平同步信號 後肩
            hfront-porch = <24>;              //水平同步信號 前肩
            vback-porch = <8>;
            vfront-porch = <8>;            
            hsync-len = <4>;                //水平同步信號
            vsync-len = <4>;
            hsync-active = <0>;              //hync 極性控制 置 1 反轉極性
            vsync-active = <0>;
            de-active = <0>;                 //DEN 極性控制
            pixelclk-active = <0>;           //dclk 極性控制
            swap-rb = <0>;                   //設 1 反轉顏色 red 和 blue
            swap-rg = <0>;
            swap-gb = <0>;
    };
};

2.1.3 init cmds

屏場給的初始化時序往往不會是 RK 平臺的。我們可能需要自己轉換一下。
不過一般也很好理解,我們分別分析兩組平臺的例子:

展訊平臺
GP_COMMAD_PA(02);SPI_WriteData(0x53);SPI_WriteData(0x24);
GP_COMMAD_PA(03);SPI_WriteData(0xf0);SPI_WriteData(0x5a);SPI_WriteData(0x5a); Delay_ms(30);
GP_COMMAD_PA(01);SPI_WriteData(0x11); Delay_ms(100);
GP_COMMAD_PA(01);SPI_WriteData(0x29); Delay_ms(30);
GP_COMMAD_PA(04);SPI_WriteData(0xc3);SPI_WriteData(0x40);SPI_WriteData(0x00);SPI_WriteData(0x28);
GP_COMMAD_PA(02);SPI_WriteData(0x50);SPI_WriteData(0x77);
GP_COMMAD_PA(02);SPI_WriteData(0xe1);SPI_WriteData(0x66);
GP_COMMAD_PA(02);SPI_WriteData(0xdc);SPI_WriteData(0x67);
GP_COMMAD_PA(02);SPI_WriteData(0xd3);SPI_WriteData(0xc8);
GP_COMMAD_PA(02);SPI_WriteData(0x50);SPI_WriteData(0x00);
GP_COMMAD_PA(02);SPI_WriteData(0xf0);SPI_WriteData(0x5a);
GP_COMMAD_PA(02);SPI_WriteData(0xf5);SPI_WriteData(0x80);
Delay(120);

GP_COMMAD_PA 表示 dsi packets 的個數
SPI_WriteData 接口用來寫數據
Delay_ms 表示延時 xx 毫秒
所以
GP_COMMAD_PA(02);SPI_WriteData(0x53);SPI_WriteData(0x24);
表示給屏 0x53 指令,有一個指令參數,為 0x24
GP_COMMAD_PA(03);SPI_WriteData(0xf0);SPI_WriteData(0x5a);SPI_WriteData(0x5a); Delay_ms(30);
表示給屏 0xf0 指令,有兩個指令參數 0x5a 和 0x5a ,並且延時 30ms
GP_COMMAD_PA(01);SPI_WriteData(0x11); Delay_ms(100);
表示給屏 0x11 指令,沒有指令參數,並且延時 100ms
GP_COMMAD_PA(01);SPI_WriteData(0x29); Delay_ms(30);
表示給屏 0x29 指令,沒有指令參數,並且延時 30ms

後面同理。

細心的同學發現瞭我這裡強調瞭指令參數的個數。
因為這涉及到瞭 dsi 協議中 dsi 傳輸的數據類型。
根據 《MIPI-DSI-specification-v1-1.pdf》49 頁我們可以看到,有如下這些數據類型。

我們隻需要關註 0x05 ,0x15,0x39,他們分別對應的 dsi 參數類型是 無參指令(Short No parameters)、單參數指令(Short 1 parameter)、多參數指令(Long Command Packets)。

MTK 平臺
data_array[0]=0x00043902;
data_array[1]=0x8983FFB9; 
dsi_set_cmdq(&data_array, 2, 1); 
MDELAY(10);

分析得知
array[0] 中 04 代表要傳輸的字節數,3902 代表傳輸的是多參指令
//MTK平臺 3900 代表無參 3905 表示單參 3902 表示多參
array1 中的參數全部為傳輸的參數,而且正確的傳參數據是倒著的 B9 FF 83 89
所以移植到 RK 平臺應該是

rockchip,on-cmds1 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = ;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x39 0xB9 0xFF 0x83 0x89>;
                            //0x39 為 DSI 數據類型、  0xB9 為LCD 命令、後面為參數
                            rockchip,cmd_delay = <10>;
}
* Mipi DSI 協議中 Generic 和 DCS 的區別*

另外,值得一提的是。在上面 Mipi 的 Spec 中,大傢可以看到 0x29 和 0x39 都可以表示多參,0x03 和 0x05 都可以表示無參,0x13 和 0x15 都可以表示單參。但他們不是沒有區別的。

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

RK 平臺

上述兩個例子舉完瞭。我們繼續寫 RK 平臺 RM72014 的 inital cmds:

對應的 inital cmds

 disp_mipi_init_cmds: screen-on-cmds {
    rockchip,cmd_debug = <0>;
    compatible = "rockchip,screen-on-cmds";
    rockchip,on-cmds1 {
        compatible = "rockchip,on-cmds";
        rockchip,cmd_type = ;
        rockchip,dsi_id = <2>;
        rockchip,cmd = <0x15 0x53 0x24>;
        rockchip,cmd_delay = <0>;
    };

    rockchip,on-cmds2 {
        compatible = "rockchip,on-cmds";
        rockchip,cmd_type = ;
        rockchip,dsi_id = <2>;
        rockchip,cmd = <0x39 0xf0 0x5a 0x5a>;
        rockchip,cmd_delay = <30>;
    };

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

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

//... 

  rockchip,on-cmds11 {
        compatible = "rockchip,on-cmds";
        rockchip,cmd_type = ;
        rockchip,dsi_id = <2>;
        rockchip,cmd = <0x15 0xf0 0x5a>;
        rockchip,cmd_delay = <0>;
    };

  rockchip,on-cmds12 {
        compatible = "rockchip,on-cmds";
        rockchip,cmd_type = ;
        rockchip,dsi_id = <2>;
        rockchip,cmd = <0x15 0xf5 0x80>;
        rockchip,cmd_delay = <120>;
    };

cmd_type 表示 dsi 傳輸類型,分為 HSDT 高速(Video 模式) 和 LPDT 低速(command 模式)
dsi_id 表示通過哪一組 mipi 發送。0 表示第一組 Mipi ,2 表示兩組同時發。1 表示第二組 Mipi,但是一般不會出現隻用第二組的情況,所以不會是 1 。

### 2.2 硬件管腳 GPIO 配置

有兩種方式控制屏相關的 GPIO,一種是在屏 dtsi 中配置,一種是交由 vop 進行控制。

前者的例子如下,比如可以在 dtsi 中完成電源控制配置
“`c
## 屏電源控制配置
disp_mipi_power_ctr: mipi_power_ctr {
compatible = “rockchip,mipi_power_ctr”;
mipi_lcd_rst:mipi_lcd_rst{
compatible = “rockchip,lcd_rst”;
rockchip,gpios = <&gpio4 GPIO_D6 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};

    // 配置 lcd_en GPIO 哪一路 ,有可能沒有 LCD_EN 那麼就是 VCC 常供電
    mipi_lcd_en:mipi_lcd_en {
            compatible = "rockchip,lcd_en";
            rockchip,gpios = <&gpio1 GPIO_B5 GPIO_ACTIVE_HIGH>;
            rockchip,delay = <10>;
    };

    //還可能有片選 cs

};
“`
也可以交由 vop 控制,比如這樣:

&vopl_rk_fb {
    status = "okay";
  rockchip,prop = ;
  assigned-clocks = <&cru DCLK_VOP1_DIV>;
  assigned-clock-parents = <&cru PLL_CPLL>;
    power_ctr: power_ctr {
        rockchip,debug = <0>;
        lcd_en: lcd-en {
            rockchip,power_type = ;
            gpios = <&gpio1 GPIO_B5 GPIO_ACTIVE_HIGH>;
            rockchip,delay = <10>;
        };
        lcd_rst: lcd-rst {
            rockchip,power_type = ;
            gpios = <&gpio4 GPIO_D6 GPIO_ACTIVE_HIGH>;
            rockchip,delay = <10>;
        };
    };
};

GPIO_A / B C 的定義在 kernel/arch/arm64/boot/dts/include/dt-binding/pinctl/rk.h 中
delay 需要根據上面的時序圖進行設置,一般 10ms 可以適配大部分的屏幕瞭。
這裡的 rockchip,gpios 我們根據硬件進行配置:

        rockchip,gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>;  // GPIO4_D6

        rockchip,gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; //GPIO1_B5

三、背光 Backlight

背光常用的有三種情況:
一是 常開。
二是 背光 IC 使能後,輸入 PWM 信號調光。
三是 背光 IC 使能後,通過 FB 獲得反饋自動進行調光。

比如我曾用到一顆 背光 IC 是這樣的:

enter description here

enter description here

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

根據相關的原理圖

enter description here
enter description here

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

完成 dts 中 backlight 相關的配置

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 背光使能管腳
    };

四、確認驅動代碼和 vop/lcdc 通道打開

make menuconfig 確認一下三個宏打開

enter description here

dts 中確認

//   RK3399 平臺
    &mipi0_rk_fb {
      status = "disabled";
    };

// RK3288 平臺
    &dsi_host {
      status = "disabled";
    };

五、調試流程

一般按照上面的順序,編譯,燒錄後。
幸運的話,屏就可以點亮(有東西顯示)瞭。

但是這個世界對長的帥的人就是如此不公平。
至少我從來沒有一次就直接點亮過。

下面我們開始進入調試階段。

5.1 檢查電壓

檢查原理圖上各個供電管腳的電壓
VCC 、VCC IO 是否正常。
VCC IO 是給 GPIO 供電用,比如 RST。有的屏會兼容 3.3V 和 1.8 V 的 IO 電平,但是大部分不會。
VCC_LCDA 、VCC_LCDK 電壓是否滿足要求。

確認電壓正常後,關機,上屏,結合 開機 Log 看屏部分是否正常初始化。

5.2 背光是否正常

背光沒亮的話確認一下接上屏的時候,量一量 VDD_LCDA 的電壓為多少(串聯電路大概能到 20V+)
沒有就去檢查背光電路供電電壓和 backlight 相關的配置(比如背光功能使能的 GPIO 有沒有控制到、PWM通道是否配置正確)。

5.3 framebuffer 是否有數據產生

3368/3399 的命令為

echo bmp > sys/class/graphics/fb0/dump_buf 
或者
echo bin > sys/class/graphics/fb0/dump_buf

312x 的命令為

cat /dev/graphics/fb0 > /data/fb0.yuv

將生成的文件 adb pull 出來後可以通過圖片查看軟件,譬如 7YUV 讀取輸出的 bmp 文件或者 bin 文件。
如果有軟件能正常顯示畫面,說明是 mipi 的問題。
如果軟件不能正常顯示畫面,說明 fb 刷下來的數據有問題

5.4 打印 Mipi LCD 相關 Log 信息

打開 Mipi DBG 的接口

driver/video/rockchip/transmitter/rk32_mipi_dsi.c 中的:
    #define MIPI_DBG(x...) printk(KERN_INFO x)

driver/video/rockchip/screen/lcd_mipi.c 中的:
    #define MIPI_SCREEN_DBG(x...) printk(KERN_ERR x)

看看 log 中是否有異常。

譬如
probe 函數是否正常;
是否有調用到 rk32_dsi_enable() 函數,該函數為 lcdc 調用 mipi 的入口函數;
初始化 mipi 的過程中是否有報錯等等

電源控制部分對應的操作函數:driver/video/rockchip/screen/lcd_mipi.c 的
rk_mipi_screen_pwr_enable(),rk_mipi_screen_pwr_disable()。

Clock 部分在 drivers/video/rockchip/transmitter/rk32_mipi_dsi.c 可以添加如下打印

 256 static int rk312x_mipi_dsi_phy_set_gotp(struct dsi *dsi, u32 offset, int n)
 257 {
 258     u32 val = 0, temp = 0, Tlpx = 0;
 259     u32 ddr_clk = dsi->phy.ddr_clk;
 260     u32 Ttxbyte_clk = dsi->phy.Ttxbyte_clk;
 261     u32 Tsys_clk = dsi->phy.Tsys_clk;
 262     u32 Ttxclkesc = dsi->phy.Ttxclkesc;
 263     printk("%s : ddr_clk %d\n", __func__, ddr_clk);

1123 static int rk32_mipi_dsi_enable_hs_clk(void *arg, u32 enable)
1124 {
1125     struct dsi *dsi = arg;
1126     printk("rk32_mipi_dsi_enable_hs_clk,enable=%d\n",enable);
1127     rk32_dsi_set_bits(dsi, enable, phy_txrequestclkhs);
1128     return 0;
1129 }

dts 中也有一些 Debug 的開關可以打開以協助分析問題。RK 手冊中會有更加詳細的描述,這裡不贅述瞭。

5.5 上電時序是否正常

根據前面我們從 datasheet 中扣出來的上電時序圖,確認上電時序是否正常,VCC、RST、MIPI 順序是否正常。
1. VCC 使能有沒有起作用。
2. RST 是否有一個 低-高 的變化,沒有則是 rst 設置的觸發方式可能反瞭
3. 在 RST 變高後會開始傳輸數據,量 lanes 是否有數據輸出。抓取數據需要一定規格的示波器和差分探頭,我們用普通的示波器大致看看有沒有數據輸出就夠瞭。

如果到這篇文章中的所有辦法都用完瞭還沒有點亮,隻能來這裡重新測 data 和 clk 波形是否正常。
如果也正常,那就需要確認 mipi phy 是否把初始化命令正確發送出來。用差分探頭在單端模式下抓 mipi phy 的 lane0N 和 lane0P。
命令也是正常的,屏依舊還沒有點亮,隻能進一步分析 mipi 協議瞭。

5.6 clock 是否正常

用示波器量波形看 DCLK 的頻率為多少,是否為 dsi_hs_clk 中設置的(可能實際的會略低一點)。
實際的 DCLK 是否滿足屏的要求。

5.7 可以顯示瞭但是 花屏/閃屏/抖動 等

見後面的問題集錦

六、問題集錦

RK 的官方文檔中描述瞭不少問題,我這邊就不再贅述瞭。
以下是我碰到的一些問題的解決辦法,還有一些從網上搜到的發揮瞭作用的解決辦法,一並都附在這裡瞭。

6.1 RST 復位不正常

我們 RST 是低電平有效,所以我想當然的將 RST 設置為
ACTIVE_LOW。

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

!你設置的觸發電平
你設置的觸發電平

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

!ACTIVE_LOW
ACTIVE_LOW

即先高再低。
所以是錯的,改為 ACTIVE_HIGH 後正常。

但是雖然填的是 ACTIVE_HIGH ,但是根據驅動應該還是屬於低電平有效的,這裡是 RK 平臺 driver 的實現有問題。
修改後 lane 有數據傳遞瞭。

6.2 有數據傳輸,但是 cmds 有問題

cmds 有的參數超過瞭 32個字節(有個有36個字節,有個有39個字節),完成 dtsi 中 cmds 編寫後
燒錄,板子跑飛,空指針異常。
發現傳遞 這個超長 參數的時候有內存溢出情況。
於是跟代碼發現 dcs_cmd.cmds 的數據類型為 int cmds[32],所以擅自想當然的將包拆成瞭 39 = 28+11,還將其中的延時設置為 0 。
這樣當然是不行的。但是一切都是基於這個拆瞭包的 cmds 來調,走瞭不少彎路。

於是去聯系原廠的工程師,說平臺參數大小有限制,咨詢拆包是否可行。
他們說可以直接修改 cmds 數組大小,將 cmds[32] 改成瞭 cmds[400] 。

這個問題在 RK 後來的 kernel 中被更新瞭。

所以有時候碰到問題需要確認一下 kernel 是不是最新的,也許會有意想不到的效果。

6.3 開機 Logo 閃爍,且水平方向向右偏移壓縮瞭半個屏幕

在點亮屏後剛開始有開機 logo 閃爍,向右偏移瞭近半個屏幕的長度。
重新確認 clock-frequence 後發現少打瞭一個 0 。
修改後解決瞭 閃爍,大偏移 的問題。

6.4 偏移巨大

如下面這張圖,偏移的特別多,可能是 dclk 有問題,修改 dsi_hs_clk 由 504 降到 496 解決。

enter description here

比如下面這張圖,也是偏移的很多,將 dclk 增加解決。

6.5 偏移一點點

如下圖,一般修改 HBP、HFP、VBP、VFP 即可。

enter description here

6.6 水平方向似乎被裁剪(偏移)

如下圖,實際是 HBP 的問題。
增大 HBP 後解決,將 HBP 由 10 增加到 30。

enter description here

6.7 正常開機可以點亮,休眠喚醒無法點亮。

dclk 有問題。
用示波器去測究竟 dclk 出來的是多少。
比如我設置的 470 開機啟動可以點亮,休眠喚醒無法點亮。
用示波器一測,竟然才 200 Mbps,修改到 584 後(實際出來為 450) 休眠喚醒才也可以點亮。

6.8 白屏(偶爾)

白屏有可能是靜電問題,把 LCD 拿到頭發上擦幾下,如果很容易出現白屏那肯定就是靜電問題瞭。
另外一個在有Backend IC的情況下,也有可能bypass沒處理好。

6.9 白屏(開機 Logo 到 Android 動畫之間)

結束開機logo至Android動畫出現之間出現閃屏或者閃白光的情況。
原因:在這個時間點kernel會會對屏再次初始化,我們可以軟件上屏蔽第一次初始化動作從而解決。

6.10 白屏(進入睡眠 suspend / 開始顯示 resume 時)

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

6.11 花屏

LCD 初始化成功,但是 RGB 沒有刷過來。
優先確認 timing 中的 pclk,另外還有可能是總線速度有問題。

開機花屏最簡單的解決方式是,在 Init 結束的地方加一個刷黑屏的功能。也可以在睡眠函數裡加延時函數。

6.12 閃爍(快速,大量)

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

6.13 閃爍(偶爾)

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

6.14 閃爍(喚醒 resume 時)

RST 後下載初始化時序時間過長,適當減少 delay 時間可以解決。

6.15 抖動

測時序,延時不足

6.16 灰屏(喚醒時)

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

6.17 水波紋

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

6.18 調節對比度

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

6.19 圖像顏色不正常

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

6.20 明暗色過渡部分,出現不停閃動的亮點

pixel clock 極性,由上升沿采樣改為下降沿采樣即可。

最後,我上面說的都是廢話。
最好的資料就是 RK 官方的TRM 、屏的 Spec 和 Mipi DSI 協議規格書。
LCD 這邊的變數太多瞭,一萬個工程師可以碰到一萬種屏不顯示的情況。
網上搜再多資料也沒有抓波、抓上電時序,對照官方手冊確認 來的實在。

You May Also Like