高通移植mipi LCD的過程LK代碼


lk部分:(實現LCD兼容)

1. 函數定位

aboot_init()來到target_display_init()
這就是高通原生lk LCD 兼容的關鍵所在。至於你需要兼容多少LCD 就在while()設置了,具體代碼就不跟下去了。

然后根據target中的不同文件來判斷是否進入哪一個函數來處理:
target_display_init() 函數里有很重要函數就是gcdb_display_init();

如果平台支持屏幕最大個數自動檢測,msm8953支持兼容兩個屏。(GCDB:Global Component Database全局組件數據庫);

gcdb_display_init初始化pll_clk_func、power_func、bl_func等功能(指明相應的函數指針),初始化好之后就調用msm_display_init()函數。

在msm_display_init()里先Turn on panel,再Turn on backlight;

panel.power_func = mdss_dsi_panel_power;		//turn on panel
panel.bl_func = mdss_dsi_bl_enable;				//turn on backlight

函數指向相應的函數中去;

2. 打開lcd

/* Turn on panel */

1. 調用mdss_dsi_panel_power()中的regulator_enable()給L2、L6、L17供電

if (pdata->power_func)
	ret = pdata->power_func(1, &(panel->panel_info));

2. 調用mdss_dsi_mipi_dfps_config函數:

if (pdata->dfps_func)
		ret = pdata->dfps_func(&(panel->panel_info));

3. 調用mdss_dsi_panel_clock()

調用calculate_clock_config(pinfo)計算時鍾配置和調用target_panel_clock(enable, pinfo)配置目標panel的時鍾。

4. 分配並設置幀緩存:

msm_fb_alloc(&(panel->fb))fbcon_setup(&(panel->fb))為幀緩沖器(frame buffer)分配內存。

5. 獲取logo圖片:

調用fetch_image_from_partition()從splash分區獲取lk logo圖片,如果splash分區沒有滿足要求的數據,就顯示默認的logo。

6. DSI轉HDMI:

if ((panel->dsi2HDMI_config) && (panel->panel_info.has_bridge_chip))
		ret = panel->dsi2HDMI_config(&(panel->panel_info));

7. msm_display_config()函數:

7.1 mdss_dsi_phy_init()

mdss_dsi_phy_init(&mipi_pinfo,MIPI_DSI0_BASE, DSI0_PHY_BASE);
       if(pinfo->mipi.dual_dsi)

如果有兩個MIPI DSI接口MIPI_DSI0和MIPI_DSI1就調用兩次mdss_dsi_phy_init(),msm8909只有MIPI_DSI0,MSM8994等有兩個DSI接口。

mdss_dsi_phy_init(&mipi_pinfo,MIPI_DSI1_BASE, DSI1_PHY_BASE);

7.2 ret = mdss_dsi_host_init(mipi, mipi->dual_dsi, mipi->broadcast);
初始化DSI接口的host控制器。

7.3 調用if (panel->pre_init_func) {}函數:
static int mdss_dsi_panel_pre_init(void)
{
intret = NO_ERROR;

   if(panelstruct.paneldata->panel_lp11_init) {
          ret= mdss_dsi_panel_reset(1);
          if(ret) {
                 dprintf(CRITICAL,"panel reset failed\n");
                 returnret;
          }
   }

   if(panelstruct.paneldata->panel_init_delay)
          udelay(panelstruct.paneldata->panel_init_delay);

   dprintf(SPEW,"Panel pre init done\n");
   returnret;

}
因為panelstruct.paneldata->panel_lp11_initinit_panel_data()函數賦值為1,所以調用mdss_dsi_panel_reset()根據reset時序來復位panel。

8. ret = msm_display_on();

主要部分:

case MIPI_VIDEO_PANEL:
		dprintf(INFO, "Turn on MIPI_VIDEO_PANEL.\n");
		ret = mdp_dsi_video_on(pinfo);
		if (ret)
			goto msm_display_on_out;

		ret = mdss_dsi_post_on(panel);
		if (ret)
			goto msm_display_on_out;

		ret = mipi_dsi_on(pinfo);
		if (ret)
			goto msm_display_on_out;
		break;

8.1 調用mdp_dsi_video_on()使能DSI VIDEO
8.2 mdss_dsi_post_on()使用初始化命令來初始化panel
8.3 mipi_dsi_on()

9. 打開背光:

/* Turn on backlight */
if (pdata->bl_func)
	ret = pdata->bl_func(1);

3. 增加一個panel需要做的事:

1、在gcdb_display_init()函數中有一個函數oem_panel_select()函數:

(這個函數需要做的工作是:主要是識別不同IC,賦值給參數panel_id,panel_id的使用在同一文件中的 init_panel_data()函數中。)

pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info),
				 &dsi_video_mode_phy_db);

2、uint32_t hw_id = board_hardware_id();

//判斷是高通哪一款平台,這里不需要看,hw_id是不需要管的,因為在下面語句中會直接跳到init_panel_data函數中來

3、在oem_panel_select()函數中需要根據你的hw_id來確定使用哪一款的LCD;

panel_override_id = panel_name_to_id(supp_panels,
				ARRAY_SIZE(supp_panels), panel_name);
supp_panels是struct panel_list,如果要增加一個panel就需要在這里增加一個supp_panels,例如:
static struct panel_list supp_panels[] = {
	{"truly_1080p_video", TRULY_1080P_VIDEO_PANEL},
	{"truly_1080p_cmd", TRULY_1080P_CMD_PANEL},
	{"r69006_1080p_video", R69006_1080P_VIDEO_PANEL},
	{"r69006_1080p_cmd", R69006_1080P_CMD_PANEL},
	{"truly_wuxga_video", TRULY_WUXGA_VIDEO_PANEL},
	{"nt35523_720p_video", NT35523_720P_VIDEO_PANEL},
	{"a914_nhd_video", A914_NHD_VIDEO_PANEL},
};

4、在這個枚舉中也需要增加相應的panel:

/*---------------------------------------------------------------------------*/
enum {
	TRULY_1080P_VIDEO_PANEL,
	TRULY_1080P_CMD_PANEL,
	R69006_1080P_VIDEO_PANEL,
	R69006_1080P_CMD_PANEL,
	TRULY_WUXGA_VIDEO_PANEL,
	NT35523_720P_VIDEO_PANEL,
	A914_NHD_VIDEO_PANEL,
	UNKNOWN_PANEL
};

if (panel_name) {
		panel_override_id = panel_name_to_id(supp_panels,
				ARRAY_SIZE(supp_panels), panel_name);

		if (panel_override_id < 0) {
			dprintf(CRITICAL, "Not able to search the panel:%s\n",
					 panel_name + strspn(panel_name, " "));
		} else if (panel_override_id < UNKNOWN_PANEL) {
			/* panel override using fastboot oem command */
			panel_id = panel_override_id;

			dprintf(INFO, "OEM panel override:%s\n",
					panel_name + strspn(panel_name, " "));
			goto panel_init;
		}
	}
	……
panel_init:
	/*
	 * Update all data structures after 'panel_init' label. Only panel
	 * selection is supposed to happen before that.
	 */
	pinfo->pipe_type = MDSS_MDP_PIPE_TYPE_RGB;
	return init_panel_data(panelstruct, pinfo, phy_db);

確保能直接跳到panel_init函數中來;

5、同樣來到init_panel_data()函數中來:

在這里也需要增加一個panel:(當然了,要增加相應的頭文件#include "include/panel_a914_nhd_video.h"這個頭文件是LCM供應商給的文件,一般來說都要自己根據時序圖來參照)

case TRULY_WUXGA_VIDEO_PANEL:
		panelstruct->paneldata    = &truly_wuxga_video_panel_data;
		panelstruct->paneldata->panel_with_enable_gpio = 1;
		panelstruct->panelres     = &truly_wuxga_video_panel_res;
		panelstruct->color        = &truly_wuxga_video_color;
		panelstruct->videopanel   = &truly_wuxga_video_video_panel;
		panelstruct->commandpanel = &truly_wuxga_video_command_panel;
		panelstruct->state        = &truly_wuxga_video_state;
		panelstruct->laneconfig   = &truly_wuxga_video_lane_config;
		panelstruct->paneltiminginfo
			= &truly_wuxga_video_timing_info;
		panelstruct->panelresetseq
					 = &truly_wuxga_video_panel_reset_seq;
		panelstruct->backlightinfo = &truly_wuxga_video_backlight;
		pinfo->mipi.panel_on_cmds
			= truly_wuxga_video_on_command;
		pinfo->mipi.num_of_panel_on_cmds
			= TRULY_WUXGA_VIDEO_ON_COMMAND;
		pinfo->mipi.panel_off_cmds
			= truly_wuxga_video_off_command;
		pinfo->mipi.num_of_panel_off_cmds
			= TRULY_WUXGA_VIDEO_OFF_COMMAND;
		memcpy(phy_db->timing,
			truly_wuxga_14nm_video_timings, MAX_TIMING_CONFIG * sizeof(uint32_t));
		pinfo->dfps.panel_dfps = truly_wuxga_video_dfps;
		pinfo->mipi.signature 	= TRULY_WUXGA_VIDEO_SIGNATURE;
		break;
case A914_NHD_VIDEO_PANEL:
		panelstruct->paneldata    = &a914_nhd_video_panel_data;
		panelstruct->panelres     = &a914_nhd_video_panel_res;
		panelstruct->color        = &a914_nhd_video_color;
		panelstruct->videopanel   = &a914_nhd_video_video_panel;
		panelstruct->commandpanel = &a914_nhd_video_command_panel;
		panelstruct->state        = &a914_nhd_video_state;
		panelstruct->laneconfig   = &a914_nhd_video_lane_config;
		panelstruct->paneltiminginfo
			= &a914_nhd_video_timing_info;
		panelstruct->panelresetseq
					 = &a914_nhd_video_panel_reset_seq;
		panelstruct->backlightinfo = &a914_nhd_video_backlight;
		pinfo->mipi.panel_on_cmds
			= a914_nhd_video_on_command;
		pinfo->mipi.num_of_panel_on_cmds
			= A914_NHD_VIDEO_ON_COMMAND;
		pinfo->mipi.panel_off_cmds
			= a914_nhd_video_off_command;
		pinfo->mipi.num_of_panel_off_cmds
			= A914_NHD_VIDEO_OFF_COMMAND;
		memcpy(phy_db->timing,
			a914_nhd_video_timings, MAX_TIMING_CONFIG * sizeof(uint32_t));
		pinfo->mipi.signature 	= A914_NHD_VIDEO_SIGNATURE;
		break;

6、調整背光:

gcdb_display_init()函數中有一個函數指針mdss_dsi_bl_enable
這個函數是用來調整背光的和使能背光的,通過PWM來作用:(具體要看原理圖)

static int mdss_dsi_bl_enable(uint8_t enable)
{
	int ret = NO_ERROR;

	ret = panel_backlight_ctrl(enable);
	if (ret)
		dprintf(CRITICAL, "Backlight %s failed\n", enable ? "enable" :
							"disable");
	return ret;
}

static uint32_t panel_backlight_ctrl(uint8_t enable)
{
	uint32_t ret = NO_ERROR;
	if (panelstruct.backlightinfo)
		ret = target_backlight_ctrl(panelstruct.backlightinfo, enable);
	return ret;
}

所以bootloader的背光是通過target_backlight_ctrl()控制的,找到該項目的這個函數修改:
wled_backlight_ctrl

7、更改LCD的參數:

LCD的一些參數:
VBPD(verticalback porch):表示在一幀圖像開始時,垂直同步信號以后的無效的行數。
VFPD(verticalfront porch):表示在一幀圖像結束后,垂直同步信號以前的無效的行數。
VSPW(verticalsync pulse width):表示垂直同步脈沖的寬度,用行數計算。
HBPD(horizontal back porch):表示從水平同步信號開始到一行的有效數據開始之間的VCL的個數。
HFPD(horizontal front porch):表示一行的有效數據結束到下一個水平同步信號開始 之間的VCLK的個數。
HSPW(horizontalsync pulse width):表示水平同步信號的寬度,用VCLK計算。


免責聲明!

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



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