1、 lk 阶段 lcm 兼容原理
aboot_init
|--|target_display_init(device.display_panel);
|--|do { //遍历panel_name_my数组
|memcpy(oem.panel, (panel_name_my + panel_loop), 64);//把panel_name_my拷贝到oem.panel中
|ret = gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR);
| |--oem_panel_select(panel_name, &panelstruct, &(panel.panel_info), &dsi_video_mode_phy_db);
| | |--panel_override_id = panel_name_to_id(supp_panels,ARRAY_SIZE(supp_panels), panel_name);//根据panel name返回panel_id
| | |--goto panel_init;//if 从enum 枚举,判断panel id,打印lcm的名字,之前绑定了id和name。如果有这个lcm则跳转到panel_init
| | |--init_panel_data(panelstruct, pinfo, phy_db);
| | |--switch(panel_id){
| | ...
| | case panel id:
| | ...//相应的初始化
| | }
| |
| |-- msm_display_init(&panel);
| |--msm_display_config();
| |--mdss_dsi_config(panel);
| |-- mdss_dsi_panel_initialize(mipi, mipi->broadcast);//
| |--mdss_dsi_read_panel_signature(mipi);
| |
| |
| |
| | //读取手机实际接的lcd的id号
| |--chip_id = oem_panel_compare_chip_id(mipi);
| | |
| | |-- mdss_dsi_cmds_tx(mipi, mipi->panel_compare_id_page_cmds, 1, 0);
| | |
| | |--mdss_dsi_cmds_tx(mipi, mipi->panel_compare_id_read_cmds, 1, 0);
| | |
| | |--mdss_dsi_cmds_rx(mipi, &lp, 1, 1)
| | |
| | |--return (ntohl(*lp) >> 16) & 0xFF;
| |//比对驱动对应的lcd的id,与实际lcd的id做对比,compare_id在/lk / target/msm8952_A306 的 init_panel_data()定义
| |--if (chip_id == mipi->compare_chipid)
| | return 0;
| |--else return1;
|
|
|////当屏幕匹配到了,或一块没匹配到,就跳出遍历的循环。
|-- if (!ret || ret == ERR_NOT_SUPPORTED) {
break;
}
} while (++panel_loop <= oem_panel_max_auto_detect_panels());
2、LCM 中驱动中背光在哪里控制,背光控制原理?哪里点亮背光,哪里设置背光等级?
lk阶段:
gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR);
|--oem_panel_select(panel_name, &panelstruct, &(panel.panel_info), &dsi_video_mode_phy_db);
| |--panel_override_id = panel_name_to_id(supp_panels,ARRAY_SIZE(supp_panels), panel_name);//根据panel name返回panel_id
| |--goto panel_init;//if 从enum 枚举,判断panel id,打印lcm的名字,之前绑定了id和name。如果有这个lcm则跳转到panel_init
| |--init_panel_data(panelstruct, pinfo, phy_db);
| |--switch(panel_id){
| ...
| case panel id:
| panelstruct->backlightinfo = &HX83102_B_720p_hsd_video_backlight;//背光相应的信息填充
| }
|--mdss_dsi_bl_enable //背光使能函数
|--ret = panel_backlight_ctrl(enable);
|--ret = target_backlight_ctrl(panelstruct.backlightinfo, enable);
|--msm8952_wled_backlight_ctrl(enable);
|--qpnp_wled_enable_backlight(enable); //使能
|--qpnp_wled_set_level(gwled, QPNP_WLED_MAX_BR_LEVEL); //设置背光等级
kernel阶段:在屏驱动下
//一些描述leds参数的信息结构体和枚举
enum led_brightness {
LED_OFF = 0,
LED_HALF = 127,
LED_FULL = 255,
};//背光的强度
struct led_classdev {
const char *name;
enum led_brightness brightness;
enum led_brightness max_brightness;
...
}
W:\work\TP_A306_0410\kernel\msm-3.18\drivers\video\msm\mdss\mdss_fb.c
module_init(mdss_fb_init);
|--int __init mdss_fb_init(void)
|--static struct platform_driver mdss_fb_driver = {
.probe = mdss_fb_probe,...}
|--static int mdss_fb_probe(struct platform_device *pdev)
|--led_classdev_register(&pdev->dev, &backlight_led);
|--.brightness_set = mdss_fb_set_bl_brightness,
|--mdss_fb_set_backlight(mfd, bl_lvl);
if (value > mfd->panel_info->brightness_max)
value = mfd->panel_info->brightness_max; //value值为屏幕获取的亮度条的值,这里可以定制亮度
|--pdata->set_backlight; //调用set_backlight,设置背光,搜索set_backlight,看在哪里绑定了函数
ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl;
|--static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata,u32 bl_level)
|--led_trigger_event(bl_led_trigger, bl_level);//控制PMI的WLED引脚控制背光
3、LCM ESD check 是什么意思?代码位置?如何修改 esd check 的频率?
答:是一种释放lcm静电的防护机制,在相应的屏幕的设备树文件中添加esd check
的代码即可。驱动流程如下:
int mdss_dsi_panel_init(struct device_node *node,struct mdss_dsi_ctrl_pdata
*ctrl_pdata,int ndx)
|--static int mdss_panel_parse_dt(struct device_node *np,struct
mdss_dsi_ctrl_pdata *ctrl_pdata)
|--rc = mdss_dsi_parse_panel_features(np, ctrl_pdata);
|--mdss_dsi_parse_esd_params(np, ctrl);
|--static void mdss_dsi_parse_esd_params(struct device_node *np,struct
mdss_dsi_ctrl_pdata *ctrl)
|--rc = of_property_read_string(np,"qcom,mdss-dsi-panel-status-check-mode", &string);//读取dts中的节点名字匹配到"reg_read"时执行ESD检查
|--ctrl->check_read_status =mdss_dsi_gen_read_status;
|--static int mdss_dsi_gen_read_status(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
|--static bool mdss_dsi_cmp_panel_reg_v2(struct mdss_dsi_ctrl_pdata *ctrl)
static int mdss_mdp_register_driver(void);
|--.probe = mdss_mdp_probe,>>static int mdss_mdp_probe(struct platform_device *pdev)
|--rc = mdss_fb_register_mdp_instance(&mdp5);
|--.check_dsi_status = mdss_check_dsi_ctrl_status,
|--ret = ctrl_pdata->check_status(ctrl_pdata);>>mdss_dsi_reg_status_check;
|--if (ret > 0) {
printk("lcd esd check success %s %d\n", __func__, __LINE__);
schedule_delayed_work(&pstatus_data->check_status,
msecs_to_jiffies(interval));
}
调试过程中,可以通过相关log看esd机制有没有生效。如下:搜索关键字(lcd esd)