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

Commit cbb42f37 authored by Ravit Katzav's avatar Ravit Katzav
Browse files

msm: ipa: notify uC before going to clock gating



Before APPS is voting for IPA clocks to be disabled,
it first needs to make sure IPA uC is idle.

After APPS is voting for IPA clocks to be enabled,
uC is notified to start processing.

Change-Id: Ied9374a12d1ca2a1afe0c1aa30e6150089064101
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarRavit Katzav <rkatzav@codeaurora.org>
parent bba41e29
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2307,6 +2307,7 @@ void _ipa_enable_clks_v2_0(void)
		clk_enable(ipa_clk);
		IPADBG("curr_ipa_clk_rate=%d", ipa_ctx->curr_ipa_clk_rate);
		clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate);
		ipa_uc_notify_clk_state(true);
	} else {
		WARN_ON(1);
	}
@@ -2405,6 +2406,7 @@ void _ipa_disable_clks_v1(void)
void _ipa_disable_clks_v2_0(void)
{
	IPADBG("disabling gcc_ipa_clk\n");
	ipa_uc_notify_clk_state(false);
	if (ipa_clk)
		clk_disable_unprepare(ipa_clk);
	else
+82 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@

#define IPA_PKT_FLUSH_TO_US 100

#define IPA_UC_POLL_SLEEP_USEC 100
#define IPA_UC_POLL_MAX_RETRY 10000
#define IPA_RAM_UC_SMEM_SIZE 128
#define IPA_HW_INTERFACE_VERSION     0x0111
#define IPA_HW_INTERFACE_WDI_VERSION 0x0001
@@ -2129,3 +2131,83 @@ int ipa_sps_connect_safe(struct sps_pipe *h, struct sps_connect *connect,
	return sps_connect(h, connect);
}
EXPORT_SYMBOL(ipa_sps_connect_safe);

/**
 * ipa_uc_notify_clk_state() - notify to uC of clock enable / disable
 * @enabled: true if clock are enabled
 *
 * The function uses the uC interface in order to notify uC bofore IPA clocks
 * are disabled to make sure uC is not in the middle of operation.
 * Also after clocks are enabled ned to notify uC to start processing.
 *
 * Returns: 0 on success, negative on failure
 */
int ipa_uc_notify_clk_state(bool enabled)
{
	int i;
	union IpaHwCpuCmdCompletedResponseData_t uc_rsp;

	if (!ipa_ctx->uc_ctx.uc_inited) {
		IPADBG("uC interface not initialized\n");
		return 0;
	}

	if (!ipa_ctx->uc_ctx.uc_loaded) {
		IPADBG("uC is not loaded\n");
		return 0;
	}

	mutex_lock(&ipa_ctx->uc_ctx.uc_lock);

	/* Write to shared memory */
	ipa_ctx->uc_ctx.uc_sram_mmio->cmdParams = 0;
	ipa_ctx->uc_ctx.uc_sram_mmio->cmdOp = (enabled) ?
						IPA_CPU_2_HW_CMD_CLK_UNGATE :
						IPA_CPU_2_HW_CMD_CLK_GATE;
	ipa_ctx->uc_ctx.pending_cmd = ipa_ctx->uc_ctx.uc_sram_mmio->cmdOp;

	IPADBG("uC clock %s notification\n", (enabled) ? "UNGATE" : "GATE");

	/* Indicate the uC on the written command */
	ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_EE_UC_n_OFFS(0), 0x1);

	/*
	 * for GATING / UNGATING notification no interrupt is generated form uC
	 * Need to poll on the response
	 */
	ipa_ctx->uc_ctx.uc_sram_mmio->responseOp = 0;
	ipa_ctx->uc_ctx.uc_sram_mmio->responseParams = 0;
	for (i = 0; i < IPA_UC_POLL_MAX_RETRY; i++) {
		if (ipa_ctx->uc_ctx.uc_sram_mmio->responseOp ==
		    IPA_HW_2_CPU_RESPONSE_CMD_COMPLETED) {
			uc_rsp.raw32b =
				ipa_ctx->uc_ctx.uc_sram_mmio->responseParams;
			if (uc_rsp.params.originalCmdOp ==
			    ipa_ctx->uc_ctx.pending_cmd)
				break;
		}
		usleep(IPA_UC_POLL_SLEEP_USEC);
	}

	/* In case of a timeout, this indicates an issue in IPA HW */
	if (i == IPA_UC_POLL_MAX_RETRY) {
		IPAERR("uC timed out in clock gate notification\n");
		mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
		BUG();
		return -EFAULT;
	}

	/*
	 * In case of an unexpected response, the current operation
	 * should fail, but we should allow the next reset requests
	 * to be executed.
	 */
	if (ipa_ctx->uc_ctx.uc_status != 0) {
		IPAERR("uC failed for clk notofication\n");
		mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
		return -EFAULT;
	}
	mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -1251,4 +1251,5 @@ int ipa_uc_interface_init(void);
int ipa_uc_reset_pipe(enum ipa_client_type ipa_client);
void ipa_register_panic_hdlr(void);
int create_nat_device(void);
int ipa_uc_notify_clk_state(bool enabled);
#endif /* _IPA_I_H_ */