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

Commit 1d95f2e5 authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

drm/msm/sde: add CWB and LUTDMA VBIF remap setting



Add parsing logic and configuring logic in SDE driver
for setting the CWB and LUTDMA VBIF remapper configuration.

Change-Id: I08f209e8583d4749c052a1ae54e3b702d63a7b86
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 08c90a00
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -139,12 +139,13 @@ static void sde_encoder_phys_wb_set_qos_remap(
	qos_params.xin_id = hw_wb->caps->xin_id;
	qos_params.clk_ctrl = hw_wb->caps->clk_ctrl;
	qos_params.num = hw_wb->idx - WB_0;
	qos_params.is_rt = sde_crtc_get_client_type(crtc) != NRT_CLIENT;
	qos_params.client_type = phys_enc->in_clone_mode ?
					VBIF_CWB_CLIENT : VBIF_NRT_CLIENT;

	SDE_DEBUG("[qos_remap] wb:%d vbif:%d xin:%d rt:%d\n",
	SDE_DEBUG("[qos_remap] wb:%d vbif:%d xin:%d rt:%d clone:%d\n",
			qos_params.num,
			qos_params.vbif_idx,
			qos_params.xin_id, qos_params.is_rt);
			qos_params.xin_id, qos_params.client_type);

	sde_vbif_set_qos_remap(phys_enc->sde_kms, &qos_params);
}
+109 −94
Original line number Diff line number Diff line
@@ -379,10 +379,12 @@ enum {
	VBIF_DEFAULT_OT_WR_LIMIT,
	VBIF_DYNAMIC_OT_RD_LIMIT,
	VBIF_DYNAMIC_OT_WR_LIMIT,
	VBIF_QOS_RT_REMAP,
	VBIF_QOS_NRT_REMAP,
	VBIF_MEMTYPE_0,
	VBIF_MEMTYPE_1,
	VBIF_QOS_RT_REMAP,
	VBIF_QOS_NRT_REMAP,
	VBIF_QOS_CWB_REMAP,
	VBIF_QOS_LUTDMA_REMAP,
	VBIF_PROP_MAX,
};

@@ -397,6 +399,8 @@ enum {
	REG_DMA_VERSION,
	REG_DMA_TRIGGER_OFF,
	REG_DMA_BROADCAST_DISABLED,
	REG_DMA_XIN_ID,
	REG_DMA_CLK_CTRL,
	REG_DMA_PROP_MAX
};

@@ -698,12 +702,16 @@ static struct sde_prop_type vbif_prop[] = {
		PROP_TYPE_U32_ARRAY},
	{VBIF_DYNAMIC_OT_WR_LIMIT, "qcom,sde-vbif-dynamic-ot-wr-limit", false,
		PROP_TYPE_U32_ARRAY},
	{VBIF_MEMTYPE_0, "qcom,sde-vbif-memtype-0", false, PROP_TYPE_U32_ARRAY},
	{VBIF_MEMTYPE_1, "qcom,sde-vbif-memtype-1", false, PROP_TYPE_U32_ARRAY},
	{VBIF_QOS_RT_REMAP, "qcom,sde-vbif-qos-rt-remap", false,
		PROP_TYPE_U32_ARRAY},
	{VBIF_QOS_NRT_REMAP, "qcom,sde-vbif-qos-nrt-remap", false,
		PROP_TYPE_U32_ARRAY},
	{VBIF_MEMTYPE_0, "qcom,sde-vbif-memtype-0", false, PROP_TYPE_U32_ARRAY},
	{VBIF_MEMTYPE_1, "qcom,sde-vbif-memtype-1", false, PROP_TYPE_U32_ARRAY},
	{VBIF_QOS_CWB_REMAP, "qcom,sde-vbif-qos-cwb-remap", false,
		PROP_TYPE_U32_ARRAY},
	{VBIF_QOS_LUTDMA_REMAP, "qcom,sde-vbif-qos-lutdma-remap", false,
		PROP_TYPE_U32_ARRAY},
};

static struct sde_prop_type uidle_prop[] = {
@@ -721,6 +729,10 @@ static struct sde_prop_type reg_dma_prop[REG_DMA_PROP_MAX] = {
		PROP_TYPE_U32},
	[REG_DMA_BROADCAST_DISABLED] = {REG_DMA_BROADCAST_DISABLED,
		"qcom,sde-reg-dma-broadcast-disabled", false, PROP_TYPE_BOOL},
	[REG_DMA_XIN_ID] = {REG_DMA_XIN_ID,
		"qcom,sde-reg-dma-xin-id", false, PROP_TYPE_U32},
	[REG_DMA_CLK_CTRL] = {REG_DMA_XIN_ID,
		"qcom,sde-reg-dma-clk-ctrl", false, PROP_TYPE_BIT_OFFSET_ARRAY},
};

static struct sde_prop_type merge_3d_prop[] = {
@@ -2692,60 +2704,40 @@ static int _sde_vbif_populate_qos_parsing(struct sde_mdss_cfg *sde_cfg,
	struct sde_vbif_cfg *vbif, struct sde_prop_value *prop_value,
	int *prop_count)
{
	int j;

	vbif->qos_rt_tbl.npriority_lvl =
			prop_count[VBIF_QOS_RT_REMAP];
	SDE_DEBUG("qos_rt_tbl.npriority_lvl=%u\n",
			vbif->qos_rt_tbl.npriority_lvl);
	if (vbif->qos_rt_tbl.npriority_lvl == sde_cfg->vbif_qos_nlvl) {
		vbif->qos_rt_tbl.priority_lvl = kcalloc(
			vbif->qos_rt_tbl.npriority_lvl, sizeof(u32),
			GFP_KERNEL);
		if (!vbif->qos_rt_tbl.priority_lvl)
			return -ENOMEM;
	} else if (vbif->qos_rt_tbl.npriority_lvl) {
		vbif->qos_rt_tbl.npriority_lvl = 0;
		vbif->qos_rt_tbl.priority_lvl = NULL;
		SDE_ERROR("invalid qos rt table\n");
	}

	for (j = 0; j < vbif->qos_rt_tbl.npriority_lvl; j++) {
		vbif->qos_rt_tbl.priority_lvl[j] =
			PROP_VALUE_ACCESS(prop_value,
					VBIF_QOS_RT_REMAP, j);
		SDE_DEBUG("lvl[%d]=%u\n", j,
				vbif->qos_rt_tbl.priority_lvl[j]);
	}

	vbif->qos_nrt_tbl.npriority_lvl =
			prop_count[VBIF_QOS_NRT_REMAP];
	SDE_DEBUG("qos_nrt_tbl.npriority_lvl=%u\n",
			vbif->qos_nrt_tbl.npriority_lvl);

	if (vbif->qos_nrt_tbl.npriority_lvl == sde_cfg->vbif_qos_nlvl) {
		vbif->qos_nrt_tbl.priority_lvl = kcalloc(
			vbif->qos_nrt_tbl.npriority_lvl, sizeof(u32),
			GFP_KERNEL);
		if (!vbif->qos_nrt_tbl.priority_lvl)
	int i, j;
	int prop_index = VBIF_QOS_RT_REMAP;

	for (i = VBIF_RT_CLIENT;
			((i < VBIF_MAX_CLIENT) && (prop_index < VBIF_PROP_MAX));
				i++, prop_index++) {
		vbif->qos_tbl[i].npriority_lvl = prop_count[prop_index];
		SDE_DEBUG("qos_tbl[%d].npriority_lvl=%u\n",
				i, vbif->qos_tbl[i].npriority_lvl);

		if (vbif->qos_tbl[i].npriority_lvl == sde_cfg->vbif_qos_nlvl) {
			vbif->qos_tbl[i].priority_lvl = kcalloc(
					vbif->qos_tbl[i].npriority_lvl,
					sizeof(u32), GFP_KERNEL);
			if (!vbif->qos_tbl[i].priority_lvl)
				return -ENOMEM;
	} else if (vbif->qos_nrt_tbl.npriority_lvl) {
		vbif->qos_nrt_tbl.npriority_lvl = 0;
		vbif->qos_nrt_tbl.priority_lvl = NULL;
		SDE_ERROR("invalid qos nrt table\n");
		} else if (vbif->qos_tbl[i].npriority_lvl) {
			vbif->qos_tbl[i].npriority_lvl = 0;
			vbif->qos_tbl[i].priority_lvl = NULL;
			SDE_ERROR("invalid qos table for client:%d, prop:%d\n",
					i, prop_index);
		}

	for (j = 0; j < vbif->qos_nrt_tbl.npriority_lvl; j++) {
		vbif->qos_nrt_tbl.priority_lvl[j] =
			PROP_VALUE_ACCESS(prop_value,
					VBIF_QOS_NRT_REMAP, j);
		SDE_DEBUG("lvl[%d]=%u\n", j,
				vbif->qos_nrt_tbl.priority_lvl[j]);
		for (j = 0; j < vbif->qos_tbl[i].npriority_lvl; j++) {
			vbif->qos_tbl[i].priority_lvl[j] =
				PROP_VALUE_ACCESS(prop_value, prop_index, j);
			SDE_DEBUG("client:%d, prop:%d, lvl[%d]=%u\n",
					i, prop_index, j,
					vbif->qos_tbl[i].priority_lvl[j]);
		}

	if (vbif->qos_rt_tbl.npriority_lvl ||
			vbif->qos_nrt_tbl.npriority_lvl)
		if (vbif->qos_tbl[i].npriority_lvl)
			set_bit(SDE_VBIF_QOS_REMAP, &vbif->features);
	}

	return 0;
}
@@ -2829,6 +2821,16 @@ static int sde_vbif_parse_dt(struct device_node *np,
	if (rc)
		goto end;

	rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1,
			&prop_count[VBIF_MEMTYPE_0], NULL);
	if (rc)
		goto end;

	rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1,
			&prop_count[VBIF_MEMTYPE_1], NULL);
	if (rc)
		goto end;

	rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_RT_REMAP], 1,
			&prop_count[VBIF_QOS_RT_REMAP], NULL);
	if (rc)
@@ -2839,13 +2841,13 @@ static int sde_vbif_parse_dt(struct device_node *np,
	if (rc)
		goto end;

	rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_0], 1,
			&prop_count[VBIF_MEMTYPE_0], NULL);
	rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_CWB_REMAP], 1,
			&prop_count[VBIF_QOS_CWB_REMAP], NULL);
	if (rc)
		goto end;

	rc = _validate_dt_entry(np, &vbif_prop[VBIF_MEMTYPE_1], 1,
			&prop_count[VBIF_MEMTYPE_1], NULL);
	rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_LUTDMA_REMAP], 1,
			&prop_count[VBIF_QOS_LUTDMA_REMAP], NULL);
	if (rc)
		goto end;

@@ -3152,40 +3154,52 @@ static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
static int sde_parse_reg_dma_dt(struct device_node *np,
		struct sde_mdss_cfg *sde_cfg)
{
	u32 val;
	int rc = 0;
	int i = 0;
	int rc = 0, i, prop_count[REG_DMA_PROP_MAX];
	struct sde_prop_value *prop_value = NULL;
	u32 off_count;
	bool prop_exists[REG_DMA_PROP_MAX];

	sde_cfg->reg_dma_count = 0;
	for (i = 0; i < REG_DMA_PROP_MAX; i++) {
		if (reg_dma_prop[i].type == PROP_TYPE_BOOL) {
			val = of_property_read_bool(np,
					reg_dma_prop[i].prop_name);
		} else {
			rc = of_property_read_u32(np, reg_dma_prop[i].prop_name,
					&val);
			if (rc)
				break;
		}
		switch (i) {
		case REG_DMA_OFF:
			sde_cfg->dma_cfg.base = val;
			break;
		case REG_DMA_VERSION:
			sde_cfg->dma_cfg.version = val;
			break;
		case REG_DMA_TRIGGER_OFF:
			sde_cfg->dma_cfg.trigger_sel_off = val;
			break;
		case REG_DMA_BROADCAST_DISABLED:
			sde_cfg->dma_cfg.broadcast_disabled = val;
			break;
		default:
			break;
	prop_value = kcalloc(REG_DMA_PROP_MAX,
			sizeof(struct sde_prop_value), GFP_KERNEL);
	if (!prop_value) {
		rc = -ENOMEM;
		goto end;
	}

	rc = _validate_dt_entry(np, reg_dma_prop, ARRAY_SIZE(reg_dma_prop),
			prop_count, &off_count);
	if (rc || !off_count)
		goto end;

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

	sde_cfg->reg_dma_count = off_count;
	sde_cfg->dma_cfg.base = PROP_VALUE_ACCESS(prop_value, REG_DMA_OFF, 0);
	sde_cfg->dma_cfg.version = PROP_VALUE_ACCESS(prop_value,
						REG_DMA_VERSION, 0);
	sde_cfg->dma_cfg.trigger_sel_off = PROP_VALUE_ACCESS(prop_value,
						REG_DMA_TRIGGER_OFF, 0);
	sde_cfg->dma_cfg.broadcast_disabled = PROP_VALUE_ACCESS(prop_value,
						REG_DMA_BROADCAST_DISABLED, 0);
	sde_cfg->dma_cfg.xin_id = PROP_VALUE_ACCESS(prop_value,
						REG_DMA_XIN_ID, 0);
	sde_cfg->dma_cfg.clk_ctrl = SDE_CLK_CTRL_LUTDMA;
	sde_cfg->dma_cfg.vbif_idx = VBIF_RT;

	for (i = 0; i < sde_cfg->mdp_count; i++) {
		sde_cfg->mdp[i].clk_ctrls[sde_cfg->dma_cfg.clk_ctrl].reg_off =
			PROP_BITVALUE_ACCESS(prop_value,
					REG_DMA_CLK_CTRL, 0, 0);
		sde_cfg->mdp[i].clk_ctrls[sde_cfg->dma_cfg.clk_ctrl].bit_off =
			PROP_BITVALUE_ACCESS(prop_value,
					REG_DMA_CLK_CTRL, 0, 1);
	}
	if (!rc && i == REG_DMA_PROP_MAX)
		sde_cfg->reg_dma_count = 1;

end:
	kfree(prop_value);
	/* reg dma is optional feature hence return 0 */
	return 0;
}
@@ -3914,7 +3928,7 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg,

void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
{
	int i;
	int i, j;

	if (!sde_cfg)
		return;
@@ -3940,8 +3954,9 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg)
	for (i = 0; i < sde_cfg->vbif_count; i++) {
		kfree(sde_cfg->vbif[i].dynamic_ot_rd_tbl.cfg);
		kfree(sde_cfg->vbif[i].dynamic_ot_wr_tbl.cfg);
		kfree(sde_cfg->vbif[i].qos_rt_tbl.priority_lvl);
		kfree(sde_cfg->vbif[i].qos_nrt_tbl.priority_lvl);

		for (j = VBIF_RT_CLIENT; j < VBIF_MAX_CLIENT; j++)
			kfree(sde_cfg->vbif[i].qos_tbl[j].priority_lvl);
	}

	for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++)
+25 −4
Original line number Diff line number Diff line
@@ -705,6 +705,7 @@ enum sde_clk_ctrl_type {
	SDE_CLK_CTRL_WB0,
	SDE_CLK_CTRL_WB1,
	SDE_CLK_CTRL_WB2,
	SDE_CLK_CTRL_LUTDMA,
	SDE_CLK_CTRL_MAX,
};

@@ -997,6 +998,22 @@ struct sde_vbif_qos_tbl {
	u32 *priority_lvl;
};

/**
 * enum sde_vbif_client_type
 * @VBIF_RT_CLIENT: real time client
 * @VBIF_NRT_CLIENT: non-realtime clients like writeback
 * @VBIF_CWB_CLIENT: concurrent writeback client
 * @VBIF_LUTDMA_CLIENT: LUTDMA client
 * @VBIF_MAX_CLIENT: max number of clients
 */
enum sde_vbif_client_type {
	VBIF_RT_CLIENT,
	VBIF_NRT_CLIENT,
	VBIF_CWB_CLIENT,
	VBIF_LUTDMA_CLIENT,
	VBIF_MAX_CLIENT
};

/**
 * struct sde_vbif_cfg - information of VBIF blocks
 * @id                 enum identifying this block
@@ -1007,8 +1024,7 @@ struct sde_vbif_qos_tbl {
 * @xin_halt_timeout   maximum time (in usec) for xin to halt
 * @dynamic_ot_rd_tbl  dynamic OT read configuration table
 * @dynamic_ot_wr_tbl  dynamic OT write configuration table
 * @qos_rt_tbl         real-time QoS priority table
 * @qos_nrt_tbl        non-real-time QoS priority table
 * @qos_tbl            Array of QoS priority table
 * @memtype_count      number of defined memtypes
 * @memtype            array of xin memtype definitions
 */
@@ -1019,8 +1035,7 @@ struct sde_vbif_cfg {
	u32 xin_halt_timeout;
	struct sde_vbif_dynamic_ot_tbl dynamic_ot_rd_tbl;
	struct sde_vbif_dynamic_ot_tbl dynamic_ot_wr_tbl;
	struct sde_vbif_qos_tbl qos_rt_tbl;
	struct sde_vbif_qos_tbl qos_nrt_tbl;
	struct sde_vbif_qos_tbl qos_tbl[VBIF_MAX_CLIENT];
	u32 memtype_count;
	u32 memtype[MAX_XIN_COUNT];
};
@@ -1032,12 +1047,18 @@ struct sde_vbif_cfg {
 * @version            version of lutdma hw block
 * @trigger_sel_off    offset to trigger select registers of lutdma
 * @broadcast_disabled flag indicating if broadcast usage should be avoided
 * @xin_id             VBIF xin client-id for LUTDMA
 * @vbif_idx           VBIF id (RT/NRT)
 * @clk_ctrl           VBIF xin client clk-ctrl
 */
struct sde_reg_dma_cfg {
	SDE_HW_BLK_INFO;
	u32 version;
	u32 trigger_sel_off;
	u32 broadcast_disabled;
	u32 xin_id;
	u32 vbif_idx;
	enum sde_clk_ctrl_type clk_ctrl;
};

/**
+20 −0
Original line number Diff line number Diff line
@@ -3014,6 +3014,25 @@ static void sde_kms_init_shared_hw(struct sde_kms *sde_kms)
	sde_hw_sid_rotator_set(sde_kms->hw_sid);
}

static void _sde_kms_set_lutdma_vbif_remap(struct sde_kms *sde_kms)
{
	struct sde_vbif_set_qos_params qos_params;
	struct sde_mdss_cfg *catalog;

	if (!sde_kms->catalog)
		return;

	catalog = sde_kms->catalog;

	memset(&qos_params, 0, sizeof(qos_params));
	qos_params.vbif_idx = catalog->dma_cfg.vbif_idx;
	qos_params.xin_id = catalog->dma_cfg.xin_id;
	qos_params.clk_ctrl = catalog->dma_cfg.clk_ctrl;
	qos_params.client_type = VBIF_LUTDMA_CLIENT;

	sde_vbif_set_qos_remap(sde_kms, &qos_params);
}

static void sde_kms_handle_power_event(u32 event_type, void *usr)
{
	struct sde_kms *sde_kms = usr;
@@ -3030,6 +3049,7 @@ static void sde_kms_handle_power_event(u32 event_type, void *usr)
		sde_irq_update(msm_kms, true);
		sde_vbif_init_memtypes(sde_kms);
		sde_kms_init_shared_hw(sde_kms);
		_sde_kms_set_lutdma_vbif_remap(sde_kms);
		sde_kms->first_kickoff = true;
	} else if (event_type == SDE_POWER_EVENT_PRE_DISABLE) {
		sde_irq_update(msm_kms, false);
+3 −2
Original line number Diff line number Diff line
@@ -670,12 +670,13 @@ static void _sde_plane_set_qos_remap(struct drm_plane *plane)
	qos_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl;
	qos_params.xin_id = psde->pipe_hw->cap->xin_id;
	qos_params.num = psde->pipe_hw->idx - SSPP_VIG0;
	qos_params.is_rt = psde->is_rt_pipe;
	qos_params.client_type = psde->is_rt_pipe ?
					VBIF_RT_CLIENT : VBIF_NRT_CLIENT;

	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.client_type,
			qos_params.clk_ctrl);

	sde_vbif_set_qos_remap(sde_kms, &qos_params);
Loading