mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 08:07:32 -04:00
Merge tag 'LA.UM.9.14.r1-25800-LAHAINA.QSSI15.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/dataipa into android13-5.4-lahaina
"LA.UM.9.14.r1-25800-LAHAINA.QSSI15.0" * tag 'LA.UM.9.14.r1-25800-LAHAINA.QSSI15.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/dataipa: msm: ipa: Check GSI status during deepsleep resume msm: ipa3: supporting hibernate & cleanup unused deepsleep API's Conflicts: techpack/dataipa/drivers/platform/msm/ipa/ipa_v3/ipa.c Change-Id: I7a69389ca80dee1ecb236f14706965b1d2bf3adb
This commit is contained in:
commit
d1d77077b6
4 changed files with 141 additions and 39 deletions
|
|
@ -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 <linux/of.h>
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ static void ipa_gsi_notify_cb(struct gsi_per_notify *notify);
|
|||
static int ipa3_attach_to_smmu(void);
|
||||
static int ipa3_alloc_pkt_init(void);
|
||||
|
||||
#ifdef CONFIG_DEEPSLEEP
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP) || IS_ENABLED(CONFIG_HIBERNATION)
|
||||
static void ipa3_deepsleep_resume(void);
|
||||
static void ipa3_deepsleep_suspend(void);
|
||||
#endif
|
||||
|
|
@ -469,17 +469,25 @@ EXPORT_SYMBOL(ipa_smmu_free_sgt);
|
|||
static int ipa_pm_notify(struct notifier_block *b, unsigned long event, void *p)
|
||||
{
|
||||
IPADBG("Entry\n");
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP) || IS_ENABLED(CONFIG_HIBERNATION)
|
||||
switch (event) {
|
||||
case PM_POST_SUSPEND:
|
||||
#ifdef CONFIG_DEEPSLEEP
|
||||
if (mem_sleep_current == PM_SUSPEND_MEM && ipa3_ctx->deepsleep) {
|
||||
IPADBG("Enter deepsleep resume\n");
|
||||
ipa3_deepsleep_resume();
|
||||
IPADBG("Exit deepsleep resume\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case PM_POST_HIBERNATION:
|
||||
/*Using the same deepsleep flag to check if freeze happened or not.*/
|
||||
if (ipa3_ctx->deepsleep) {
|
||||
IPADBG("Enter hibernate restore\n");
|
||||
ipa3_deepsleep_resume();
|
||||
IPADBG("Exit hibernate restore\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
IPADBG("Exit\n");
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
|
@ -491,7 +499,11 @@ static struct notifier_block ipa_pm_notifier = {
|
|||
|
||||
static const struct dev_pm_ops ipa_pm_ops = {
|
||||
.suspend_late = ipa3_ap_suspend,
|
||||
#if IS_ENABLED(CONFIG_HIBERNATION)
|
||||
.freeze_late = ipa3_ap_freeze,
|
||||
#endif
|
||||
.resume_early = ipa3_ap_resume,
|
||||
.restore_early = ipa3_ap_resume,
|
||||
};
|
||||
|
||||
static struct platform_driver ipa_plat_drv = {
|
||||
|
|
@ -6678,7 +6690,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");
|
||||
|
|
@ -6760,7 +6772,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
|
|||
ipa3_register_to_fmwk();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEEPSLEEP
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP) || IS_ENABLED(CONFIG_HIBERNATION)
|
||||
if (!ipa3_is_ready())
|
||||
ipa_fmwk_deepsleep_exit_ipa();
|
||||
#endif
|
||||
|
|
@ -6880,10 +6892,9 @@ static int ipa3_pil_load_ipa_fws(const char *sub_sys)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEEPSLEEP
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP) || IS_ENABLED(CONFIG_HIBERNATION)
|
||||
static int ipa3_pil_unload_ipa_fws(void)
|
||||
{
|
||||
|
||||
IPADBG("PIL FW unloading process initiated sub_sys\n");
|
||||
|
||||
if (ipa3_ctx->subsystem_get_retval)
|
||||
|
|
@ -6901,7 +6912,7 @@ static void ipa3_load_ipa_fw(struct work_struct *work)
|
|||
IPADBG("Entry\n");
|
||||
|
||||
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
|
||||
|
||||
|
||||
result = ipa3_attach_to_smmu();
|
||||
if (result) {
|
||||
IPAERR("IPA attach to smmu failed %d\n", result);
|
||||
|
|
@ -6912,38 +6923,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) {
|
||||
|
|
@ -9646,7 +9673,7 @@ int ipa3_ap_suspend(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEEPSLEEP
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP)
|
||||
if (mem_sleep_current == PM_SUSPEND_MEM) {
|
||||
IPADBG("Enter deepsleep suspend\n");
|
||||
ipa3_deepsleep_suspend();
|
||||
|
|
@ -9660,6 +9687,46 @@ int ipa3_ap_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_HIBERNATION)
|
||||
/**
|
||||
* ipa3_ap_freeze() - hibernate freeze callback for runtime_pm
|
||||
* @dev: pointer to device
|
||||
*
|
||||
* This callback will be invoked by the runtime_pm framework when an AP
|
||||
* hibernate freeze operation is invoked, usually by pressing a hibernate button.
|
||||
*
|
||||
* Returns -EAGAIN to runtime_pm framework in case IPA is in use by AP.
|
||||
* This will postpone the suspend/freeze operation until IPA is no longer used by AP.
|
||||
*/
|
||||
int ipa3_ap_freeze(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
IPADBG("Enter\n");
|
||||
|
||||
if (!of_device_is_compatible(dev->of_node,"qcom,ipa"))
|
||||
return 0;
|
||||
/* In case there is a tx/rx handler in polling mode fail to suspend */
|
||||
for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) {
|
||||
if (ipa3_ctx->ep[i].sys &&
|
||||
atomic_read(&ipa3_ctx->ep[i].sys->curr_polling_state)) {
|
||||
IPAERR("EP %d is in polling state, do not suspend\n",
|
||||
i);
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
IPADBG("Enter hibernate freeze\n");
|
||||
ipa3_deepsleep_suspend();
|
||||
IPADBG("Exit hibernate freeze\n");
|
||||
|
||||
ipa_pm_deactivate_all_deferred();
|
||||
|
||||
IPADBG("Exit\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ipa3_ap_resume() - resume callback for runtime_pm
|
||||
* @dev: pointer to device
|
||||
|
|
@ -9686,7 +9753,7 @@ bool ipa3_get_lan_rx_napi(void)
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DEEPSLEEP
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP) || IS_ENABLED(CONFIG_HIBERNATION)
|
||||
static void ipa3_deepsleep_suspend(void)
|
||||
{
|
||||
IPADBG("Entry\n");
|
||||
|
|
@ -9696,7 +9763,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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -3114,6 +3115,7 @@ struct iommu_domain *ipa3_get_smmu_domain_by_type
|
|||
int ipa3_iommu_map(struct iommu_domain *domain, unsigned long iova,
|
||||
phys_addr_t paddr, size_t size, int prot);
|
||||
int ipa3_ap_suspend(struct device *dev);
|
||||
int ipa3_ap_freeze(struct device *dev);
|
||||
int ipa3_ap_resume(struct device *dev);
|
||||
int ipa3_init_interrupts(void);
|
||||
struct iommu_domain *ipa3_get_smmu_domain(void);
|
||||
|
|
|
|||
Loading…
Reference in a new issue