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

Commit 299f19c3 authored by Ravinder Konka's avatar Ravinder Konka
Browse files

msm: ipa: Move holb discard for Q6 zip pipes to AFTER_SHUTDOWN



There is a possibility that we have pending Q6 ZIP transacations
with IPA during modem shutdown. To prevent Q6 ZIP operations to
be blocking, move setting of holb discard and pipe delay for Q6 ZIP
pipes to AFTER_SHUTDOWN.

Change-Id: I10e2d9a9c37fc439f1e8f7ff375ff92a00e4cd74
Acked-by: default avatarChaitanya Pratapa <cpratapa@qti.qualcomm.com>
Signed-off-by: default avatarRavinder Konka <rkonka@codeaurora.org>
parent ec7db6c5
Loading
Loading
Loading
Loading
+89 −50
Original line number Diff line number Diff line
@@ -1349,14 +1349,24 @@ static void ipa_free_buffer(void *user1, int user2)
	kfree(user1);
}

static int ipa_q6_pipe_delay(void)
static int ipa_q6_pipe_delay(bool zip_pipes)
{
	u32 reg_val = 0;
	int client_idx;
	int ep_idx;

	/* For ZIP pipes, processing is done in AFTER_SHUTDOWN callback. */
	for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) {
		if (IPA_CLIENT_IS_Q6_PROD(client_idx)) {
		/* Skip the processing for non Q6 pipes. */
		if (!IPA_CLIENT_IS_Q6_PROD(client_idx))
			continue;
		/* Skip the processing for NON-ZIP pipes. */
		else if (zip_pipes && IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client_idx))
			continue;
		/* Skip the processing for ZIP pipes. */
		else if (!zip_pipes && IPA_CLIENT_IS_Q6_ZIP_PROD(client_idx))
			continue;

		ep_idx = ipa2_get_ep_mapping(client_idx);
		if (ep_idx == -1)
			continue;
@@ -1368,12 +1378,11 @@ static int ipa_q6_pipe_delay(void)
		ipa_write_reg(ipa_ctx->mmio,
			IPA_ENDP_INIT_CTRL_N_OFST(ep_idx), reg_val);
	}
	}

	return 0;
}

static int ipa_q6_avoid_holb(void)
static int ipa_q6_avoid_holb(bool zip_pipes)
{
	u32 reg_val;
	int ep_idx;
@@ -1383,8 +1392,18 @@ static int ipa_q6_avoid_holb(void)
	memset(&avoid_holb, 0, sizeof(avoid_holb));
	avoid_holb.ipa_ep_suspend = true;

	/* For ZIP pipes, processing is done in AFTER_SHUTDOWN callback. */
	for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) {
		if (IPA_CLIENT_IS_Q6_CONS(client_idx)) {
		/* Skip the processing for non Q6 pipes. */
		if (!IPA_CLIENT_IS_Q6_CONS(client_idx))
			continue;
		/* Skip the processing for NON-ZIP pipes. */
		else if (zip_pipes && IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx))
			continue;
		/* Skip the processing for ZIP pipes. */
		else if (!zip_pipes && IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx))
			continue;

		ep_idx = ipa2_get_ep_mapping(client_idx);
		if (ep_idx == -1)
			continue;
@@ -1415,7 +1434,6 @@ static int ipa_q6_avoid_holb(void)

		ipa2_cfg_ep_ctrl(ep_idx, &avoid_holb);
	}
	}

	return 0;
}
@@ -1635,7 +1653,8 @@ static int ipa_q6_set_ex_path_dis_agg(void)

	/* Disable AGGR on IPA->Q6 pipes */
	for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) {
		if (IPA_CLIENT_IS_Q6_CONS(client_idx)) {
		if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx) ||
			IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx)) {
			reg_write = kzalloc(sizeof(*reg_write), GFP_KERNEL);

			if (!reg_write) {
@@ -1675,15 +1694,16 @@ static int ipa_q6_set_ex_path_dis_agg(void)
}

/**
* ipa_q6_cleanup() - A cleanup for all Q6 related configuration
*                    in IPA HW. This is performed in case of SSR.
* ipa_q6_pre_shutdown_cleanup() - A cleanup for all Q6 related configuration
*                    in IPA HW before modem shutdown. This is performed in
*                    case of SSR.
*
* Return codes:
* 0: success
* This is a mandatory procedure, in case one of the steps fails, the
* AP needs to restart.
*/
int ipa_q6_cleanup(void)
int ipa_q6_pre_shutdown_cleanup(void)
{
	/* If uC has notified the APPS upon a ZIP engine error,
	 * APPS need to assert (This is a non recoverable error).
@@ -1692,12 +1712,15 @@ int ipa_q6_cleanup(void)
		BUG();

	ipa_inc_client_enable_clks();

	if (ipa_q6_pipe_delay()) {
	/*
	 * pipe delay and holb discard for ZIP pipes are handled
	 * in post shutdown callback.
	 */
	if (ipa_q6_pipe_delay(false)) {
		IPAERR("Failed to delay Q6 pipes\n");
		BUG();
	}
	if (ipa_q6_avoid_holb()) {
	if (ipa_q6_avoid_holb(false)) {
		IPAERR("Failed to set HOLB on Q6 pipes\n");
		BUG();
	}
@@ -1715,27 +1738,43 @@ int ipa_q6_cleanup(void)
}

/**
* ipa_q6_pipe_reset() - A cleanup for the Q6 pipes
*                    in IPA HW. This is performed in case of SSR.
* ipa_q6_post_shutdown_cleanup() - A cleanup for the Q6 pipes
*                    in IPA HW after modem shutdown. This is performed
*                    in case of SSR.
*
* Return codes:
* 0: success
* This is a mandatory procedure, in case one of the steps fails, the
* AP needs to restart.
*/
int ipa_q6_pipe_reset(void)
int ipa_q6_post_shutdown_cleanup(void)
{
	int client_idx;
	int res;

	/*
	 * pipe delay and holb discard for ZIP pipes are handled in
	 * post shutdown.
	 */
	if (ipa_q6_pipe_delay(true)) {
		IPAERR("Failed to delay Q6 ZIP pipes\n");
		BUG();
	}
	if (ipa_q6_avoid_holb(true)) {
		IPAERR("Failed to set HOLB on Q6 ZIP pipes\n");
		BUG();
	}

	if (!ipa_ctx->uc_ctx.uc_loaded) {
		IPAERR("uC is not loaded, won't reset Q6 pipes\n");
		return 0;
	}

	for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++)
		if (IPA_CLIENT_IS_Q6_CONS(client_idx) ||
			IPA_CLIENT_IS_Q6_PROD(client_idx)) {
		if (IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client_idx) ||
			IPA_CLIENT_IS_Q6_ZIP_CONS(client_idx) ||
			IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client_idx) ||
			IPA_CLIENT_IS_Q6_ZIP_PROD(client_idx)) {
			res = ipa_uc_reset_pipe(client_idx);
			if (res)
				BUG();
+2 −2
Original line number Diff line number Diff line
@@ -1940,8 +1940,8 @@ int ipa_write_qmapid_wdi_pipe(u32 clnt_hdl, u8 qmap_id);
int ipa_tag_process(struct ipa_desc *desc, int num_descs,
		    unsigned long timeout);

int ipa_q6_cleanup(void);
int ipa_q6_pipe_reset(void);
int ipa_q6_pre_shutdown_cleanup(void);
int ipa_q6_post_shutdown_cleanup(void);
int ipa_init_q6_smem(void);

int ipa_sps_connect_safe(struct sps_pipe *h, struct sps_connect *connect,
+2 −2
Original line number Diff line number Diff line
@@ -2179,7 +2179,7 @@ static int ssr_notifier_cb(struct notifier_block *this,
		if (SUBSYS_BEFORE_SHUTDOWN == code) {
			pr_info("IPA received MPSS BEFORE_SHUTDOWN\n");
			atomic_set(&is_ssr, 1);
			ipa_q6_cleanup();
			ipa_q6_pre_shutdown_cleanup();
			if (ipa_netdevs[0])
				netif_stop_queue(ipa_netdevs[0]);
			ipa_qmi_stop_workqueues();
@@ -2193,7 +2193,7 @@ static int ssr_notifier_cb(struct notifier_block *this,
		if (SUBSYS_AFTER_SHUTDOWN == code) {
			pr_info("IPA received MPSS AFTER_SHUTDOWN\n");
			if (atomic_read(&is_ssr))
				ipa_q6_pipe_reset();
				ipa_q6_post_shutdown_cleanup();
			pr_info("IPA AFTER_SHUTDOWN handling is complete\n");
			return NOTIFY_DONE;
		}
+19 −0
Original line number Diff line number Diff line
@@ -239,6 +239,25 @@ enum ipa_client_type {
	(client) == IPA_CLIENT_Q6_DECOMP_PROD || \
	(client) == IPA_CLIENT_Q6_DECOMP2_PROD)

#define IPA_CLIENT_IS_Q6_NON_ZIP_CONS(client) \
	((client) == IPA_CLIENT_Q6_LAN_CONS || \
	(client) == IPA_CLIENT_Q6_WAN_CONS || \
	(client) == IPA_CLIENT_Q6_DUN_CONS || \
	(client) == IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS)

#define IPA_CLIENT_IS_Q6_ZIP_CONS(client) \
	((client) == IPA_CLIENT_Q6_DECOMP_CONS || \
	(client) == IPA_CLIENT_Q6_DECOMP2_CONS)

#define IPA_CLIENT_IS_Q6_NON_ZIP_PROD(client) \
	((client) == IPA_CLIENT_Q6_LAN_PROD || \
	(client) == IPA_CLIENT_Q6_WAN_PROD || \
	(client) == IPA_CLIENT_Q6_CMD_PROD)

#define IPA_CLIENT_IS_Q6_ZIP_PROD(client) \
	((client) == IPA_CLIENT_Q6_DECOMP_PROD || \
	(client) == IPA_CLIENT_Q6_DECOMP2_PROD)

#define IPA_CLIENT_IS_MEMCPY_DMA_CONS(client) \
	((client) == IPA_CLIENT_MEMCPY_DMA_SYNC_CONS || \
	(client) == IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS)