Loading drivers/platform/msm/ipa/ipa.c +2 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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 Loading drivers/platform/msm/ipa/ipa_client.c +82 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; } drivers/platform/msm/ipa/ipa_i.h +1 −0 Original line number Diff line number Diff line Loading @@ -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_ */ Loading
drivers/platform/msm/ipa/ipa.c +2 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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 Loading
drivers/platform/msm/ipa/ipa_client.c +82 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; }
drivers/platform/msm/ipa/ipa_i.h +1 −0 Original line number Diff line number Diff line Loading @@ -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_ */