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

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

Merge "drm/msm/sde: add line insertion support for sspp"

parents 6b9d5736 5d8a9b37
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -445,6 +445,7 @@ struct msm_display_topology {
 * @wide_bus_en:	wide-bus mode cfg for interface module
 * @mdp_transfer_time_us   Specifies the mdp transfer time for command mode
 *                         panels in microseconds.
 * @vpadding:        panel stacking height
 */
struct msm_mode_info {
	uint32_t frame_rate;
@@ -458,6 +459,7 @@ struct msm_mode_info {
	struct msm_roi_caps roi_caps;
	bool wide_bus_en;
	u32 mdp_transfer_time_us;
	u32 vpadding;
};

/**
+143 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ static struct sde_crtc_custom_events custom_events[] = {
#define MAX_FRAME_COUNT			1000
#define MILI_TO_MICRO			1000

/* Line padding ratio limit */
#define MAX_VPADDING_RATIO		3

static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc)
{
	struct msm_drm_private *priv;
@@ -1058,6 +1061,18 @@ static void _sde_crtc_setup_dim_layer_cfg(struct drm_crtc *crtc,
						cstate->lm_roi[i].y;
		}

		/* update dim layer rect for panel stacking crtc */
		if (cstate->padding_height) {
			uint32_t padding_y, padding_start, padding_height;

			sde_crtc_calc_vpadding_param(crtc->state,
				split_dim_layer.rect.y, split_dim_layer.rect.h,
				&padding_y, &padding_start, &padding_height);

			split_dim_layer.rect.y = padding_y;
			split_dim_layer.rect.h = padding_height;
		}

		SDE_EVT32_VERBOSE(DRMID(crtc),
				cstate->lm_roi[i].x,
				cstate->lm_roi[i].y,
@@ -1601,6 +1616,84 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc,
	return 0;
}

static u32 _sde_crtc_calc_gcd(u32 a, u32 b)
{
	if (b == 0)
		return a;

	return _sde_crtc_calc_gcd(b, a % b);
}

static int _sde_crtc_check_panel_stacking(struct drm_crtc *crtc,
		struct drm_crtc_state *state)
{
	struct sde_kms *kms;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *sde_crtc_state;
	struct drm_connector *conn;
	struct msm_mode_info mode_info;
	u32 gcd, m, n;
	int rc;

	kms = _sde_crtc_get_kms(crtc);
	if (!kms || !kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return -EINVAL;
	}

	if (!kms->catalog->has_line_insertion)
		return 0;

	sde_crtc = to_sde_crtc(crtc);
	sde_crtc_state = to_sde_crtc_state(state);

	/* panel stacking only support single connector */
	if (sde_crtc_state->num_connectors != 1)
		return 0;

	conn = sde_crtc_state->connectors[0];
	rc = sde_connector_get_mode_info(conn->state, &mode_info);
	if (rc) {
		SDE_ERROR("failed to get mode info\n");
		return -EINVAL;
	}

	if (!mode_info.vpadding)
		goto done;

	if (mode_info.vpadding < state->mode.vdisplay) {
		SDE_ERROR("padding height %d is less than vdisplay %d\n",
			mode_info.vpadding, state->mode.vdisplay);
		return -EINVAL;
	}

	/* skip calculation if already cached */
	if (mode_info.vpadding == sde_crtc_state->padding_height)
		return 0;

	gcd = _sde_crtc_calc_gcd(mode_info.vpadding, state->mode.vdisplay);
	if (!gcd) {
		SDE_ERROR("zero gcd found for padding height %d %d\n",
			mode_info.vpadding, state->mode.vdisplay);
		return -EINVAL;
	}

	m = state->mode.vdisplay / gcd;
	n = mode_info.vpadding / gcd - m;

	if (m > MAX_VPADDING_RATIO || n > MAX_VPADDING_RATIO) {
		SDE_ERROR("unsupported panel stacking pattern %d:%d", m, n);
		return -EINVAL;
	}

	sde_crtc_state->padding_active = m;
	sde_crtc_state->padding_dummy = n;

done:
	sde_crtc_state->padding_height = mode_info.vpadding;
	return 0;
}

static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc;
@@ -5340,6 +5433,13 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
		goto end;
	}

	rc = _sde_crtc_check_panel_stacking(crtc, state);
	if (rc) {
		SDE_ERROR("crtc%d failed panel stacking check %d\n",
				crtc->base.id, rc);
		goto end;
	}

end:
	kfree(pstates);
	kfree(multirect_plane);
@@ -6872,3 +6972,46 @@ void sde_crtc_update_cont_splash_settings(struct drm_crtc *crtc)
	sde_crtc = to_sde_crtc(crtc);
	sde_crtc->cur_perf.core_clk_rate = kms->perf.max_core_clk_rate;
}

int sde_crtc_calc_vpadding_param(struct drm_crtc_state *state,
		uint32_t crtc_y, uint32_t crtc_h, uint32_t *padding_y,
		uint32_t *padding_start, uint32_t *padding_height)
{
	struct sde_kms *kms;
	struct sde_crtc_state *cstate = to_sde_crtc_state(state);
	u32 y_blocks, y_remain, y_start;
	u32 h_start, h_blocks, h_end, h_total;
	u32 m, n;

	kms = _sde_crtc_get_kms(state->crtc);
	if (!kms || !kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return -EINVAL;
	}

	if (!kms->catalog->has_line_insertion)
		return 0;

	if (!cstate->padding_active) {
		SDE_ERROR("zero padding active value\n");
		return -EINVAL;
	}

	m = cstate->padding_active;
	n = m + cstate->padding_dummy;
	y_blocks = crtc_y / m;
	y_remain = crtc_y - y_blocks * m;
	y_start = y_remain + y_blocks * n;
	h_start = m - y_remain;
	h_blocks = (crtc_h - h_start) / m;
	h_end = (crtc_h - h_start) - h_blocks * m;
	if (h_end)
		h_end += cstate->padding_dummy;
	h_total = h_start + h_end + h_blocks * n;

	*padding_y = y_start;
	*padding_start = h_start;
	*padding_height = h_total;

	return 0;
}
+20 −0
Original line number Diff line number Diff line
@@ -395,6 +395,9 @@ struct sde_crtc_respool {
 * @sbuf_clk_rate : previous and current user specified inline rotator clock
 * @sbuf_clk_shifted : whether or not sbuf_clk_rate has been shifted as part
 *	of crtc atomic check
 * @padding_height: panel height after line padding
 * @padding_active: active lines in panel stacking pattern
 * @padding_dummy: dummy lines in panel stacking pattern
 */
struct sde_crtc_state {
	struct drm_crtc_state base;
@@ -429,6 +432,10 @@ struct sde_crtc_state {
	u64 sbuf_clk_rate[2];
	bool sbuf_clk_shifted;

	u32 padding_height;
	u32 padding_active;
	u32 padding_dummy;

	struct sde_crtc_respool rp;
};

@@ -830,4 +837,17 @@ uint64_t sde_crtc_get_sbuf_clk(struct drm_crtc_state *state);
 */
void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count);

/**
 * sde_crtc_calc_vpadding_param - calculate vpadding parameters
 * @state: Pointer to DRM crtc state object
 * @crtc_y: Plane's CRTC_Y offset
 * @crtc_h: Plane's CRTC_H size
 * @padding_y: Padding Y offset
 * @padding_start: Padding start offset
 * @padding_height: Padding height in total
 */
int sde_crtc_calc_vpadding_param(struct drm_crtc_state *state,
		uint32_t crtc_y, uint32_t crtc_h, uint32_t *padding_y,
		uint32_t *padding_start, uint32_t *padding_height);

#endif /* _SDE_CRTC_H_ */
+7 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ enum sde_prop {
	UBWC_BW_CALC_VERSION,
	PIPE_ORDER_VERSION,
	SEC_SID_MASK,
	LINE_INSERTION,
	SDE_PROP_MAX,
};

@@ -447,6 +448,7 @@ static struct sde_prop_type sde_prop[] = {
	{PIPE_ORDER_VERSION, "qcom,sde-pipe-order-version", false,
			PROP_TYPE_U32},
	{SEC_SID_MASK, "qcom,sde-secure-sid-mask", false, PROP_TYPE_U32_ARRAY},
	{LINE_INSERTION, "qcom,sde-has-line-insertion", false, PROP_TYPE_BOOL},
};

static struct sde_prop_type sde_perf_prop[] = {
@@ -1397,6 +1399,9 @@ static int sde_sspp_parse_dt(struct device_node *np,
			set_bit(SDE_SSPP_TS_PREFILL_REC1, &sspp->features);
		}

		if (sde_cfg->has_line_insertion)
			set_bit(SDE_SSPP_LINE_INSERTION, &sspp->features);

		sblk->smart_dma_priority =
			PROP_VALUE_ACCESS(prop_value, SSPP_SMART_DMA, i);

@@ -3054,6 +3059,8 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
	cfg->has_idle_pc = PROP_VALUE_ACCESS(prop_value, IDLE_PC, 0);
	cfg->pipe_order_type = PROP_VALUE_ACCESS(prop_value,
		PIPE_ORDER_VERSION, 0);
	cfg->has_line_insertion = PROP_VALUE_ACCESS(prop_value,
		LINE_INSERTION, 0);
end:
	kfree(prop_value);
	return rc;
+3 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ enum {
 * @SDE_SSPP_BLOCK_SEC_UI    Blocks secure-ui layers
 * @SDE_SSPP_QOS_FL_NOCALC   Avoid fill level calculation for QoS/danger/safe
 * @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support
 * @SDE_SSPP_LINE_INSERTION  Line insertion support
 * @SDE_SSPP_MAX             maximum value
 */
enum {
@@ -199,6 +200,7 @@ enum {
	SDE_SSPP_BLOCK_SEC_UI,
	SDE_SSPP_QOS_FL_NOCALC,
	SDE_SSPP_SCALER_QSEED3LITE,
	SDE_SSPP_LINE_INSERTION,
	SDE_SSPP_MAX
};

@@ -1109,6 +1111,7 @@ struct sde_mdss_cfg {
	bool delay_prg_fetch_start;
	bool has_qsync;
	bool has_3d_merge_reset;
	bool has_line_insertion;

	bool sui_misr_supported;
	u32 sui_block_xin_mask;
Loading