前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高通移植mipi LCD的过程LK代码

高通移植mipi LCD的过程LK代码

作者头像
233333
发布2018-07-30 10:57:48
1.6K0
发布2018-07-30 10:57:48
举报
文章被收录于专栏:linux驱动个人学习

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;

代码语言:javascript
复制
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供电

代码语言:javascript
复制
if (pdata->power_func)
    ret = pdata->power_func(1, &(panel->panel_info));

2. 调用mdss_dsi_mipi_dfps_config函数:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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()

代码语言:javascript
复制
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接口。

代码语言:javascript
复制
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;

代码语言:javascript
复制
   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();

主要部分:

代码语言:javascript
复制
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. 打开背光:

代码语言:javascript
复制
/* 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()函数中。)

代码语言:javascript
复制
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;

代码语言:javascript
复制
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:

代码语言:javascript
复制
/*---------------------------------------------------------------------------*/
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供应商给的文件,一般来说都要自己根据时序图来参照)

代码语言:javascript
复制
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来作用:(具体要看原理图)

代码语言:javascript
复制
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计算。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-06-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 函数定位
  • 2. 打开lcd
    • 1. 调用mdss_dsi_panel_power()中的regulator_enable()给L2、L6、L17供电
      • 2. 调用mdss_dsi_mipi_dfps_config函数:
        • 3. 调用mdss_dsi_panel_clock()
          • 4. 分配并设置帧缓存:
            • 5. 获取logo图片:
              • 6. DSI转HDMI:
                • 7. msm_display_config()函数:
                  • 8. ret = msm_display_on();
                    • 9. 打开背光:
                    • 3. 增加一个panel需要做的事:
                      • 1、在gcdb_display_init()函数中有一个函数oem_panel_select()函数:
                        • 2、uint32_t hw_id = board_hardware_id();
                          • 3、在oem_panel_select()函数中需要根据你的hw_id来确定使用哪一款的LCD;
                            • 4、在这个枚举中也需要增加相应的panel:
                              • 5、同样来到init_panel_data()函数中来:
                                • 6、调整背光:
                                  • 7、更改LCD的参数:
                                  相关产品与服务
                                  数据库
                                  云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档