diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 2ae33a7bbb2a..c745d4ba7176 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1136,6 +1137,8 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl) return -GSI_STATUS_UNSUPPORTED_OP; } + gsi_unmap_base(); + switch (props->ver) { case GSI_VER_1_0: case GSI_VER_1_2: @@ -1481,7 +1484,6 @@ int gsi_deregister_device(unsigned long dev_hdl, bool force) __gsi_config_gen_irq(gsi_ctx->per.ee, ~0, 0); devm_free_irq(gsi_ctx->dev, gsi_ctx->per.irq, gsi_ctx); - gsi_unmap_base(); gsi_ctx->per_registered = false; return GSI_STATUS_SUCCESS; } @@ -2813,6 +2815,28 @@ int gsi_write_wdi3_channel_scratch_6_7_reg(unsigned long chan_hdl, } EXPORT_SYMBOL(gsi_write_wdi3_channel_scratch_6_7_reg); +/** + * gsi_status_enabled() - Query GSI Status + * + * Returns: true if ENABLED, false on DISABLED + * + */ +bool gsi_status_enabled(void) +{ + uint32_t val; + bool ret = false; + + if (!gsi_ctx->base) + return ret; + + val = gsi_readl(gsi_ctx->base + + GSI_EE_n_GSI_STATUS_OFFS(gsi_ctx->per.ee)); + if (val & GSI_EE_n_GSI_STATUS_ENABLED_BMSK) + ret = true; + return ret; +} +EXPORT_SYMBOL(gsi_status_enabled); + static void __gsi_read_channel_scratch(unsigned long chan_hdl, union __packed gsi_channel_scratch * val) { diff --git a/drivers/platform/msm/gsi/gsi.h b/drivers/platform/msm/gsi/gsi.h index 284965c48010..5e35443bbd98 100644 --- a/drivers/platform/msm/gsi/gsi.h +++ b/drivers/platform/msm/gsi/gsi.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef GSI_H @@ -1610,6 +1611,14 @@ int gsi_poll_channel(unsigned long chan_hdl, */ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode); +/** + * gsi_status_enabled() - Query GSI Status + * + * Returns: true if ENABLED, false on DISABLED + * + */ +bool gsi_status_enabled(void); + /** * gsi_queue_xfer - Peripheral should call this function * to queue transfers on the given channel diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 09f5b1cc2fa5..e3ca264164ba 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -6666,7 +6666,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p, /* GSI 2.2 requires to allocate all EE GSI channel * during device bootup. */ - if (gsi_props.ver == GSI_VER_2_2) { + if (gsi_props.ver == GSI_VER_2_2 && !ipa3_ctx->gsi_status) { result = ipa3_alloc_gsi_channel(); if (result) { IPAERR("Failed to alloc the GSI channels\n"); @@ -6900,38 +6900,54 @@ static void ipa3_load_ipa_fw(struct work_struct *work) return; } - 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))) { - /* 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); + ipa3_ctx->gsi_status = gsi_status_enabled(); + + if(!ipa3_ctx->gsi_status) { + 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))) { + /* some targets sharing same lunch option but + * using different signing images, adding support to + * load specific FW image to based on dt entry. + */ +#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) + if (ipa3_ctx->gsi_fw_file_name) + result = ipa3_mdt_load_ipa_fws( + ipa3_ctx->gsi_fw_file_name); + else + result = ipa3_mdt_load_ipa_fws(IPA_SUBSYSTEM_NAME); +#else /* IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */ + 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); +#endif /* IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */ + } else { + result = ipa3_manual_load_ipa_fws(); + } + + + if (result) { + ipa3_ctx->ipa_pil_load++; + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + IPADBG("IPA firmware loading deffered to a work queue\n"); + queue_delayed_work(ipa3_ctx->transport_power_mgmt_wq, + &ipa3_fw_load_failure_handle, + msecs_to_jiffies(DELAY_BEFORE_FW_LOAD)); + return; + } + mutex_lock(&ipa3_ctx->fw_load_data.lock); + ipa3_ctx->fw_load_data.state = IPA_FW_LOAD_STATE_LOADED; + mutex_unlock(&ipa3_ctx->fw_load_data.lock); + pr_info("IPA FW loaded successfully\n"); } else { - result = ipa3_manual_load_ipa_fws(); + pr_info("IPA FW is already loaded\n"); + /*uC is already loaded. Marking this as after SSR boot to avoid loading uc again*/ + ipa3_ctx->uc_ctx.uc_loaded = true; } - - if (result) { - - ipa3_ctx->ipa_pil_load++; - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - IPADBG("IPA firmware loading deffered to a work queue\n"); - queue_delayed_work(ipa3_ctx->transport_power_mgmt_wq, - &ipa3_fw_load_failure_handle, - msecs_to_jiffies(DELAY_BEFORE_FW_LOAD)); - return; - } IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - mutex_lock(&ipa3_ctx->fw_load_data.lock); - ipa3_ctx->fw_load_data.state = IPA_FW_LOAD_STATE_LOADED; - mutex_unlock(&ipa3_ctx->fw_load_data.lock); - pr_info("IPA FW loaded successfully\n"); result = ipa3_post_init(&ipa3_res, ipa3_ctx->cdev.dev); if (result) { @@ -9684,7 +9700,7 @@ static void ipa3_deepsleep_suspend(void) ipa3_ctx->deepsleep = true; /*Disabling the LAN NAPI*/ ipa3_disable_napi_lan_rx(); - /*NOt allow uC related operations until uC load again*/ + /*Not allow uC related operations until uC load again*/ ipa3_ctx->uc_ctx.uc_loaded = false; /*Disconnecting LAN PROD/LAN CONS/CMD PROD apps pipes*/ ipa3_teardown_apps_pipes(); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index ceb439f729b2..8eec978bfd39 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2163,6 +2163,7 @@ struct ipa3_context { struct ipa3_mhip_ctx mhip_ctx; struct ipa3_aqc_ctx aqc_ctx; atomic_t ipa_clk_vote; + bool gsi_status; int (*client_lock_unlock[IPA_MAX_CLNT])(bool is_lock);