高通lk屏幕向kernel传参

时间:2019-10-22
本文章向大家介绍高通lk屏幕向kernel传参,主要包括高通lk屏幕向kernel传参使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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

Bootable\bootloader\lk\dev\gcdb\display\gcdb_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\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;
}

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