Merge "disp: msm: sde: adjust DSC encoders to support all 4LM topologies"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
8975496690
@@ -364,6 +364,9 @@ struct msm_roi_caps {
|
||||
* @det_thresh_flatness: Flatness threshold.
|
||||
* @extra_width: Extra width required in timing calculations.
|
||||
* @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 drm_dsc_config config;
|
||||
@@ -382,6 +385,9 @@ struct msm_display_dsc_info {
|
||||
int det_thresh_flatness;
|
||||
u32 extra_width;
|
||||
u32 pps_delay_ms;
|
||||
bool dsc_4hsmerge_en;
|
||||
u32 dsc_4hsmerge_padding;
|
||||
u32 dsc_4hsmerge_alignment;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -678,25 +678,6 @@ static int _sde_crtc_set_roi_v1(struct drm_crtc_state *state,
|
||||
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,
|
||||
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,
|
||||
struct drm_crtc_state *state, int lm_idx)
|
||||
{
|
||||
struct sde_kms *sde_kms;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_crtc_state *crtc_state;
|
||||
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))
|
||||
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);
|
||||
crtc_state = to_sde_crtc_state(state);
|
||||
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.
|
||||
*/
|
||||
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))) {
|
||||
SDE_ERROR("Unsupported: Dest scaler/3d mux DSC + PU\n");
|
||||
return -EINVAL;
|
||||
|
@@ -71,12 +71,6 @@
|
||||
/* Maximum number of VSYNC wait attempts for RSC state transition */
|
||||
#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
|
||||
* @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 drm_connector *conn;
|
||||
int i = 0, ret;
|
||||
int num_lm, num_intf, num_pp_per_intf;
|
||||
|
||||
if (!drm_enc) {
|
||||
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 */
|
||||
_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 */
|
||||
for (i = 0; i < sde_enc->num_phys_encs; i++) {
|
||||
struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
|
||||
|
||||
if (phys) {
|
||||
if (!sde_enc->hw_pp[i] && sde_enc->topology.num_intf) {
|
||||
SDE_ERROR_ENC(sde_enc,
|
||||
"invalid pingpong block for the encoder\n");
|
||||
if (!sde_enc->hw_pp[i * num_pp_per_intf] &&
|
||||
sde_enc->topology.num_intf) {
|
||||
SDE_ERROR_ENC(sde_enc, "invalid hw_pp[%d]\n",
|
||||
i * num_pp_per_intf);
|
||||
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;
|
||||
if (phys->ops.mode_set)
|
||||
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)
|
||||
{
|
||||
struct sde_kms *sde_kms;
|
||||
void *dither_cfg = NULL;
|
||||
int ret = 0, i = 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_hw_pingpong *hw_pp;
|
||||
u32 bpp, bpc;
|
||||
int num_lm;
|
||||
|
||||
if (!phys || !phys->connector || !phys->hw_pp ||
|
||||
!phys->hw_pp->ops.setup_dither || !phys->parent)
|
||||
return;
|
||||
|
||||
sde_kms = sde_encoder_get_kms(phys->parent);
|
||||
if (!sde_kms)
|
||||
return;
|
||||
|
||||
topology = sde_connector_get_topology_name(phys->connector);
|
||||
if ((topology == SDE_RM_TOPOLOGY_PPSPLIT) &&
|
||||
(phys->split_role == ENC_ROLE_SLAVE))
|
||||
@@ -2533,17 +2542,12 @@ static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
|
||||
if (ret && ret == -ENODATA)
|
||||
return;
|
||||
|
||||
if (TOPOLOGY_DUALPIPE_MERGE_MODE(topology)) {
|
||||
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
|
||||
num_lm = sde_rm_topology_get_num_lm(&sde_kms->rm, topology);
|
||||
for (i = 0; i < num_lm; i++) {
|
||||
hw_pp = sde_enc->hw_pp[i];
|
||||
phys->hw_pp->ops.setup_dither(hw_pp,
|
||||
dither_cfg, len);
|
||||
}
|
||||
|
||||
} else {
|
||||
phys->hw_pp->ops.setup_dither(phys->hw_pp,
|
||||
dither_cfg, len);
|
||||
}
|
||||
}
|
||||
|
||||
void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
|
||||
|
@@ -38,7 +38,7 @@
|
||||
#define MAX_PHYS_ENCODERS_PER_VIRTUAL \
|
||||
(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_ERROR BIT(1)
|
||||
|
@@ -313,7 +313,8 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
|
||||
unsigned long affected_displays, int index,
|
||||
const struct sde_rect *roi, int dsc_common_mode,
|
||||
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_dsc *hw_dsc;
|
||||
@@ -345,8 +346,9 @@ static int _dce_dsc_setup_single(struct sde_encoder_virt *sde_enc,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, dsc_common_mode,
|
||||
index, active, merge_3d, disable_merge_3d);
|
||||
SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h,
|
||||
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,
|
||||
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_rect *roi;
|
||||
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;
|
||||
int this_frame_slices;
|
||||
int intf_ip_w, enc_ip_w;
|
||||
int num_intf, num_dsc, num_lm;
|
||||
int ich_res;
|
||||
int dsc_pic_width;
|
||||
int dsc_common_mode = 0;
|
||||
int i;
|
||||
int rc = 0;
|
||||
int i, rc = 0;
|
||||
|
||||
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;
|
||||
roi = &sde_enc->cur_conn_roi;
|
||||
dsc = &sde_enc->mode_info.comp_info.dsc_info;
|
||||
num_lm = def->num_lm;
|
||||
num_dsc = def->num_comp_enc;
|
||||
num_intf = def->num_intf;
|
||||
mode_3d = (topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC) ?
|
||||
BLEND_3D_H_ROW_INT : BLEND_3D_NONE;
|
||||
num_lm = def->num_lm;
|
||||
mode_3d = (num_lm > num_dsc) ? BLEND_3D_H_ROW_INT : BLEND_3D_NONE;
|
||||
merge_3d = (mode_3d != BLEND_3D_NONE) ? true : false;
|
||||
|
||||
half_panel_partial_update = _dce_check_half_panel_update(num_lm,
|
||||
affected_displays);
|
||||
merge_3d = (mode_3d != BLEND_3D_NONE) ? true : false;
|
||||
dsc_merge = ((num_dsc > num_intf) && !half_panel_partial_update) ?
|
||||
true : false;
|
||||
disable_merge_3d = (merge_3d && half_panel_partial_update) ?
|
||||
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
|
||||
* operate in tandem, same pic dimension needs to be used by
|
||||
* 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;
|
||||
intf_ip_w = this_frame_slices * dsc->config.slice_width;
|
||||
enc_ip_w = intf_ip_w;
|
||||
|
||||
if (!half_panel_partial_update)
|
||||
intf_ip_w /= def->num_intf;
|
||||
intf_ip_w /= num_intf;
|
||||
if (!half_panel_partial_update && (num_dsc > 1))
|
||||
dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
|
||||
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++) {
|
||||
rc = _dce_dsc_setup_single(sde_enc, dsc, affected_displays, i,
|
||||
roi, dsc_common_mode, merge_3d,
|
||||
disable_merge_3d, mode_3d,
|
||||
disable_merge_3d, mode_3d, dsc_4hsmerge,
|
||||
half_panel_partial_update, ich_res);
|
||||
if (rc)
|
||||
break;
|
||||
|
@@ -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(
|
||||
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;
|
||||
|
||||
topology = sde_connector_get_topology_name(phys_enc->connector);
|
||||
if (phys_enc->split_role == ENC_ROLE_SOLO &&
|
||||
(topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE ||
|
||||
topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_DSC ||
|
||||
topology == SDE_RM_TOPOLOGY_DUALPIPE_3DMERGE_VDC))
|
||||
ret = sde_connector_state_get_topology
|
||||
(phys_enc->connector->state, &def);
|
||||
if (ret)
|
||||
return BLEND_3D_NONE;
|
||||
|
||||
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_NONE;
|
||||
|
@@ -87,7 +87,7 @@
|
||||
|
||||
#define SDE_CTL_CFG_VERSION_1_0_0 0x100
|
||||
#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_MERGE_3D_PER_CTL_V1 2
|
||||
#define MAX_WB_PER_CTL_V1 1
|
||||
|
@@ -141,7 +141,11 @@ static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
|
||||
data |= BIT(0);
|
||||
|
||||
if (mode & DSC_MODE_MULTIPLEX) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -253,6 +257,11 @@ static void sde_hw_dsc_config(struct sde_hw_dsc *hw_dsc,
|
||||
data |= BIT(13);
|
||||
if (!(mode & DSC_MODE_VIDEO))
|
||||
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);
|
||||
}
|
||||
|
@@ -2142,6 +2142,63 @@ bool sde_rm_topology_is_quad_pipe(struct sde_rm *rm,
|
||||
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
|
||||
* @rm: KMS handle
|
||||
|
@@ -20,6 +20,12 @@
|
||||
x == SDE_RM_TOPOLOGY_QUADPIPE_DSCMERGE ||\
|
||||
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
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* is a quad-pipe mode one
|
||||
|
@@ -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 bytes_in_slice, total_bytes_per_intf;
|
||||
u16 bpp;
|
||||
u32 bytes_in_dsc_pair;
|
||||
u32 total_bytes_in_dsc_pair;
|
||||
|
||||
if (!dsc_info || !dsc_info->config.slice_width ||
|
||||
!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->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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user