LK把相关参数报存到cmdline上:
在Bootable\bootloader\lk\dev\gcdb\display\gcdb_display_param.c
上gcdb_display_cmdline_arg
函数里:
调用过程如图所示:
aboot_init()--> target_display_panel_node()--> gcdb_display_cmdline_arg(panel_name, pbuf, buf_size)
aboot_init()函数里面:
#define DISPLAY_DEFAULT_PREFIX "mdss_mdp" .......... if (cmdline) { if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) && target_display_panel_node(device.display_panel, display_panel_buf, MAX_PANEL_BUF_SIZE) && strlen(display_panel_buf)) { cmdline_len += strlen(display_panel_buf); } }
target_display_panel_node()函数里面:
bool gcdb_display_cmdline_arg(char *panel_name, char *pbuf, uint16_t buf_size) { char *dsi_id = NULL; char *panel_node = NULL; char *slave_panel_node = NULL; uint16_t dsi_id_len = 0, panel_node_len = 0, slave_panel_node_len = 0; uint32_t arg_size = 0; bool ret = true; bool rc; char *default_str; int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG | DST_SPLIT_FLAG; int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX); panel_name += strspn(panel_name, " "); rc = mdss_dsi_set_panel_node(panel_name, &dsi_id, &panel_node, &slave_panel_node, &panel_mode); if (!rc) { if (panelstruct.paneldata && target_cont_splash_screen()) { dsi_id = panelstruct.paneldata->panel_controller; panel_node = panelstruct.paneldata->panel_node_id; panel_mode = panelstruct.paneldata->panel_operating_mode & panel_mode; slave_panel_node = panelstruct.paneldata->slave_panel_node_id; } else { if (target_is_edp()) default_str = "0:edp:"; else default_str = "0:dsi:0:"; arg_size = prefix_string_len + strlen(default_str); if (buf_size < arg_size) { dprintf(CRITICAL, "display command line buffer is small\n"); return false; } strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size); pbuf += prefix_string_len; buf_size -= prefix_string_len; strlcpy(pbuf, default_str, buf_size); return true; } } if (dsi_id == NULL || panel_node == NULL) { dprintf(CRITICAL, "panel node or dsi ctrl not present\n"); return false; } if (panel_mode && slave_panel_node == NULL) { dprintf(CRITICAL, "slave node not present in dual dsi case\n"); return false; } dsi_id_len = strlen(dsi_id); panel_node_len = strlen(panel_node); if (!slave_panel_node) slave_panel_node = NO_PANEL_CONFIG; slave_panel_node_len = strlen(slave_panel_node); arg_size = prefix_string_len + dsi_id_len + panel_node_len + LK_OVERRIDE_PANEL_LEN + 1; arg_size += DSI_1_STRING_LEN + slave_panel_node_len; if (buf_size < arg_size) { dprintf(CRITICAL, "display command line buffer is small\n"); ret = false; } else { strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size); pbuf += prefix_string_len; buf_size -= prefix_string_len; strlcpy(pbuf, LK_OVERRIDE_PANEL, buf_size); pbuf += LK_OVERRIDE_PANEL_LEN; buf_size -= LK_OVERRIDE_PANEL_LEN; strlcpy(pbuf, dsi_id, buf_size); pbuf += dsi_id_len; buf_size -= dsi_id_len; strlcpy(pbuf, panel_node, buf_size); pbuf += panel_node_len; buf_size -= panel_node_len; strlcpy(pbuf, DSI_1_STRING, buf_size); pbuf += DSI_1_STRING_LEN; buf_size -= DSI_1_STRING_LEN; strlcpy(pbuf, slave_panel_node, buf_size); } end: return ret; }
最终传给赋值给cmdline的就是从mdss_mdp3.panel=1:dsi:0:qcom,mdss_dsi_tianshan_qhd_video:1:none
kernel获取LK保存的pbuf
调用顺序:
start_kernel()--> setup_arch()--> set_command_line()-->
这是将command_line保存下来:
/** * mdss_dsi_find_panel_of_node(): find device node of dsi panel * @pdev: platform_device of the dsi ctrl node * @panel_cfg: string containing intf specific config data * * Function finds the panel device node using the interface * specific configuration data. This configuration data is * could be derived from the result of bootloader's GCDB * panel detection mechanism. If such config data doesn't * exist then this panel returns the default panel configured * in the device tree. * * returns pointer to panel node on success, NULL on error. */ static struct device_node *mdss_dsi_find_panel_of_node( struct platform_device *pdev, char *panel_cfg) { int len, i; int ctrl_id = pdev->id - 1; char panel_name[MDSS_MAX_PANEL_LEN]; char ctrl_id_stream[3] = "0:"; char *stream = NULL, *pan = NULL; struct device_node *dsi_pan_node = NULL, *mdss_node = NULL; len = strlen(panel_cfg); if (!len) { /* no panel cfg chg, parse dt */ pr_debug("%s:%d: no cmd line cfg present\n", __func__, __LINE__); goto end; } else { if (ctrl_id == 1) strlcpy(ctrl_id_stream, "1:", 3); stream = strnstr(panel_cfg, ctrl_id_stream, len); if (!stream) { pr_err("controller config is not present\n"); goto end; } stream += 2; pan = strnchr(stream, strlen(stream), ':'); if (!pan) { strlcpy(panel_name, stream, MDSS_MAX_PANEL_LEN); } else { for (i = 0; (stream + i) < pan; i++) panel_name[i] = *(stream + i); panel_name[i] = 0; } pr_debug("%s:%d:%s:%s\n", __func__, __LINE__, panel_cfg, panel_name); mdss_node = of_parse_phandle(pdev->dev.of_node, "qcom,mdss-mdp", 0); if (!mdss_node) { pr_err("%s: %d: mdss_node null\n", __func__, __LINE__); return NULL; } dsi_pan_node = of_find_node_by_name(mdss_node, panel_name); if (!dsi_pan_node) { pr_err("%s: invalid pan node, selecting prim panel\n", __func__); goto end; } return dsi_pan_node; } end: //最后如果都没有匹配到的话,就使用这个qcom,dsi-pref-prim-pan节点上的 if (strcmp(panel_name, NONE_PANEL)) dsi_pan_node = mdss_dsi_pref_prim_panel(pdev); return dsi_pan_node; }