1. spi調試問題: 問題描述: spi屏幕lk啟動的時候正常出現小企鵝,到kernel啟動的過程黑屏並且花屏才到開機動畫; 2. 黑屏的三個階段: 參照: "黑屏分析" 分析開機過程黑屏,首先需要定位黑屏問題發生的時間段,開機過程中涉及到顯示logo 或者是播放動畫的主要有如下三個階段: 顯示 ...
1. spi調試問題:
問題描述:
spi屏幕lk啟動的時候正常出現小企鵝,到kernel啟動的過程黑屏並且花屏才到開機動畫;
2. 黑屏的三個階段:
參照:黑屏分析
分析開機過程黑屏,首先需要定位黑屏問題發生的時間段,開機過程中涉及到顯示logo 或者是播放動畫的主要有如下三個階段:
- 顯示 lk logo ;
- 顯示kernel logo;
- 開機動畫 Bootanimation
如下這張ENG 版本開機過程顯示圖,說明瞭主要的三個過程:
如下解釋:
(階段1)、帶有”normal boot“的lk logo,會在lk階段顯示。顯示時間一般1s左右。
(階段2)、啟動到kernel的前7s左右,顯示的是帶”normal boot“字樣的lk logo。(這裡L/M版本和KK/JB版本很不同,不在此處細說)
(階段3)、之後顯示kernel logo的時間段很短,一般只有2s左右.
(階段4)、顯示bootanimation動畫。
3. 調試過程:
如上所示,我們是在(階段一)(階段二)之間黑屏,這時候要看一下lk中DEFINES += DISPLAY_SPLASH_SCREEN = 1
的巨集有沒有打開;(target/xxx/rules.mk
),再將qcom,cont-splash-enabled
增加到你對應廠商的屏代碼的設備樹中;
重新燒錄軟體,開機;
依然出現問題:
我們這時候發現lk到kernel的第二階段已經完全正常了,但是又出現問題。。。這時候kernel的開機動畫出現抖動,並且無法正常顯示(第三階段);關鍵來了,滅屏後,一切屏幕正常;
這時候,我已經開始懷疑lk和kernel的spi屏初始化代碼有區別:
將lk代碼修改為kernel中的初始化代碼,結果lk也有問題,出現不斷的抖動和閃爍;於是,我只能接受spi 屏kernel和lk初始化代碼不一樣的結論了;但問題是為什麼我們第三階段已經屬於我們kernel啟動的時候了,但是為什麼沒有初始化呢?(滅屏後再次開啟已經啟用了resume了);
讀源碼吧:
找到我們kernel源碼中的qcom,mdss-spi-on-command
節點,在解析設備樹用到的,最後我們定位在mdss_spi_panel_on
函數中初始化:
int mdss_spi_panel_on(struct mdss_panel_data *pdata)
{
struct spi_panel_data *ctrl = NULL;
struct mdss_panel_info *pinfo;
int i;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
}
pinfo = &pdata->panel_info;
ctrl = container_of(pdata, struct spi_panel_data,
panel_data);
for (i = 0; i < ctrl->on_cmds.cmd_cnt; i++) {
mdss_spi_tx_command(ctrl->on_cmds.cmds[i].command);
if (ctrl->on_cmds.cmds[i].dchdr.dlen > 1) {
mdss_spi_tx_parameter(ctrl->on_cmds.cmds[i].parameter,
ctrl->on_cmds.cmds[i].dchdr.dlen-1);
}
if (ctrl->on_cmds.cmds[i].dchdr.wait != 0)
msleep(ctrl->on_cmds.cmds[i].dchdr.wait);
}
pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK;
pr_debug("%s:-\n", __func__);
return 0;
}
增加log列印,最後判斷在第三階段中上述函數中並沒有被調用到,而是由lk的初始化代碼一直維持屏的狀態;
在mdss_spi_panel_init
函數中,註冊了相應的回調函數:
int mdss_spi_panel_init(struct device_node *node,
struct spi_panel_data *ctrl_pdata,
bool cmd_cfg_cont_splash)
{
int rc = 0;
static const char *panel_name;
struct mdss_panel_info *pinfo;
if (!node || !ctrl_pdata) {
pr_err("%s: Invalid arguments\n", __func__);
return -ENODEV;
}
pinfo = &ctrl_pdata->panel_data.panel_info;
.......
ctrl_pdata->on = mdss_spi_panel_on;
ctrl_pdata->off = mdss_spi_panel_off;
ctrl_pdata->panel_data.set_backlight = mdss_spi_panel_bl_ctrl;
return 0;
}
而這個回調函數是在什麼時候作用到的呢?
在mdss_spi_panel_unblank
函數中:
static int mdss_spi_panel_unblank(struct mdss_panel_data *pdata)
{
int ret = 0;
struct spi_panel_data *ctrl_pdata = NULL;
if (pdata == NULL) {
pr_err("%s: Invalid input data\n", __func__);
return -EINVAL;
}
ctrl_pdata = container_of(pdata, struct spi_panel_data,
panel_data);
// if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {
ret = ctrl_pdata->on(pdata);
if (ret) {
pr_err("%s: unable to initialize the panel\n",
__func__);
return ret;
}
ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
// }
return ret;
}
修改後,patch地址: patch地址
開機正常,spi正常,一切正常;