From c6e2859a34e7347a7dfcfcc247e4ddb976a296d8 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 18 Aug 2021 15:34:56 -0700 Subject: [PATCH] msm: ipa: debugfs: Update keep_awake to use PM APIs Update the keep_awake script to call into IPA PM and add/remove dummy clients to change the clk vote dynamically based on the loaded device's power thresholds. Change-Id: Ifaa4ef1e312428245605008998ac59afddf09d99 Signed-off-by: Michael Adisumarta --- drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c | 39 ++--- drivers/platform/msm/ipa/ipa_v3/ipa_pm.c | 145 +++++++++++++++++- drivers/platform/msm/ipa/ipa_v3/ipa_pm.h | 14 +- 3 files changed, 167 insertions(+), 31 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 27c7af5693..2586e01d04 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -503,40 +503,21 @@ static ssize_t ipa3_write_keep_awake(struct file *file, const char __user *buf, { s8 option = 0; int ret; - uint32_t bw_mbps = 0; ret = kstrtos8_from_user(buf, count, 0, &option); if (ret) return ret; - switch (option) { - case 0: - IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - bw_mbps = 0; - break; - case 1: - IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 0; - break; - case 2: - IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 700; - break; - case 3: - IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 3000; - break; - case 4: - IPA_ACTIVE_CLIENTS_INC_SIMPLE(); - bw_mbps = 7000; - break; - default: - pr_err("Not support this vote (%d)\n", option); - return -EFAULT; - } - if (ipa3_vote_for_bus_bw(&bw_mbps)) { - IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps); - return -EFAULT; + if (option == 0) { + if (ipa_pm_remove_dummy_clients()) { + pr_err("Failed to remove dummy clients\n"); + return -EFAULT; + } + } else { + if (ipa_pm_add_dummy_clients(option - 1)) { + pr_err("Failed to add dummy clients\n"); + return -EFAULT; + } } return count; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c index afee786a3d..2fe1139558 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c @@ -195,6 +195,8 @@ static const char *ipa_pm_group_to_str[IPA_PM_GROUP_MAX] = { __stringify(IPA_PM_GROUP_MODEM), }; +static int dummy_hdl_1, dummy_hdl_2, tput_modem, tput_apps; + /** * pop_max_from_array() -pop the max and move the last element to where the * max was popped @@ -1511,4 +1513,145 @@ int ipa_pm_get_pm_clnt_throughput(enum ipa_client_type client_type) mutex_unlock(&ipa_pm_ctx->client_mutex); return 0; } -} \ No newline at end of file +} + +/** + * ipa_pm_add_dummy_clients() - add 2 dummy clients for modem and apps + * @power_plan: [in] The power plan for the dummy clients + * 0 = SVS (lowest plan), 1 = SVS2, ... etc + * + * Returns: 0 on success, negative on failure + */ +int ipa_pm_add_dummy_clients(s8 power_plan) +{ + int rc = 0; + int tput; + int hdl_1, hdl_2; + + struct ipa_pm_register_params dummy1_params = { + .name = "DummyModem", + .group = IPA_PM_GROUP_MODEM, + .skip_clk_vote = 0, + .callback = NULL, + .user_data = NULL + }; + + struct ipa_pm_register_params dummy2_params = { + .name = "DummyApps", + .group = IPA_PM_GROUP_APPS, + .skip_clk_vote = 0, + .callback = NULL, + .user_data = NULL + }; + + if (power_plan < 0 || + (power_plan - 1) >= ipa_pm_ctx->clk_scaling.threshold_size) { + pr_err("Invalid power plan(%d)\n", power_plan); + return -EFAULT; + } + + /* 0 is SVS case which is not part of the threshold */ + if (power_plan == 0) + tput = 0; + else + tput = ipa_pm_ctx->clk_scaling.current_threshold[power_plan-1]; + + /* + * register with local handles to prevent overwriting global handles + * in the case of a failure + */ + rc = ipa_pm_register(&dummy1_params, &hdl_1); + if (rc) { + pr_err("fail to register client 1 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_register(&dummy2_params, &hdl_2); + if (rc) { + pr_err("fail to register client 2 rc = %d\n", rc); + return -EFAULT; + } + + /* replace global handles */ + dummy_hdl_1 = hdl_1; + dummy_hdl_2 = hdl_2; + + /* save the old throughputs for removal */ + tput_modem = ipa_pm_ctx->group_tput[IPA_PM_GROUP_MODEM]; + tput_apps = ipa_pm_ctx->group_tput[IPA_PM_GROUP_APPS]; + + rc = ipa_pm_set_throughput(dummy_hdl_1, tput); + if (rc) { + IPAERR("fail to set tput for client 1 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_set_throughput(dummy_hdl_2, tput); + if (rc) { + IPAERR("fail to set tput for client 2 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_activate_sync(dummy_hdl_1); + if (rc) { + IPAERR("fail to activate sync for client 1 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_activate_sync(dummy_hdl_2); + if (rc) { + IPAERR("fail to activate sync for client 2 rc = %d\n", rc); + return -EFAULT; + } + + return rc; +} + +/** + * ipa_pm_remove_dummy_clients() - remove the 2 dummy clients for modem and apps + * + * Returns: 0 on success, negative on failure + */ +int ipa_pm_remove_dummy_clients(void) +{ + int rc = 0; + + rc = ipa_pm_deactivate_sync(dummy_hdl_1); + if (rc) { + IPAERR("fail to deactivate client 1 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_deactivate_sync(dummy_hdl_2); + if (rc) { + IPAERR("fail to deactivate client 2 rc = %d\n", rc); + return -EFAULT; + } + + /* reset the modem and apps tputs back to old values */ + rc = ipa_pm_set_throughput(dummy_hdl_1, tput_modem); + if (rc) { + IPAERR("fail to reset tput for client 1 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_set_throughput(dummy_hdl_2, tput_apps); + if (rc) { + IPAERR("fail to reset tput for client 2 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_deregister(dummy_hdl_1); + if (rc) { + IPAERR("fail to deregister client 1 rc = %d\n", rc); + return -EFAULT; + } + + rc = ipa_pm_deregister(dummy_hdl_2); + if (rc) { + IPAERR("fail to deregister client 2 rc = %d\n", rc); + return -EFAULT; + } + + return rc; +} diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h index a4103ede46..78b76a7085 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef _IPA_PM_H_ @@ -103,6 +103,8 @@ int ipa_pm_deactivate_all_deferred(void); int ipa_pm_stat(char *buf, int size); int ipa_pm_exceptions_stat(char *buf, int size); void ipa_pm_set_clock_index(int index); +int ipa_pm_add_dummy_clients(s8 power_plan); +int ipa_pm_remove_dummy_clients(void); #else /* IS_ENABLED(CONFIG_IPA3) */ @@ -178,6 +180,16 @@ static inline int ipa_pm_exceptions_stat(char *buf, int size) { return -EPERM; } + +static inline int ipa_pm_add_dummy_clients(s8 power_plan); +{ + return -EPERM; +} + +static inline int ipa_pm_remove_dummy_clients(void); +{ + return -EPERM; +} #endif /* IS_ENABLED(CONFIG_IPA3) */ #endif /* _IPA_PM_H_ */