Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89754966 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents ed868466 b121756b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
};


+8 −20
Original line number Diff line number Diff line
@@ -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;
+23 −19
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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)
+25 −13
Original line number Diff line number Diff line
@@ -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;
Loading