生活随笔
收集整理的這篇文章主要介紹了
高通平台MSM8916LCM模块移植(一)-bootloader部分
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
此次移植打算分成兩個(gè)模塊來說,bootloader部分和kernel部分。在實(shí)際的移植調(diào)試過程中也是這么分成了兩個(gè)部分分別調(diào)試。
? ? ? ? ? ?高通平臺(tái)中的bootloader叫做LK(Little Kernel,對(duì)于LCM來說LK部分相當(dāng)重要,它不僅要負(fù)責(zé)開機(jī)部分的LCD顯示任務(wù),還要負(fù)責(zé)傳參給kernel的LCM驅(qū)動(dòng),指導(dǎo)kernel選擇合適的LCM參數(shù)。
1、LK中LCM啟動(dòng)流程
注:read_panel_id()和read_panel_id_ddr3()為私有添加,非高通庫上代碼。
在這個(gè)流程圖中,需要著重了解的有oem_panel_select() mdss_dsi_initialize() 和read_panel_id()函數(shù),這三個(gè)函數(shù)主要是做lcd兼容,下面來具體看函數(shù)內(nèi)容。
2、oem_panel_select()
這個(gè)函數(shù)在 android/bootloader/lk/target/msm8916/oem_panel.c文件中主要是識(shí)別不同IC,賦值給參數(shù)panel_id,panel_id的使用在同一文件中的 init_panel_data()函數(shù)中。
[objc]?view plaincopy
/********************************************************??*Name:????????oem_panel_select??*Function:????selection?different?lcm?panel??*Description:?1)This?func?will?be?roaded?twice,first?time?use?default?value??[objc]?view plaincopy
????????????????second?time?depend?on?lk_lcd_id?value?match?correct?branch.??*Author:??????Jerry.peng??*********************************************************/??bool?oem_panel_select(const?charchar?*panel_name,?struct?panel_struct?*panelstruct,??????????????struct?msm_panel_info?*pinfo,??????????????struct?mdss_dsi_phy_ctrl?*phy_db)??{??????uint32_t?soc_version?=?board_soc_version();??????uint32_t?gpio_state?=?0;????????gpio_tlmm_config(LCM_GPIO_DETECT,?0,?GPIO_INPUT,?GPIO_NO_PULL,?GPIO_8MA,?GPIO_ENABLE);<span?style="color:#33ff33;">?</span><span?style="color:#009900;">??????mdelay(10);??????gpio_state?=?gpio_status(LCM_GPIO_DETECT);??????dprintf(CRITICAL,?"[PHC]:oem_panel.c?soc_version?=?0X%x?value,gpio_state=%d\n",soc_version,gpio_state);??????????????if(0x6089?==?lk_lcd_id?||?0xFFFF?==?lk_lcd_id){?????????????????????<span?style="color:#009900;">????????????????????if(gpio_state){????????????????????????????????????????????<span?style="color:#009900;">??????????????????????panel_id?=?ILI9806E_WVGA_VIDEO_HONGTAO_PANEL;??????????????????????dprintf(CRITICAL,"[PHC]:?ILI9806E?hongtao?panel?choosed\n");??????????????????}?else?{??????????????????????panel_id?=?ILI9806E_WVGA_VIDEO_HAIFEI_PANEL;??????????????????????dprintf(CRITICAL,"[PHC]:?ILI9806E?haifei?panel?choosed\n");??????????????????}??????????????}??[objc]?view plaincopy
else?if(0x8018?==?lk_lcd_id){?????????????????????????????????????<span?style="background-color:?rgb(255,?255,?255);"><span?style="color:#009900;">??????if(gpio_state){??????????panel_id?=?OTM8019_WVGA_VIDEO_SUXIAN_PANEL;??????????dprintf(CRITICAL,"[PHC]:?otm8019?panel?choosed\n");??????}?else?{??????????panel_id?=?OTM8019_WVGA_VIDEO_HAOSHITONG_PANEL;??????????dprintf(CRITICAL,"[PHC]:?otm8018b?panel?choosed\n");??????}??}??[objc]?view plaincopy
????????????else?if?(0x3551?==?lk_lcd_id){???????????????????????????????<span?style="font-family:?Arial,?Helvetica,?sans-serif;"><span?style="color:#009900;">????????????????????????panel_id?=?NT35512S_WVGA_VIDEO_HAIFEI_PANEL;??????????????????????dprintf(CRITICAL,"[PHC]:?NT35512S?haifei?panel?choosed\n");??????????????}??panel_init:??????pinfo->pipe_type?=?MDSS_MDP_PIPE_TYPE_RGB;??????return?init_panel_data(panelstruct,?pinfo,?phy_db);??}??3、mdss_dsi_initialize()
mdss_dsi_initialize() 在文件Android/bootable/bootloader/lk/platform/msm_shared/mipi_dsi.c 中
在 mipi_dsi.c 文件開始先申明全局變量 lk_lcd_id
[cpp]?view plaincopy
uint32_t?lk_lcd_id?=?0xFFFF;??[cpp]?view plaincopy
???????int?mdss_dsi_panel_initialize(struct?mipi_dsi_panel_config?*pinfo,?uint32_t??????????broadcast)??{??????int?status?=?0;????????#if?(DISPLAY_TYPE_MDSS?==?1)??<span?style="background-color:?rgb(255,?255,?255);"><span?style="color:#cc33cc;">???if?(0xffff?==?lk_lcd_id?){??????????????????????????????????????</span><span?style="color:#009900;">??????????????lk_lcd_id?=?read_panel_id();???????????????????</span><span?style="color:#009900;">???????????target_force_cont_splash_disable(true);??????????msm_display_off();??????????target_force_cont_splash_disable(false);??????????target_display_init(NULL);?????????????????????????????</span><span?style="color:#009900;">??????????return?1;??????}</span></span>??????if?(pinfo->panel_cmds)?{??????????if?(broadcast)?{??????????????status?=?mdss_dual_dsi_cmds_tx(pinfo->panel_cmds,??????????????????????pinfo->num_of_panel_cmds);????????????}?else?{??????????????status?=?mipi_dsi_cmds_tx(pinfo->panel_cmds,??????????????????????pinfo->num_of_panel_cmds);??????????????if?(!status?&&?target_panel_auto_detect_enabled())??????????????????status?=??????????????????????mdss_dsi_read_panel_signature(pinfo->signature);??????????}??????????dprintf(CRITICAL,"[PHC]:?status=%d\n",status);??????}??#endif??????return?status;??}??4、read_panel_id()
read_panel_id()為讀取LCM ID的函數(shù),里面包括讀取各中IC函數(shù),詳細(xì)看下面代碼。
[cpp]?view plaincopy
<pre?name="code"?class="cpp">????????uint32_t?read_panel_id(void)??{??????uint32_t?lcd_id?=?0xffff;??[cpp]?view plaincopy
<span?style="white-space:pre">????</span>if(?mdss_dsi_read_ili9806e_id()?)??<span?style="white-space:pre">????????</span>lcd_id?=?0x6089;?????????<span?style="white-space:pre">????</span>else?if(?mdss_dsi_read_otm8018b_id())??<span?style="white-space:pre">????????</span>lcd_id?=?0x8018;?????????<span?style="white-space:pre">????</span>else?if(?mdss_dsi_read_nt35512s_id()?)??<span?style="white-space:pre">????????</span>lcd_id?=?0x3551;?????????????if(lcd_id?==?0xffff){??????????lcd_id?=?0x1283;??????????dprintf(CRITICAL,"[PHC]:?no?panel?id?readed?use?default?\n");??????return?lcd_id;??}??不同IC的讀取ID的函數(shù)都大同小異,我這里就用ili9806e這顆IC來舉例:
[cpp]?view plaincopy
<pre?name="code"?class="cpp">static?struct?mipi_dsi_cmd?apex_ili9806e_panel_set_cmd[]?=?{?????????{sizeof(apex_ili9806e_cmd0),?apex_ili9806e_cmd0},??};????static?char?apex_ili9806e_panel_set_pkt_size[4]?=?{0x08,?0x00,?0x37,?0x80};??static?struct?mipi_dsi_cmd?apex_ili9806e_panel_set_pkt_size_cmd[]?=?{??????{sizeof(apex_ili9806e_panel_set_pkt_size),?apex_ili9806e_panel_set_pkt_size},};??static?char?apex_ili9806e_panel_manufacture_id[4]?=?{0x00,?0x00,?0x06,?0xA0};??static?struct?mipi_dsi_cmd?apex_ili9806e_panel_manufacture_id_cmd[]?=?{??????{sizeof(apex_ili9806e_panel_manufacture_id),?apex_ili9806e_panel_manufacture_id},};??[cpp]?view plaincopy
<pre?name="code"?class="cpp">static?bool?mdss_dsi_read_ili9806e_id(void)??{??????char?rec_buf[24];??????char?*rp?=?rec_buf;??????uint32_t?*lp,temp,ret,?data?=?0;??????????????ret?=?mipi_dsi_cmds_tx(apex_ili9806e_panel_set_cmd,?ARRAY_SIZE(apex_ili9806e_panel_set_cmd));??????????mdelay(10);??????????ret?=?mipi_dsi_cmds_tx(apex_ili9806e_panel_set_pkt_size_cmd,?ARRAY_SIZE(apex_ili9806e_panel_set_pkt_size_cmd));??????????mdelay(10);??????????ret?=?mipi_dsi_cmds_tx(apex_ili9806e_panel_manufacture_id_cmd,?ARRAY_SIZE(apex_ili9806e_panel_manufacture_id_cmd));??????????mdelay(10);??????????if(ret?==?1)??????????????lcm_id_retry?+=?1;??????????mipi_dsi_cmds_rx(&rp,?3);??????????????lp?=?(uint32_t?*)rp;??????????data?=?(uint32_t)*lp;??????????data?=?ntohl(data);??????????????data?=?data?&?0xFF;??????????dprintf(CRITICAL,"[PHC]:?ili9806e?id:?0x%x\n",?data);??????????if(data?==?0x98)?{??????????????lcm_id_retry?=?0;??????????????return?true;??????????}??????????else??????????????return?false;??}??? ? ? ?到此,整個(gè)lk中LCM兼容和移植的主體部分就已經(jīng)完成了,剩下就是填LCM參數(shù)進(jìn).h文件,這里再對(duì)整個(gè)流程進(jìn)行一個(gè)補(bǔ)充整理。
? ? ? ?首先解釋下為什么不用高通默認(rèn)的兼容方法,因?yàn)楦咄J(rèn)的兼容需要用到各種硬件id,平臺(tái)id,這些都是在SBL中設(shè)定的,修改起來麻煩,而且可以兼容的屏幕個(gè)數(shù)有限,我上面所說的這種方法加上我拓展的一些代碼,已經(jīng)可以兼容十多塊屏幕。
整個(gè)兼容方法的思路是,在LCM進(jìn)行第一遍初始化的時(shí)候,什么都不變,但進(jìn)行到mipi_dsi.c文件中的mdss_dsi_initialize()函數(shù)的時(shí)候,回去讀當(dāng)前使用的LCM IC 的id
,如果和默認(rèn)的屏幕id一樣,則不進(jìn)行第二次初始化,若不一樣,則重新初始化,這個(gè)時(shí)候全局變量lk_lcd_id已經(jīng)被賦值,當(dāng)?shù)诙槌跏蓟搅薿em_panel.c文件的oem_panel_select()函數(shù)中,函數(shù)根據(jù)lk_lcd_id的值來匹配正確的屏幕變量。匹配完成之后繼續(xù)未完成的屏幕初始化,至此整個(gè)流程走完,屏幕點(diǎn)亮!
? ? ? 文章介紹完畢,如有錯(cuò)誤歡迎大家指正~
頂
0
總結(jié)
以上是生活随笔為你收集整理的高通平台MSM8916LCM模块移植(一)-bootloader部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。