[RK3288][Android6.0] MIPI DSI顯示屏移植除錯總結
阿新 • • 發佈:2019-01-09
Platform: ROCKCHIP
OS: Android 6.0
Kernel: 3.10.92
DTSI解析:
1. MIPI初始化
disp_mipi_init: mipi_dsi_init{
compatible = "rockchip,mipi_dsi_init";
//螢幕是否需要初始化
rockchip,screen_init = <1>;
//有幾條Lane, lcd drvier需要配置移植.
rockchip,dsi_lane = <4>;
//參考http://blog.csdn.net/kris_fei/article/details/52701053
//單位是MHz,範圍在90~1500MHz, 實際會有點偏差.
rockchip,dsi_hs_clk = <600>;
//單MIPI還是雙MIPI.
rockchip,mipi_dsi_num = <1>;
};
2. 上電時序
GPIO根據你在連到螢幕的pin作修改.
disp_mipi_power_ctr: mipi_power_ctr {
compatible = "rockchip,mipi_power_ctr";
mipi_lcd_rst:mipi_lcd_rst{
compatible = "rockchip,lcd_rst";
//reset pin,用的是gpio7的A4 pin, 高電平有效 .
rockchip,gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>;
//延時多久,根據lcd spec來確定具體值.
rockchip,delay = <10>;
};
mipi_lcd_en:mipi_lcd_en {
compatible = "rockchip,lcd_en";
//enable pin
rockchip,gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};
};
注意,這裡RK在使用GPIO_ACTIVE_HIGH是反了,比如SPEC中寫著是低電平有效,那麼這裡要配置為GPIO_ACTIVE_HIGH,而不是GPIO_ACTIVE_LOW.
這兩個PIN在lcdc節點中有重複配置,只要使用其中一組就可以.
/*lcdc0 as PRMRY(LCD),lcdc1 as EXTEND(HDMI)*/
&lcdc0 {
status = "okay";
rockchip,mirror = <NO_MIRROR>;
rockchip,cabc_mode = <0>;
power_ctr: power_ctr {
rockchip,debug = <0>;
/*lcd_en:lcd_en {
rockchip,power_type = <GPIO>;
gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};
lcd_cs:lcd_cs {
rockchip,power_type = <GPIO>;
gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_LOW>;
rockchip,delay = <10>;
};*/
};
};
3. 初始化命令
初始化命令問屏供應商獲取.
disp_mipi_init_cmds: screen-on-cmds {
compatible = "rockchip,screen-on-cmds";
//是否開啟cmd除錯
rockchip,cmd_debug = <1>;
//on-cmdsxxx可以隨便取,只要不重複就可以,code會按照放置而不是數字順序讀取.
rockchip,on-cmds1 {
compatible = "rockchip,on-cmds";
//命令在low power 還是 high speed (HSDT)傳送,一般都是LPDT.
rockchip,cmd_type = <LPDT>;
//用的平臺哪個通道dsi,單MIPI是0, 雙MIPI是2.
rockchip,dsi_id = <0>;
//依次是type|cmd|data, 只有一個引數用0x15.
rockchip,cmd = <0x15 0xcd 0xaa>;
rockchip,cmd_delay = <0>;
};
//......
rockchip,on-cmds17 {
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>;
rockchip,dsi_id = <0>;
//依次是type|cmd|data0|data1|datax..., 長包用0x39
rockchip,cmd = <0x39 0x57 0x00 0x00 0x00 0x00>;
rockchip,cmd_delay = <0>;
};
//.......
//下面兩條命令廠家有時候不會提供,需要自己補上.
rockchip,on-cmds40 {
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>;
rockchip,dsi_id = <0>;
//dcs_exit_sleep_mode在code中有定義,可以直接使用,包括下面的dcs_set_display_on.
rockchip,cmd = <0x05 dcs_exit_sleep_mode>;
rockchip,cmd_delay = <120>;
};
rockchip,on-cmds41 {
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>;
rockchip,dsi_id = <0>;
//只有命令沒有引數用0x05.
rockchip,cmd = <0x05 dcs_set_display_on>;
//這個延時很重要.
rockchip,cmd_delay = <120>;
};
};
4. 螢幕Timing
下面幾個引數需要參考屏spec來確定.
disp_timings: display-timings {
native-mode = <&timing0>;
compatible = "rockchip,display-timings";
timing0: timing0 {
//螢幕型別,雙MIPI是SCREEN_DUAL_MIPI.
screen-type = <SCREEN_MIPI>;
//無效引數
lvds-format = <LVDS_8BIT_2>;
//螢幕pixel format
out-face = <OUT_P888>;
//參考: http://blog.csdn.net/kris_fei/article/details/52701053
//此值影響fps,剛開始fps可以低一些,比如fps,後面再慢慢加大.
clock-frequency = <58200000>;
//水平有效畫素
hactive = <480>;
//垂直有效畫素
vactive = <1280>;
//hbp
hback-porch = <160>;
//hfp
hfront-porch = <160>;
//vbp
vback-porch = <10>;
//vfp
vfront-porch = <12>;
//h-sync
hsync-len = <24>;
//v-sync
vsync-len = <2>;
//下面幾個引數基本上不需要變化,除非螢幕顯示有異常.
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
swap-rb = <0>;
swap-rg = <0>;
swap-gb = <0>;
};
};
除錯過程:
1. Log檢視驅動是否已經正常跑起來,檔案有一些除錯巨集可以開啟,以獲取更多有用資訊.
2. 確認屏的供電電壓以及復位電壓正常(有遇到過板子的一個5V電源竄到復位引腳),上電時序要符合spec要求,這時螢幕可以不接,以免燒壞.
3. 如果螢幕需要初始化,確認命令是否傳送成功.有如下幾種方法確認:
a) 用示波器抓取Lan0N和Lane0P,難度較大,不到最後一步不用.
b) 把發出去的命令讀回來看是否一致,前提是讀取介面要正常.(我遇到的讀介面就沒成功,不知是不是介面問題,沒有深究)
c) 和廠商確認是否有型別工廠測試命令,配置完後屏可以自己顯示7彩色種類的畫面.
4. 如果還不亮,需要測量下Lane上面的電壓,LPDT在1.2V左右,HSDT在200mV左右.如果還是正常,就需要分析MIPI協議了,這一步一個是需要裝置,一個是分析時間會很長.
5.還有個情況就是是否使用了轉接板,因為是高速訊號,所以fpc線要求要高. 我就被這問題折磨了整整一週,後來換了插口和短的線就有顯示了.
OS: Android 6.0
Kernel: 3.10.92
DTSI解析:
1. MIPI初始化
disp_mipi_init: mipi_dsi_init{
compatible = "rockchip,mipi_dsi_init";
//螢幕是否需要初始化
rockchip,screen_init = <1>;
//有幾條Lane, lcd drvier需要配置移植.
rockchip,dsi_lane = <4>;
//參考http://blog.csdn.net/kris_fei/article/details/52701053
//單位是MHz,範圍在90~1500MHz, 實際會有點偏差.
rockchip,dsi_hs_clk = <600>;
//單MIPI還是雙MIPI.
rockchip,mipi_dsi_num = <1>;
};
2. 上電時序
GPIO根據你在連到螢幕的pin作修改.
disp_mipi_power_ctr: mipi_power_ctr {
compatible = "rockchip,mipi_power_ctr";
mipi_lcd_rst:mipi_lcd_rst{
compatible = "rockchip,lcd_rst";
//reset pin,用的是gpio7的A4 pin, 高電平有效
rockchip,gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_HIGH>;
//延時多久,根據lcd spec來確定具體值.
rockchip,delay = <10>;
};
mipi_lcd_en:mipi_lcd_en {
compatible = "rockchip,lcd_en";
//enable pin
rockchip,gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};
};
注意,這裡RK在使用GPIO_ACTIVE_HIGH是反了,比如SPEC中寫著是低電平有效,那麼這裡要配置為GPIO_ACTIVE_HIGH,而不是GPIO_ACTIVE_LOW.
這兩個PIN在lcdc節點中有重複配置,只要使用其中一組就可以.
/*lcdc0 as PRMRY(LCD),lcdc1 as EXTEND(HDMI)*/
&lcdc0 {
status = "okay";
rockchip,mirror = <NO_MIRROR>;
rockchip,cabc_mode = <0>;
power_ctr: power_ctr {
rockchip,debug = <0>;
/*lcd_en:lcd_en {
rockchip,power_type = <GPIO>;
gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};
lcd_cs:lcd_cs {
rockchip,power_type = <GPIO>;
gpios = <&gpio7 GPIO_A4 GPIO_ACTIVE_LOW>;
rockchip,delay = <10>;
};*/
};
};
3. 初始化命令
初始化命令問屏供應商獲取.
disp_mipi_init_cmds: screen-on-cmds {
compatible = "rockchip,screen-on-cmds";
//是否開啟cmd除錯
rockchip,cmd_debug = <1>;
//on-cmdsxxx可以隨便取,只要不重複就可以,code會按照放置而不是數字順序讀取.
rockchip,on-cmds1 {
compatible = "rockchip,on-cmds";
//命令在low power 還是 high speed (HSDT)傳送,一般都是LPDT.
rockchip,cmd_type = <LPDT>;
//用的平臺哪個通道dsi,單MIPI是0, 雙MIPI是2.
rockchip,dsi_id = <0>;
//依次是type|cmd|data, 只有一個引數用0x15.
rockchip,cmd = <0x15 0xcd 0xaa>;
rockchip,cmd_delay = <0>;
};
//......
rockchip,on-cmds17 {
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>;
rockchip,dsi_id = <0>;
//依次是type|cmd|data0|data1|datax..., 長包用0x39
rockchip,cmd = <0x39 0x57 0x00 0x00 0x00 0x00>;
rockchip,cmd_delay = <0>;
};
//.......
//下面兩條命令廠家有時候不會提供,需要自己補上.
rockchip,on-cmds40 {
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>;
rockchip,dsi_id = <0>;
//dcs_exit_sleep_mode在code中有定義,可以直接使用,包括下面的dcs_set_display_on.
rockchip,cmd = <0x05 dcs_exit_sleep_mode>;
rockchip,cmd_delay = <120>;
};
rockchip,on-cmds41 {
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>;
rockchip,dsi_id = <0>;
//只有命令沒有引數用0x05.
rockchip,cmd = <0x05 dcs_set_display_on>;
//這個延時很重要.
rockchip,cmd_delay = <120>;
};
};
4. 螢幕Timing
下面幾個引數需要參考屏spec來確定.
disp_timings: display-timings {
native-mode = <&timing0>;
compatible = "rockchip,display-timings";
timing0: timing0 {
//螢幕型別,雙MIPI是SCREEN_DUAL_MIPI.
screen-type = <SCREEN_MIPI>;
//無效引數
lvds-format = <LVDS_8BIT_2>;
//螢幕pixel format
out-face = <OUT_P888>;
//參考: http://blog.csdn.net/kris_fei/article/details/52701053
//此值影響fps,剛開始fps可以低一些,比如fps,後面再慢慢加大.
clock-frequency = <58200000>;
//水平有效畫素
hactive = <480>;
//垂直有效畫素
vactive = <1280>;
//hbp
hback-porch = <160>;
//hfp
hfront-porch = <160>;
//vbp
vback-porch = <10>;
//vfp
vfront-porch = <12>;
//h-sync
hsync-len = <24>;
//v-sync
vsync-len = <2>;
//下面幾個引數基本上不需要變化,除非螢幕顯示有異常.
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
swap-rb = <0>;
swap-rg = <0>;
swap-gb = <0>;
};
};
除錯過程:
1. Log檢視驅動是否已經正常跑起來,檔案有一些除錯巨集可以開啟,以獲取更多有用資訊.
2. 確認屏的供電電壓以及復位電壓正常(有遇到過板子的一個5V電源竄到復位引腳),上電時序要符合spec要求,這時螢幕可以不接,以免燒壞.
3. 如果螢幕需要初始化,確認命令是否傳送成功.有如下幾種方法確認:
a) 用示波器抓取Lan0N和Lane0P,難度較大,不到最後一步不用.
b) 把發出去的命令讀回來看是否一致,前提是讀取介面要正常.(我遇到的讀介面就沒成功,不知是不是介面問題,沒有深究)
c) 和廠商確認是否有型別工廠測試命令,配置完後屏可以自己顯示7彩色種類的畫面.
4. 如果還不亮,需要測量下Lane上面的電壓,LPDT在1.2V左右,HSDT在200mV左右.如果還是正常,就需要分析MIPI協議了,這一步一個是需要裝置,一個是分析時間會很長.
5.還有個情況就是是否使用了轉接板,因為是高速訊號,所以fpc線要求要高. 我就被這問題折磨了整整一週,後來換了插口和短的線就有顯示了.