Loading drivers/platform/msm/ipa/ipa_client.c +12 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,12 @@ int ipa_connect(const struct ipa_connect_params *in, struct ipa_sps_params *sps, ep->priv = in->priv; ep->keep_ipa_awake = in->keep_ipa_awake; /* Notify uc to start monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(in->client)) { ipa_uc_monitor_holb(in->client, true); IPADBG("Enabling holb monitor for client:%d", in->client); } result = ipa_enable_data_path(ipa_ep_idx); if (result) { IPAERR("enable data path failed res=%d clnt=%d.\n", result, Loading Loading @@ -472,6 +478,12 @@ int ipa_disconnect(u32 clnt_hdl) if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); IPADBG("Disabling holb monitor for client: %d\n", ep->client); } result = ipa_disable_data_path(clnt_hdl); if (result) { IPAERR("disable data path failed res=%d clnt=%d.\n", result, Loading drivers/platform/msm/ipa/ipa_i.h +1 −0 Original line number Diff line number Diff line Loading @@ -1560,6 +1560,7 @@ int ipa_mhi_handle_ipa_config_req(struct ipa_config_req_msg_v01 *config_req); int ipa_uc_interface_init(void); int ipa_uc_reset_pipe(enum ipa_client_type ipa_client); int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable); int ipa_uc_state_check(void); int ipa_uc_send_cmd(u32 cmd, u32 opcode, u32 expected_status, bool polling_mode, unsigned long timeout_jiffies); Loading drivers/platform/msm/ipa/ipa_uc.c +92 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ enum ipa_cpu_2_hw_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 7), IPA_CPU_2_HW_CMD_RESET_PIPE = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 8), IPA_CPU_2_HW_CMD_UPDATE_HOLB_MONITORING = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 9), }; /** Loading Loading @@ -135,6 +137,25 @@ union IpaHwResetPipeCmdData_t { u32 raw32b; } __packed; /** * union IpaHwmonitorHolbCmdData_t - Structure holding the parameters * for IPA_CPU_2_HW_CMD_UPDATE_HOLB_MONITORING command. * @monitorPipe : Indication whether to monitor the pipe. 0 Do not Monitor Pipe, 1 Monitor Pipe * @pipeNum : Pipe to be monitored/not monitored * @reserved_02_03 : Reserved * * The parameters are passed as immediate params in the shared memory */ union IpaHwmonitorHolbCmdData_t { struct IpaHwmonitorHolbCmdParams_t { u8 monitorPipe; u8 pipeNum; u32 reserved_02_03:16; } __packed params; u32 raw32b; } __packed; /** * union IpaHwCpuCmdCompletedResponseData_t - Structure holding the parameters * for IPA_HW_2_CPU_RESPONSE_CMD_COMPLETED response. Loading Loading @@ -426,6 +447,8 @@ static void ipa_uc_response_hdlr(enum ipa_irq_type interrupt, if (uc_hdlrs[i].ipa_uc_loaded_hdlr) uc_hdlrs[i].ipa_uc_loaded_hdlr(); } /* Enable holb monitoring on IPA-USB Producer pipe if valid. */ ipa_uc_monitor_holb(IPA_CLIENT_USB_CONS, true); } else 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; Loading Loading @@ -699,6 +722,75 @@ int ipa_uc_reset_pipe(enum ipa_client_type ipa_client) } EXPORT_SYMBOL(ipa_uc_reset_pipe); /** * ipa_uc_monitor_holb() - Enable/Disable holb monitoring of a producer pipe. * @ipa_client: [in] ipa client handle representing the pipe * * The function uses the uC interface in order to disable/enable holb * monitoring. * * Returns: 0 on success, negative on failure */ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) { union IpaHwmonitorHolbCmdData_t cmd; int ep_idx; int ret; struct ipa_ep_context *ep; /* HOLB monitoring is applicable only to 2.6L. */ if (ipa_ctx->ipa_hw_type != IPA_HW_v2_6L) { IPADBG("Not applicable on this target\n"); return 0; } ep_idx = ipa_get_ep_mapping(ipa_client); if (ep_idx == -1) { IPAERR("Invalid IPA client\n"); return 0; } ep = &ipa_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); return 0; } /* * If the uC interface has not been initialized yet, * continue with the sequence without resetting the * pipe. */ if (ipa_uc_state_check()) { IPADBG("uC interface will not be used to reset %s pipe %d\n", IPA_CLIENT_IS_PROD(ipa_client) ? "CONS" : "PROD", ep_idx); return 0; } /* * IPA consumer = 0, IPA producer = 1. * IPA driver concept of PROD/CONS is the opposite of the * IPA HW concept. Therefore, IPA AP CLIENT PRODUCER = IPA CONSUMER, * and vice-versa. */ cmd.params.monitorPipe = (u8)(enable ? 1 : 0); cmd.params.pipeNum = (u8)ep_idx; IPADBG("uC holb monitoring on IPA pipe %d\n, Enable: %d", ep_idx, enable); ret = ipa_uc_send_cmd(cmd.raw32b, IPA_CPU_2_HW_CMD_UPDATE_HOLB_MONITORING, 0, true, 10*HZ); return ret; } EXPORT_SYMBOL(ipa_uc_monitor_holb); /** * ipa_uc_notify_clk_state() - notify to uC of clock enable / disable * @enabled: true if clock are enabled Loading Loading
drivers/platform/msm/ipa/ipa_client.c +12 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,12 @@ int ipa_connect(const struct ipa_connect_params *in, struct ipa_sps_params *sps, ep->priv = in->priv; ep->keep_ipa_awake = in->keep_ipa_awake; /* Notify uc to start monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(in->client)) { ipa_uc_monitor_holb(in->client, true); IPADBG("Enabling holb monitor for client:%d", in->client); } result = ipa_enable_data_path(ipa_ep_idx); if (result) { IPAERR("enable data path failed res=%d clnt=%d.\n", result, Loading Loading @@ -472,6 +478,12 @@ int ipa_disconnect(u32 clnt_hdl) if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); /* Notify uc to stop monitoring holb on USB BAM Producer pipe. */ if (IPA_CLIENT_IS_USB_CONS(ep->client)) { ipa_uc_monitor_holb(ep->client, false); IPADBG("Disabling holb monitor for client: %d\n", ep->client); } result = ipa_disable_data_path(clnt_hdl); if (result) { IPAERR("disable data path failed res=%d clnt=%d.\n", result, Loading
drivers/platform/msm/ipa/ipa_i.h +1 −0 Original line number Diff line number Diff line Loading @@ -1560,6 +1560,7 @@ int ipa_mhi_handle_ipa_config_req(struct ipa_config_req_msg_v01 *config_req); int ipa_uc_interface_init(void); int ipa_uc_reset_pipe(enum ipa_client_type ipa_client); int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable); int ipa_uc_state_check(void); int ipa_uc_send_cmd(u32 cmd, u32 opcode, u32 expected_status, bool polling_mode, unsigned long timeout_jiffies); Loading
drivers/platform/msm/ipa/ipa_uc.c +92 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,8 @@ enum ipa_cpu_2_hw_commands { FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 7), IPA_CPU_2_HW_CMD_RESET_PIPE = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 8), IPA_CPU_2_HW_CMD_UPDATE_HOLB_MONITORING = FEATURE_ENUM_VAL(IPA_HW_FEATURE_COMMON, 9), }; /** Loading Loading @@ -135,6 +137,25 @@ union IpaHwResetPipeCmdData_t { u32 raw32b; } __packed; /** * union IpaHwmonitorHolbCmdData_t - Structure holding the parameters * for IPA_CPU_2_HW_CMD_UPDATE_HOLB_MONITORING command. * @monitorPipe : Indication whether to monitor the pipe. 0 Do not Monitor Pipe, 1 Monitor Pipe * @pipeNum : Pipe to be monitored/not monitored * @reserved_02_03 : Reserved * * The parameters are passed as immediate params in the shared memory */ union IpaHwmonitorHolbCmdData_t { struct IpaHwmonitorHolbCmdParams_t { u8 monitorPipe; u8 pipeNum; u32 reserved_02_03:16; } __packed params; u32 raw32b; } __packed; /** * union IpaHwCpuCmdCompletedResponseData_t - Structure holding the parameters * for IPA_HW_2_CPU_RESPONSE_CMD_COMPLETED response. Loading Loading @@ -426,6 +447,8 @@ static void ipa_uc_response_hdlr(enum ipa_irq_type interrupt, if (uc_hdlrs[i].ipa_uc_loaded_hdlr) uc_hdlrs[i].ipa_uc_loaded_hdlr(); } /* Enable holb monitoring on IPA-USB Producer pipe if valid. */ ipa_uc_monitor_holb(IPA_CLIENT_USB_CONS, true); } else 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; Loading Loading @@ -699,6 +722,75 @@ int ipa_uc_reset_pipe(enum ipa_client_type ipa_client) } EXPORT_SYMBOL(ipa_uc_reset_pipe); /** * ipa_uc_monitor_holb() - Enable/Disable holb monitoring of a producer pipe. * @ipa_client: [in] ipa client handle representing the pipe * * The function uses the uC interface in order to disable/enable holb * monitoring. * * Returns: 0 on success, negative on failure */ int ipa_uc_monitor_holb(enum ipa_client_type ipa_client, bool enable) { union IpaHwmonitorHolbCmdData_t cmd; int ep_idx; int ret; struct ipa_ep_context *ep; /* HOLB monitoring is applicable only to 2.6L. */ if (ipa_ctx->ipa_hw_type != IPA_HW_v2_6L) { IPADBG("Not applicable on this target\n"); return 0; } ep_idx = ipa_get_ep_mapping(ipa_client); if (ep_idx == -1) { IPAERR("Invalid IPA client\n"); return 0; } ep = &ipa_ctx->ep[ep_idx]; if (!ep->valid) { IPAERR("EP not valid.\n"); return 0; } /* * If the uC interface has not been initialized yet, * continue with the sequence without resetting the * pipe. */ if (ipa_uc_state_check()) { IPADBG("uC interface will not be used to reset %s pipe %d\n", IPA_CLIENT_IS_PROD(ipa_client) ? "CONS" : "PROD", ep_idx); return 0; } /* * IPA consumer = 0, IPA producer = 1. * IPA driver concept of PROD/CONS is the opposite of the * IPA HW concept. Therefore, IPA AP CLIENT PRODUCER = IPA CONSUMER, * and vice-versa. */ cmd.params.monitorPipe = (u8)(enable ? 1 : 0); cmd.params.pipeNum = (u8)ep_idx; IPADBG("uC holb monitoring on IPA pipe %d\n, Enable: %d", ep_idx, enable); ret = ipa_uc_send_cmd(cmd.raw32b, IPA_CPU_2_HW_CMD_UPDATE_HOLB_MONITORING, 0, true, 10*HZ); return ret; } EXPORT_SYMBOL(ipa_uc_monitor_holb); /** * ipa_uc_notify_clk_state() - notify to uC of clock enable / disable * @enabled: true if clock are enabled Loading