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

Commit 1e71ccb7 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: configure VBIF QoS setting related to inline rotation



Add parsing logic to get the xin-ids and clk-ctrl related to
inline rotation and configure the RT VBIF QoS remapper and OT
setting for inline rotation usecase.

Change-Id: I5c79c1ea8c013f7a59fe87215160353a588aaa8c
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 23ef3f39
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -320,6 +320,19 @@ Optional properties:
- qcom,sde-cdp-setting:		Array of 2 cell property, with a format of
				<read enable, write enable> for cdp use cases in
				order of <real_time>, and <non_real_time>.
- qcom,sde-inline-rot-xin:	An integer array of xin-ids related to inline
				rotation.
- qcom,sde-inline-rot-xin-type:	A string array indicating the type of xin,
				namely sspp or wb. Number of entries should match
				the number of xin-ids defined in
				property: qcom,sde-inline-rot-xin
- qcom,sde-inline-rot-clk-ctrl:	Array of offsets describing clk control
				offsets for dynamic clock gating. 1st value
				in the array represents offset of the control
				register. 2nd value represents bit offset within
				control register. Number of offsets defined should
				match the number of xin-ids defined in
				property: qcom,sde-inline-rot-xin

Bus Scaling Subnodes:
- qcom,sde-reg-bus:		Property to provide Bus scaling for register access for
@@ -589,6 +602,9 @@ Example:
    };

    qcom,sde-inline-rotator = <&mdss_rotator 0>;
    qcom,sde-inline-rot-xin = <10 11>;
    qcom,sde-inline-rot-xin-type = "sspp", "wb";
    qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>;

    qcom,platform-supply-entries {
       #address-cells = <1>;
+99 −1
Original line number Diff line number Diff line
@@ -300,6 +300,13 @@ enum {
	REG_DMA_PROP_MAX
};

enum {
	INLINE_ROT_XIN,
	INLINE_ROT_XIN_TYPE,
	INLINE_ROT_CLK_CTRL,
	INLINE_ROT_PROP_MAX
};

/*************************************************************
 * dts property definition
 *************************************************************/
@@ -542,6 +549,15 @@ static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = {
		PROP_TYPE_U32},
};

static struct sde_prop_type inline_rot_prop[INLINE_ROT_PROP_MAX] = {
	{INLINE_ROT_XIN, "qcom,sde-inline-rot-xin", false,
							PROP_TYPE_U32_ARRAY},
	{INLINE_ROT_XIN_TYPE, "qcom,sde-inline-rot-xin-type", false,
							PROP_TYPE_STRING_ARRAY},
	{INLINE_ROT_CLK_CTRL, "qcom,sde-inline-rot-clk-ctrl", false,
						PROP_TYPE_BIT_OFFSET_ARRAY},
};

/*************************************************************
 * static API list
 *************************************************************/
@@ -1644,6 +1660,87 @@ static void _sde_dspp_setup_blocks(struct sde_mdss_cfg *sde_cfg,
	}
}

static void _sde_inline_rot_parse_dt(struct device_node *np,
		struct sde_mdss_cfg *sde_cfg, struct sde_rot_cfg *rot)
{
	int rc, prop_count[INLINE_ROT_PROP_MAX], i, j, index;
	struct sde_prop_value *prop_value = NULL;
	bool prop_exists[INLINE_ROT_PROP_MAX];
	u32 off_count, sspp_count = 0, wb_count = 0;
	const char *type;

	prop_value = kzalloc(INLINE_ROT_PROP_MAX *
			sizeof(struct sde_prop_value), GFP_KERNEL);
	if (!prop_value)
		return;

	rc = _validate_dt_entry(np, inline_rot_prop,
			ARRAY_SIZE(inline_rot_prop), prop_count, &off_count);
	if (rc)
		goto end;

	rc = _read_dt_entry(np, inline_rot_prop, ARRAY_SIZE(inline_rot_prop),
			prop_count, prop_exists, prop_value);
	if (rc)
		goto end;

	for (i = 0; i < off_count; i++) {
		rot->vbif_cfg[i].xin_id = PROP_VALUE_ACCESS(prop_value,
							INLINE_ROT_XIN, i);
		of_property_read_string_index(np,
				inline_rot_prop[INLINE_ROT_XIN_TYPE].prop_name,
				i, &type);

		if (!strcmp(type, "sspp")) {
			rot->vbif_cfg[i].num = INLINE_ROT0_SSPP + sspp_count;
			rot->vbif_cfg[i].is_read = true;
			rot->vbif_cfg[i].clk_ctrl =
					SDE_CLK_CTRL_INLINE_ROT0_SSPP
					+ sspp_count;
			sspp_count++;
		} else if (!strcmp(type, "wb")) {
			rot->vbif_cfg[i].num = INLINE_ROT0_WB + wb_count;
			rot->vbif_cfg[i].is_read = false;
			rot->vbif_cfg[i].clk_ctrl =
					SDE_CLK_CTRL_INLINE_ROT0_WB
					+ wb_count;
			wb_count++;
		} else {
			SDE_ERROR("invalid rotator vbif type:%s\n", type);
			goto end;
		}

		index = rot->vbif_cfg[i].clk_ctrl;
		if (index < 0 || index >= SDE_CLK_CTRL_MAX) {
			SDE_ERROR("invalid clk_ctrl enum:%d\n", index);
			goto end;
		}

		for (j = 0; j < sde_cfg->mdp_count; j++) {
			sde_cfg->mdp[j].clk_ctrls[index].reg_off =
				PROP_BITVALUE_ACCESS(prop_value,
						INLINE_ROT_CLK_CTRL, i, 0);
			sde_cfg->mdp[j].clk_ctrls[index].bit_off =
				PROP_BITVALUE_ACCESS(prop_value,
						INLINE_ROT_CLK_CTRL, i, 1);
		}

		SDE_DEBUG("rot- xin:%d, num:%d, rd:%d, clk:%d:0x%x/%d\n",
				rot->vbif_cfg[i].xin_id,
				rot->vbif_cfg[i].num,
				rot->vbif_cfg[i].is_read,
				rot->vbif_cfg[i].clk_ctrl,
				sde_cfg->mdp[0].clk_ctrls[index].reg_off,
				sde_cfg->mdp[0].clk_ctrls[index].bit_off);
	}

	rot->vbif_idx = VBIF_RT;
	rot->xin_count = off_count;

end:
	kfree(prop_value);
}

static int sde_rot_parse_dt(struct device_node *np,
		struct sde_mdss_cfg *sde_cfg)
{
@@ -1689,10 +1786,11 @@ static int sde_rot_parse_dt(struct device_node *np,
				rot->slice_size = llcc_get_slice_size(slice);
				rot->pdev = pdev;
				llcc_slice_putd(slice);
				sde_cfg->rot_count++;
				SDE_DEBUG("rot:%d scid:%d slice_size:%zukb\n",
						rot->id, rot->scid,
						rot->slice_size);
				_sde_inline_rot_parse_dt(np, sde_cfg, rot);
				sde_cfg->rot_count++;
			}
		} else {
			rot->pdev = NULL;
+23 −0
Original line number Diff line number Diff line
@@ -486,6 +486,8 @@ enum sde_clk_ctrl_type {
	SDE_CLK_CTRL_WB0,
	SDE_CLK_CTRL_WB1,
	SDE_CLK_CTRL_WB2,
	SDE_CLK_CTRL_INLINE_ROT0_SSPP,
	SDE_CLK_CTRL_INLINE_ROT0_WB,
	SDE_CLK_CTRL_MAX,
};

@@ -645,6 +647,20 @@ struct sde_wb_cfg {
	enum sde_clk_ctrl_type clk_ctrl;
};

/**
 * struct sde_rot_vbif_cfg - inline rotator vbif configs
 * @xin_id             xin client id
 * @num                enum identifying this block
 * @is_read            indicates read/write client
 * @clk_ctrl           index to clk control
 */
struct sde_rot_vbif_cfg {
	u32 xin_id;
	u32 num;
	bool is_read;
	enum sde_clk_ctrl_type clk_ctrl;
};

/**
 * struct sde_rot_cfg - information of rotator blocks
 * @id                 enum identifying this block
@@ -654,12 +670,19 @@ struct sde_wb_cfg {
 * @pdev               private device handle
 * @scid               subcache identifier
 * @slice_size         subcache slice size
 * @vbif_idx           vbif identifier
 * @xin_count          number of xin clients
 * @vbif_cfg           vbif settings related to rotator
 */
struct sde_rot_cfg {
	SDE_HW_BLK_INFO;
	void *pdev;
	int scid;
	size_t slice_size;
	u32 vbif_idx;

	u32 xin_count;
	struct sde_rot_vbif_cfg vbif_cfg[MAX_BLOCKS];
};

/**
+7 −0
Original line number Diff line number Diff line
@@ -283,6 +283,13 @@ enum sde_rot {
	ROT_MAX
};

enum sde_inline_rot {
	INLINE_ROT_NONE,
	INLINE_ROT0_SSPP,
	INLINE_ROT0_WB,
	INLINE_ROT_MAX
};

/**
 * SDE HW,Component order color map
 */
+105 −2
Original line number Diff line number Diff line
@@ -627,10 +627,11 @@ static void _sde_plane_set_qos_remap(struct drm_plane *plane)
	qos_params.num = psde->pipe_hw->idx - SSPP_VIG0;
	qos_params.is_rt = psde->is_rt_pipe;

	SDE_DEBUG("plane%d pipe:%d vbif:%d xin:%d rt:%d\n",
	SDE_DEBUG("plane%d pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
			plane->base.id, qos_params.num,
			qos_params.vbif_idx,
			qos_params.xin_id, qos_params.is_rt);
			qos_params.xin_id, qos_params.is_rt,
			qos_params.clk_ctrl);

	sde_vbif_set_qos_remap(sde_kms, &qos_params);
}
@@ -704,6 +705,90 @@ static void _sde_plane_set_input_fence(struct sde_plane *psde,
	SDE_DEBUG_PLANE(psde, "0x%llX\n", fd);
}

/**
 * _sde_plane_inline_rot_set_ot_limit - set OT limit for the given inline
 * rotation xin client
 * @plane: pointer to drm plane
 * @crtc: pointer to drm crtc
 * @cfg: pointer to rotator vbif config
 * @rect_w: rotator frame width
 * @rect_h: rotator frame height
 */
static void _sde_plane_inline_rot_set_ot_limit(struct drm_plane *plane,
		struct drm_crtc *crtc, const struct sde_rot_vbif_cfg *cfg,
		u32 rect_w, u32 rect_h)
{
	struct sde_vbif_set_ot_params ot_params;
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;

	if (!plane || !plane->dev) {
		SDE_ERROR("invalid arguments\n");
		return;
	}

	priv = plane->dev->dev_private;
	if (!priv || !priv->kms) {
		SDE_ERROR("invalid KMS reference\n");
		return;
	}

	sde_kms = to_sde_kms(priv->kms);

	memset(&ot_params, 0, sizeof(ot_params));
	ot_params.xin_id = cfg->xin_id;
	ot_params.num = cfg->num;
	ot_params.width = rect_w;
	ot_params.height = rect_h;
	ot_params.is_wfd = false;
	ot_params.frame_rate = crtc->mode.vrefresh;
	ot_params.vbif_idx = VBIF_RT;
	ot_params.clk_ctrl = cfg->clk_ctrl;
	ot_params.rd = cfg->is_read;

	sde_vbif_set_ot_limit(sde_kms, &ot_params);
}

/**
 * _sde_plane_inline_rot_set_qos_remap - set vbif QoS for the given inline
 * rotation xin client
 * @plane: Pointer to drm plane
 * @cfg: Pointer to rotator vbif cfg
 */
static void _sde_plane_inline_rot_set_qos_remap(struct drm_plane *plane,
		const struct sde_rot_vbif_cfg *cfg)
{
	struct sde_vbif_set_qos_params qos_params;
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;

	if (!plane || !plane->dev) {
		SDE_ERROR("invalid arguments\n");
		return;
	}

	priv = plane->dev->dev_private;
	if (!priv || !priv->kms) {
		SDE_ERROR("invalid KMS reference\n");
		return;
	}

	sde_kms = to_sde_kms(priv->kms);

	memset(&qos_params, 0, sizeof(qos_params));
	qos_params.vbif_idx = VBIF_RT;
	qos_params.xin_id = cfg->xin_id;
	qos_params.clk_ctrl = cfg->clk_ctrl;
	qos_params.num = cfg->num;
	qos_params.is_rt = true;

	SDE_DEBUG("vbif:%d xin:%d num:%d rt:%d clk_ctrl:%d\n",
			qos_params.vbif_idx, qos_params.xin_id,
			qos_params.num, qos_params.is_rt, qos_params.clk_ctrl);

	sde_vbif_set_qos_remap(sde_kms, &qos_params);
}

int sde_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms)
{
	struct sde_plane *psde;
@@ -1695,6 +1780,24 @@ static int sde_plane_rot_submit_command(struct drm_plane *plane,
			rot_cmd->dst_len[i] = layout.plane_size[i];
		}
		rot_cmd->dst_planes = layout.num_planes;

		/* VBIF remapper settings */
		for (i = 0; rstate->rot_hw->caps->xin_count; i++) {
			const struct sde_rot_vbif_cfg *cfg =
					&rstate->rot_hw->caps->vbif_cfg[i];

			_sde_plane_inline_rot_set_qos_remap(plane, cfg);

			if (cfg->is_read) {
				_sde_plane_inline_rot_set_ot_limit(plane,
					state->crtc, cfg, rot_cmd->src_rect_w,
					rot_cmd->src_rect_h);
			} else {
				_sde_plane_inline_rot_set_ot_limit(plane,
					state->crtc, cfg, rot_cmd->dst_rect_w,
					rot_cmd->dst_rect_h);
			}
		}
	}

	ret = rstate->rot_hw->ops.commit(rstate->rot_hw, rot_cmd, hw_cmd);