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

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

Merge "msm: ipa: notify uC before going to clock gating"

parents 70edd6ad cbb42f37
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
@@ -2149,3 +2151,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_ */