diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 836945e208f1..009a172d658b 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -32,6 +32,7 @@ #include "mdss_debug.h" #define XO_CLK_RATE 19200000 +#define CMDLINE_DSI_CTL_NUM_STRING_LEN 2 /* Master structure to hold all the information about the DSI/panel */ static struct mdss_dsi_data *mdss_dsi_res; @@ -2210,11 +2211,12 @@ static struct device_node *mdss_dsi_pref_prim_panel( static struct device_node *mdss_dsi_find_panel_of_node( struct platform_device *pdev, char *panel_cfg) { - int len, i; + int len, i = 0; int ctrl_id = pdev->id - 1; char panel_name[MDSS_MAX_PANEL_LEN] = ""; char ctrl_id_stream[3] = "0:"; - char *stream = NULL, *pan = NULL, *override_cfg = NULL; + char *str1 = NULL, *str2 = NULL, *override_cfg = NULL; + char cfg_np_name[MDSS_MAX_PANEL_LEN] = ""; struct device_node *dsi_pan_node = NULL, *mdss_node = NULL; struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev); struct mdss_panel_info *pinfo = &ctrl_pdata->panel_data.panel_info; @@ -2240,46 +2242,85 @@ static struct device_node *mdss_dsi_find_panel_of_node( 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"); + /* get controller number */ + str1 = strnstr(panel_cfg, ctrl_id_stream, len); + if (!str1) { + pr_err("%s: controller %s is not present in %s\n", + __func__, ctrl_id_stream, panel_cfg); goto end; } - stream += 2; + if ((str1 != panel_cfg) && (*(str1-1) != ':')) { + str1 += CMDLINE_DSI_CTL_NUM_STRING_LEN; + pr_debug("false match with config node name in \"%s\". search again in \"%s\"\n", + panel_cfg, str1); + str1 = strnstr(str1, ctrl_id_stream, len); + if (!str1) { + pr_err("%s: 2. controller %s is not present in %s\n", + __func__, ctrl_id_stream, str1); + goto end; + } + } + str1 += CMDLINE_DSI_CTL_NUM_STRING_LEN; - pan = strnchr(stream, strlen(stream), ':'); - if (!pan) { - strlcpy(panel_name, stream, MDSS_MAX_PANEL_LEN); + /* get panel name */ + str2 = strnchr(str1, strlen(str1), ':'); + if (!str2) { + strlcpy(panel_name, str1, MDSS_MAX_PANEL_LEN); } else { - for (i = 0; (stream + i) < pan; i++) - panel_name[i] = *(stream + i); + for (i = 0; (str1 + i) < str2; i++) + panel_name[i] = *(str1 + i); panel_name[i] = 0; } - - pr_debug("%s:%d:%s:%s\n", __func__, __LINE__, - panel_cfg, panel_name); + pr_info("%s: cmdline:%s panel_name:%s\n", + __func__, panel_cfg, panel_name); + if (!strcmp(panel_name, NONE_PANEL)) + goto exit; mdss_node = of_parse_phandle(pdev->dev.of_node, - "qcom,mdss-mdp", 0); - + "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); + 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__); + pr_err("%s: invalid pan node \"%s\"\n", + __func__, panel_name); goto end; + } else { + /* extract config node name if present */ + str1 += i; + str2 = strnstr(str1, "config", strlen(str1)); + if (str2) { + str1 = strnchr(str2, strlen(str2), ':'); + if (str1) { + for (i = 0; ((str2 + i) < str1) && + i < MDSS_MAX_PANEL_LEN; i++) + cfg_np_name[i] = *(str2 + i); + cfg_np_name[i] = 0; + } else { + strlcpy(cfg_np_name, str2, + MDSS_MAX_PANEL_LEN); + } + } + + pr_debug("%s: cfg_np_name:%s\n", __func__, cfg_np_name); + if (str2) { + ctrl_pdata->panel_data.cfg_np = + of_get_child_by_name(dsi_pan_node, + cfg_np_name); + if (!ctrl_pdata->panel_data.cfg_np) + pr_warn("%s: can't find config node:%s. either no such node or bad name\n", + __func__, cfg_np_name); + } } return dsi_pan_node; } end: if (strcmp(panel_name, NONE_PANEL)) dsi_pan_node = mdss_dsi_pref_prim_panel(pdev); - +exit: return dsi_pan_node; } @@ -2853,11 +2894,15 @@ static int mdss_dsi_parse_hw_cfg(struct platform_device *pdev, char *pan_cfg) cfg_prim = strnstr(pan_cfg, "cfg:", strlen(pan_cfg)); if (cfg_prim) { cfg_prim += 4; + cfg_sec = strnchr(cfg_prim, strlen(cfg_prim), ':'); if (!cfg_sec) cfg_sec = cfg_prim + strlen(cfg_prim); - for (i = 0; (cfg_prim + i) < cfg_sec; i++) + + for (i = 0; ((cfg_prim + i) < cfg_sec) && + (*(cfg_prim+i) != '#'); i++) dsi_cfg[i] = *(cfg_prim + i); + dsi_cfg[i] = '\0'; data = dsi_cfg; } else { diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index de18145dc7f8..da8abaabc3b5 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -1374,6 +1374,11 @@ static int mdss_dsi_parse_dsc_params(struct device_node *np, int rc = 0; struct dsc_desc *dsc = &timing->dsc; + if (!np) { + pr_err("%s: device node pointer is NULL\n", __func__); + return -EINVAL; + } + rc = of_property_read_u32(np, "qcom,mdss-dsc-encoders", &data); if (rc) { if (!of_find_property(np, "qcom,mdss-dsc-encoders", NULL)) { @@ -1471,32 +1476,40 @@ end: } static int mdss_dsi_parse_compression_params(struct device_node *np, - struct dsi_panel_timing *pt, bool is_split_display) + struct dsi_panel_timing *pt, struct mdss_panel_data *panel_data) { int rc = 0; + bool is_split_display = panel_data->panel_info.is_split_display; const char *data; - struct device_node *cfg_np = NULL; struct mdss_panel_timing *timing = &pt->timing; + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + struct device_node *cfg_np; - if (of_find_property(np, "qcom,config-select", NULL)) { + ctrl_pdata = container_of(panel_data, struct mdss_dsi_ctrl_pdata, + panel_data); + cfg_np = ctrl_pdata->panel_data.cfg_np; + + if (!cfg_np && of_find_property(np, "qcom,config-select", NULL)) { cfg_np = of_parse_phandle(np, "qcom,config-select", 0); - if (!cfg_np) { - pr_err("%s: error parsing qcom,config-select\n", - __func__); - } else { - if (!of_property_read_u32_array(cfg_np, "qcom,lm-split", - timing->lm_widths, 2)) { - if (is_split_display && - (timing->lm_widths[1] != 0)) { - pr_err("%s: lm-split not allowed with split display\n", - __func__); - rc = -EINVAL; - goto end; - } + if (!cfg_np) + pr_err("%s:err parsing qcom,config-select\n", __func__); + ctrl_pdata->panel_data.cfg_np = cfg_np; + } + + if (cfg_np) { + if (!of_property_read_u32_array(cfg_np, "qcom,lm-split", + timing->lm_widths, 2)) { + if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) + && (timing->lm_widths[1] != 0)) { + pr_err("%s: lm-split not allowed with split display\n", + __func__); + rc = -EINVAL; + goto end; } } - } else { - pr_debug("%s: qcom,config-select is not present\n", __func__); + pr_info("%s: cfg_node name %s lm_split:%dx%d\n", __func__, + cfg_np->name, + timing->lm_widths[0], timing->lm_widths[1]); } if ((timing->lm_widths[0] == 0) && (timing->lm_widths[1] == 0)) @@ -2225,7 +2238,7 @@ static int mdss_dsi_panel_config_res_properties(struct device_node *np, "qcom,mdss-dsi-timing-switch-command-state"); rc = mdss_dsi_parse_compression_params(np, pt, - panel_data->panel_info.is_split_display); + panel_data); if (rc) { pr_err("%s: parsing compression params failed. rc:%d\n", __func__, rc); diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index e4e49ce45a1e..45c08a84cce0 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -4144,12 +4144,17 @@ static int __init mdss_mdp_driver_init(void) module_param_string(panel, mdss_mdp_panel, MDSS_MAX_PANEL_LEN, 0); MODULE_PARM_DESC(panel, - "panel=:: " + "panel=::: " "where is "1"-lk/gcdb config or "0" non-lk/non-gcdb " "config; is dsi: or hdmi or edp " " is panel interface specific string " "Ex: This string is panel's device node name from DT " "for DSI interface " - "hdmi/edp interface does not use this string"); + "hdmi/edp interface does not use this string " + " is an optional string. Currently it is " + "only valid for DSI panels. In dual-DSI case, it needs to be" + "used on both panels or none. When used, format is config%d " + "where %d is one of the configuration found in device node of " + "panel selected by "); module_init(mdss_mdp_driver_init); diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 3d5a38ba2123..f6f3e56f4e99 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -14,6 +14,7 @@ #ifndef MDSS_PANEL_H #define MDSS_PANEL_H +#include #include #include #include @@ -689,6 +690,7 @@ struct mdss_panel_data { struct mdss_panel_timing *current_timing; bool active; + struct device_node *cfg_np; /* NULL if config node is not present */ struct mdss_panel_data *next; };