Merge "disp: msm: sde: adjust DSC encoders to support all 4LM topologies"

This commit is contained in:
qctecmdr
2020-06-09 23:42:42 -07:00
committed by Gerrit - the friendly Code Review server
11 changed files with 189 additions and 62 deletions

View File

@@ -364,6 +364,9 @@ struct msm_roi_caps {
* @det_thresh_flatness: Flatness threshold. * @det_thresh_flatness: Flatness threshold.
* @extra_width: Extra width required in timing calculations. * @extra_width: Extra width required in timing calculations.
* @pps_delay_ms: Post PPS command delay in milliseconds. * @pps_delay_ms: Post PPS command delay in milliseconds.
* @dsc_4hsmerge_en: Using DSC 4HS merge topology
* @dsc_4hsmerge_padding 4HS merge DSC pair padding value in bytes
* @dsc_4hsmerge_alignment 4HS merge DSC alignment value in bytes
*/ */
struct msm_display_dsc_info { struct msm_display_dsc_info {
struct drm_dsc_config config; struct drm_dsc_config config;
@@ -382,6 +385,9 @@ struct msm_display_dsc_info {
int det_thresh_flatness; int det_thresh_flatness;
u32 extra_width; u32 extra_width;
u32 pps_delay_ms; u32 pps_delay_ms;
bool dsc_4hsmerge_en;
u32 dsc_4hsmerge_padding;
u32 dsc_4hsmerge_alignment;
}; };

View File

@@ -678,25 +678,6 @@ static int _sde_crtc_set_roi_v1(struct drm_crtc_state *state,
return 0; return 0;
} }
static bool _sde_crtc_setup_is_3dmux_dsc(struct drm_crtc_state *state)
{
int i;
struct sde_crtc_state *cstate;
bool is_3dmux_dsc = false;
cstate = to_sde_crtc_state(state);
for (i = 0; i < cstate->num_connectors; i++) {
struct drm_connector *conn = cstate->connectors[i];
if (sde_connector_get_topology_name(conn) ==
SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC)
is_3dmux_dsc = true;
}
return is_3dmux_dsc;
}
static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc, static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc,
struct drm_crtc_state *state) struct drm_crtc_state *state)
{ {
@@ -836,6 +817,7 @@ static int _sde_crtc_check_autorefresh(struct drm_crtc *crtc,
static int _sde_crtc_set_lm_roi(struct drm_crtc *crtc, static int _sde_crtc_set_lm_roi(struct drm_crtc *crtc,
struct drm_crtc_state *state, int lm_idx) struct drm_crtc_state *state, int lm_idx)
{ {
struct sde_kms *sde_kms;
struct sde_crtc *sde_crtc; struct sde_crtc *sde_crtc;
struct sde_crtc_state *crtc_state; struct sde_crtc_state *crtc_state;
const struct sde_rect *crtc_roi; const struct sde_rect *crtc_roi;
@@ -845,6 +827,12 @@ static int _sde_crtc_set_lm_roi(struct drm_crtc *crtc,
if (!crtc || !state || lm_idx >= ARRAY_SIZE(crtc_state->lm_bounds)) if (!crtc || !state || lm_idx >= ARRAY_SIZE(crtc_state->lm_bounds))
return -EINVAL; return -EINVAL;
sde_kms = _sde_crtc_get_kms(crtc);
if (!sde_kms || !sde_kms->catalog) {
SDE_ERROR("invalid parameters\n");
return -EINVAL;
}
sde_crtc = to_sde_crtc(crtc); sde_crtc = to_sde_crtc(crtc);
crtc_state = to_sde_crtc_state(state); crtc_state = to_sde_crtc_state(state);
crtc_roi = &crtc_state->crtc_roi; crtc_roi = &crtc_state->crtc_roi;
@@ -864,7 +852,7 @@ static int _sde_crtc_set_lm_roi(struct drm_crtc *crtc,
* hence, crtc roi must match the mixer dimensions. * hence, crtc roi must match the mixer dimensions.
*/ */
if (crtc_state->num_ds_enabled || if (crtc_state->num_ds_enabled ||
_sde_crtc_setup_is_3dmux_dsc(state)) { sde_rm_topology_is_3dmux_dsc(&sde_kms->rm, state)) {
if (memcmp(lm_roi, lm_bounds, sizeof(struct sde_rect))) { if (memcmp(lm_roi, lm_bounds, sizeof(struct sde_rect))) {
SDE_ERROR("Unsupported: Dest scaler/3d mux DSC + PU\n"); SDE_ERROR("Unsupported: Dest scaler/3d mux DSC + PU\n");
return -EINVAL; return -EINVAL;

View File

@@ -71,12 +71,6 @@
/* Maximum number of VSYNC wait attempts for RSC state transition */ /* Maximum number of VSYNC wait attempts for RSC state transition */
#define MAX_RSC_WAIT 5 #define MAX_RSC_WAIT 5
#define TOPOLOGY_DUALPIPE_MERGE_MODE(x) \
(((x) == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE) || \
((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE) || \
((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC) || \
((x) == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC))
/** /**
* enum sde_enc_rc_events - events for resource control state machine * enum sde_enc_rc_events - events for resource control state machine
* @SDE_ENC_RC_EVENT_KICKOFF: * @SDE_ENC_RC_EVENT_KICKOFF:
@@ -2215,6 +2209,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
struct sde_kms *sde_kms; struct sde_kms *sde_kms;
struct drm_connector *conn; struct drm_connector *conn;
int i = 0, ret; int i = 0, ret;
int num_lm, num_intf, num_pp_per_intf;
if (!drm_enc) { if (!drm_enc) {
SDE_ERROR("invalid encoder\n"); SDE_ERROR("invalid encoder\n");
@@ -2276,17 +2271,25 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
/* assign the reserved HW blocks to this encoder */ /* assign the reserved HW blocks to this encoder */
_sde_encoder_virt_populate_hw_res(drm_enc); _sde_encoder_virt_populate_hw_res(drm_enc);
/* determine left HW PP block to map to INTF */
num_lm = sde_enc->mode_info.topology.num_lm;
num_intf = sde_enc->mode_info.topology.num_intf;
num_pp_per_intf = num_lm / num_intf;
if (!num_pp_per_intf)
num_pp_per_intf = 1;
/* perform mode_set on phys_encs */ /* perform mode_set on phys_encs */
for (i = 0; i < sde_enc->num_phys_encs; i++) { for (i = 0; i < sde_enc->num_phys_encs; i++) {
struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
if (phys) { if (phys) {
if (!sde_enc->hw_pp[i] && sde_enc->topology.num_intf) { if (!sde_enc->hw_pp[i * num_pp_per_intf] &&
SDE_ERROR_ENC(sde_enc, sde_enc->topology.num_intf) {
"invalid pingpong block for the encoder\n"); SDE_ERROR_ENC(sde_enc, "invalid hw_pp[%d]\n",
i * num_pp_per_intf);
return; return;
} }
phys->hw_pp = sde_enc->hw_pp[i]; phys->hw_pp = sde_enc->hw_pp[i * num_pp_per_intf];
phys->connector = conn->state->connector; phys->connector = conn->state->connector;
if (phys->ops.mode_set) if (phys->ops.mode_set)
phys->ops.mode_set(phys, mode, adj_mode); phys->ops.mode_set(phys, mode, adj_mode);
@@ -2493,6 +2496,7 @@ static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys) static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
{ {
struct sde_kms *sde_kms;
void *dither_cfg = NULL; void *dither_cfg = NULL;
int ret = 0, i = 0; int ret = 0, i = 0;
size_t len = 0; size_t len = 0;
@@ -2502,11 +2506,16 @@ static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
struct sde_encoder_virt *sde_enc; struct sde_encoder_virt *sde_enc;
struct sde_hw_pingpong *hw_pp; struct sde_hw_pingpong *hw_pp;
u32 bpp, bpc; u32 bpp, bpc;
int num_lm;
if (!phys || !phys->connector || !phys->hw_pp || if (!phys || !phys->connector || !phys->hw_pp ||
!phys->hw_pp->ops.setup_dither || !phys->parent) !phys->hw_pp->ops.setup_dither || !phys->parent)
return; return;
sde_kms = sde_encoder_get_kms(phys->parent);
if (!sde_kms)
return;
topology = sde_connector_get_topology_name(phys->connector); topology = sde_connector_get_topology_name(phys->connector);
if ((topology == SDE_RM_TOPOLOGY_PPSPLIT) && if ((topology == SDE_RM_TOPOLOGY_PPSPLIT) &&
(phys->split_role == ENC_ROLE_SLAVE)) (phys->split_role == ENC_ROLE_SLAVE))
@@ -2533,15 +2542,10 @@ static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
if (ret && ret == -ENODATA) if (ret && ret == -ENODATA)
return; return;
if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology)) { num_lm = sde_rm_topology_get_num_lm(&sde_kms->rm, topology);
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { for (i = 0; i < num_lm; i++) {
hw_pp = sde_enc->hw_pp[i]; hw_pp = sde_enc->hw_pp[i];
phys->hw_pp->ops.setup_dither(hw_pp, phys->hw_pp->ops.setup_dither(hw_pp,
dither_cfg, len);
}
} else {
phys->hw_pp->ops.setup_dither(phys->hw_pp,
dither_cfg, len); dither_cfg, len);
} }
} }

View File

@@ -38,7 +38,7 @@
#define MAX_PHYS_ENCODERS_PER_VIRTUAL \ #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
(MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES) (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
#define MAX_CHANNELS_PER_ENC 2 #define MAX_CHANNELS_PER_ENC 4
#define SDE_ENCODER_FRAME_EVENT_DONE BIT(0) #define SDE_ENCODER_FRAME_EVENT_DONE BIT(0)
#define SDE_ENCODER_FRAME_EVENT_ERROR BIT(1) #define SDE_ENCODER_FRAME_EVENT_ERROR BIT(1)

View File

@@ -313,7 +313,8 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
unsigned long affected_displays, int index, unsigned long affected_displays, int index,
const struct sde_rect *roi, int dsc_common_mode, const struct sde_rect *roi, int dsc_common_mode,
bool merge_3d, bool disable_merge_3d, bool mode_3d, bool merge_3d, bool disable_merge_3d, bool mode_3d,
bool half_panel_partial_update, int ich_res) bool dsc_4hsmerge, bool half_panel_partial_update,
int ich_res)
{ {
struct sde_hw_ctl *hw_ctl; struct sde_hw_ctl *hw_ctl;
struct sde_hw_dsc *hw_dsc; struct sde_hw_dsc *hw_dsc;
@@ -345,8 +346,9 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
return -EINVAL; return -EINVAL;
} }
SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode, SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
index, active, merge_3d, disable_merge_3d); dsc_common_mode, index, active, merge_3d,
disable_merge_3d, dsc_4hsmerge);
_dce_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res, _dce_dsc_pipe_cfg(hw_dsc, hw_pp, dsc, dsc_common_mode, ich_res,
hw_dsc_pp, mode_3d, disable_merge_3d, active, hw_dsc_pp, mode_3d, disable_merge_3d, active,
@@ -401,15 +403,15 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc,
const struct sde_rm_topology_def *def; const struct sde_rm_topology_def *def;
const struct sde_rect *roi; const struct sde_rect *roi;
enum sde_3d_blend_mode mode_3d; enum sde_3d_blend_mode mode_3d;
bool half_panel_partial_update, dsc_merge, merge_3d; bool half_panel_partial_update, dsc_merge, merge_3d, dsc_4hsmerge;
bool disable_merge_3d = false; bool disable_merge_3d = false;
int this_frame_slices; int this_frame_slices;
int intf_ip_w, enc_ip_w; int intf_ip_w, enc_ip_w;
int num_intf, num_dsc, num_lm; int num_intf, num_dsc, num_lm;
int ich_res; int ich_res;
int dsc_pic_width;
int dsc_common_mode = 0; int dsc_common_mode = 0;
int i; int i, rc = 0;
int rc = 0;
sde_kms = sde_encoder_get_kms(&sde_enc->base); sde_kms = sde_encoder_get_kms(&sde_enc->base);
@@ -420,33 +422,43 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc,
enc_master = sde_enc->cur_master; enc_master = sde_enc->cur_master;
roi = &sde_enc->cur_conn_roi; roi = &sde_enc->cur_conn_roi;
dsc = &sde_enc->mode_info.comp_info.dsc_info; dsc = &sde_enc->mode_info.comp_info.dsc_info;
num_lm = def->num_lm;
num_dsc = def->num_comp_enc; num_dsc = def->num_comp_enc;
num_intf = def->num_intf; num_intf = def->num_intf;
mode_3d = (topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) ? mode_3d = (num_lm > num_dsc) ? BLEND_3D_H_ROW_INT : BLEND_3D_NONE;
BLEND_3D_H_ROW_INT : BLEND_3D_NONE; merge_3d = (mode_3d != BLEND_3D_NONE) ? true : false;
num_lm = def->num_lm;
half_panel_partial_update = _dce_check_half_panel_update(num_lm, half_panel_partial_update = _dce_check_half_panel_update(num_lm,
affected_displays); affected_displays);
merge_3d = (mode_3d != BLEND_3D_NONE) ? true : false;
dsc_merge = ((num_dsc > num_intf) && !half_panel_partial_update) ? dsc_merge = ((num_dsc > num_intf) && !half_panel_partial_update) ?
true : false; true : false;
disable_merge_3d = (merge_3d && half_panel_partial_update) ? disable_merge_3d = (merge_3d && half_panel_partial_update) ?
false : true; false : true;
dsc_4hsmerge = (dsc_merge && num_dsc == 4 && num_intf == 1) ?
true : false;
/* /*
* If this encoder is driving more than one DSC encoder, they * If this encoder is driving more than one DSC encoder, they
* operate in tandem, same pic dimension needs to be used by * operate in tandem, same pic dimension needs to be used by
* each of them.(pp-split is assumed to be not supported) * each of them.(pp-split is assumed to be not supported)
*
* If encoder is driving more than 2 DSCs, each DSC pair will operate
* on half of the picture in tandem.
*/ */
_dce_dsc_update_pic_dim(dsc, roi->w, roi->h); if (num_dsc > 2) {
dsc_pic_width = roi->w / 2;
dsc->dsc_4hsmerge_en = dsc_4hsmerge;
} else
dsc_pic_width = roi->w;
_dce_dsc_update_pic_dim(dsc, dsc_pic_width, roi->h);
this_frame_slices = roi->w / dsc->config.slice_width; this_frame_slices = roi->w / dsc->config.slice_width;
intf_ip_w = this_frame_slices * dsc->config.slice_width; intf_ip_w = this_frame_slices * dsc->config.slice_width;
enc_ip_w = intf_ip_w; enc_ip_w = intf_ip_w;
if (!half_panel_partial_update) if (!half_panel_partial_update)
intf_ip_w /= def->num_intf; intf_ip_w /= num_intf;
if (!half_panel_partial_update && (num_dsc > 1)) if (!half_panel_partial_update && (num_dsc > 1))
dsc_common_mode |= DSC_MODE_SPLIT_PANEL; dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
if (dsc_merge) { if (dsc_merge) {
@@ -478,7 +490,7 @@ static int _dce_dsc_setup_helper(struct sde_encoder_virt *sde_enc,
for (i = 0; i < num_dsc; i++) { for (i = 0; i < num_dsc; i++) {
rc = _dce_dsc_setup_single(sde_enc, dsc, affected_displays, i, rc = _dce_dsc_setup_single(sde_enc, dsc, affected_displays, i,
roi, dsc_common_mode, merge_3d, roi, dsc_common_mode, merge_3d,
disable_merge_3d, mode_3d, disable_merge_3d, mode_3d, dsc_4hsmerge,
half_panel_partial_update, ich_res); half_panel_partial_update, ich_res);
if (rc) if (rc)
break; break;

View File

@@ -603,16 +603,29 @@ void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc);
static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode( static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
struct sde_encoder_phys *phys_enc) struct sde_encoder_phys *phys_enc)
{ {
enum sde_rm_topology_name topology; struct msm_display_topology def;
enum sde_enc_split_role split_role;
int ret, num_lm;
bool mode_3d;
if (!phys_enc || phys_enc->enable_state == SDE_ENC_DISABLING) if (!phys_enc || phys_enc->enable_state == SDE_ENC_DISABLING ||
!phys_enc->connector || !phys_enc->connector->state)
return BLEND_3D_NONE; return BLEND_3D_NONE;
topology = sde_connector_get_topology_name(phys_enc->connector); ret = sde_connector_state_get_topology
if (phys_enc->split_role == ENC_ROLE_SOLO && (phys_enc->connector->state, &def);
(topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE || if (ret)
topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC || return BLEND_3D_NONE;
topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC))
num_lm = def.num_lm;
mode_3d = (num_lm > def.num_enc) ? true : false;
split_role = phys_enc->split_role;
if (split_role == ENC_ROLE_SOLO && num_lm == 2 && mode_3d)
return BLEND_3D_H_ROW_INT;
if ((split_role == ENC_ROLE_MASTER || split_role == ENC_ROLE_SLAVE)
&& num_lm == 4 && mode_3d)
return BLEND_3D_H_ROW_INT; return BLEND_3D_H_ROW_INT;
return BLEND_3D_NONE; return BLEND_3D_NONE;

View File

@@ -87,7 +87,7 @@
#define SDE_CTL_CFG_VERSION_1_0_0 0x100 #define SDE_CTL_CFG_VERSION_1_0_0 0x100
#define MAX_INTF_PER_CTL_V1 2 #define MAX_INTF_PER_CTL_V1 2
#define MAX_DSC_PER_CTL_V1 2 #define MAX_DSC_PER_CTL_V1 4
#define MAX_CWB_PER_CTL_V1 2 #define MAX_CWB_PER_CTL_V1 2
#define MAX_MERGE_3D_PER_CTL_V1 2 #define MAX_MERGE_3D_PER_CTL_V1 2
#define MAX_WB_PER_CTL_V1 1 #define MAX_WB_PER_CTL_V1 1

View File

@@ -141,7 +141,11 @@ static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
data |= BIT(0); data |= BIT(0);
if (mode & DSC_MODE_MULTIPLEX) { if (mode & DSC_MODE_MULTIPLEX) {
slice_count_per_enc = dsc->config.slice_count >> 1; if (dsc->dsc_4hsmerge_en)
slice_count_per_enc = dsc->config.slice_count >> 2;
else
slice_count_per_enc = dsc->config.slice_count >> 1;
data |= BIT(1); data |= BIT(1);
} }
@@ -253,6 +257,11 @@ static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
data |= BIT(13); data |= BIT(13);
if (!(mode & DSC_MODE_VIDEO)) if (!(mode & DSC_MODE_VIDEO))
data |= BIT(17); data |= BIT(17);
if (dsc->dsc_4hsmerge_en) {
data |= dsc->dsc_4hsmerge_padding << 18;
data |= dsc->dsc_4hsmerge_alignment << 22;
data |= BIT(16);
}
SDE_REG_WRITE(dsc_c, DSC_CFG + idx, data); SDE_REG_WRITE(dsc_c, DSC_CFG + idx, data);
} }

View File

@@ -2142,6 +2142,63 @@ bool sde_rm_topology_is_quad_pipe(struct sde_rm *rm,
return false; return false;
} }
bool sde_rm_topology_is_dual_pipe(struct sde_rm *rm,
struct drm_crtc_state *state)
{
int i;
struct sde_crtc_state *cstate;
uint64_t topology = SDE_RM_TOPOLOGY_NONE;
if ((!rm) || (!state)) {
pr_err("invalid arguments: rm:%d state:%d\n",
rm == NULL, state == NULL);
return false;
}
cstate = to_sde_crtc_state(state);
for (i = 0; i < cstate->num_connectors; i++) {
struct drm_connector *conn = cstate->connectors[i];
topology = sde_connector_get_topology_name(conn);
if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology))
return true;
}
return false;
}
bool sde_rm_topology_is_3dmux_dsc(struct sde_rm *rm,
struct drm_crtc_state *state)
{
int i;
struct sde_crtc_state *cstate;
uint64_t topology = SDE_RM_TOPOLOGY_NONE;
const struct sde_rm_topology_def *def;
int num_lm, num_enc;
if ((!rm) || (!state)) {
pr_err("invalid arguments: rm:%d state:%d\n",
rm == NULL, state == NULL);
return false;
}
cstate = to_sde_crtc_state(state);
for (i = 0; i < cstate->num_connectors; i++) {
struct drm_connector *conn = cstate->connectors[i];
topology = sde_connector_get_topology_name(conn);
def = sde_rm_topology_get_topology_def(rm, topology);
num_lm = def->num_lm;
num_enc = def->num_comp_enc;
if (num_lm > num_enc && num_enc)
return true;
}
return false;
}
/** /**
* _sde_rm_release_rsvp - release resources and release a reservation * _sde_rm_release_rsvp - release resources and release a reservation
* @rm: KMS handle * @rm: KMS handle

View File

@@ -20,6 +20,12 @@
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_DUALPIPE_MERGE_MODE(x) \
(x == SDE_RM_TOPOLOGY_DUALPIPE_DSCMERGE || \
x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE || \
x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC || \
x == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC)
/** /**
* 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
@@ -343,6 +349,26 @@ static inline int sde_rm_topology_get_num_lm(struct sde_rm *rm,
return rm->topology_tbl[topology].num_lm; return rm->topology_tbl[topology].num_lm;
} }
/**
* sde_rm_topology_is_dual_pipe - check if the topology used
* is a dual-pipe mode one
* @rm: SDE Resource Manager handle
* @state: drm state of the crtc
* @return: true if attached connector is in dual-pipe mode
*/
bool sde_rm_topology_is_dual_pipe(struct sde_rm *rm,
struct drm_crtc_state *state);
/**
* sde_rm_topology_is_3dmux_dsc - check if the topology used
* is a 3dmerge dsc mode one
* @rm: SDE Resource Manager handle
* @state: drm state of the crtc
* @return: true if attached connector is in 3DMERGE DSC mode
*/
bool sde_rm_topology_is_3dmux_dsc(struct sde_rm *rm,
struct drm_crtc_state *state);
/** /**
* sde_rm_topology_is_quad_pipe - check if the topology used * sde_rm_topology_is_quad_pipe - check if the topology used
* is a quad-pipe mode one * is a quad-pipe mode one

View File

@@ -309,6 +309,8 @@ int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info,
int slice_per_pkt, slice_per_intf; int slice_per_pkt, slice_per_intf;
int bytes_in_slice, total_bytes_per_intf; int bytes_in_slice, total_bytes_per_intf;
u16 bpp; u16 bpp;
u32 bytes_in_dsc_pair;
u32 total_bytes_in_dsc_pair;
if (!dsc_info || !dsc_info->config.slice_width || if (!dsc_info || !dsc_info->config.slice_width ||
!dsc_info->config.slice_height || !dsc_info->config.slice_height ||
@@ -360,6 +362,16 @@ int sde_dsc_populate_dsc_private_params(struct msm_display_dsc_info *dsc_info,
dsc_info->bytes_per_pkt = bytes_in_slice * slice_per_pkt; dsc_info->bytes_per_pkt = bytes_in_slice * slice_per_pkt;
dsc_info->pkt_per_line = slice_per_intf / slice_per_pkt; dsc_info->pkt_per_line = slice_per_intf / slice_per_pkt;
bytes_in_dsc_pair = DIV_ROUND_UP(bytes_in_slice * 2, 3);
if (bytes_in_dsc_pair % 8) {
dsc_info->dsc_4hsmerge_padding = 8 - (bytes_in_dsc_pair % 8);
total_bytes_in_dsc_pair = bytes_in_dsc_pair +
dsc_info->dsc_4hsmerge_padding;
if (total_bytes_in_dsc_pair % 16)
dsc_info->dsc_4hsmerge_alignment = 16 -
(total_bytes_in_dsc_pair % 16);
}
return 0; return 0;
} }