disp: msm: add support for seamless dsc switch

This change adds logic to determine dsc switch based on
the connector property "CONNECTOR_PROP_DSC_MODE" and
performs seamless DSC switch if there is any change in
DSC configuration. The connector property is populated
in msm_sub_mode based on which suitable mode is selected.

Change-Id: Ifc4931f16dfb814781bc1d72b103e09103e6bfee
Signed-off-by: Yashwanth <yvulapu@codeaurora.org>
This commit is contained in:
Yashwanth
2021-04-26 13:37:48 +05:30
committed by Gerrit - the friendly Code Review server
parent ffc7cdbe08
commit 7e03fb61fd
17 changed files with 156 additions and 36 deletions

View File

@@ -398,7 +398,8 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge,
struct dsi_display_mode dsi_mode, cur_dsi_mode, *panel_dsi_mode;
struct drm_crtc_state *crtc_state;
struct drm_connector_state *drm_conn_state;
struct sde_connector_state *conn_state;
struct sde_connector_state *conn_state, *old_conn_state;
struct msm_sub_mode new_sub_mode;
crtc_state = container_of(mode, struct drm_crtc_state, mode);
@@ -435,12 +436,15 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge,
convert_to_dsi_mode(mode, &dsi_mode);
msm_parse_mode_priv_info(&conn_state->msm_mode, &dsi_mode);
new_sub_mode.dsc_mode = sde_connector_get_property(drm_conn_state,
CONNECTOR_PROP_DSC_MODE);
/*
* retrieve dsi mode from dsi driver's cache since not safe to take
* the drm mode config mutex in all paths
*/
rc = dsi_display_find_mode(display, &dsi_mode, &panel_dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, &new_sub_mode,
&panel_dsi_mode);
if (rc)
return rc;
@@ -474,10 +478,11 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge,
crtc_state->crtc) {
const struct drm_display_mode *cur_mode =
&crtc_state->crtc->state->mode;
old_conn_state = to_sde_connector_state(display->drm_conn->state);
convert_to_dsi_mode(cur_mode, &cur_dsi_mode);
cur_dsi_mode.timing.dsc_enabled =
dsi_mode.priv_info->dsc_enabled;
cur_dsi_mode.timing.dsc = &dsi_mode.priv_info->dsc;
msm_parse_mode_priv_info(&old_conn_state->msm_mode, &cur_dsi_mode);
rc = dsi_display_validate_mode_change(c_bridge->display,
&cur_dsi_mode, &dsi_mode);
if (rc) {
@@ -546,6 +551,7 @@ u32 dsi_drm_get_dfps_maxfps(void *display)
int dsi_conn_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res)
{
@@ -557,7 +563,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
return -EINVAL;
convert_to_dsi_mode(drm_mode, &partial_dsi_mode);
rc = dsi_display_find_mode(display, &partial_dsi_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &partial_dsi_mode, sub_mode, &dsi_mode);
if (rc || !dsi_mode->priv_info)
return -EINVAL;
@@ -831,25 +837,21 @@ enum drm_connector_status dsi_conn_detect(struct drm_connector *conn,
void dsi_connector_put_modes(struct drm_connector *connector,
void *display)
{
struct drm_display_mode *drm_mode;
struct dsi_display_mode dsi_mode, *full_dsi_mode = NULL;
struct dsi_display *dsi_display;
int rc = 0;
int count, i;
if (!connector || !display)
return;
list_for_each_entry(drm_mode, &connector->modes, head) {
convert_to_dsi_mode(drm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, &full_dsi_mode);
if (rc)
continue;
dsi_display = display;
count = dsi_display->panel->num_display_modes;
for (i = 0; i < count; i++) {
struct dsi_display_mode *dsi_mode = &dsi_display->modes[i];
dsi_display_put_mode(display, full_dsi_mode);
dsi_display_put_mode(dsi_display, dsi_mode);
}
/* free the display structure modes also */
dsi_display = display;
kfree(dsi_display->modes);
dsi_display->modes = NULL;
}
@@ -1050,7 +1052,7 @@ enum drm_mode_status dsi_conn_mode_valid(struct drm_connector *connector,
if (conn_state)
msm_parse_mode_priv_info(&conn_state->msm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, &full_dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, NULL, &full_dsi_mode);
if (rc) {
DSI_ERR("could not find mode %s\n", mode->name);
return MODE_ERROR;
@@ -1273,7 +1275,7 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector,
convert_to_dsi_mode(drm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, &panel_dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, NULL, &panel_dsi_mode);
if (rc)
return;
@@ -1290,7 +1292,7 @@ void dsi_conn_set_allowed_mode_switch(struct drm_connector *connector,
convert_to_dsi_mode(cmp_drm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode,
&cmp_panel_dsi_mode);
NULL, &cmp_panel_dsi_mode);
if (rc)
return;