bootloader lcd init

1  display_init

  1. void display_init(void)  
  2. {  
  3.     dprintf(ALWAYS, "%s: lcd_type = %d\n", __func__, lcd_type);  
  4.     if (display_enable)  
  5.         return;  
  6.     mipi_global_video_init(&(panel.panel_info), lcd_type); // this function is implemented by specific lcd driver   
  7.     panel.clk_func = msm8960_mipi_panel_clock;  
  8.     panel.power_func = msm8960_mipi_panel_power;  
  9.     panel.fb.base = 0x89000000;  
  10.     panel.fb.width =  panel.panel_info.xres;  
  11.     panel.fb.height =  panel.panel_info.yres;  
  12.     panel.fb.stride =  panel.panel_info.xres;  
  13.     panel.fb.bpp =  panel.panel_info.bpp;  
  14.     panel.fb.format = FB_FORMAT_RGB888;  
  15.     panel.mdp_rev = MDP_REV_42;  
  16.     if (msm_display_init(&panel, display_enable)) {  
  17.         dprintf(CRITICAL, "Display init failed!\n");  
  18.         return;  
  19.     }  
  20.     display_enable = 1;  
  21. }  
void display_init(void)
{
	dprintf(ALWAYS, "%s: lcd_type = %d\n", __func__, lcd_type);
	if (display_enable)
		return;
	mipi_global_video_init(&(panel.panel_info), lcd_type); // this function is implemented by specific lcd driver
	panel.clk_func = msm8960_mipi_panel_clock;
	panel.power_func = msm8960_mipi_panel_power;
	panel.fb.base = 0x89000000;
	panel.fb.width =  panel.panel_info.xres;
	panel.fb.height =  panel.panel_info.yres;
	panel.fb.stride =  panel.panel_info.xres;
	panel.fb.bpp =  panel.panel_info.bpp;
	panel.fb.format = FB_FORMAT_RGB888;
	panel.mdp_rev = MDP_REV_42;
	if (msm_display_init(&panel, display_enable)) {
		dprintf(CRITICAL, "Display init failed!\n");
		return;
	}
	display_enable = 1;
}

Above code is the first initialization of lcd. The file is at lk/target/msm8960/target_display.c. So how to open power and clock, as follow:

  1. void msm8960_mipi_panel_reset(void)  
  2. {  
  3.     gpio_tlmm_config(LCD_GPIO_RST, 0, GPIO_OUTPUT, GPIO_NO_PULL,GPIO_8MA, 1);  
  4.     gpio_tlmm_config(LCD_GPIO_IM, 0, GPIO_OUTPUT, GPIO_NO_PULL,GPIO_8MA, 1);  
  5.     /*select video mode*/  
  6.     gpio_set(LCD_GPIO_IM, 1<<1);  
  7.     mdelay(10);  
  8.     /*hw reset sign*/  
  9.     gpio_set(LCD_GPIO_RST, 1<<1);  
  10.     mdelay(10);  
  11.     gpio_set(LCD_GPIO_RST, 0);  
  12.     mdelay(10);  
  13.     gpio_set(LCD_GPIO_RST, 1<<1);  
  14.     mdelay(120);  
  15. }  
void msm8960_mipi_panel_reset(void)
{
	gpio_tlmm_config(LCD_GPIO_RST, 0, GPIO_OUTPUT, GPIO_NO_PULL,GPIO_8MA, 1);
	gpio_tlmm_config(LCD_GPIO_IM, 0, GPIO_OUTPUT, GPIO_NO_PULL,GPIO_8MA, 1);
	/*select video mode*/
	gpio_set(LCD_GPIO_IM, 1<<1);
	mdelay(10);
	/*hw reset sign*/
	gpio_set(LCD_GPIO_RST, 1<<1);
	mdelay(10);
	gpio_set(LCD_GPIO_RST, 0);
	mdelay(10);
	gpio_set(LCD_GPIO_RST, 1<<1);
	mdelay(120);
}
  1. static int msm8960_mipi_panel_clock(int enable)  
  2. {  
  3.     if (enable) {  
  4.         mdp_clock_init(); // acpuclock.c   
  5.         mmss_clock_init(); // acpuclock.c   
  6.     } else if (!target_cont_splash_screen()) {  
  7.             mmss_clock_disable(); // acpuclock.c   
  8.     }  
  9.     return 0;  
  10. }  
  11.   
  12.   
  13. static int msm8960_mipi_panel_power(int enable)  
  14. {  
  15.     if (enable) {  
  16.         pm8921_ldo_set_voltage(LDO_11, LDO_VOLTAGE_1_8V); // L11   
  17.         pm8921_low_voltage_switch_enable(lvs_2); // lvs_2   
  18.         /* Turn on LDO2 for vdda_mipi_dsi */  
  19.         pm8921_ldo_set_voltage(LDO_2, LDO_VOLTAGE_1_2V); // L2   
  20.         pm8921_ldo_set_voltage(LDO_9, LDO_VOLTAGE_2_85V); // L9   
  21.     }  
  22.   
  23.     return 0;  
  24. }  
static int msm8960_mipi_panel_clock(int enable)
{
	if (enable) {
		mdp_clock_init(); // acpuclock.c
		mmss_clock_init(); // acpuclock.c
	} else if (!target_cont_splash_screen()) {
			mmss_clock_disable(); // acpuclock.c
	}
	return 0;
}


static int msm8960_mipi_panel_power(int enable)
{
	if (enable) {
		pm8921_ldo_set_voltage(LDO_11, LDO_VOLTAGE_1_8V); // L11
		pm8921_low_voltage_switch_enable(lvs_2); // lvs_2
		/* Turn on LDO2 for vdda_mipi_dsi */
		pm8921_ldo_set_voltage(LDO_2, LDO_VOLTAGE_1_2V); // L2
		pm8921_ldo_set_voltage(LDO_9, LDO_VOLTAGE_2_85V); // L9
	}

	return 0;
}

How to shut down lvs and ldo voltage, as follows:

  1. pm8921_ldo_lvs_disable(LDO_9); // pm8921.c   
  2. pm8921_ldo_lvs_disable(LDO_2);  
  3. pm8921_ldo_lvs_disable(lvs_2);  
  4. msm_display_off(1/0); // check if lcd should be closed  
        pm8921_ldo_lvs_disable(LDO_9); // pm8921.c
        pm8921_ldo_lvs_disable(LDO_2);
        pm8921_ldo_lvs_disable(lvs_2);
        msm_display_off(1/0); // check if lcd should be closed
The following implementation can be placed at lk/dev/pmic/pm8921/pm8921.c

  1. int pm8921_ldo_lvs_disable(uint32_t ldo_id)  
  2. {  
  3.     uint32_t ldo_num = (ldo_id & ~LDO_P_MASK);  
  4.     uint32_t val = 0;  
  5.     if (ldo_id == lvs_2) {  
  6.         pm8921_masked_write(PM8921_LVS_CTRL_REG(lvs_2), 0x80, val); // shut down lvs2 voltage, TEST_REG can be used for reading status   
  7.         return 0;  
  8.     }  
  9.   
  10.     pm8921_masked_write(PM8921_LDO_CTRL_REG(ldo_num), 0x80, val); // shut down ldo voltage, TEST_REG can be used for reading status   
  11.   
  12.     return 0;  
  13. }  
int pm8921_ldo_lvs_disable(uint32_t ldo_id)
{
    uint32_t ldo_num = (ldo_id & ~LDO_P_MASK);
    uint32_t val = 0;
    if (ldo_id == lvs_2) {
        pm8921_masked_write(PM8921_LVS_CTRL_REG(lvs_2), 0x80, val); // shut down lvs2 voltage, TEST_REG can be used for reading status
        return 0;
    }

    pm8921_masked_write(PM8921_LDO_CTRL_REG(ldo_num), 0x80, val); // shut down ldo voltage, TEST_REG can be used for reading status

    return 0;
}
How to enable lvs voltage, as follow:
  1. int pm8921_low_voltage_switch_enable(uint8_t lvs_id)  
  2. {  
  3.     int ret =  NO_ERROR;  
  4.     uint8_t val;  
  5.   
  6.     if (lvs_id < lvs_start || lvs_id > lvs_end) {  
  7.         dprintf(CRITICAL, "Requested unsupported LVS.\n");  
  8.         return ERROR;  
  9.     }  
  10.   
  11.     if (lvs_id == lvs_2) {  
  12.         dprintf(CRITICAL, "No support for LVS2 yet!\n");  
  13.         // return ERROR; // lvs_2 should be enabled   
  14.     }  
  15.     /* Read LVS_TEST Reg first*/  
  16.     ret = dev->read(&val, 1, PM8921_LVS_TEST_REG(lvs_id));  
  17.     if (ret) {  
  18.         dprintf(CRITICAL, "Failed to read LVS_TEST Reg ret=%d.\n", ret);  
  19.         return ret;  
  20.     }  
  21.   
  22.     /* Check if switch is already ON */  
  23.     val = val & PM8921_LVS_100_TEST_VOUT_OK;  
  24.     if (val)  
  25.         return ret;  
  26.   
  27.     /* Turn on switch in normal mode */  
  28.     val = 0;  
  29.     val |= PM8921_LVS_100_CTRL_SW_EN; /* Enable Switch */  
  30.     val |= PM8921_LVS_100_CTRL_SLEEP_B_IGNORE; /* Ignore sleep mode pin */  
  31.     ret = dev->write(&val, 1, PM8921_LVS_CTRL_REG(lvs_id));  
  32.     if (ret)  
  33.         dprintf(CRITICAL, "Failed to write LVS_CTRL Reg ret=%d.\n", ret);  
  34.   
  35.     return ret;  
  36. }  
int pm8921_low_voltage_switch_enable(uint8_t lvs_id)
{
	int ret =  NO_ERROR;
	uint8_t val;

	if (lvs_id < lvs_start || lvs_id > lvs_end) {
		dprintf(CRITICAL, "Requested unsupported LVS.\n");
		return ERROR;
	}

	if (lvs_id == lvs_2) {
		dprintf(CRITICAL, "No support for LVS2 yet!\n");
		// return ERROR; // lvs_2 should be enabled
	}
	/* Read LVS_TEST Reg first*/
	ret = dev->read(&val, 1, PM8921_LVS_TEST_REG(lvs_id));
	if (ret) {
		dprintf(CRITICAL, "Failed to read LVS_TEST Reg ret=%d.\n", ret);
		return ret;
	}

	/* Check if switch is already ON */
	val = val & PM8921_LVS_100_TEST_VOUT_OK;
	if (val)
		return ret;

	/* Turn on switch in normal mode */
	val = 0;
	val |= PM8921_LVS_100_CTRL_SW_EN; /* Enable Switch */
	val |= PM8921_LVS_100_CTRL_SLEEP_B_IGNORE; /* Ignore sleep mode pin */
	ret = dev->write(&val, 1, PM8921_LVS_CTRL_REG(lvs_id));
	if (ret)
		dprintf(CRITICAL, "Failed to write LVS_CTRL Reg ret=%d.\n", ret);

	return ret;
}

1.1  clock enable

mdp clock enable

  1. void mdp_clock_init(void)  
  2. {  
  3.     /* Turn on the PLL2, to ramp up the MDP clock to max (200MHz) */  
  4.     nt_pll_enable(PLL_2, 1);  
  5.   
  6.     config_mdp_clk(MDP_NS_VAL, MDP_MD_VAL,  
  7.                MDP_CC_VAL, MDP_NS_REG, MDP_MD_REG, MDP_CC_REG);  
  8. }  
void mdp_clock_init(void)
{
	/* Turn on the PLL2, to ramp up the MDP clock to max (200MHz) */
	nt_pll_enable(PLL_2, 1);

	config_mdp_clk(MDP_NS_VAL, MDP_MD_VAL,
		       MDP_CC_VAL, MDP_NS_REG, MDP_MD_REG, MDP_CC_REG);
}

dsi, byte, bit, esc clock enable. The following function is at lk/platform/msm8960/acpuclock.c.

  1. /* Initialize all clocks needed by Display */  
  2. void mmss_clock_init(void)  
  3. {  
  4.     /* enable AHB clk */  
  5.     writel(0x205116,AHB_NS_REG);  
  6.     writel(0xd5040600,AHB_EN_REG);  
  7.     /* Configure Pixel clock */  
  8.     config_mmss_clk(PIXEL_NS_VAL, PIXEL_MD_VAL, PIXEL_CC_VAL,DSI_PIXEL_NS_REG, DSI_PIXEL_MD_REG, DSI_PIXEL_CC_REG);  
  9.     /* Configure DSI clock */  
  10.     config_mmss_clk(DSI_NS_VAL, DSI_MD_VAL, DSI_CC_VAL, DSI_NS_REG,DSI_MD_REG, DSI_CC_REG);  
  11.     /* Configure Byte clock */  
  12.     config_mmss_clk(BYTE_NS_VAL, 0x0, BYTE_CC_VAL, DSI1_BYTE_NS_REG, 0x0,DSI1_BYTE_CC_REG);  
  13.     /* Configure ESC clock */  
  14.     config_mmss_clk(ESC_NS_VAL, 0x0, ESC_CC_VAL, DSI1_ESC_NS_REG, 0x0,DSI1_ESC_CC_REG);  
  15. }  
/* Initialize all clocks needed by Display */
void mmss_clock_init(void)
{
	/* enable AHB clk */
	writel(0x205116,AHB_NS_REG);
	writel(0xd5040600,AHB_EN_REG);
	/* Configure Pixel clock */
	config_mmss_clk(PIXEL_NS_VAL, PIXEL_MD_VAL, PIXEL_CC_VAL,DSI_PIXEL_NS_REG, DSI_PIXEL_MD_REG, DSI_PIXEL_CC_REG);
	/* Configure DSI clock */
	config_mmss_clk(DSI_NS_VAL, DSI_MD_VAL, DSI_CC_VAL, DSI_NS_REG,DSI_MD_REG, DSI_CC_REG);
	/* Configure Byte clock */
	config_mmss_clk(BYTE_NS_VAL, 0x0, BYTE_CC_VAL, DSI1_BYTE_NS_REG, 0x0,DSI1_BYTE_CC_REG);
	/* Configure ESC clock */
	config_mmss_clk(ESC_NS_VAL, 0x0, ESC_CC_VAL, DSI1_ESC_NS_REG, 0x0,DSI1_ESC_CC_REG);
}


clock disable

  1. void mmss_clock_disable(void)  
  2. {  
  3.     writel(0x0, DSI1_BYTE_CC_REG);  
  4.     writel(0x0, DSI_PIXEL_CC_REG);  
  5.     writel(0x0, DSI1_ESC_CC_REG);  
  6.   
  7.     /* Disable root clock */  
  8.     writel(0x0, DSI_CC_REG);  
  9. }  
void mmss_clock_disable(void)
{
	writel(0x0, DSI1_BYTE_CC_REG);
	writel(0x0, DSI_PIXEL_CC_REG);
	writel(0x0, DSI1_ESC_CC_REG);

	/* Disable root clock */
	writel(0x0, DSI_CC_REG);
}

2  Now it's time to look at the function msm_display_init

The function is at lk/platform/msm_shared/display.c, as follow:

  1. int msm_display_init(struct msm_fb_panel_data *pdata, int mode)  
  2. {  
  3.     int ret = NO_ERROR;  
  4.   
  5.     dprintf(CRITICAL, "init mode = %d!\n", mode);  
  6.     if (!mode) {  
  7.     panel = pdata;  
  8.     if (!panel) {  
  9.     <SPAN style="WHITE-SPACE: pre"> </SPAN>ret = ERR_INVALID_ARGS;  
  10.     <SPAN style="WHITE-SPACE: pre"> </SPAN>goto msm_display_init_out;  
  11.     }  
  12.   
  13.     /* Enable clock */  
  14.     if (pdata->clk_func)  
  15.         ret = pdata->clk_func(1);  
  16.   
  17.     if (ret)  
  18.         goto msm_display_init_out;  
  19.   
  20.     /* Turn on panel */  
  21.     if (pdata->power_func)  
  22.         ret = pdata->power_func(1);  
  23.   
  24.     if (ret)  
  25.         goto msm_display_init_out;  
  26.   
  27.     ret = msm_fb_alloc(&(panel->fb)); // allocate memory: the base address is 0x89000000   
  28.     if (ret)  
  29.         goto msm_display_init_out;  
  30.   
  31.     fbcon_setup(&(panel->fb));  
  32.     }  
  33.     ret = msm_display_config(); // This function is important. It will call mipi_config, mdp_dsi_video_config in order.   
  34.     if (ret)  
  35.         goto msm_display_init_out;  
  36.   
  37.     ret = msm_display_on(); // Enable host dsi. It will call mdp_dsi_video_on, mipi_dsi_on in order.   
  38.     if (ret)  
  39.         goto msm_display_init_out;  
  40.         mdelay(60);  
  41. msm_display_init_out:  
  42.     return ret;  
  43. }  
int msm_display_init(struct msm_fb_panel_data *pdata, int mode)
{
	int ret = NO_ERROR;

	dprintf(CRITICAL, "init mode = %d!\n", mode);
	if (!mode) {
	panel = pdata;
	if (!panel) {
		ret = ERR_INVALID_ARGS;
		goto msm_display_init_out;
	}

	/* Enable clock */
	if (pdata->clk_func)
		ret = pdata->clk_func(1);

	if (ret)
		goto msm_display_init_out;

	/* Turn on panel */
	if (pdata->power_func)
		ret = pdata->power_func(1);

	if (ret)
		goto msm_display_init_out;

	ret = msm_fb_alloc(&(panel->fb)); // allocate memory: the base address is 0x89000000
	if (ret)
		goto msm_display_init_out;

	fbcon_setup(&(panel->fb));
	}
	ret = msm_display_config(); // This function is important. It will call mipi_config, mdp_dsi_video_config in order.
	if (ret)
		goto msm_display_init_out;

	ret = msm_display_on(); // Enable host dsi. It will call mdp_dsi_video_on, mipi_dsi_on in order.
	if (ret)
		goto msm_display_init_out;
		mdelay(60);
msm_display_init_out:
	return ret;
}

The function msm_display_config is at lk/platform/msm_shared/display.c, as follow:

  1. int msm_display_config()  
  2. {  
  3.     int ret = NO_ERROR;  
  4.     struct msm_panel_info *pinfo;  
  5.   
  6.     if (!panel)  
  7.         return ERR_INVALID_ARGS;  
  8.   
  9.     pinfo = &(panel->panel_info);  
  10.   
  11.     /* Set MDP revision */  
  12.     mdp_set_revision(panel->mdp_rev);  
  13.   
  14.     switch (pinfo->type) {  
  15.     case MIPI_VIDEO_PANEL:  
  16.         dprintf(INFO, "Config MIPI_VIDEO_PANEL.\n");  
  17.         ret = mipi_config(panel);  
  18.         if (ret)  
  19.             goto msm_display_config_out;  
  20.   
  21.         if (pinfo->early_config)  
  22.             ret = pinfo->early_config((void *)pinfo);  
  23.   
  24.         ret = mdp_dsi_video_config(pinfo, &(panel->fb));  
  25.         if (ret)  
  26.             goto msm_display_config_out;  
  27.         break;  
  28. <SPAN style="WHITE-SPACE: pre"> </SPAN>}  
  29.     if (pinfo->config) // mipi_global_video_init:pinfo->config = mipi_global_video_config;   
  30.         ret = pinfo->config((void *)pinfo);  
  31. }  
int msm_display_config()
{
	int ret = NO_ERROR;
	struct msm_panel_info *pinfo;

	if (!panel)
		return ERR_INVALID_ARGS;

	pinfo = &(panel->panel_info);

	/* Set MDP revision */
	mdp_set_revision(panel->mdp_rev);

	switch (pinfo->type) {
	case MIPI_VIDEO_PANEL:
		dprintf(INFO, "Config MIPI_VIDEO_PANEL.\n");
		ret = mipi_config(panel);
		if (ret)
			goto msm_display_config_out;

		if (pinfo->early_config)
			ret = pinfo->early_config((void *)pinfo);

		ret = mdp_dsi_video_config(pinfo, &(panel->fb));
		if (ret)
			goto msm_display_config_out;
		break;
	}
	if (pinfo->config) // mipi_global_video_init:pinfo->config = mipi_global_video_config;
		ret = pinfo->config((void *)pinfo);
}


mipi_global_video_config will call mipi_dsi_video_mode_config, which will get these parametersrelated to lcd and whose driver ic, such as x resolution, y resolution, HFP, HBP, VFP, VBP, dst_format, traffic_mode, lane, interleave, h_pulse_width, v_pulse_width and so on. All of these parameters related to driver ic and lcd will write into corresponding registers of dsi engine. This function is at /lk/platform/msm_shared/mipi_dsi.c

  1. int mipi_dsi_video_mode_config(unsigned short disp_width,  
  2.     unsigned short disp_height,  
  3.     unsigned short img_width,  
  4.     unsigned short img_height,  
  5.     unsigned short hsync_porch0_fp,  
  6.     unsigned short hsync_porch0_bp,  
  7.     unsigned short vsync_porch0_fp,  
  8.     unsigned short vsync_porch0_bp,  
  9.     unsigned short hsync_width,  
  10.     unsigned short vsync_width,  
  11.     unsigned short dst_format,  
  12.     unsigned short traffic_mode,  
  13.     unsigned char lane_en,  
  14.     unsigned low_pwr_stop_mode,  
  15.     unsigned char eof_bllp_pwr,  
  16.     unsigned char interleav)  
  17. {  
  18.   
  19.     int status = 0;  
  20.   
  21.     /* disable mdp first */  
  22.     mdp_disable();  
  23.     writel(0x00000000, DSI_CLK_CTRL);  
  24.     writel(0x00000000, DSI_CLK_CTRL);  
  25.     writel(0x00000000, DSI_CLK_CTRL);  
  26.     writel(0x00000000, DSI_CLK_CTRL);  
  27.     writel(0x00000002, DSI_CLK_CTRL);  
  28.     writel(0x00000006, DSI_CLK_CTRL);  
  29.     writel(0x0000000e, DSI_CLK_CTRL);  
  30.     writel(0x0000001e, DSI_CLK_CTRL);  
  31.     writel(0x0000003e, DSI_CLK_CTRL);  
  32.   
  33.     writel(0, DSI_CTRL);  
  34.   
  35.     writel(0, DSI_ERR_INT_MASK0);  
  36.   
  37.     writel(0x02020202, DSI_INT_CTRL);  
  38.   
  39.     writel(((disp_width + hsync_porch0_bp) << 16) | hsync_porch0_bp,  
  40.             DSI_VIDEO_MODE_ACTIVE_H);  
  41.     writel(((disp_height + vsync_porch0_bp) << 16) | (vsync_porch0_bp),  
  42.             DSI_VIDEO_MODE_ACTIVE_V);  
  43.   
  44.     if (mdp_get_revision() >= MDP_REV_41) {  
  45.         writel(((disp_height + vsync_porch0_fp  
  46.             + vsync_porch0_bp - 1) << 16)  
  47.             | (disp_width + hsync_porch0_fp  
  48.             + hsync_porch0_bp - 1),  
  49.             DSI_VIDEO_MODE_TOTAL);  
  50.     } else {  
  51.         writel(((disp_height + vsync_porch0_fp  
  52.             + vsync_porch0_bp) << 16)  
  53.             | (disp_width + hsync_porch0_fp  
  54.             + hsync_porch0_bp),  
  55.             DSI_VIDEO_MODE_TOTAL);  
  56.     }  
  57.     writel((hsync_width << 16) | 0, DSI_VIDEO_MODE_HSYNC);  
  58.   
  59.     writel(0 << 16 | 0, DSI_VIDEO_MODE_VSYNC);  
  60.   
  61.     writel(vsync_width << 16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS);  
  62.   
  63.     writel(1, DSI_EOT_PACKET_CTRL);  
  64.   
  65.     writel(0x00000100, DSI_MISR_VIDEO_CTRL);  
  66.   
  67.     if (mdp_get_revision() >= MDP_REV_41) {  
  68.         writel(low_pwr_stop_mode << 16 |  
  69.                 eof_bllp_pwr << 12 | traffic_mode << 8  
  70.                 | dst_format << 4 | 0x0, DSI_VIDEO_MODE_CTRL);  
  71.     } else {  
  72.         writel(1 << 28 | 1 << 24 | 1 << 20 | low_pwr_stop_mode << 16 |  
  73.                 eof_bllp_pwr << 12 | traffic_mode << 8  
  74.                 | dst_format << 4 | 0x0, DSI_VIDEO_MODE_CTRL);  
  75.     }  
  76.     writel(0x67, DSI_CAL_STRENGTH_CTRL);  
  77.     writel(0x80006711, DSI_CAL_CTRL);  
  78.     writel(0x00010100, DSI_MISR_VIDEO_CTRL);  
  79.   
  80.     writel(0x00010100, DSI_INT_CTRL);  
  81.     writel(0x02010202, DSI_INT_CTRL);  
  82.     writel(0x02030303, DSI_INT_CTRL);  
  83.   
  84.     writel(interleav << 30 | 0 << 24 | 0 << 20 | lane_en << 4  
  85.             | 0x103, DSI_CTRL);  
  86.   
  87.     return status;  
  88. }  
int mipi_dsi_video_mode_config(unsigned short disp_width,
	unsigned short disp_height,
	unsigned short img_width,
	unsigned short img_height,
	unsigned short hsync_porch0_fp,
	unsigned short hsync_porch0_bp,
	unsigned short vsync_porch0_fp,
	unsigned short vsync_porch0_bp,
	unsigned short hsync_width,
	unsigned short vsync_width,
	unsigned short dst_format,
	unsigned short traffic_mode,
	unsigned char lane_en,
	unsigned low_pwr_stop_mode,
	unsigned char eof_bllp_pwr,
	unsigned char interleav)
{

	int status = 0;

	/* disable mdp first */
	mdp_disable();
	writel(0x00000000, DSI_CLK_CTRL);
	writel(0x00000000, DSI_CLK_CTRL);
	writel(0x00000000, DSI_CLK_CTRL);
	writel(0x00000000, DSI_CLK_CTRL);
	writel(0x00000002, DSI_CLK_CTRL);
	writel(0x00000006, DSI_CLK_CTRL);
	writel(0x0000000e, DSI_CLK_CTRL);
	writel(0x0000001e, DSI_CLK_CTRL);
	writel(0x0000003e, DSI_CLK_CTRL);

	writel(0, DSI_CTRL);

	writel(0, DSI_ERR_INT_MASK0);

	writel(0x02020202, DSI_INT_CTRL);

	writel(((disp_width + hsync_porch0_bp) << 16) | hsync_porch0_bp,
			DSI_VIDEO_MODE_ACTIVE_H);
	writel(((disp_height + vsync_porch0_bp) << 16) | (vsync_porch0_bp),
			DSI_VIDEO_MODE_ACTIVE_V);

	if (mdp_get_revision() >= MDP_REV_41) {
		writel(((disp_height + vsync_porch0_fp
			+ vsync_porch0_bp - 1) << 16)
			| (disp_width + hsync_porch0_fp
			+ hsync_porch0_bp - 1),
			DSI_VIDEO_MODE_TOTAL);
	} else {
		writel(((disp_height + vsync_porch0_fp
			+ vsync_porch0_bp) << 16)
			| (disp_width + hsync_porch0_fp
			+ hsync_porch0_bp),
			DSI_VIDEO_MODE_TOTAL);
	}
	writel((hsync_width << 16) | 0, DSI_VIDEO_MODE_HSYNC);

	writel(0 << 16 | 0, DSI_VIDEO_MODE_VSYNC);

	writel(vsync_width << 16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS);

	writel(1, DSI_EOT_PACKET_CTRL);

	writel(0x00000100, DSI_MISR_VIDEO_CTRL);

	if (mdp_get_revision() >= MDP_REV_41) {
		writel(low_pwr_stop_mode << 16 |
				eof_bllp_pwr << 12 | traffic_mode << 8
				| dst_format << 4 | 0x0, DSI_VIDEO_MODE_CTRL);
	} else {
		writel(1 << 28 | 1 << 24 | 1 << 20 | low_pwr_stop_mode << 16 |
				eof_bllp_pwr << 12 | traffic_mode << 8
				| dst_format << 4 | 0x0, DSI_VIDEO_MODE_CTRL);
	}
	writel(0x67, DSI_CAL_STRENGTH_CTRL);
	writel(0x80006711, DSI_CAL_CTRL);
	writel(0x00010100, DSI_MISR_VIDEO_CTRL);

	writel(0x00010100, DSI_INT_CTRL);
	writel(0x02010202, DSI_INT_CTRL);
	writel(0x02030303, DSI_INT_CTRL);

	writel(interleav << 30 | 0 << 24 | 0 << 20 | lane_en << 4
			| 0x103, DSI_CTRL);

	return status;
}

mipi_config is at lk/platform/msm_shared/mipi_dsi.c

  1. int mipi_config(struct msm_fb_panel_data *panel)  
  2. {  
  3.     int ret = NO_ERROR;  
  4.     struct msm_panel_info *pinfo;  
  5.     struct mipi_dsi_panel_config mipi_pinfo;  
  6.   
  7.     if (!panel)  
  8.         return ERR_INVALID_ARGS;  
  9.   
  10.     pinfo = &(panel->panel_info);  
  11.     mipi_pinfo.mode = pinfo->mipi.mode;  
  12.     mipi_pinfo.num_of_lanes = pinfo->mipi.num_of_lanes;  
  13.     mipi_pinfo.dsi_phy_config = pinfo->mipi.dsi_phy_db;  
  14.     mipi_pinfo.panel_cmds = pinfo->mipi.panel_cmds;  
  15.     mipi_pinfo.num_of_panel_cmds = pinfo->mipi.num_of_panel_cmds;  
  16.     mipi_pinfo.lane_swap = pinfo->mipi.lane_swap;  
  17.   
  18.     /* Enable MMSS_AHB_ARB_MATER_PORT_E for 
  19.        arbiter master0 and master 1 request */  
  20. #if (!DISPLAY_MIPI_PANEL_RENESAS)   
  21.     writel(0x00001800, MMSS_SFPB_GPREG);  
  22. #endif   
  23.   
  24.     mipi_dsi_phy_init(&mipi_pinfo); // This is related to phy timing and ctrl, regulator, strength, pll control    
  25.   
  26.     ret += mipi_dsi_panel_initialize(&mipi_pinfo);  
  27.   
  28.     if (pinfo->rotate && panel->rotate)  
  29.         pinfo->rotate();  
  30.   
  31.     return ret;  
  32. }  
int mipi_config(struct msm_fb_panel_data *panel)
{
	int ret = NO_ERROR;
	struct msm_panel_info *pinfo;
	struct mipi_dsi_panel_config mipi_pinfo;

	if (!panel)
		return ERR_INVALID_ARGS;

	pinfo = &(panel->panel_info);
	mipi_pinfo.mode = pinfo->mipi.mode;
	mipi_pinfo.num_of_lanes = pinfo->mipi.num_of_lanes;
	mipi_pinfo.dsi_phy_config = pinfo->mipi.dsi_phy_db;
	mipi_pinfo.panel_cmds = pinfo->mipi.panel_cmds;
	mipi_pinfo.num_of_panel_cmds = pinfo->mipi.num_of_panel_cmds;
	mipi_pinfo.lane_swap = pinfo->mipi.lane_swap;

	/* Enable MMSS_AHB_ARB_MATER_PORT_E for
	   arbiter master0 and master 1 request */
#if (!DISPLAY_MIPI_PANEL_RENESAS)
	writel(0x00001800, MMSS_SFPB_GPREG);
#endif

	mipi_dsi_phy_init(&mipi_pinfo); // This is related to phy timing and ctrl, regulator, strength, pll control 

	ret += mipi_dsi_panel_initialize(&mipi_pinfo);

	if (pinfo->rotate && panel->rotate)
		pinfo->rotate();

	return ret;
}

The following parameters are used for initializing dsi phy, the function is mipi_dsi_phy_init

  1. static struct mipi_dsi_phy_ctrl dsi_video_mode_otm9605a_boyi_lg_500_phy_db = {  
  2.     /* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */  
  3.     /* 0x0500: regulator */  
  4.     {0x02, 0x0a, 0x04, 0x00, 0x20},  
  5.     /* 0x0440: phy timing */  
  6.     {0x8a, 0x47, 0x14, 0x00, 0x55, 0x56, 0x19, 0x4b, 0x1f, 0x03, 0x04},  
  7.     /* 0x0470: phy ctrl */  
  8.     {0x5f, 0x00, 0x00, 0x10},  
  9.     /* 0x0480: strength */  
  10.     {0xff, 0x00, 0x06, 0x00},  
  11.     /* 0x0204: pll control */  
  12.     {0x00, 0xb4, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,  
  13.             0x01, 0x0f, 0x07, 0x00, 0x1a, 0x00, 0x0,  
  14.             0x02, 0x0, 0x20, 0x0, 0x01, 0x0},  
  15. };  
  16. #endif  
static struct mipi_dsi_phy_ctrl dsi_video_mode_otm9605a_boyi_lg_500_phy_db = {
	/* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
	/* 0x0500: regulator */
	{0x02, 0x0a, 0x04, 0x00, 0x20},
	/* 0x0440: phy timing */
	{0x8a, 0x47, 0x14, 0x00, 0x55, 0x56, 0x19, 0x4b, 0x1f, 0x03, 0x04},
	/* 0x0470: phy ctrl */
	{0x5f, 0x00, 0x00, 0x10},
	/* 0x0480: strength */
	{0xff, 0x00, 0x06, 0x00},
	/* 0x0204: pll control */
	{0x00, 0xb4, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,
			0x01, 0x0f, 0x07, 0x00, 0x1a, 0x00, 0x0,
			0x02, 0x0, 0x20, 0x0, 0x01, 0x0},
};
#endif
Now we can look at how to initialize phy (at platform/msm_shared/mipi_dsi_phy.c)

  1. int mipi_dsi_phy_init(struct mipi_dsi_panel_config *pinfo)  
  2. {  
  3.     struct mipi_dsi_phy_ctrl *pd;  
  4.     uint32_t i, off = 0;  
  5.     int mdp_rev;  
  6.   
  7.     mdp_rev = mdp_get_revision();  
  8.     writel(0x0001, MIPI_DSI_BASE + 0x128);  /* start phy sw reset */  
  9.     udelay(1);  
  10.     writel(0x0000, MIPI_DSI_BASE + 0x128);  /* end phy sw reset */  
  11.     udelay(1);  
  12.     /* disable DCDC & enable LDO */  
  13.     writel(0x0002, MIPI_DSI_BASE + 0x500);  
  14.   
  15.     writel(0x0001, MIPI_DSI_BASE + 0x504);  /* regulator_ctrl_1 */  
  16.     writel(0x0001, MIPI_DSI_BASE + 0x508);  /* regulator_ctrl_2 */  
  17.     writel(0x0000, MIPI_DSI_BASE + 0x50c);  /* regulator_ctrl_3 */  
  18.     writel(0x0100, MIPI_DSI_BASE + 0x510);  /* regulator_ctrl_4 */  
  19.     /* enable LDO mode */  
  20.     writel(0x05, MIPI_DSI_BASE + 0x4b0);  
  21.     pd = (pinfo->dsi_phy_config);  
  22.     off = 0x0480;       /* strength 0 - 2 */  
  23.     for (i = 0; i < 3; i++) {  
  24.         writel(pd->strength[i], MIPI_DSI_BASE + off);  
  25.         off += 4;  
  26.     }  
  27.     off = 0x0470;       /* ctrl 0 - 3 */  
  28.     for (i = 0; i < 4; i++) {  
  29.         writel(pd->ctrl[i], MIPI_DSI_BASE + off);  
  30.         off += 4;  
  31.     }  
  32.     off = 0x0500;       /* regulator ctrl 0 - 4 */  
  33.     for (i = 0; i < 5; i++) {  
  34.         writel(pd->regulator[i], MIPI_DSI_BASE + off);  
  35.         off += 4;  
  36.     }  
  37.     mipi_dsi_calibration();  
  38.     mipi_dsi_lane_cfg();  
  39.     mipi_dsi_bist_ctrl();  
  40.   
  41.     off = 0x0204;       /* pll ctrl 1 - 19, skip 0 */  
  42.     for (i = 1; i < 20; i++) {  
  43.         writel(pd->pll[i], MIPI_DSI_BASE + off);  
  44.         off += 4;  
  45.     }  
  46.   
  47.     /* pll ctrl 0 */  
  48.     writel(pd->pll[0], MIPI_DSI_BASE + 0x200);  
  49.     writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);  
  50.   
  51.     /* Check that PHY is ready */  
  52.     while (!(readl(DSIPHY_PLL_RDY) & 0x01))  
  53.         udelay(1);  
  54.   
  55.     writel(0x202D, DSI_CLKOUT_TIMING_CTRL);  
  56.     off = 0x0440;       /* phy timing ctrl 0 - 11 */  
  57.     for (i = 0; i < 12; i++) {  
  58.         writel(pd->timing[i], MIPI_DSI_BASE + off);  
  59.         off += 4;  
  60.     }  
  61.     if (pinfo->lane_swap)  
  62.         writel(pinfo->lane_swap, MIPI_DSI_BASE + 0xac);  
  63.     return 0;  
  64. }  
int mipi_dsi_phy_init(struct mipi_dsi_panel_config *pinfo)
{
	struct mipi_dsi_phy_ctrl *pd;
	uint32_t i, off = 0;
	int mdp_rev;

	mdp_rev = mdp_get_revision();
	writel(0x0001, MIPI_DSI_BASE + 0x128);	/* start phy sw reset */
	udelay(1);
	writel(0x0000, MIPI_DSI_BASE + 0x128);	/* end phy sw reset */
	udelay(1);
	/* disable DCDC & enable LDO */
	writel(0x0002, MIPI_DSI_BASE + 0x500);

	writel(0x0001, MIPI_DSI_BASE + 0x504);	/* regulator_ctrl_1 */
	writel(0x0001, MIPI_DSI_BASE + 0x508);	/* regulator_ctrl_2 */
	writel(0x0000, MIPI_DSI_BASE + 0x50c);	/* regulator_ctrl_3 */
	writel(0x0100, MIPI_DSI_BASE + 0x510);	/* regulator_ctrl_4 */
	/* enable LDO mode */
	writel(0x05, MIPI_DSI_BASE + 0x4b0);
	pd = (pinfo->dsi_phy_config);
	off = 0x0480;		/* strength 0 - 2 */
	for (i = 0; i < 3; i++) {
		writel(pd->strength[i], MIPI_DSI_BASE + off);
		off += 4;
	}
	off = 0x0470;		/* ctrl 0 - 3 */
	for (i = 0; i < 4; i++) {
		writel(pd->ctrl[i], MIPI_DSI_BASE + off);
		off += 4;
	}
	off = 0x0500;		/* regulator ctrl 0 - 4 */
	for (i = 0; i < 5; i++) {
		writel(pd->regulator[i], MIPI_DSI_BASE + off);
		off += 4;
	}
	mipi_dsi_calibration();
	mipi_dsi_lane_cfg();
	mipi_dsi_bist_ctrl();

	off = 0x0204;		/* pll ctrl 1 - 19, skip 0 */
	for (i = 1; i < 20; i++) {
		writel(pd->pll[i], MIPI_DSI_BASE + off);
		off += 4;
	}

	/* pll ctrl 0 */
	writel(pd->pll[0], MIPI_DSI_BASE + 0x200);
	writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);

	/* Check that PHY is ready */
	while (!(readl(DSIPHY_PLL_RDY) & 0x01))
		udelay(1);

	writel(0x202D, DSI_CLKOUT_TIMING_CTRL);
	off = 0x0440;		/* phy timing ctrl 0 - 11 */
	for (i = 0; i < 12; i++) {
		writel(pd->timing[i], MIPI_DSI_BASE + off);
		off += 4;
	}
	if (pinfo->lane_swap)
		writel(pinfo->lane_swap, MIPI_DSI_BASE + 0xac);
	return 0;
}

mdp_dsi_video_config is at lk/platform/msm_shared/mdp4.c. (porch, vsync, hsync, framebuffer base address and so on)

  1. /* MDP_AXI_RDMASTER_CONFIG set all master to read from 
  2.    AXI port 0, that's the only port connected */  
  3. writel(0x00290000, MDP_AXI_RDMASTER_CONFIG);  
  4. writel(0x00000004, MDP_AXI_WRMASTER_CONFIG);  
  5. writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG);  
  6.   
  7. /* Set up CMD_INTF_SEL, VIDEO_INTF_SEL, 
  8.    EXT_INTF_SEL, SEC_INTF_SEL, PRIM_INTF_SEL */  
  9. writel(0x00000049, MDP_DISP_INTF_SEL);  
  10.   
  11. /* DMA P */  
  12. writel(0x0000000b, MDP_OVERLAYPROC0_CFG);  
  13.   
  14. /* write fb addr in MDP_DMA_P_BUF_ADDR */  
  15. writel(fb->base, MDP_DMA_P_BUF_ADDR);  
  16.   
  17. /* write active region size*/  
  18. mdp_rgb_size = (fb->height << 16) + fb->width;  
  19. writel(mdp_rgb_size, MDP_DMA_P_SIZE);  
  20.   
  21. /* set Y-stride value in bytes */  
  22. /* Y-stride is defined as the number of bytes 
  23.    in a line. 
  24.  */  
  25. writel((fb->stride * fb->bpp/8), MDP_DMA_P_BUF_Y_STRIDE);  
  26.   
  27. /* Start XY coordinates */  
  28. writel(0, MDP_DMA_P_OUT_XY);  
	/* MDP_AXI_RDMASTER_CONFIG set all master to read from
	   AXI port 0, that's the only port connected */
	writel(0x00290000, MDP_AXI_RDMASTER_CONFIG);
	writel(0x00000004, MDP_AXI_WRMASTER_CONFIG);
	writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG);

	/* Set up CMD_INTF_SEL, VIDEO_INTF_SEL,
	   EXT_INTF_SEL, SEC_INTF_SEL, PRIM_INTF_SEL */
	writel(0x00000049, MDP_DISP_INTF_SEL);

	/* DMA P */
	writel(0x0000000b, MDP_OVERLAYPROC0_CFG);

	/* write fb addr in MDP_DMA_P_BUF_ADDR */
	writel(fb->base, MDP_DMA_P_BUF_ADDR);

	/* write active region size*/
	mdp_rgb_size = (fb->height << 16) + fb->width;
	writel(mdp_rgb_size, MDP_DMA_P_SIZE);

	/* set Y-stride value in bytes */
	/* Y-stride is defined as the number of bytes
	   in a line.
	 */
	writel((fb->stride * fb->bpp/8), MDP_DMA_P_BUF_Y_STRIDE);

	/* Start XY coordinates */
	writel(0, MDP_DMA_P_OUT_XY);

mdp_dsi_video_on is at lk/platform/msm_shared/mdp4.c

mipi_dsi_on is at lk/platform/msm_shared/mipi_dsi.c.

  1. case MIPI_VIDEO_PANEL:  
  2.     dprintf(INFO, "Turn on MIPI_VIDEO_PANEL.\n");  
  3.     ret = mdp_dsi_video_on();  
  4.     if (ret)  
  5.         goto msm_display_on_out;  
  6.     ret = mipi_dsi_on();  
  7.     if (ret)  
  8.         goto msm_display_on_out;  
  9.     break;  
	case MIPI_VIDEO_PANEL:
		dprintf(INFO, "Turn on MIPI_VIDEO_PANEL.\n");
		ret = mdp_dsi_video_on();
		if (ret)
			goto msm_display_on_out;
		ret = mipi_dsi_on();
		if (ret)
			goto msm_display_on_out;
		break;
  1. int mdp_dsi_video_on()  
  2. {  
  3.     int ret = NO_ERROR;  
  4.   
  5.     writel(0x00000001, MDP_DSI_VIDEO_EN);  
  6.   
  7.     return ret;  
  8. }  
int mdp_dsi_video_on()
{
	int ret = NO_ERROR;

	writel(0x00000001, MDP_DSI_VIDEO_EN);

	return ret;
}

  1. int mipi_dsi_on()  
  2. {  
  3.     int ret = NO_ERROR;  
  4.     unsigned long ReadValue;  
  5.     unsigned long count = 0;  
  6.   
  7.     ReadValue = readl(DSI_INT_CTRL) & 0x00010000;  
  8.   
  9.     mdelay(10);  
  10.   
  11.     while (ReadValue != 0x00010000) {  
  12.         ReadValue = readl(DSI_INT_CTRL) & 0x00010000;  
  13.         count++;  
  14.         if (count > 0xffff) {  
  15.             dprintf(CRITICAL, "Video lane test failed\n");  
  16.             return ERROR;  
  17.         }  
  18.     }  
  19.   
  20.     dprintf(INFO, "Video lane tested successfully\n");  
  21.     return ret;  
  22. }  
int mipi_dsi_on()
{
	int ret = NO_ERROR;
	unsigned long ReadValue;
	unsigned long count = 0;

	ReadValue = readl(DSI_INT_CTRL) & 0x00010000;

	mdelay(10);

	while (ReadValue != 0x00010000) {
		ReadValue = readl(DSI_INT_CTRL) & 0x00010000;
		count++;
		if (count > 0xffff) {
			dprintf(CRITICAL, "Video lane test failed\n");
			return ERROR;
		}
	}

	dprintf(INFO, "Video lane tested successfully\n");
	return ret;
}

lcd off, (msm_display_off at lk/platform/msm_shared/display.c)as follow:

  1. int msm_display_off(int enable)  
  2. {  
  3.     int ret = NO_ERROR;  
  4.     struct msm_panel_info *pinfo;  
  5.   
  6.     dprintf(CRITICAL, "display off mode = %d!\n", enable);  
  7.     if (!panel)  
  8.         return ERR_INVALID_ARGS;  
  9.   
  10.     pinfo = &(panel->panel_info);  
  11.   
  12.     switch (pinfo->type) {  
  13.     case MIPI_VIDEO_PANEL:  
  14.         dprintf(INFO, "Turn off MIPI_VIDEO_PANEL.\n");  
  15.         if (!enable)  
  16.             mipi_panel_off();  
  17.         ret = mdp_dsi_video_off(enable);  
  18.         if (ret)  
  19.             goto msm_display_off_out;  
  20.         ret = mipi_dsi_off(enable);  
  21.         if (ret)  
  22.             goto msm_display_off_out;  
  23.         break;  
  24.     default:  
  25.         return ERR_INVALID_ARGS;  
  26.     };  
  27.   
  28.     if (pinfo->off)  
  29.         ret = pinfo->off();  
  30.   
  31.     /* Disable clock */  
  32.     if (panel->clk_func)  
  33.         ret = panel->clk_func(0);  
  34.   
  35.     if (ret)  
  36.         goto msm_display_off_out;  
  37.   
  38.     /* Disable panel */  
  39.     if (panel->power_func)  
  40.         ret = panel->power_func(0);  
  41.   
  42. msm_display_off_out:  
  43.     return ret;  
  44. }  
int msm_display_off(int enable)
{
	int ret = NO_ERROR;
	struct msm_panel_info *pinfo;

	dprintf(CRITICAL, "display off mode = %d!\n", enable);
	if (!panel)
		return ERR_INVALID_ARGS;

	pinfo = &(panel->panel_info);

	switch (pinfo->type) {
	case MIPI_VIDEO_PANEL:
		dprintf(INFO, "Turn off MIPI_VIDEO_PANEL.\n");
		if (!enable)
			mipi_panel_off();
		ret = mdp_dsi_video_off(enable);
		if (ret)
			goto msm_display_off_out;
		ret = mipi_dsi_off(enable);
		if (ret)
			goto msm_display_off_out;
		break;
	default:
		return ERR_INVALID_ARGS;
	};

	if (pinfo->off)
		ret = pinfo->off();

	/* Disable clock */
	if (panel->clk_func)
		ret = panel->clk_func(0);

	if (ret)
		goto msm_display_off_out;

	/* Disable panel */
	if (panel->power_func)
		ret = panel->power_func(0);

msm_display_off_out:
	return ret;
}

3  Last, it's time to init and show pictures

The function system_boot at lk/platform/msm8960/power_on_event.c, as follows:

  1. display_init();  
  2. fbcon_clear();  
  3. show_white_color(0, 0);  
  4. mipi_backlight_tx(100);  
  5. msm_display_off(0 or 1);  
display_init();
fbcon_clear();
show_white_color(0, 0);
mipi_backlight_tx(100);
msm_display_off(0 or 1);

4  Frequently asked questions

4.1 Flower Screen

a. pclk is not correct.
If the actual pclk is larger than required clock, the result will be as follow: there is backlight lighted up, but no picture;
If the actual pclk is smaller than required clock, the result will be as follow: flower screen(high frequency flicker);

b. Resolution ratio is not correct.
If so, static incorrect picture will be seen, but the outline can still  be seen, no matter that the resolution is set to be larger or smaller.
If only x axis['æksɪs](轴线坐标轴or only y axis is not right, the outline will be more clear, maybe a little stretch, but can be shown.

c. dsi clock is incorrect
If so, lcd can't show picture

d. byte clock is incorrect
If so, lcd can't show picture

e. mdp underrun
If mdp underrun, maybe flower screen would appear.

4.2 Flicker
In most cases, flicker is caused by backlight. If the analog voltage (2.85V, 1.2V) and digital voltage (1.8V) are not appropriate, lcd would flicker too. So the power supply should be checked first. At the beginning of hardware design, we often encounter that the power supply get disturbed. Meanwhile if lcd work well, it would interfere[ɪntə'fɪə] with other peripherals. Please pay attention to these things.

4.3 residual[rɪ'zɪdjʊəl] shadows


4.4 blank screen


4.5 backlight good


4.6 color cast (偏色)


4.7 gamma larger or smaller


4.8 backlight too bright


4.9 power consumption too much


4.10 color inversion


4.11 VBP, VFP, HBP, HFP

a. If the picture jitters up and down and you can see clearly the content, maybe VBP or VFP is too small. So by means of adjusting the value of VBP and VFP, this scene can be fixed.

b. If you can see some additional lines on the edge of lcd, maybe HBP or HFP is not appropriate. So by means of adjusting the value of HBP and HFP, this scene can be fixed.

5  lcd power down(pm8038, 2.85V, 1.8V, 1.2V)

  1. int pm8921_ldo_lvs_disable(uint32_t ldo_id)  
  2. {  
  3.        uint32_t ldo_num = (ldo_id & ~LDO_P_MASK);  
  4.        uint32_t val = 0;  
  5.        if (ldo_id == lvs_2) {  
  6.                pm8921_masked_write(PM8921_LVS_CTRL_REG(lvs_2), 0x80, val);  
  7.                return 0;  
  8.        }  
  9.        pm8921_masked_write(PM8921_LDO_CTRL_REG(ldo_num), 0x80, val);  
  10.        return 0;  
  11. }  
展开阅读全文

没有更多推荐了,返回首页