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

Commit c5601708 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "defconfig: enable rimps plh interface"

parents 92efb2ac 8897d961
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -179,6 +179,9 @@ CONFIG_QTI_HW_MEMLAT_SCMI_CLIENT=y
CONFIG_SRAM=y
CONFIG_QTI_HW_MEMLAT_LOG=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_QTI_SCMI_PLH_PROTOCOL=y
CONFIG_QTI_PLH=y
CONFIG_QTI_PLH_SCMI_CLIENT=y
# CONFIG_USB_CONFIGFS_RNDIS is not set
CONFIG_QCOM_INITIAL_LOGBUF=y
CONFIG_QCOM_MINIDUMP_FTRACE=y
+10 −0
Original line number Diff line number Diff line
@@ -600,6 +600,16 @@ config MSM_PERFORMANCE
          fmin and fmax. The user space can request  the cpu freq change by
          writing cpu#:freq values

config QTI_PLH
	bool "Qualcomm Technologies Inc. RIMPS PLH interface"
	depends on ARM_SCMI_PROTOCOL && MSM_PERFORMANCE
	default n
	help
	  Interface between RIMPS PLH and userspace.

	  This interface is responsible for handling the communication
	  with RIMPS PLH such as passing tunables, enable and disable.

config QMP_DEBUGFS_CLIENT
	bool "Debugfs Client to communicate with AOP using QMP protocol"
	depends on DEBUG_FS
+164 −10
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/perf_event.h>
#include <linux/errno.h>
#include <linux/topology.h>
#include <linux/scmi_protocol.h>

/*
 * Sched will provide the data for every 20ms window,
@@ -926,20 +927,162 @@ static const struct kernel_param_ops param_ops_game_start_pid = {
module_param_cb(evnt_gplaf_pid, &param_ops_game_start_pid, NULL, 0644);

/*******************************GFX Call************************************/
#ifdef CONFIG_QTI_PLH
static struct scmi_handle *plh_handle;
void rimps_plh_init(struct scmi_handle *handle)
{
	if (handle)
		plh_handle = handle;
}
EXPORT_SYMBOL(rimps_plh_init);

static int splh_notif, splh_init_done, plh_log_level;

#define PLH_MIN_LOG_LEVEL			0
#define PLH_MAX_LOG_LEVEL			0xF
#define SPLH_FPS_MAX_CNT			8
#define SPLH_IPC_FREQ_VTBL_MAX_CNT		5 /* ipc freq pair */
#define SPLH_INIT_IPC_FREQ_TBL_PARAMS	\
			(2 + SPLH_FPS_MAX_CNT * (1 + (2 * SPLH_IPC_FREQ_VTBL_MAX_CNT)))

static int set_plh_log_level(const char *buf, const struct kernel_param *kp)
{
	int ret, log_val_backup;
	struct scmi_plh_vendor_ops *ops;

	if (!plh_handle || !plh_handle->plh_ops) {
		pr_err("msm_perf: plh scmi handle or vendor ops null\n");
		return -EINVAL;
	}

	ops = plh_handle->plh_ops;

	log_val_backup = plh_log_level;

	ret = param_set_int(buf, kp); /* Updates plh_log_level */
	if (ret < 0) {
		pr_err("msm_perf: getting new plh_log_level failed, ret=%d\n", ret);
		return ret;
	}

	plh_log_level = clamp(plh_log_level, PLH_MIN_LOG_LEVEL, PLH_MAX_LOG_LEVEL);
	ret = ops->set_plh_log_level(plh_handle, plh_log_level);
	if (ret < 0) {
		plh_log_level = log_val_backup;
		pr_err("msm_perf: setting new plh_log_level failed, ret=%d\n", ret);
		return ret;
	}
	return 0;
}

static const struct kernel_param_ops param_ops_plh_log_level = {
	.set = set_plh_log_level,
	.get = param_get_int,
};
module_param_cb(plh_log_level, &param_ops_plh_log_level, &plh_log_level, 0644);

static int splh_notif;
static void init_splh_notif(const char *buf)
static int init_splh_notif(const char *buf)
{
	int i, j, ret;
	u16 tmp[SPLH_INIT_IPC_FREQ_TBL_PARAMS];
	u16 *ptmp = tmp, ntokens, nfps, n_ipc_freq_pair, tmp_valid_len = 0;
	const char *cp, *cp1;
	struct scmi_plh_vendor_ops *ops;

	/* buf contains the init info from user */
	if (buf == NULL)
		return;
	if (buf == NULL || !plh_handle || !plh_handle->plh_ops)
		return -EINVAL;

	cp = buf;
	ntokens = 0;
	while ((cp = strpbrk(cp + 1, ":")))
		ntokens++;

	/* format of cmd nfps, n_ipc_freq_pair, <fps0, <ipc0, freq0>,...>,... */
	cp = buf;
	if (sscanf(cp, INIT ":%hu", &nfps)) {
		if ((nfps != ntokens-1) || (nfps == 0) || (nfps > SPLH_FPS_MAX_CNT))
			return -EINVAL;

		cp = strnchr(cp, strlen(cp), ':');	/* skip INIT */
		cp++;
		cp = strnchr(cp, strlen(cp), ':');	/* skip nfps */

		*ptmp++ = nfps;		/* nfps is first cmd param */
		tmp_valid_len++;
		cp1 = cp;
		ntokens = 0;
		/* get count of nfps * n_ipc_freq_pair * <ipc freq pair values> */
		while ((cp1 = strpbrk(cp1 + 1, ",")))
			ntokens++;

		if (ntokens % (2 * nfps)) /* ipc freq pair values should be multiple of nfps */
			return -EINVAL;

		n_ipc_freq_pair = ntokens / (2 * nfps); /* ipc_freq pair values for each FPS */
		if ((n_ipc_freq_pair == 0) || (n_ipc_freq_pair > SPLH_IPC_FREQ_VTBL_MAX_CNT))
			return -EINVAL;

		*ptmp++ = n_ipc_freq_pair; /* n_ipc_freq_pair is second cmd param */
		tmp_valid_len++;
		cp1 = cp;
		for (i = 0; i < nfps; i++) {
			if (sscanf(cp1, ":%hu", ptmp) != 1)
				return -EINVAL;

			ptmp++;		/* increment after storing FPS val */
			tmp_valid_len++;
			cp1 = strnchr(cp1, strlen(cp1), ','); /* move to ,ipc */
			for (j = 0; j < 2 * n_ipc_freq_pair; j++) {
				if (sscanf(cp1, ",%hu", ptmp) != 1)
					return -EINVAL;

				ptmp++;	/* increment after storing ipc or freq */
				tmp_valid_len++;
				cp1++;
				if (j != (2 * n_ipc_freq_pair - 1))
					cp1 = strnchr(cp1, strlen(cp1), ','); /* move to next */
			}

			if (i != (nfps - 1))
				cp1 = strnchr(cp1, strlen(cp1), ':'); /* move to next FPS val */

	pr_debug("msm_perf:Init info for scroll :: %s\n", buf);
		}
	} else {
		return -EINVAL;
	}

	ops = plh_handle->plh_ops;
	ret = ops->init_splh_ipc_freq_tbl(plh_handle, tmp, tmp_valid_len);
	if (ret < 0)
		return -EINVAL;

	pr_info("msm_perf: nfps=%hu n_ipc_freq_pair=%hu last_freq_val=%hu len=%hu\n",
		nfps, n_ipc_freq_pair, *--ptmp, tmp_valid_len);
	splh_init_done = 1;
	return 0;
}

static void activate_splh_notif(void)
{
	int ret;
	struct scmi_plh_vendor_ops *ops;
	/* received event notification here */
	if (!plh_handle || !plh_handle->plh_ops) {
		pr_err("msm_perf: splh not supported\n");
		return;
	}
	ops = plh_handle->plh_ops;

	if (splh_notif)
		ret = ops->start_splh(plh_handle, splh_notif); /* splh_notif is fps */
	else
		ret = ops->stop_splh(plh_handle);

	if (ret < 0) {
		pr_err("msm_perf: splh start or stop failed, ret=%d\n", ret);
		return;
	}
}

static int set_splh_notif(const char *buf, const struct kernel_param *kp)
@@ -947,8 +1090,17 @@ static int set_splh_notif(const char *buf, const struct kernel_param *kp)
	int ret;

	if (strnstr(buf, INIT, sizeof(INIT)) != NULL) {
		init_splh_notif(buf);
		return 0;
		splh_init_done = 0;
		ret = init_splh_notif(buf);
		if (ret < 0)
			pr_err("msm_perf: splh ipc freq tbl init failed, ret=%d\n", ret);

		return ret;
	}

	if (!splh_init_done) {
		pr_err("msm_perf: splh ipc freq tbl not initialized\n");
		return -EINVAL;
	}

	ret = param_set_int(buf, kp);
@@ -957,7 +1109,7 @@ static int set_splh_notif(const char *buf, const struct kernel_param *kp)

	activate_splh_notif();

	return ret;
	return 0;
}

static const struct kernel_param_ops param_ops_splh_notification = {
@@ -965,6 +1117,8 @@ static const struct kernel_param_ops param_ops_splh_notification = {
	.get = param_get_int,
};
module_param_cb(splh_notif, &param_ops_splh_notification, &splh_notif, 0644);
#endif /* CONFIG_QTI_PLH */


static int __init msm_performance_init(void)
{