bootloader lcd init
来源:互联网 发布:淘宝被骗怎么投诉举报 编辑:程序博客网 时间:2024/05/16 06:39
1 display_init
- 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;
- }
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 driverpanel.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:
- 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);
- }
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);}
- 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;
- }
static int msm8960_mipi_panel_clock(int enable){if (enable) {mdp_clock_init(); // acpuclock.cmmss_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); // L11pm8921_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); // L2pm8921_ldo_set_voltage(LDO_9, LDO_VOLTAGE_2_85V); // L9}return 0;}
How to shut down lvs and ldo voltage, as follows:
- 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
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 closedThe following implementation can be placed at lk/dev/pmic/pm8921/pm8921.c
- 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;
- }
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:
- 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;
- }
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
- 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);
- }
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.
- /* 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);
- }
/* 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);}
- 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);
- }
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:
- 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) {
- <SPAN style="WHITE-SPACE: pre"> </SPAN>ret = ERR_INVALID_ARGS;
- <SPAN style="WHITE-SPACE: pre"> </SPAN>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;
- }
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 0x89000000if (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:
- 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;
- <SPAN style="WHITE-SPACE: pre"> </SPAN>}
- if (pinfo->config) // mipi_global_video_init:pinfo->config = mipi_global_video_config;
- ret = pinfo->config((void *)pinfo);
- }
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
- 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;
- }
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.
- 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;
- }
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);#endifmipi_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
- 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
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},};#endifNow we can look at how to initialize phy (at platform/msm_shared/mipi_dsi_phy.c)
- 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;
- }
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)
- /* 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_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.
- 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;
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;
- int mdp_dsi_video_on()
- {
- int ret = NO_ERROR;
- writel(0x00000001, MDP_DSI_VIDEO_EN);
- return ret;
- }
int mdp_dsi_video_on(){int ret = NO_ERROR;writel(0x00000001, MDP_DSI_VIDEO_EN);return ret;}
- 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;
- }
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:
- 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;
- }
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:
- display_init();
- fbcon_clear();
- show_white_color(0, 0);
- mipi_backlight_tx(100);
- 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.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)
- 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);
- return 0;
- }
- pm8921_masked_write(PM8921_LDO_CTRL_REG(ldo_num), 0x80, val);
- return 0;
- }
- bootloader lcd init
- bootloader lcd init
- 增加bootloader LCD亮度
- TE2440II-bootloader-2440init.s
- MTK lcd debug method----update lcd init code online
- 简易bootloader的LCD白屏问题(mini2440)
- 自己写bootloader笔记3---init.c分析
- 自己写bootloader笔记3---init.c分析
- Bootloader
- BootLoader
- BootLoader
- BootLoader
- Bootloader
- bootLoader
- bootloader
- bootloader
- bootloader
- BootLoader
- 一个bug
- iptables
- TCP/IP详解学习笔记(13)-TCP坚持定时器,TCP保活定时器
- js 去掉重复的字符串
- cocos2d-x Lua 自定义类的Lua接口生成
- bootloader lcd init
- mysql 返回多个函数计算结果
- 关于继承的一些知识点和实现方法
- 好像真有感觉
- TCP长连接与短连接的区别
- 如何快速在数据库中插入数据
- 【数据结构】之二叉树的java实现
- jQuery.Autocomplete 中文支持
- HTML5中播放媒体文件