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

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

Merge "soc: qcom: Set QOS only to silver cluster"

parents 9d29e4d3 197ef58c
Loading
Loading
Loading
Loading
+115 −19
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
 */

/*
@@ -13,6 +13,7 @@

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/string.h>
#include <linux/err.h>
@@ -179,6 +180,7 @@ struct cdsprm {
	bool				b_rpmsg_register;
	bool				b_qosinitdone;
	bool				b_applyingNpuLimit;
	bool				b_silver_en;
	int					latency_request;
	struct dentry			*debugfs_dir;
	struct dentry			*debugfs_file;
@@ -186,6 +188,9 @@ struct cdsprm {
	int (*set_l3_freq_cached)(unsigned int freq_khz);
	int (*set_corner_limit)(enum cdsprm_npu_corner);
	int (*set_corner_limit_cached)(enum cdsprm_npu_corner);
	u32 *coreno;
	u32 corecount;
	struct dev_pm_qos_request *dev_pm_qos_req;
};

static struct cdsprm gcdsprm;
@@ -454,8 +459,84 @@ void cdsprm_unregister_cdspl3gov(void)
}
EXPORT_SYMBOL(cdsprm_unregister_cdspl3gov);

static void qos_cores_init(struct device *dev)
{
	int i, err = 0;
	u32 *cpucores = NULL;

	of_find_property(dev->of_node,
					"qcom,qos-cores", &gcdsprm.corecount);

	if (gcdsprm.corecount) {
		gcdsprm.corecount /= sizeof(u32);

		cpucores = kcalloc(gcdsprm.corecount,
					sizeof(u32), GFP_KERNEL);

		if (cpucores == NULL) {
			dev_err(dev,
					"kcalloc failed for cpucores\n");
			gcdsprm.b_silver_en = false;
		} else {
			for (i = 0; i < gcdsprm.corecount; i++) {
				err = of_property_read_u32_index(dev->of_node,
					"qcom,qos-cores", i, &cpucores[i]);
				if (err) {
					dev_err(dev,
						"%s: failed to read QOS coree for core:%d\n",
							__func__, i);
					gcdsprm.b_silver_en = false;
				}
			}

			gcdsprm.coreno = cpucores;

			gcdsprm.dev_pm_qos_req = kcalloc(gcdsprm.corecount,
				sizeof(struct dev_pm_qos_request), GFP_KERNEL);

			if (gcdsprm.dev_pm_qos_req == NULL) {
				dev_err(dev,
						"kcalloc failed for dev_pm_qos_req\n");
				gcdsprm.b_silver_en = false;
			}
		}
	}
}

static void set_qos_latency(int latency)
{
	int err = 0;
	u32 ii = 0;
	int cpu;

	if (gcdsprm.b_silver_en) {

		for (ii = 0; ii < gcdsprm.corecount; ii++) {
			cpu = gcdsprm.coreno[ii];

			if (!gcdsprm.qos_request) {
				err = dev_pm_qos_add_request(
						get_cpu_device(cpu),
						&gcdsprm.dev_pm_qos_req[ii],
						DEV_PM_QOS_RESUME_LATENCY,
						latency);
			} else {
				err = dev_pm_qos_update_request(
						&gcdsprm.dev_pm_qos_req[ii],
						latency);
			}

			if (err < 0) {
				pr_err("%s: %s: PM voting cpu:%d fail,err %d,QoS update %d\n",
					current->comm, __func__, cpu,
					err, gcdsprm.qos_request);
				break;
			}
		}

		if (err >= 0)
			gcdsprm.qos_request = true;
	} else {
		if (!gcdsprm.qos_request) {
			pm_qos_add_request(&gcdsprm.pm_qos_req,
			PM_QOS_CPU_DMA_LATENCY, latency);
@@ -465,6 +546,7 @@ static void set_qos_latency(int latency)
			latency);
		}
	}
}

static void process_rm_request(struct sysmon_msg *msg)
{
@@ -506,9 +588,10 @@ static void process_rm_request(struct sysmon_msg *msg)
		} else if ((rm_msg->b_qos_flag ==
					SYSMON_CDSP_QOS_FLAG_DISABLE) &&
				(gcdsprm.latency_request !=
					QOS_LATENCY_DISABLE_VALUE)) {
			set_qos_latency(QOS_LATENCY_DISABLE_VALUE);
			gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE;
					PM_QOS_RESUME_LATENCY_DEFAULT_VALUE)) {
			set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE);
			gcdsprm.latency_request =
					PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
			pr_debug("Set qos latency to %d\n",
					gcdsprm.latency_request);
		}
@@ -549,8 +632,8 @@ static void process_delayed_rm_request(struct work_struct *work)
		curr_timestamp = arch_counter_get_cntvct();
	}

	set_qos_latency(QOS_LATENCY_DISABLE_VALUE);
	gcdsprm.latency_request = QOS_LATENCY_DISABLE_VALUE;
	set_qos_latency(PM_QOS_RESUME_LATENCY_DEFAULT_VALUE);
	gcdsprm.latency_request = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
	pr_debug("Set qos latency to %d\n", gcdsprm.latency_request);
	gcdsprm.dt_state = CDSP_DELAY_THREAD_EXITING;

@@ -640,16 +723,22 @@ static int process_cdsp_request_thread(void *data)
		result = wait_event_interruptible(cdsprm_wq,
						(req = get_next_request()));

		if (kthread_should_stop())
			break;

		if (result)
			continue;

		if (!req)
			break;

		msg = &req->msg;

		if ((msg->feature_id == SYSMON_CDSP_FEATURE_RM_RX) &&
		if (msg && (msg->feature_id == SYSMON_CDSP_FEATURE_RM_RX) &&
			gcdsprm.b_qosinitdone) {
			process_rm_request(msg);
		} else if (msg->feature_id ==
			SYSMON_CDSP_FEATURE_L3_RX) {
		} else if (msg && (msg->feature_id ==
			SYSMON_CDSP_FEATURE_L3_RX)) {
			l3_clock_khz = msg->fs.l3_struct.l3_clock_khz;

			spin_lock_irqsave(&gcdsprm.l3_lock, flags);
@@ -661,8 +750,8 @@ static int process_cdsp_request_thread(void *data)
				pr_debug("Set L3 clock %d done\n",
					l3_clock_khz);
			}
		} else if (msg->feature_id ==
				SYSMON_CDSP_FEATURE_NPU_LIMIT_RX) {
		} else if (msg && (msg->feature_id ==
				SYSMON_CDSP_FEATURE_NPU_LIMIT_RX)) {
			mutex_lock(&gcdsprm.npu_activity_lock);

			gcdsprm.set_corner_limit_cached =
@@ -706,8 +795,8 @@ static int process_cdsp_request_thread(void *data)
				pr_err("rpmsg send failed %d\n", result);
			else
				pr_debug("NPU limit ack sent\n");
		} else if (msg->feature_id ==
				SYSMON_CDSP_FEATURE_VERSION_RX) {
		} else if (msg && (msg->feature_id ==
				SYSMON_CDSP_FEATURE_VERSION_RX)) {
			cdsprm_rpmsg_send_details();
			pr_debug("Sent preserved data to DSP\n");
		}
@@ -928,6 +1017,12 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev)
	struct thermal_cooling_device *tcdev = 0;
	unsigned int cooling_cells = 0;

	gcdsprm.b_silver_en = of_property_read_bool(dev->of_node,
					"qcom,qos-cores");

	if (gcdsprm.b_silver_en)
		qos_cores_init(dev);

	if (of_property_read_u32(dev->of_node,
			"qcom,qos-latency-us", &gcdsprm.qos_latency_us)) {
		return -EINVAL;
@@ -1101,6 +1196,7 @@ static int __init cdsprm_init(void)
		goto bail;
	}


	err = platform_driver_register(&hvx_rm);

	if (err) {