高通調試 SPI 屏的 開機一段時間黑屏


1. spi調試問題:

問題描述:

  1. 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正常,一切正常;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM