高通lk屏幕向kernel传参

LK把相关参数报存到cmdline上:

Bootableootloaderlkdevgcdbdisplaygcdb_display_param.cgcdb_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
");
				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
");
		return false;
	}

	if (panel_mode && slave_panel_node == NULL) {
		dprintf(CRITICAL, "slave node not present in dual dsi case
");
		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
");
		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
",
			 __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
");
			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
", __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
",
			       __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
",
			       __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;
}

原文地址:https://www.cnblogs.com/linhaostudy/p/11720678.html