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

Commit 95c3ec72 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ARM: dts: msm: enable WA for IPA channel 20 for msmcobalt"

parents 0c591911 bad1fe6c
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -65,7 +65,9 @@ memory allocation over a PCIe bridge
- qcom,use-rg10-limitation-mitigation:	Boolean context flag to activate
					the mitigation to register group 10
					AP access limitation

- qcom,do-not-use-ch-gsi-20:	Boolean context flag to activate
				software workaround for IPA limitation
				to not use GSI physical channel 20
- qcom,tethered-flow-control:   Boolean context flag to indicate whether
                                apps based flow control is needed for tethered
                                call.
+1 −0
Original line number Diff line number Diff line
@@ -827,6 +827,7 @@
		qcom,use-gsi;
		qcom,use-ipa-tethering-bridge;
		qcom,modem-cfg-emb-pipe-flt;
		qcom,do-not-use-ch-gsi-20;
		qcom,ipa-wdi2;
		clock-names = "core_clk";
		clocks = <&clock_gcc clk_ipa_clk>;
+18 −0
Original line number Diff line number Diff line
@@ -2634,6 +2634,15 @@ static int ipa3_setup_apps_pipes(void)
	struct ipa_sys_connect_params sys_in;
	int result = 0;

	if (ipa3_ctx->gsi_ch20_wa) {
		IPADBG("Allocating GSI physical channel 20\n");
		result = ipa_gsi_ch20_wa();
		if (result) {
			IPAERR("ipa_gsi_ch20_wa failed %d\n", result);
			goto fail_cmd;
		}
	}

	/* CMD OUT (AP->IPA) */
	memset(&sys_in, 0, sizeof(struct ipa_sys_connect_params));
	sys_in.client = IPA_CLIENT_APPS_CMD_PROD;
@@ -3986,6 +3995,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	ipa3_ctx->transport_prototype = resource_p->transport_prototype;
	ipa3_ctx->ee = resource_p->ee;
	ipa3_ctx->apply_rg10_wa = resource_p->apply_rg10_wa;
	ipa3_ctx->gsi_ch20_wa = resource_p->gsi_ch20_wa;
	ipa3_ctx->ipa3_active_clients_logging.log_rdy = false;

	/* default aggregation parameters */
@@ -4486,6 +4496,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
	ipa_drv_res->ipa_wdi2 = false;
	ipa_drv_res->wan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
	ipa_drv_res->apply_rg10_wa = false;
	ipa_drv_res->gsi_ch20_wa = false;

	smmu_disable_htw = of_property_read_bool(pdev->dev.of_node,
			"qcom,smmu-disable-htw");
@@ -4671,6 +4682,13 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
		ipa_drv_res->apply_rg10_wa
		? "True" : "False");

	ipa_drv_res->gsi_ch20_wa =
		of_property_read_bool(pdev->dev.of_node,
		"qcom,do-not-use-ch-gsi-20");
	IPADBG(": GSI CH 20 WA is = %s\n",
		ipa_drv_res->apply_rg10_wa
		? "Needed" : "Not needed");

	return 0;
}

+76 −1
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@
#define IPA_GSI_MAX_CH_LOW_WEIGHT 15
#define IPA_GSI_EVT_RING_INT_MODT 3200 /* 0.1s under 32KHz clock */

#define IPA_GSI_CH_20_WA_NUM_CH_TO_ALLOC 10
/* The below virtual channel cannot be used by any entity */
#define IPA_GSI_CH_20_WA_VIRT_CHAN 29

static struct sk_buff *ipa3_get_skb_ipa_rx(unsigned int len, gfp_t flags);
static void ipa3_replenish_wlan_rx_cache(struct ipa3_sys_context *sys);
static void ipa3_replenish_rx_cache(struct ipa3_sys_context *sys);
@@ -3597,7 +3601,6 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify)
	}
}


static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
	struct ipa3_ep_context *ep)
{
@@ -3891,3 +3894,75 @@ static uint64_t pointer_to_tag_wa(struct ipa3_tx_pkt_wrapper *tx_pkt)
	}
	return (unsigned long)tx_pkt & 0x0000FFFFFFFFFFFF;
}

/**
 * ipa_gsi_ch20_wa() - software workaround for IPA GSI channel 20
 *
 * A hardware limitation requires to avoid using GSI physical channel 20.
 * This function allocates GSI physical channel 20 and holds it to prevent
 * others to use it.
 *
 * Return codes: 0 on success, negative on failure
 */
int ipa_gsi_ch20_wa(void)
{
	struct gsi_chan_props gsi_channel_props;
	dma_addr_t dma_addr;
	int result;
	int i;
	unsigned long chan_hdl[IPA_GSI_CH_20_WA_NUM_CH_TO_ALLOC];
	unsigned long chan_hdl_to_keep;


	memset(&gsi_channel_props, 0, sizeof(gsi_channel_props));
	gsi_channel_props.prot = GSI_CHAN_PROT_GPI;
	gsi_channel_props.dir = GSI_CHAN_DIR_TO_GSI;
	gsi_channel_props.evt_ring_hdl = ~0;
	gsi_channel_props.re_size = GSI_CHAN_RE_SIZE_16B;
	gsi_channel_props.ring_len = 4 * gsi_channel_props.re_size;
	gsi_channel_props.ring_base_vaddr =
		dma_alloc_coherent(ipa3_ctx->pdev, gsi_channel_props.ring_len,
		&dma_addr, 0);
	gsi_channel_props.ring_base_addr = dma_addr;
	gsi_channel_props.use_db_eng = GSI_CHAN_DB_MODE;
	gsi_channel_props.max_prefetch = GSI_ONE_PREFETCH_SEG;
	gsi_channel_props.low_weight = 1;
	gsi_channel_props.err_cb = ipa_gsi_chan_err_cb;
	gsi_channel_props.xfer_cb = ipa_gsi_irq_tx_notify_cb;

	/* first allocate channels up to channel 20 */
	for (i = 0; i < IPA_GSI_CH_20_WA_NUM_CH_TO_ALLOC; i++) {
		gsi_channel_props.ch_id = i;
		result = gsi_alloc_channel(&gsi_channel_props,
			ipa3_ctx->gsi_dev_hdl,
			&chan_hdl[i]);
		if (result != GSI_STATUS_SUCCESS) {
			IPAERR("failed to alloc channel %d err %d\n",
				i, result);
			return result;
		}
	}

	/* allocate channel 20 */
	gsi_channel_props.ch_id = IPA_GSI_CH_20_WA_VIRT_CHAN;
	result = gsi_alloc_channel(&gsi_channel_props, ipa3_ctx->gsi_dev_hdl,
		&chan_hdl_to_keep);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("failed to alloc channel %d err %d\n",
			i, result);
		return result;
	}

	/* release all other channels */
	for (i = 0; i < IPA_GSI_CH_20_WA_NUM_CH_TO_ALLOC; i++) {
		result = gsi_dealloc_channel(chan_hdl[i]);
		if (result != GSI_STATUS_SUCCESS) {
			IPAERR("failed to dealloc channel %d err %d\n",
				i, result);
			return result;
		}
	}

	/* DMA memory shall not be freed as it is used by channel 20 */
	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -1419,6 +1419,7 @@ struct ipa3_ready_cb_info {
 * @ipa_num_pipes: The number of pipes used by IPA HW
 * @skip_uc_pipe_reset: Indicates whether pipe reset via uC needs to be avoided
 * @apply_rg10_wa: Indicates whether to use register group 10 workaround
 * @gsi_ch20_wa: Indicates whether to apply GSI physical channel 20 workaround
 * @w_lock: Indicates the wakeup source.
 * @wakelock_ref_cnt: Indicates the number of times wakelock is acquired
 * @ipa_initialization_complete: Indicates that IPA is fully initialized
@@ -1531,6 +1532,7 @@ struct ipa3_context {
	unsigned long gsi_dev_hdl;
	u32 ee;
	bool apply_rg10_wa;
	bool gsi_ch20_wa;
	bool smmu_present;
	bool smmu_s1_bypass;
	unsigned long peer_bam_iova;
@@ -1584,6 +1586,7 @@ struct ipa3_plat_drv_res {
	bool skip_uc_pipe_reset;
	enum ipa_transport_type transport_prototype;
	bool apply_rg10_wa;
	bool gsi_ch20_wa;
	bool tethered_flow_control;
};

@@ -2241,4 +2244,5 @@ void ipa3_dec_release_wakelock(void);
int ipa3_load_fws(const struct firmware *firmware);
int ipa3_register_ipa_ready_cb(void (*ipa_ready_cb)(void *), void *user_data);
const char *ipa_hw_error_str(enum ipa3_hw_errors err_type);
int ipa_gsi_ch20_wa(void);
#endif /* _IPA3_I_H_ */