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

Commit ef118485 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 4ec71ffb 16a2c185
Loading
Loading
Loading
Loading
+103 −14
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018-2020, 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>
@@ -231,6 +232,7 @@ struct cdsprm {
	bool				b_rpmsg_register;
	bool				b_qosinitdone;
	bool				b_applyingNpuLimit;
	bool				b_silver_en;
	int					latency_request;
	int					b_cdsprm_devinit;
	int					b_hvxrm_devinit;
@@ -245,6 +247,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;
@@ -594,8 +599,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;
		}

		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);
@@ -605,6 +686,7 @@ static void set_qos_latency(int latency)
				latency);
		}
	}
}

static void process_rm_request(struct sysmon_msg *msg)
{
@@ -646,9 +728,9 @@ 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);
		}
@@ -689,8 +771,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;

@@ -1142,10 +1224,17 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev)
{
	int n, m, i, ret;
	u32 p;

	struct device *dev = &pdev->dev;
	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;
@@ -1505,8 +1594,8 @@ static void __exit cdsprm_exit(void)

	pr_info("Exit module called\n");
	if (gcdsprm.qos_request) {
		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;
	}

	if (gcdsprm.hvx_tcdev)