kernel階段
總結**環境:
android p今天想記錄和分享的是mtk平台lcm的相容,當然,在學習相容原理的時候肯定需要大概知道lcm的載入流程,於是借鑑前輩們的經驗(文章最後會貼上參考的文章),淺顯的去學習了一下,lcm方面深入的知識以後有機會再慢慢研究,保持一顆學習的心~
kmain() -> platform_init() -> mt_disp_init() -> primary_display_init() -> disp_lcm_probe()1、檔案路徑:vendor/mediatek/proprietary/bootable/bootloader/lk/kernel/main.c
呼叫kmain()函式。
/* called from crt0.s */
void
kmain
(void
) __no_return __externally_visible;
void
kmain
(void
)/*省略部分***/
}static
intbootstrap2
(void
*arg)
2、檔案路徑:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/platform.c
呼叫platform_init()函式。
void
platform_init
(void
)
3、檔案路徑:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/mt_disp_drv.c
呼叫mt_disp_init()函式。
void
mt_disp_init
(void
*lcdbase)
vendor/mediatek/proprietary/bootable/bootloader/lk/dev/lcm/mt65xx_lcm_list.c
4、檔案路徑:
vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6580/primary_display.c
呼叫primary_display_init()函式。
int
primary_display_init
(char
*lcm_name)
elseif(
_lcm_count()
==1)else
if(lcm_drv->init_power)
if(lcm_drv->compare_id !=
null)}
_display_inte***ce_path_deinit
(handle)
;//暫時還沒去研究;}if
(islcmfound == false)
}else}}
if(islcmfound == false)..
....
....
....
....
....
.}
從primary_display_init()函式可以看出,在lk階段就會去尋找和硬體匹配的驅動,主要是通過compare_id()函式來實現;_lcm_count()函式會返回當前系統的總的驅動數量,如下:
int
_lcm_count
(void
)
lcm_count變數定義在mt65xx_lcm_list.c(lk和kernel下面都有該檔案)中,如下:
unsigned int lcm_count = sizeof(lcm_driver_list) / sizeof(lcm_driver *);lcm_driver的定義 如下:lcm_driver *lcm_driver_list = ;
struct lcm_driver
compare_id()函式是需要我們自己在驅動裡面實現的;mtk平台,lcm的驅動需要使用lcm_driver這個結構體來定義名為「***_***_***_lcm_drv」的結構體變數,以hx8394c_wxga_9806為例,如下:
lcm_driver hx8394c_wxga_9806_lcm_drv =
;static
unsigned
intlcm_compare_id
(void
)
從最後一行**可以看出,從軟、硬體兩個方面進行了驅動與硬體是否匹配的判斷;lcm_id是指需要匹配的值,id是從ic暫存器裡面讀出來的值,也稱軟體id;若是兩者相等,說明當前驅動有可能是與lcm相匹配的,為什麼是有可能呢?因為不同的模組廠可能採用相同的ic,不同的玻璃,對於兩塊ic相同的lcm,通過軟體id就沒有辦法作區分了,這時就需要從硬體入手,在lcm上留出id腳(留幾個id腳需要根據具體的lcd來看,id腳的個數越多可相容屏的數量就越多),拉高拉低對應不同的lcd,上述**段中的maker_id就指的是硬體id,獲取maker_id的實現函式是lcm_makerid_check(),如下:
static
intlcm_makerid_check
(void
)
通過gpio_get_value()去獲取gpio:gpio_lcm_maker_id的值,0:低電平;1:高電平;若軟體id和硬體id都匹配,則返回1;若有乙個不滿足條件,則返回0。
lk階段的相容就到此為止,在kernel中不會再次通過compare_id()函式去獲取驅動的資訊,也就是說compare_id()函式只會在lk中被呼叫;lcm驅動相關的資訊會從lk傳遞到kernel,具體怎麼傳遞的我沒有去研究,也不再這篇文章的討論範疇內,感興趣的道友可以到文末貼的鏈結文章裡面去看。
1、檔案路徑:kernel-4.9/drivers/misc/mediatek/video/mt6765/videox/mtkfb.c
呼叫mtkfb_probe()函式。
static
intmtkfb_probe
(struct platform_device *pdev)
2、檔案路徑:kernel-4.9/drivers/misc/mediatek/video/mt6765/videox/primary_display.c
呼叫primary_display_init()函式(似曾相識的函式名),該函式的第乙個引數是由lk傳遞下來的驅動名稱。
int
primary_display_init
(char
*lcm_name,
unsigned
int lcm_fps,
int is_lcm_inited)
/*lk階段也有個probe函式,熟悉的配方,不同的味道; 這裡只會分析和lk階段不同的部分。*/
struct disp_lcm_handle *
disp_lcm_probe
(char
*plcm_name,
enum lcm_inte***ce_id lcm_id,
int is_lcm_inited)
elseif(
_lcm_count()
==1)else
islcminited = true;
islcmfound = true;}if
(!is_lcm_inited)
lcmindex =0;
}else
else}if
(!islcmfound)
elseif(
!is_lcm_inited)
}/* todo: */
}}
找到可用驅動後剩下的就是一些初始化的東西了,不在本文討論的範圍內;kernel階段分析得比較粗略,但是個人認為對於理解lcm是如何進行相容的足夠了。
實際上我lcm上手除錯的次數並不多,記憶中只有2次;lcm相容只做過一次,除錯的時候並沒有理解到這篇文章的程度;自身的原因,不弄明白它的原理就像是事情做到一半沒做完,難受。對於lcm的除錯,現目前也只是停留在上電、i2c位址、加初始化**和調一些簡單引數的階段,在實際工作中還沒有太多機會接觸到更深入的一些東西。不過「邊工作邊學習」是我的信仰,「努力攻關」是我的態度,up up up!
最後附上參考文章的鏈結,再次感謝前輩們的分享:
mtk平台lcm驅動載入過程-lk階段
mtk平台lcm驅動載入過程-kernel階段
mt8176平台lcd driver載入流程&相容實現及常見問題分析
MTK平台LCM驅動載入流程
安卓系統從power鍵按下釋放,到lcm驅動顯示,整個驅動的載入流程as follows lk階段 首先執行main.c vendor mediatek proprietary bootable bootloader preloader platform mt6739 src core main.c...
mtk6572配置lcm背光
mtk6572配置lcm背光 配置lcm背光的控制腳 lcm背光控制主要有兩個引腳 使能腳en和亮度控制引腳vfb。使能腳用來控制背光的使能與否,比如這裡是1為enable,0為disable 亮度控制引腳則是用來接pwm輸出,通過pwm的占空比來控制背光亮度,這裡是低為亮,高為滅。mtk的電路圖上...
mtk平台關於lcm初始化code的一點總結
最近公司有個專案需要更換lcm,差別如下 原屏mipi 4lane 1280 720 新屏mipi 2lane 800 480 區別很少,按理說最多2天就能亮,結果沒有按理,折騰了8,9天,最後經fae指點發現平台mipi傳送code的方式有坑,又漲姿勢了,總結一下。mipi傳送初始化code有兩種...