网友通过本文主要向大家介绍了cmdline,cmdline是什么意思,proc/cmdline,torch.cmdline,cmdline.execute等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
如何通过cmdline获取panel型号的dtsi文件节点(qcom,lcd,id)
platform:msm8976 android 7.111. 在lk层,常用的方法是通过读取panel的id来确定当前使用的panel的型号,然后将panel的型号放在cmdline里面,如下:
project:/ # cat /proc/cmdline
... ... ... androidconfig.secureboot=enabled mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_ili9885_lide_hcg_auo_fhd_video:1:none:cfg:single_dsi ... ... ...
2. 在kernel层,通过cmdline寻找panel的dtsi文件节点并得到属性,这个过程是在mdss_dsi_config_panel函数进行的,如下:
(x:\work\project\kernel\drivers\video\msm\mdss\Mdss_dsi.c)mdss_dsi_ctrl_probe-->mdss_dsi_config_panel
3. mdss_dsi_config_panel函数主要是由三个部分组成:
- static struct device_node *mdss_dsi_config_panel(struct platform_device *pdev)
- {
- struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev);
- char panel_cfg[MDSS_MAX_PANEL_LEN];
- struct device_node *dsi_pan_node = NULL;
- int rc = 0;
- if (!ctrl_pdata) {
- pr_err("%s: Unable to get the ctrl_pdata\n", __func__);
- return NULL;
- }
- /* DSI panels can be different between controllers */
- rc = mdss_dsi_get_panel_cfg(panel_cfg, ctrl_pdata);
- if (!rc)
- /* dsi panel cfg not present */
- pr_warn("%s:%d:dsi specific cfg not present\n",
- __func__, __LINE__);
- /* find panel device node */
- dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg);
- if (!dsi_pan_node) {
- pr_err("%s: can't find panel node %s\n", __func__, panel_cfg);
- of_node_put(dsi_pan_node);
- return NULL;
- }
- rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata);
- if (rc) {
- pr_err("%s: dsi panel init failed\n", __func__);
- of_node_put(dsi_pan_node);
- return NULL;
- }
- return dsi_pan_node;
- }
3.1. 解析lk层传给kernel层cmdline的mdss_mdp.panel属性,在mdss_dsi_get_panel_cfg函数进行,
3.2. 根据cmdline的mdss_mdp.panel属性寻找panel的dtsi文件节点,在mdss_dsi_find_panel_of_node函数进行
3.3. 解析panel dtsi文件节点中的属性并配置panel的操作集,在mdss_dsi_panel_init函数进行
4. 下面我们依次来说明这三个部分,首先是mdss_dsi_get_panel_cfg函数
vim x:\work\project\kernel\drivers\video\msm\mdss\Mdss_dsi.c
通过日志,我们看到panel_cfg的字符串内容(0:qcom,mdss_dsi_ili9885_lide_hcg_auo_fhd_video:1:none:cfg:single_dsi),如下:
- static int mdss_dsi_get_panel_cfg(char *panel_cfg,
- struct mdss_dsi_ctrl_pdata *ctrl)
- {
- int rc;
- struct mdss_panel_cfg *pan_cfg = NULL;
- if (!panel_cfg)
- return MDSS_PANEL_INTF_INVALID;
- pan_cfg = ctrl->mdss_util->panel_intf_type(MDSS_PANEL_INTF_DSI);
- if (IS_ERR(pan_cfg)) {
- return PTR_ERR(pan_cfg);
- } else if (!pan_cfg) {
- panel_cfg[0] = 0;
- return 0;
- }
- pr_debug("%s:%d: cfg:[%s]\n", __func__, __LINE__,
- pan_cfg->arg_cfg);
- rc = strlcpy(panel_cfg, pan_cfg->arg_cfg,
- sizeof(pan_cfg->arg_cfg));
- return rc;
- }
[ 1.045387] mdss_dsi_get_panel_cfg:629: cfg:[0:qcom,mdss_dsi_ili9885_lide_hcg_auo_fhd_video:1:none:cfg:single_dsi]
//0表示dsi0,说明panel_cfg的字符串内容包含panel的型号名称和panel所属的dsi number
5. 接下来我们来看看mdss_dsi_find_panel_of_node函数
vim x:\work\project\kernel\drivers\video\msm\mdss\Mdss_dsi.c
6. 接下来我们来看看mdss_dsi_panel_init函数
- 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); //根据panel_cfg的字符串的内容,得到panel的型号名称是qcom,mdss_dsi_ili9885_lide_hcg_auo_fhd_video
- } 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);
- //日志如下:[ 1.045392] mdss_dsi_find_panel_of_node:2355:0:qcom,mdss_dsi_ili9885_lide_hcg_auo_fhd_video:1:none:cfg:single_dsi:qcom,mdss_dsi_ili9885_lide_hcg_auo_fhd_video
- mdss_node = of_parse_phandle(pdev->dev.of_node, //得到mdss_mdp节点,因为所有的panel型号都是挂在mdss_mdp节点下面,mdss_mdp节点的compatible = "qcom,mdss_mdp";
- "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的型号名称找到panel型号的dtsi文件节点
- panel_name);
- if (!dsi_pan_node) {
- pr_err("%s: invalid pan node, selecting prim panel\n",
- __func__);
- goto end;
- }
- return dsi_pan_node; //返回panel型号的dtsi文件节点
- }
- end:
- if (strcmp(panel_name, NONE_PANEL))
- dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
- return dsi_pan_node;
- }
vim x:\work\xxx\kernel\drivers\video\msm\mdss\Mdss_dsi_panel.c
- int mdss_dsi_panel_init(struct device_node *node,
- struct mdss_dsi_ctrl_pdata *ctrl_pdata)
- {
- int rc = 0;
- static const char *panel_name;
- struct mdss_panel_info *pinfo;
- if (!node || !ctrl_pdata) {
- pr_err("%s: Invalid arguments\n", __func__);
- return -ENODEV;
- }
- pinfo = &ctrl_pdata->panel_data.panel_info;
- pr_debug("%s:%d\n", __func__, __LINE__);
- pinfo->panel_name[0] = '\0';
- panel_name = of_get_property(node, "qcom,mdss-dsi-panel-name", NULL); //得到panel节点的qcom,mdss-dsi-panel-name属性
- if (!panel_name) {
- pr_info("%s:%d, Panel name not specified\n",
- __func__, __LINE__);
- } else {
- pr_info("%s: Panel Name = %s\n", _