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

Commit c823bc6d authored by Ghanim Fodi's avatar Ghanim Fodi
Browse files

msm: ipa3: Add support to configure dynamic MHI event ring IDs



MHI event ring IDs are chosen from a pre-defined range. This
range may differ among different devices. This change uses
a range defined through device tree property instead
of being hard coded.

Change-Id: I51ff26398d6a38197042b0939f77b96f94076185
CRs-fixed: 2073043
Signed-off-by: default avatarSkylar Chang <chiaweic@codeaurora.org>
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
parent 0620a466
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ memory allocation over a PCIe bridge
- qcom,rx-polling-sleep-ms:	Receive Polling Timeout in millisecond,
				default is 1 millisecond.
- qcom,ipa-polling-iteration:	IPA Polling Iteration Count,default is 40.
- qcom,mhi-event-ring-id-limits: Two elements property. Start and End limits
					for MHI event rings ids.
- qcom,ipa-tz-unlock-reg:       Register start addresses and ranges which
                                need to be unlocked by TZ.

+18 −7
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@
#define GSI_CMD_TIMEOUT (5*HZ)
#define GSI_STOP_CMD_TIMEOUT_MS 20
#define GSI_MAX_CH_LOW_WEIGHT 15
#define GSI_MHI_ER_START 10
#define GSI_MHI_ER_END 16

#define GSI_RESET_WA_MIN_SLEEP 1000
#define GSI_RESET_WA_MAX_SLEEP 2000
@@ -829,10 +827,23 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl)
		return -GSI_STATUS_ERROR;
	}

	/* bitmap is max events excludes reserved events */
	if (props->mhi_er_id_limits_valid &&
	    props->mhi_er_id_limits[0] > (gsi_ctx->max_ev - 1)) {
		devm_iounmap(gsi_ctx->dev, gsi_ctx->base);
		gsi_ctx->base = NULL;
		devm_free_irq(gsi_ctx->dev, props->irq, gsi_ctx);
		GSIERR("MHI event ring start id %u is beyond max %u\n",
			props->mhi_er_id_limits[0], gsi_ctx->max_ev);
		return -GSI_STATUS_ERROR;
	}

	gsi_ctx->evt_bmap = ~((1 << gsi_ctx->max_ev) - 1);
	gsi_ctx->evt_bmap |= ((1 << (GSI_MHI_ER_END + 1)) - 1) ^
		((1 << GSI_MHI_ER_START) - 1);

	/* exclude reserved mhi events */
	if (props->mhi_er_id_limits_valid)
		gsi_ctx->evt_bmap |=
			((1 << (props->mhi_er_id_limits[1] + 1)) - 1) ^
			((1 << (props->mhi_er_id_limits[0])) - 1);

	/*
	 * enable all interrupts but GSI_BREAK_POINT.
@@ -1084,8 +1095,8 @@ static int gsi_validate_evt_ring_props(struct gsi_evt_ring_props *props)

	if (props->intf == GSI_EVT_CHTYPE_MHI_EV &&
			(!props->evchid_valid ||
			props->evchid > GSI_MHI_ER_END ||
			props->evchid < GSI_MHI_ER_START)) {
			props->evchid > gsi_ctx->per.mhi_er_id_limits[1] ||
			props->evchid < gsi_ctx->per.mhi_er_id_limits[0])) {
		GSIERR("MHI requires evchid valid=%d val=%u\n",
				props->evchid_valid, props->evchid);
		return -GSI_STATUS_INVALID_PARAMS;
+1 −7
Original line number Diff line number Diff line
@@ -41,11 +41,6 @@
#define IPA_MHI_MAX_UL_CHANNELS 1
#define IPA_MHI_MAX_DL_CHANNELS 1

#if (IPA_MHI_MAX_UL_CHANNELS + IPA_MHI_MAX_DL_CHANNELS) > \
	(IPA_MHI_GSI_ER_END - IPA_MHI_GSI_ER_START)
#error not enought event rings for MHI
#endif

/* bit #40 in address should be asserted for MHI transfers over pcie */
#define IPA_MHI_CLIENT_HOST_ADDR_COND(addr) \
	((ipa_mhi_client_ctx->assert_bit40)?(IPA_MHI_HOST_ADDR(addr)):(addr))
@@ -1574,8 +1569,7 @@ int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, u32 *clnt_hdl)
		internal.start.gsi.mhi = &channel->ch_scratch.mhi;
		internal.start.gsi.cached_gsi_evt_ring_hdl =
				&channel->cached_gsi_evt_ring_hdl;
		internal.start.gsi.evchid =
				channel->index + IPA_MHI_GSI_ER_START;
		internal.start.gsi.evchid = channel->index;

		res = ipa_connect_mhi_pipe(&internal, clnt_hdl);
		if (res) {
+0 −3
Original line number Diff line number Diff line
@@ -145,9 +145,6 @@ struct ipa_mem_buffer {
	u32 size;
};

#define IPA_MHI_GSI_ER_START 10
#define IPA_MHI_GSI_ER_END 16

/**
 * enum ipa3_mhi_burst_mode - MHI channel burst mode state
 *
+42 −0
Original line number Diff line number Diff line
@@ -86,6 +86,9 @@
#define IPA3_ACTIVE_CLIENT_LOG_TYPE_RESOURCE 2
#define IPA3_ACTIVE_CLIENT_LOG_TYPE_SPECIAL 3

#define IPA_MHI_GSI_EVENT_RING_ID_START 10
#define IPA_MHI_GSI_EVENT_RING_ID_END 12

#define IPA_SMEM_SIZE (8 * 1024)

#define IPA_GSI_CHANNEL_HALT_MIN_SLEEP 5000
@@ -4286,6 +4289,12 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
	gsi_props.req_clk_cb = NULL;
	gsi_props.rel_clk_cb = NULL;

	if (ipa3_ctx->ipa_config_is_mhi) {
		gsi_props.mhi_er_id_limits_valid = true;
		gsi_props.mhi_er_id_limits[0] = resource_p->mhi_evid_limits[0];
		gsi_props.mhi_er_id_limits[1] = resource_p->mhi_evid_limits[1];
	}

	result = gsi_register_device(&gsi_props,
		&ipa3_ctx->gsi_dev_hdl);
	if (result != GSI_STATUS_SUCCESS) {
@@ -4667,6 +4676,8 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	ipa3_ctx->gsi_ch20_wa = resource_p->gsi_ch20_wa;
	ipa3_ctx->use_ipa_pm = resource_p->use_ipa_pm;
	ipa3_ctx->ipa3_active_clients_logging.log_rdy = false;
	ipa3_ctx->mhi_evid_limits[0] = resource_p->mhi_evid_limits[0];
	ipa3_ctx->mhi_evid_limits[1] = resource_p->mhi_evid_limits[1];
	if (resource_p->ipa_tz_unlock_reg) {
		ipa3_ctx->ipa_tz_unlock_reg_num =
			resource_p->ipa_tz_unlock_reg_num;
@@ -5240,6 +5251,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
	struct resource *resource;
	u32 *ipa_tz_unlock_reg;
	int elem_num;
	u32 mhi_evid_limits[2];

	/* initialize ipa3_res */
	ipa_drv_res->ipa_pipe_mem_start_ofst = IPA_PIPE_MEM_START_OFST;
@@ -5256,6 +5268,8 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
	ipa_drv_res->gsi_ch20_wa = false;
	ipa_drv_res->ipa_tz_unlock_reg_num = 0;
	ipa_drv_res->ipa_tz_unlock_reg = NULL;
	ipa_drv_res->mhi_evid_limits[0] = IPA_MHI_GSI_EVENT_RING_ID_START;
	ipa_drv_res->mhi_evid_limits[1] = IPA_MHI_GSI_EVENT_RING_ID_END;

	/* Get IPA HW Version */
	result = of_property_read_u32(pdev->dev.of_node, "qcom,ipa-hw-ver",
@@ -5431,6 +5445,34 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
		ipa_drv_res->apply_rg10_wa
		? "Needed" : "Not needed");

	elem_num = of_property_count_elems_of_size(pdev->dev.of_node,
		"qcom,mhi-event-ring-id-limits", sizeof(u32));

	if (elem_num == 2) {
		if (of_property_read_u32_array(pdev->dev.of_node,
			"qcom,mhi-event-ring-id-limits", mhi_evid_limits, 2)) {
			IPAERR("failed to read mhi event ring id limits\n");
			return -EFAULT;
		}
		if (mhi_evid_limits[0] > mhi_evid_limits[1]) {
			IPAERR("mhi event ring id low limit > high limit\n");
			return -EFAULT;
		}
		ipa_drv_res->mhi_evid_limits[0] = mhi_evid_limits[0];
		ipa_drv_res->mhi_evid_limits[1] = mhi_evid_limits[1];
		IPADBG(": mhi-event-ring-id-limits start=%u end=%u\n",
			mhi_evid_limits[0], mhi_evid_limits[1]);
	} else {
		if (elem_num > 0) {
			IPAERR("Invalid mhi event ring id limits number %d\n",
				elem_num);
			return -EINVAL;
		}
		IPADBG("use default mhi evt ring id limits start=%u end=%u\n",
			ipa_drv_res->mhi_evid_limits[0],
			ipa_drv_res->mhi_evid_limits[1]);
	}

	elem_num = of_property_count_elems_of_size(pdev->dev.of_node,
		"qcom,ipa-tz-unlock-reg", sizeof(u32));

Loading