Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 885fd0dc authored by Michael Adisumarta's avatar Michael Adisumarta Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarMichael Adisumarta <madisuma@codeaurora.org>
parent 2672ec32
Loading
Loading
Loading
Loading
+10 −29
Original line number Diff line number Diff line
@@ -322,41 +322,22 @@ 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);
	if (option == 0) {
		if (ipa_pm_remove_dummy_clients()) {
			pr_err("Failed to remove dummy clients\n");
			return -EFAULT;
		}
	if (ipa3_vote_for_bus_bw(&bw_mbps)) {
		IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps);
	} else {
		if (ipa_pm_add_dummy_clients(option - 1)) {
			pr_err("Failed to add dummy clients\n");
			return -EFAULT;
		}
	}

	return count;
}
+144 −1
Original line number Diff line number Diff line
@@ -190,6 +190,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
@@ -1379,7 +1381,7 @@ int ipa_pm_stat(char *buf, int size)
 * ipa_pm_exceptions_stat() - print PM exceptions stat
 * @buf: [in] The user buff used to print
 * @size: [in] The size of buf
 * Returns: number of bytes used on success, negative on failure
 * Returns: 0 on success, negative on failure
 *
 * This function is called by ipa_debugfs in order to receive
 * a full picture of the exceptions in the PM
@@ -1422,3 +1424,144 @@ int ipa_pm_exceptions_stat(char *buf, int size)

	return cnt;
}

/**
 * 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;
}
+13 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _IPA_PM_H_
@@ -101,6 +101,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

@@ -176,6 +178,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

#endif /* _IPA_PM_H_ */