disp: msm: Add support for seamless panel operating mode switch

DSI display may support video mode and command mode both and it may
support transition between these two modes.
This change adds seamless transition between these two modes for DSI
display by avoiding crtc enable/disable and panel power on/off
during modeset.

Change-Id: Id7ddaef7d1f0f7cc7d52283755bad53a246adec6
Signed-off-by: Lei Chen <chenlei@codeaurora.org>
このコミットが含まれているのは:
Lei Chen
2019-04-25 17:57:09 +08:00
committed by Gerrit - the friendly Code Review server
コミット 21edecd3b1
12個のファイルの変更376行の追加85行の削除

ファイルの表示

@@ -1360,6 +1360,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel)
{
int rc = 0;
struct dsi_parser_utils *utils = &panel->utils;
bool panel_mode_switch_enabled;
enum dsi_op_mode panel_mode;
const char *mode;
@@ -1378,7 +1379,13 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel)
goto error;
}
if (panel_mode == DSI_OP_VIDEO_MODE) {
panel_mode_switch_enabled = utils->read_bool(utils->data,
"qcom,mdss-dsi-panel-mode-switch");
pr_info("%s: panel operating mode switch feature %s\n", __func__,
(panel_mode_switch_enabled ? "enabled" : "disabled"));
if (panel_mode == DSI_OP_VIDEO_MODE || panel_mode_switch_enabled) {
rc = dsi_panel_parse_video_host_config(&panel->video_config,
utils,
panel->name);
@@ -1389,7 +1396,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel)
}
}
if (panel_mode == DSI_OP_CMD_MODE) {
if (panel_mode == DSI_OP_CMD_MODE || panel_mode_switch_enabled) {
rc = dsi_panel_parse_cmd_host_config(&panel->cmd_config,
utils,
panel->name);
@@ -1401,6 +1408,7 @@ static int dsi_panel_parse_panel_mode(struct dsi_panel *panel)
}
panel->panel_mode = panel_mode;
panel->panel_mode_switch_enabled = panel_mode_switch_enabled;
error:
return rc;
}
@@ -2654,6 +2662,33 @@ static int dsi_panel_parse_partial_update_caps(struct dsi_display_mode *mode,
return rc;
}
static int dsi_panel_parse_panel_mode_caps(struct dsi_display_mode *mode,
struct dsi_parser_utils *utils)
{
bool vid_mode_support, cmd_mode_support;
if (!mode || !mode->priv_info) {
pr_err("invalid arguments\n");
return -EINVAL;
}
vid_mode_support = utils->read_bool(utils->data,
"qcom,mdss-dsi-video-mode");
cmd_mode_support = utils->read_bool(utils->data,
"qcom,mdss-dsi-cmd-mode");
if (cmd_mode_support)
mode->panel_mode = DSI_OP_CMD_MODE;
else if (vid_mode_support)
mode->panel_mode = DSI_OP_VIDEO_MODE;
else
return -EINVAL;
return 0;
};
static int dsi_panel_parse_dms_info(struct dsi_panel *panel)
{
int dms_enabled;
@@ -3340,6 +3375,17 @@ int dsi_panel_get_mode(struct dsi_panel *panel,
rc = dsi_panel_parse_partial_update_caps(mode, utils);
if (rc)
pr_err("failed to partial update caps, rc=%d\n", rc);
if (panel->panel_mode_switch_enabled) {
rc = dsi_panel_parse_panel_mode_caps(mode, utils);
if (rc) {
pr_err("PMS: failed to parse panel mode\n");
rc = 0;
mode->panel_mode = panel->panel_mode;
}
} else {
mode->panel_mode = panel->panel_mode;
}
}
goto done;
@@ -3698,6 +3744,86 @@ int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx,
return rc;
}
int dsi_panel_pre_mode_switch_to_video(struct dsi_panel *panel)
{
int rc = 0;
if (!panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
mutex_lock(&panel->panel_lock);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_CMD_TO_VID_SWITCH);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n",
panel->name, rc);
mutex_unlock(&panel->panel_lock);
return rc;
}
int dsi_panel_pre_mode_switch_to_cmd(struct dsi_panel *panel)
{
int rc = 0;
if (!panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
mutex_lock(&panel->panel_lock);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_VID_TO_CMD_SWITCH);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n",
panel->name, rc);
mutex_unlock(&panel->panel_lock);
return rc;
}
int dsi_panel_mode_switch_to_cmd(struct dsi_panel *panel)
{
int rc = 0;
if (!panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
mutex_lock(&panel->panel_lock);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_VID_TO_CMD_SWITCH);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n",
panel->name, rc);
mutex_unlock(&panel->panel_lock);
return rc;
}
int dsi_panel_mode_switch_to_vid(struct dsi_panel *panel)
{
int rc = 0;
if (!panel) {
pr_err("Invalid params\n");
return -EINVAL;
}
mutex_lock(&panel->panel_lock);
rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_POST_CMD_TO_VID_SWITCH);
if (rc)
pr_err("[%s] failed to send DSI_CMD_SET_CMD_TO_VID_SWITCH cmds, rc=%d\n",
panel->name, rc);
mutex_unlock(&panel->panel_lock);
return rc;
}
int dsi_panel_switch(struct dsi_panel *panel)
{
int rc = 0;