diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index c35be34637ea..7401c92b2162 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6229,10 +6229,19 @@ static void ipa3_load_ipa_fw(struct work_struct *work) if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_EMULATION && ((ipa3_ctx->platform_type != IPA_PLAT_TYPE_MDM) || - (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5))) - result = ipa3_pil_load_ipa_fws(IPA_SUBSYSTEM_NAME); - else + (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5))) { + /* some targets sharing same lunch option but + * using different signing images, adding support to + * load specific FW image to based on dt entry. + */ + if (ipa3_ctx->gsi_fw_file_name) + result = ipa3_pil_load_ipa_fws( + ipa3_ctx->gsi_fw_file_name); + else + result = ipa3_pil_load_ipa_fws(IPA_SUBSYSTEM_NAME); + } else { result = ipa3_manual_load_ipa_fws(); + } IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); @@ -6261,7 +6270,11 @@ static void ipa3_load_ipa_fw(struct work_struct *work) /* Unvoting will happen when uC loaded event received. */ ipa3_proxy_clk_vote(); - result = ipa3_pil_load_ipa_fws(IPA_UC_SUBSYSTEM_NAME); + if (ipa3_ctx->uc_fw_file_name) + result = ipa3_pil_load_ipa_fws( + ipa3_ctx->uc_fw_file_name); + else + result = ipa3_pil_load_ipa_fws(IPA_UC_SUBSYSTEM_NAME); if (result) { IPAERR("IPA uC loading process has failed result=%d\n", result); @@ -6660,6 +6673,34 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, ipa3_ctx->lan_rx_napi_enable = resource_p->lan_rx_napi_enable; ipa3_ctx->rmnet_ctl_enable = resource_p->rmnet_ctl_enable; + if (resource_p->gsi_fw_file_name) { + ipa3_ctx->gsi_fw_file_name = + kzalloc(((strlen(resource_p->gsi_fw_file_name)+1) * + sizeof(const char)), GFP_KERNEL); + if (ipa3_ctx->gsi_fw_file_name == NULL) { + IPAERR_RL("Failed to alloc GSI FW file name\n"); + result = -ENOMEM; + goto fail_gsi_file_alloc; + } + memcpy(ipa3_ctx->gsi_fw_file_name, + (void const *)resource_p->gsi_fw_file_name, + strlen(resource_p->gsi_fw_file_name)); + } + + if (resource_p->uc_fw_file_name) { + ipa3_ctx->uc_fw_file_name = + kzalloc(((strlen(resource_p->uc_fw_file_name)+1) * + sizeof(const char)), GFP_KERNEL); + if (ipa3_ctx->uc_fw_file_name == NULL) { + IPAERR_RL("Failed to alloc uC FW file name\n"); + result = -ENOMEM; + goto fail_uc_file_alloc; + } + memcpy(ipa3_ctx->uc_fw_file_name, + (void const *)resource_p->uc_fw_file_name, + strlen(resource_p->uc_fw_file_name)); + } + if (ipa3_ctx->secure_debug_check_action == USE_SCM) { if (ipa_is_mem_dump_allowed()) ipa3_ctx->sd_state = SD_ENABLED; @@ -7165,6 +7206,9 @@ fail_mem_ctrl: fail_tz_unlock_reg: if (ipa3_ctx->logbuf) ipc_log_context_destroy(ipa3_ctx->logbuf); +fail_uc_file_alloc: + kfree(ipa3_ctx->gsi_fw_file_name); +fail_gsi_file_alloc: fail_mem_ctx: return result; } @@ -7539,6 +7583,18 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_drv_res->rmnet_ctl_enable ? "True" : "False"); + result = of_property_read_string(pdev->dev.of_node, + "qcom,use-gsi-ipa-fw", &ipa_drv_res->gsi_fw_file_name); + if (!result) + IPADBG("GSI IPA FW name %s\n", ipa_drv_res->gsi_fw_file_name); + else + IPADBG("GSI IPA FW file not defined. Using default one\n"); + result = of_property_read_string(pdev->dev.of_node, + "qcom,use-uc-ipa-fw", &ipa_drv_res->uc_fw_file_name); + if (!result) + IPADBG("uC IPA FW name = %s\n", ipa_drv_res->uc_fw_file_name); + else + IPADBG("uC IPA FW file not defined. Using default one\n"); /* Get IPA wrapper address */ resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipa-base"); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 3b721e20485e..3d1db0261437 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1882,6 +1882,8 @@ struct ipa3_app_clock_vote { * @icc_clk - table for icc bw clock value * @coal_cmd_pyld: holds the coslescing close frame command payload * @rmnet_ctl_enable: enable pipe support fow low latency data + * @gsi_fw_file_name: GSI IPA fw file name + * @uc_fw_file_name: uC IPA fw file name */ struct ipa3_context { struct ipa3_char_device_context cdev; @@ -2063,6 +2065,8 @@ struct ipa3_context { struct ipa3_app_clock_vote app_clock_vote; bool clients_registered; bool rmnet_ctl_enable; + char *gsi_fw_file_name; + char *uc_fw_file_name; }; struct ipa3_plat_drv_res { @@ -2116,6 +2120,8 @@ struct ipa3_plat_drv_res { const char *icc_path_name[IPA_ICC_PATH_MAX]; u32 icc_clk_val[IPA_ICC_LVL_MAX][IPA_ICC_MAX]; bool rmnet_ctl_enable; + const char *gsi_fw_file_name; + const char *uc_fw_file_name; }; /**