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

@@ -377,6 +377,7 @@ end:
int dp_connector_get_mode_info(struct drm_connector *connector, int dp_connector_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res) void *display, const struct msm_resource_caps_info *avail_res)
{ {

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/ */
#ifndef _DP_DRM_H_ #ifndef _DP_DRM_H_
@@ -103,12 +103,14 @@ enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector,
* @connector: Pointer to drm connector structure * @connector: Pointer to drm connector structure
* @drm_mode: Display mode set for the display * @drm_mode: Display mode set for the display
* @mode_info: Out parameter. Information of the mode * @mode_info: Out parameter. Information of the mode
* @sub_mode: Additional mode info to drm display mode
* @display: Pointer to private display structure * @display: Pointer to private display structure
* @avail_res: Pointer with curr available resources * @avail_res: Pointer with curr available resources
* Returns: zero on success * Returns: zero on success
*/ */
int dp_connector_get_mode_info(struct drm_connector *connector, int dp_connector_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res); void *display, const struct msm_resource_caps_info *avail_res);
@@ -216,6 +218,7 @@ static inline enum drm_mode_status dp_connector_mode_valid(
static inline int dp_connector_get_mode_info(struct drm_connector *connector, static inline int dp_connector_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res) void *display, const struct msm_resource_caps_info *avail_res)
{ {

View File

@@ -1116,6 +1116,7 @@ int dp_mst_connector_get_info(struct drm_connector *connector,
int dp_mst_connector_get_mode_info(struct drm_connector *connector, int dp_mst_connector_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, void *display,
const struct msm_resource_caps_info *avail_res) const struct msm_resource_caps_info *avail_res)
@@ -1125,7 +1126,7 @@ int dp_mst_connector_get_mode_info(struct drm_connector *connector,
DP_MST_DEBUG("enter:\n"); DP_MST_DEBUG("enter:\n");
SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, connector->base.id); SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, connector->base.id);
rc = dp_connector_get_mode_info(connector, drm_mode, mode_info, rc = dp_connector_get_mode_info(connector, drm_mode, NULL, mode_info,
display, avail_res); display, avail_res);
DP_MST_DEBUG("mst connector:%d get mode info. rc:%d\n", DP_MST_DEBUG("mst connector:%d get mode info. rc:%d\n",

View File

@@ -36,10 +36,6 @@
#define SEC_PANEL_NAME_MAX_LEN 256 #define SEC_PANEL_NAME_MAX_LEN 256
#define DSI_MODE_MATCH_ACTIVE_TIMINGS (1 << 0)
#define DSI_MODE_MATCH_PORCH_TIMINGS (1 << 1)
#define DSI_MODE_MATCH_FULL_TIMINGS (DSI_MODE_MATCH_ACTIVE_TIMINGS | DSI_MODE_MATCH_PORCH_TIMINGS)
u8 dbgfs_tx_cmd_buf[SZ_4K]; u8 dbgfs_tx_cmd_buf[SZ_4K];
static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN]; static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN];
static char dsi_display_secondary[MAX_CMDLINE_PARAM_LEN]; static char dsi_display_secondary[MAX_CMDLINE_PARAM_LEN];
@@ -6235,7 +6231,7 @@ static int dsi_display_ext_get_info(struct drm_connector *connector,
} }
static int dsi_display_ext_get_mode_info(struct drm_connector *connector, static int dsi_display_ext_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode, struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res) void *display, const struct msm_resource_caps_info *avail_res)
{ {
@@ -7167,11 +7163,16 @@ static bool dsi_display_mode_match(const struct dsi_display_mode *mode1,
!dsi_display_match_timings(mode1, mode2, match_flags)) !dsi_display_match_timings(mode1, mode2, match_flags))
return false; return false;
if ((match_flags & DSI_MODE_MATCH_DSC_CONFIG) &&
mode1->priv_info->dsc_enabled != mode2->priv_info->dsc_enabled)
return false;
return true; return true;
} }
int dsi_display_find_mode(struct dsi_display *display, int dsi_display_find_mode(struct dsi_display *display,
const struct dsi_display_mode *cmp, struct dsi_display_mode *cmp,
struct msm_sub_mode *sub_mode,
struct dsi_display_mode **out_mode) struct dsi_display_mode **out_mode)
{ {
u32 count, i; u32 count, i;
@@ -7179,6 +7180,7 @@ int dsi_display_find_mode(struct dsi_display *display,
struct dsi_display_mode *m; struct dsi_display_mode *m;
struct dsi_dyn_clk_caps *dyn_clk_caps; struct dsi_dyn_clk_caps *dyn_clk_caps;
unsigned int match_flags = DSI_MODE_MATCH_FULL_TIMINGS; unsigned int match_flags = DSI_MODE_MATCH_FULL_TIMINGS;
struct dsi_display_mode_priv_info priv_info;
if (!display || !out_mode) if (!display || !out_mode)
return -EINVAL; return -EINVAL;
@@ -7209,6 +7211,15 @@ int dsi_display_find_mode(struct dsi_display *display,
if (dyn_clk_caps->maintain_const_fps) if (dyn_clk_caps->maintain_const_fps)
match_flags = DSI_MODE_MATCH_ACTIVE_TIMINGS; match_flags = DSI_MODE_MATCH_ACTIVE_TIMINGS;
if (sub_mode && sub_mode->dsc_mode) {
match_flags |= DSI_MODE_MATCH_DSC_CONFIG;
cmp->priv_info = &priv_info;
memset(cmp->priv_info, 0,
sizeof(struct dsi_display_mode_priv_info));
cmp->priv_info->dsc_enabled = (sub_mode->dsc_mode ==
MSM_DISPLAY_DSC_MODE_ENABLED) ? true : false;
}
if (dsi_display_mode_match(cmp, m, match_flags)) { if (dsi_display_mode_match(cmp, m, match_flags)) {
*out_mode = m; *out_mode = m;
rc = 0; rc = 0;
@@ -7286,11 +7297,20 @@ int dsi_display_validate_mode_change(struct dsi_display *display,
if (sde_conn->expected_panel_mode == MSM_DISPLAY_VIDEO_MODE && if (sde_conn->expected_panel_mode == MSM_DISPLAY_VIDEO_MODE &&
display->config.panel_mode == DSI_OP_CMD_MODE) { display->config.panel_mode == DSI_OP_CMD_MODE) {
adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_VID; adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_VID;
SDE_EVT32(SDE_EVTLOG_FUNC_CASE1, sde_conn->expected_panel_mode,
display->config.panel_mode);
DSI_DEBUG("Panel operating mode change to video detected\n"); DSI_DEBUG("Panel operating mode change to video detected\n");
} else if (sde_conn->expected_panel_mode == MSM_DISPLAY_CMD_MODE && } else if (sde_conn->expected_panel_mode == MSM_DISPLAY_CMD_MODE &&
display->config.panel_mode == DSI_OP_VIDEO_MODE) { display->config.panel_mode == DSI_OP_VIDEO_MODE) {
adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_CMD; adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_POMS_TO_CMD;
SDE_EVT32(SDE_EVTLOG_FUNC_CASE2, sde_conn->expected_panel_mode,
display->config.panel_mode);
DSI_DEBUG("Panel operating mode change to command detected\n"); DSI_DEBUG("Panel operating mode change to command detected\n");
} else if (cur_mode->timing.dsc_enabled != adj_mode->timing.dsc_enabled) {
adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_DMS;
SDE_EVT32(SDE_EVTLOG_FUNC_CASE3, cur_mode->timing.dsc_enabled,
adj_mode->timing.dsc_enabled);
DSI_DEBUG("DSC mode change detected\n");
} else { } else {
dyn_clk_caps = &(display->panel->dyn_clk_caps); dyn_clk_caps = &(display->panel->dyn_clk_caps);
/* dfps and dynamic clock with const fps use case */ /* dfps and dynamic clock with const fps use case */
@@ -7300,7 +7320,7 @@ int dsi_display_validate_mode_change(struct dsi_display *display,
dyn_clk_caps->maintain_const_fps) { dyn_clk_caps->maintain_const_fps) {
DSI_DEBUG("Mode switch is seamless variable refresh\n"); DSI_DEBUG("Mode switch is seamless variable refresh\n");
adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR; adj_mode->dsi_mode_flags |= DSI_MODE_FLAG_VRR;
SDE_EVT32(SDE_EVTLOG_FUNC_CASE1, SDE_EVT32(SDE_EVTLOG_FUNC_CASE4,
cur_mode->timing.refresh_rate, cur_mode->timing.refresh_rate,
adj_mode->timing.refresh_rate, adj_mode->timing.refresh_rate,
cur_mode->timing.h_front_porch, cur_mode->timing.h_front_porch,
@@ -7333,7 +7353,7 @@ int dsi_display_validate_mode_change(struct dsi_display *display,
adj_mode->dsi_mode_flags |= adj_mode->dsi_mode_flags |=
DSI_MODE_FLAG_DYN_CLK; DSI_MODE_FLAG_DYN_CLK;
SDE_EVT32(SDE_EVTLOG_FUNC_CASE2, SDE_EVT32(SDE_EVTLOG_FUNC_CASE5,
cur_mode->pixel_clk_khz, cur_mode->pixel_clk_khz,
adj_mode->pixel_clk_khz); adj_mode->pixel_clk_khz);
} }

View File

@@ -24,6 +24,12 @@
#define DSI_CLIENT_NAME_SIZE 20 #define DSI_CLIENT_NAME_SIZE 20
#define MAX_CMDLINE_PARAM_LEN 512 #define MAX_CMDLINE_PARAM_LEN 512
#define MAX_CMD_PAYLOAD_SIZE 256 #define MAX_CMD_PAYLOAD_SIZE 256
#define DSI_MODE_MATCH_ACTIVE_TIMINGS (1 << 0)
#define DSI_MODE_MATCH_PORCH_TIMINGS (1 << 1)
#define DSI_MODE_MATCH_FULL_TIMINGS (DSI_MODE_MATCH_ACTIVE_TIMINGS | DSI_MODE_MATCH_PORCH_TIMINGS)
#define DSI_MODE_MATCH_DSC_CONFIG (1 << 2)
/* /*
* DSI Validate Mode modifiers * DSI Validate Mode modifiers
* @DSI_VALIDATE_FLAG_ALLOW_ADJUST: Allow mode validation to also do fixup * @DSI_VALIDATE_FLAG_ALLOW_ADJUST: Allow mode validation to also do fixup
@@ -436,12 +442,14 @@ int dsi_display_get_avr_step_req_fps(void *dsi_display, u32 mode_fps);
* dsi_display_find_mode() - retrieve cached DSI mode given relevant params * dsi_display_find_mode() - retrieve cached DSI mode given relevant params
* @display: Handle to display. * @display: Handle to display.
* @cmp: Mode to use as comparison to find original * @cmp: Mode to use as comparison to find original
* @sub_mode: Additional mode info to drm display mode
* @out_mode: Output parameter, pointer to retrieved mode * @out_mode: Output parameter, pointer to retrieved mode
* *
* Return: error code. * Return: error code.
*/ */
int dsi_display_find_mode(struct dsi_display *display, int dsi_display_find_mode(struct dsi_display *display,
const struct dsi_display_mode *cmp, struct dsi_display_mode *cmp,
struct msm_sub_mode *sub_mode,
struct dsi_display_mode **out_mode); struct dsi_display_mode **out_mode);
/** /**
* dsi_display_validate_mode() - validates if mode is supported by display * dsi_display_validate_mode() - validates if mode is supported by display

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 dsi_display_mode dsi_mode, cur_dsi_mode, *panel_dsi_mode;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
struct drm_connector_state *drm_conn_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); 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); convert_to_dsi_mode(mode, &dsi_mode);
msm_parse_mode_priv_info(&conn_state->msm_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 * retrieve dsi mode from dsi driver's cache since not safe to take
* the drm mode config mutex in all paths * 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) if (rc)
return rc; return rc;
@@ -474,10 +478,11 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge,
crtc_state->crtc) { crtc_state->crtc) {
const struct drm_display_mode *cur_mode = const struct drm_display_mode *cur_mode =
&crtc_state->crtc->state->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); convert_to_dsi_mode(cur_mode, &cur_dsi_mode);
cur_dsi_mode.timing.dsc_enabled = msm_parse_mode_priv_info(&old_conn_state->msm_mode, &cur_dsi_mode);
dsi_mode.priv_info->dsc_enabled;
cur_dsi_mode.timing.dsc = &dsi_mode.priv_info->dsc;
rc = dsi_display_validate_mode_change(c_bridge->display, rc = dsi_display_validate_mode_change(c_bridge->display,
&cur_dsi_mode, &dsi_mode); &cur_dsi_mode, &dsi_mode);
if (rc) { if (rc) {
@@ -546,6 +551,7 @@ u32 dsi_drm_get_dfps_maxfps(void *display)
int dsi_conn_get_mode_info(struct drm_connector *connector, int dsi_conn_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res) 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; return -EINVAL;
convert_to_dsi_mode(drm_mode, &partial_dsi_mode); 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) if (rc || !dsi_mode->priv_info)
return -EINVAL; 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 dsi_connector_put_modes(struct drm_connector *connector,
void *display) void *display)
{ {
struct drm_display_mode *drm_mode;
struct dsi_display_mode dsi_mode, *full_dsi_mode = NULL;
struct dsi_display *dsi_display; struct dsi_display *dsi_display;
int rc = 0; int count, i;
if (!connector || !display) if (!connector || !display)
return; return;
list_for_each_entry(drm_mode, &connector->modes, head) { dsi_display = display;
convert_to_dsi_mode(drm_mode, &dsi_mode); count = dsi_display->panel->num_display_modes;
rc = dsi_display_find_mode(display, &dsi_mode, &full_dsi_mode); for (i = 0; i < count; i++) {
if (rc) struct dsi_display_mode *dsi_mode = &dsi_display->modes[i];
continue;
dsi_display_put_mode(display, full_dsi_mode); dsi_display_put_mode(dsi_display, dsi_mode);
} }
/* free the display structure modes also */ /* free the display structure modes also */
dsi_display = display;
kfree(dsi_display->modes); kfree(dsi_display->modes);
dsi_display->modes = NULL; dsi_display->modes = NULL;
} }
@@ -1050,7 +1052,7 @@ enum drm_mode_status dsi_conn_mode_valid(struct drm_connector *connector,
if (conn_state) if (conn_state)
msm_parse_mode_priv_info(&conn_state->msm_mode, &dsi_mode); 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) { if (rc) {
DSI_ERR("could not find mode %s\n", mode->name); DSI_ERR("could not find mode %s\n", mode->name);
return MODE_ERROR; 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); 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) if (rc)
return; 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); convert_to_dsi_mode(cmp_drm_mode, &dsi_mode);
rc = dsi_display_find_mode(display, &dsi_mode, rc = dsi_display_find_mode(display, &dsi_mode,
&cmp_panel_dsi_mode); NULL, &cmp_panel_dsi_mode);
if (rc) if (rc)
return; return;

View File

@@ -68,6 +68,7 @@ void dsi_connector_put_modes(struct drm_connector *connector,
/** /**
* dsi_conn_get_mode_info - retrieve information on the mode selected * dsi_conn_get_mode_info - retrieve information on the mode selected
* @drm_mode: Display mode set for the display * @drm_mode: Display mode set for the display
* @sub_mode: Additional mode info to drm display mode
* @mode_info: Out parameter. information of the mode. * @mode_info: Out parameter. information of the mode.
* @display: Pointer to private display structure * @display: Pointer to private display structure
* @avail_res: Pointer with curr available resources * @avail_res: Pointer with curr available resources
@@ -75,6 +76,7 @@ void dsi_connector_put_modes(struct drm_connector *connector,
*/ */
int dsi_conn_get_mode_info(struct drm_connector *connector, int dsi_conn_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res); void *display, const struct msm_resource_caps_info *avail_res);

View File

@@ -226,6 +226,7 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE, CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
CONNECTOR_PROP_SET_PANEL_MODE, CONNECTOR_PROP_SET_PANEL_MODE,
CONNECTOR_PROP_AVR_STEP, CONNECTOR_PROP_AVR_STEP,
CONNECTOR_PROP_DSC_MODE,
/* total # of properties */ /* total # of properties */
CONNECTOR_PROP_COUNT CONNECTOR_PROP_COUNT
@@ -307,6 +308,18 @@ enum panel_op_mode {
MSM_DISPLAY_MODE_MAX = BIT(2) MSM_DISPLAY_MODE_MAX = BIT(2)
}; };
/**
* enum msm_display_dsc_mode - panel dsc mode
* @MSM_DISPLAY_DSC_MODE_NONE: No operation
* @MSM_DISPLAY_DSC_MODE_ENABLED: DSC is enabled
* @MSM_DISPLAY_DSC_MODE_DISABLED: DSC is disabled
*/
enum msm_display_dsc_mode {
MSM_DISPLAY_DSC_MODE_NONE,
MSM_DISPLAY_DSC_MODE_ENABLED,
MSM_DISPLAY_DSC_MODE_DISABLED,
};
/** /**
* struct msm_display_mode - wrapper for drm_display_mode * struct msm_display_mode - wrapper for drm_display_mode
* @base: drm_display_mode attached to this msm_mode * @base: drm_display_mode attached to this msm_mode
@@ -319,6 +332,14 @@ struct msm_display_mode {
u32 *private; u32 *private;
}; };
/**
* struct msm_sub_mode - msm display sub mode
* @dsc_enabled: boolean used to indicate if dsc should be enabled
*/
struct msm_sub_mode {
enum msm_display_dsc_mode dsc_mode;
};
/** /**
* struct msm_ratio - integer ratio * struct msm_ratio - integer ratio
* @numer: numerator * @numer: numerator

View File

@@ -295,6 +295,9 @@ static inline bool msm_is_private_mode_changed(
if (msm_is_mode_seamless_dyn_clk(msm_mode)) if (msm_is_mode_seamless_dyn_clk(msm_mode))
return true; return true;
if (msm_is_mode_seamless_dms(msm_mode))
return true;
return false; return false;
} }

View File

@@ -66,6 +66,11 @@ static const struct drm_prop_enum_list e_qsync_mode[] = {
{SDE_RM_QSYNC_CONTINUOUS_MODE, "continuous"}, {SDE_RM_QSYNC_CONTINUOUS_MODE, "continuous"},
{SDE_RM_QSYNC_ONE_SHOT_MODE, "one_shot"}, {SDE_RM_QSYNC_ONE_SHOT_MODE, "one_shot"},
}; };
static const struct drm_prop_enum_list e_dsc_mode[] = {
{MSM_DISPLAY_DSC_MODE_NONE, "none"},
{MSM_DISPLAY_DSC_MODE_ENABLED, "dsc_enabled"},
{MSM_DISPLAY_DSC_MODE_DISABLED, "dsc_disabled"},
};
static const struct drm_prop_enum_list e_frame_trigger_mode[] = { static const struct drm_prop_enum_list e_frame_trigger_mode[] = {
{FRAME_DONE_WAIT_DEFAULT, "default"}, {FRAME_DONE_WAIT_DEFAULT, "default"},
{FRAME_DONE_WAIT_SERIALIZE, "serialize_frame_trigger"}, {FRAME_DONE_WAIT_SERIALIZE, "serialize_frame_trigger"},
@@ -441,6 +446,7 @@ int sde_connector_set_msm_mode(struct drm_connector_state *conn_state,
int sde_connector_get_mode_info(struct drm_connector *conn, int sde_connector_get_mode_info(struct drm_connector *conn,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info) struct msm_mode_info *mode_info)
{ {
struct sde_connector *sde_conn; struct sde_connector *sde_conn;
@@ -455,7 +461,7 @@ int sde_connector_get_mode_info(struct drm_connector *conn,
sde_connector_get_avail_res_info(conn, &avail_res); sde_connector_get_avail_res_info(conn, &avail_res);
return sde_conn->ops.get_mode_info(conn, drm_mode, return sde_conn->ops.get_mode_info(conn, drm_mode, sub_mode,
mode_info, sde_conn->display, &avail_res); mode_info, sde_conn->display, &avail_res);
} }
@@ -2631,7 +2637,7 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
memset(&mode_info, 0, sizeof(mode_info)); memset(&mode_info, 0, sizeof(mode_info));
rc = sde_connector_get_mode_info(&c_conn->base, mode, rc = sde_connector_get_mode_info(&c_conn->base, mode, NULL,
&mode_info); &mode_info);
if (rc) { if (rc) {
SDE_ERROR_CONN(c_conn, SDE_ERROR_CONN(c_conn,
@@ -2892,6 +2898,9 @@ static int _sde_connector_install_properties(struct drm_device *dev,
CONNECTOR_PROP_AVR_STEP); CONNECTOR_PROP_AVR_STEP);
} }
msm_property_install_enum(&c_conn->property_info, "dsc_mode", 0,
0, e_dsc_mode, ARRAY_SIZE(e_dsc_mode), 0, CONNECTOR_PROP_DSC_MODE);
if (display_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) if (display_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE)
msm_property_install_enum(&c_conn->property_info, msm_property_install_enum(&c_conn->property_info,
"frame_trigger_mode", 0, 0, "frame_trigger_mode", 0, 0,

View File

@@ -138,6 +138,7 @@ struct sde_connector_ops {
* get_mode_info - retrieve mode information * get_mode_info - retrieve mode information
* @connector: Pointer to drm connector structure * @connector: Pointer to drm connector structure
* @drm_mode: Display mode set for the display * @drm_mode: Display mode set for the display
* @sub_mode: Additional mode info to drm display mode
* @mode_info: Out parameter. information of the display mode * @mode_info: Out parameter. information of the display mode
* @display: Pointer to private display structure * @display: Pointer to private display structure
* @avail_res: Pointer with curr available resources * @avail_res: Pointer with curr available resources
@@ -145,6 +146,7 @@ struct sde_connector_ops {
*/ */
int (*get_mode_info)(struct drm_connector *connector, int (*get_mode_info)(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, void *display,
const struct msm_resource_caps_info *avail_res); const struct msm_resource_caps_info *avail_res);
@@ -1080,11 +1082,13 @@ int sde_connector_set_msm_mode(struct drm_connector_state *conn_state,
* sde_connector_get_mode_info - retrieve mode info for given mode * sde_connector_get_mode_info - retrieve mode info for given mode
* @connector: Pointer to drm connector structure * @connector: Pointer to drm connector structure
* @drm_mode: Display mode set for the display * @drm_mode: Display mode set for the display
* @sub_mode: Additional mode info to drm display mode
* @mode_info: Out parameter. information of the display mode * @mode_info: Out parameter. information of the display mode
* Returns: Zero on success * Returns: Zero on success
*/ */
int sde_connector_get_mode_info(struct drm_connector *conn, int sde_connector_get_mode_info(struct drm_connector *conn,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info); struct msm_mode_info *mode_info);
/** /**

View File

@@ -933,12 +933,15 @@ static int _sde_encoder_atomic_check_reserve(struct drm_encoder *drm_enc,
{ {
int ret = 0; int ret = 0;
struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode; struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode;
struct msm_sub_mode sub_mode;
if (sde_conn && msm_atomic_needs_modeset(crtc_state, conn_state)) { if (sde_conn && msm_atomic_needs_modeset(crtc_state, conn_state)) {
struct msm_display_topology *topology = NULL; struct msm_display_topology *topology = NULL;
sub_mode.dsc_mode = sde_connector_get_property(conn_state,
CONNECTOR_PROP_DSC_MODE);
ret = sde_connector_get_mode_info(&sde_conn->base, ret = sde_connector_get_mode_info(&sde_conn->base,
adj_mode, &sde_conn_state->mode_info); adj_mode, &sub_mode, &sde_conn_state->mode_info);
if (ret) { if (ret) {
SDE_ERROR_ENC(sde_enc, SDE_ERROR_ENC(sde_enc,
"failed to get mode info, rc = %d\n", ret); "failed to get mode info, rc = %d\n", ret);
@@ -5432,6 +5435,7 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder,
struct sde_encoder_phys *phys_enc; struct sde_encoder_phys *phys_enc;
struct drm_bridge *bridge; struct drm_bridge *bridge;
int ret = 0, i; int ret = 0, i;
struct msm_sub_mode sub_mode;
if (!encoder) { if (!encoder) {
SDE_ERROR("invalid drm enc\n"); SDE_ERROR("invalid drm enc\n");
@@ -5497,9 +5501,11 @@ int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder,
return -EINVAL; return -EINVAL;
} }
sub_mode.dsc_mode = splash_display->dsc_cnt ? MSM_DISPLAY_DSC_MODE_ENABLED :
MSM_DISPLAY_DSC_MODE_DISABLED;
drm_mode = &encoder->crtc->state->adjusted_mode; drm_mode = &encoder->crtc->state->adjusted_mode;
ret = sde_connector_get_mode_info(&sde_conn->base, ret = sde_connector_get_mode_info(&sde_conn->base,
drm_mode, &sde_conn_state->mode_info); drm_mode, &sub_mode, &sde_conn_state->mode_info);
if (ret) { if (ret) {
SDE_ERROR_ENC(sde_enc, SDE_ERROR_ENC(sde_enc,
"conn: ->get_mode_info failed. ret=%d\n", ret); "conn: ->get_mode_info failed. ret=%d\n", ret);
@@ -5647,3 +5653,24 @@ void sde_encoder_enable_recovery_event(struct drm_encoder *encoder)
sde_enc = to_sde_encoder_virt(encoder); sde_enc = to_sde_encoder_virt(encoder);
sde_enc->recovery_events_enabled = true; sde_enc->recovery_events_enabled = true;
} }
bool sde_encoder_needs_dsc_disable(struct drm_encoder *drm_enc)
{
struct sde_kms *sde_kms;
struct drm_connector *conn;
struct sde_connector_state *conn_state;
if (!drm_enc)
return false;
sde_kms = sde_encoder_get_kms(drm_enc);
if (!sde_kms)
return false;
conn = sde_encoder_get_connector(sde_kms->dev, drm_enc);
if (!conn || !conn->state)
return false;
conn_state = to_sde_connector_state(conn->state);
return TOPOLOGY_DSC_MODE(conn_state->old_topology_name);
}

View File

@@ -559,6 +559,12 @@ void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable);
struct drm_connector *sde_encoder_get_connector(struct drm_device *dev, struct drm_connector *sde_encoder_get_connector(struct drm_device *dev,
struct drm_encoder *drm_enc); struct drm_encoder *drm_enc);
/**sde_encoder_needs_dsc_disable - indicates if dsc should be disabled
* based on previous topology
* @drm_enc: Pointer to drm encoder structure
*/
bool sde_encoder_needs_dsc_disable(struct drm_encoder *drm_enc);
/** /**
* sde_encoder_get_transfer_time - get the mdp transfer time in usecs * sde_encoder_get_transfer_time - get the mdp transfer time in usecs
* @drm_enc: Pointer to drm encoder structure * @drm_enc: Pointer to drm encoder structure

View File

@@ -936,7 +936,8 @@ void sde_encoder_dce_disable(struct sde_encoder_virt *sde_enc)
comp_type = sde_enc->mode_info.comp_info.comp_type; comp_type = sde_enc->mode_info.comp_info.comp_type;
if (comp_type == MSM_DISPLAY_COMPRESSION_DSC) if (comp_type == MSM_DISPLAY_COMPRESSION_DSC ||
sde_encoder_needs_dsc_disable(&sde_enc->base))
_dce_dsc_disable(sde_enc); _dce_dsc_disable(sde_enc);
else if (comp_type == MSM_DISPLAY_COMPRESSION_VDC) else if (comp_type == MSM_DISPLAY_COMPRESSION_VDC)
_dce_vdc_disable(sde_enc); _dce_vdc_disable(sde_enc);

View File

@@ -33,6 +33,14 @@
x == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE ||\ x == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE ||\
x == SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE) x == SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE)
#define TOPOLOGY_DSC_MODE(x) \
(x == SDE_RM_TOPOLOGY_SINGLEPIPE_DSC ||\
x == SDE_RM_TOPOLOGY_DUALPIPE_DSC ||\
x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC ||\
x == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE ||\
x == SDE_RM_TOPOLOGY_QUADPIPE_3DMERGE_DSC ||\
x == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE ||\
x == SDE_RM_TOPOLOGY_QUADPIPE_DSC4HSMERGE)
/** /**
* enum sde_rm_topology_name - HW resource use case in use by connector * enum sde_rm_topology_name - HW resource use case in use by connector
* @SDE_RM_TOPOLOGY_NONE: No topology in use currently * @SDE_RM_TOPOLOGY_NONE: No topology in use currently

View File

@@ -373,6 +373,7 @@ int sde_wb_get_info(struct drm_connector *connector,
int sde_wb_get_mode_info(struct drm_connector *connector, int sde_wb_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res) void *display, const struct msm_resource_caps_info *avail_res)
{ {

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/ */
#ifndef __SDE_WB_H__ #ifndef __SDE_WB_H__
@@ -196,6 +196,7 @@ int sde_wb_get_info(struct drm_connector *connector,
* sde_wb_get_mode_info - retrieve information of the mode selected * sde_wb_get_mode_info - retrieve information of the mode selected
* @connector: Pointer to drm connector structure * @connector: Pointer to drm connector structure
* @drm_mode: Display mode set for the display * @drm_mode: Display mode set for the display
* @sub_mode: Additional mode info to drm display mode
* @mode_info: Out parameter. information of the mode. * @mode_info: Out parameter. information of the mode.
* @display: Pointer to private display structure * @display: Pointer to private display structure
* @avail_res: Pointer with curr available resources * @avail_res: Pointer with curr available resources
@@ -203,6 +204,7 @@ int sde_wb_get_info(struct drm_connector *connector,
*/ */
int sde_wb_get_mode_info(struct drm_connector *connector, int sde_wb_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res); void *display, const struct msm_resource_caps_info *avail_res);
@@ -352,6 +354,7 @@ int sde_wb_connector_set_info_blob(struct drm_connector *connector,
static inline static inline
int sde_wb_get_mode_info(struct drm_connector *connector, int sde_wb_get_mode_info(struct drm_connector *connector,
const struct drm_display_mode *drm_mode, const struct drm_display_mode *drm_mode,
struct msm_sub_mode *sub_mode,
struct msm_mode_info *mode_info, struct msm_mode_info *mode_info,
void *display, const struct msm_resource_caps_info *avail_res) void *display, const struct msm_resource_caps_info *avail_res)
{ {