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

Commit 69472487 authored by Bavyasritha Alahari's avatar Bavyasritha Alahari
Browse files

soc: qcom: Add VTCM handling to cdsprm driver



VTCM handling in cdsp request manager, reads the device
tree as part of platform driver registration notifier and
sends the data to guestos driver via rpmsg channel and
exposes methods to override partition mapping via
debugfs node.

Change-Id: Ie28e750f0a27f35ec114278aa0b87952ecda70f6
Acked-by: default avatarSreekanth Gande <sgande@qti.qualcomm.com>
Signed-off-by: default avatarBavyasritha Alahari <alahari@codeaurora.org>
parent 4a2732a9
Loading
Loading
Loading
Loading
+255 −5
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#define SYSMON_CDSP_FEATURE_THERMAL_LIMIT_TX	10
#define SYSMON_CDSP_FEATURE_CAMERA_ACTIVITY_TX	11
#define SYSMON_CDSP_FEATURE_VERSION_RX		12
#define SYSMON_CDSP_FEATURE_VTCM_CONFIG		13

#define SYSMON_CDSP_QOS_FLAG_IGNORE	0
#define SYSMON_CDSP_QOS_FLAG_ENABLE	1
@@ -54,6 +55,33 @@
#define CDSPRM_MSG_QUEUE_DEPTH		50
#define CDSP_THERMAL_MAX_STATE		10
#define HVX_THERMAL_MAX_STATE		10
#define NUM_VTCM_PARTITIONS_MAX		16
#define NUM_VTCM_APPID_MAPS_MAX		32
#define SYSMON_CDSP_GLINK_VERSION	0x2

enum {
	VTCM_PARTITION_SET = 1,
	VTCM_PARTITION_REMOVE = 0,
};

struct vtcm_partition_info_t {
	unsigned char partition_id;
	unsigned int size;
	unsigned int flags;
};

struct vtcm_appid_map_t {
	unsigned char app_id;
	unsigned char partition_id;
};

struct vtcm_partition_interface {
	unsigned int command;
	unsigned char num_partitions;
	unsigned char num_app_id_maps;
	struct vtcm_partition_info_t partitions[NUM_VTCM_PARTITIONS_MAX];
	struct vtcm_appid_map_t app2partition[NUM_VTCM_APPID_MAPS_MAX];
};

struct sysmon_l3_msg {
	unsigned int l3_clock_khz;
@@ -124,6 +152,15 @@ struct sysmon_msg_tx {
	unsigned int size;
};

struct sysmon_msg_tx_v2 {
	unsigned int size;
	unsigned int cdsp_ver_info;
	unsigned int feature_id;
	union {
		struct vtcm_partition_interface vtcm_partition;
	} fs;
};

enum delay_state {
	CDSP_DELAY_THREAD_NOT_STARTED = 0,
	CDSP_DELAY_THREAD_STARTED = 1,
@@ -141,8 +178,11 @@ struct cdsprm_request {
struct cdsprm {
	unsigned int			cdsp_version;
	unsigned int			event;
	unsigned int			b_vtcm_partitioning;
	unsigned int			b_vtcm_partition_en;
	struct completion		msg_avail;
	struct cdsprm_request		msg_queue[CDSPRM_MSG_QUEUE_DEPTH];
	struct vtcm_partition_interface		vtcm_partition;
	unsigned int			msg_queue_idx;
	struct task_struct		*cdsprm_wq_task;
	struct workqueue_struct		*delay_work_queue;
@@ -183,7 +223,8 @@ struct cdsprm {
	int					b_cdsprm_devinit;
	int					b_hvxrm_devinit;
	struct dentry			*debugfs_dir;
	struct dentry			*debugfs_file;
	struct dentry			*debugfs_file_priority;
	struct dentry			*debugfs_file_vtcm;
	int (*set_l3_freq)(unsigned int freq_khz);
	int (*set_l3_freq_cached)(unsigned int freq_khz);
	int (*set_corner_limit)(enum cdsprm_npu_corner);
@@ -261,6 +302,56 @@ int cdsprm_compute_core_set_priority(unsigned int priority_idx)
}
EXPORT_SYMBOL(cdsprm_compute_core_set_priority);

int cdsprm_compute_vtcm_set_partition_map(unsigned int b_vtcm_partitioning)
{
	int i, j, result = -EINVAL;
	struct sysmon_msg_tx_v2 rpmsg_v2;

	if (gcdsprm.rpmsgdev && gcdsprm.cdsp_version > 1) {

		rpmsg_v2.cdsp_ver_info = SYSMON_CDSP_GLINK_VERSION;
		rpmsg_v2.feature_id = SYSMON_CDSP_FEATURE_VTCM_CONFIG;
		rpmsg_v2.fs.vtcm_partition.command = b_vtcm_partitioning;
		rpmsg_v2.fs.vtcm_partition.num_partitions =
				gcdsprm.vtcm_partition.num_partitions;
		rpmsg_v2.fs.vtcm_partition.num_app_id_maps =
				gcdsprm.vtcm_partition.num_app_id_maps;

		for (i = 0; i < gcdsprm.vtcm_partition.num_partitions; i++) {
			rpmsg_v2.fs.vtcm_partition.partitions[i].partition_id
			= gcdsprm.vtcm_partition.partitions[i].partition_id;
			rpmsg_v2.fs.vtcm_partition.partitions[i].size =
			gcdsprm.vtcm_partition.partitions[i].size;
			rpmsg_v2.fs.vtcm_partition.partitions[i].flags =
			gcdsprm.vtcm_partition.partitions[i].flags;
		}

		for (j = 0; j < gcdsprm.vtcm_partition.num_app_id_maps; j++) {
			rpmsg_v2.fs.vtcm_partition.app2partition[j].app_id
			= gcdsprm.vtcm_partition.app2partition[j].app_id;
			rpmsg_v2.fs.vtcm_partition.app2partition[j].partition_id
			= gcdsprm.vtcm_partition.app2partition[j].partition_id;
		}

		rpmsg_v2.size = sizeof(rpmsg_v2);
		result = rpmsg_send(gcdsprm.rpmsgdev->ept,
				&rpmsg_v2,
				sizeof(rpmsg_v2));
		gcdsprm.b_vtcm_partitioning =
				rpmsg_v2.fs.vtcm_partition.command;

		if (result)
			pr_info("VTCM partition and map failed\n");
		else {
			pr_info("VTCM partition and map info set to %d\n",
					gcdsprm.b_vtcm_partitioning);
		}
	}

	return result;
}
EXPORT_SYMBOL(cdsprm_compute_vtcm_set_partition_map);

int cdsprm_cxlimit_npu_activity_notify(unsigned int b_enabled)
{
	int result = -EINVAL;
@@ -308,6 +399,7 @@ int cdsprm_cxlimit_npu_activity_notify(unsigned int b_enabled)
	}

	mutex_unlock(&gcdsprm.npu_activity_lock);

	return result;
}
EXPORT_SYMBOL(cdsprm_cxlimit_npu_activity_notify);
@@ -357,6 +449,7 @@ enum cdsprm_npu_corner cdsprm_cxlimit_npu_corner_notify(
	}

	mutex_unlock(&gcdsprm.npu_activity_lock);

	return return_npu_corner;
}
EXPORT_SYMBOL(cdsprm_cxlimit_npu_corner_notify);
@@ -566,6 +659,10 @@ static void cdsprm_rpmsg_send_details(void)
	if (!gcdsprm.cdsp_version)
		return;

	if (gcdsprm.cdsp_version > 1 && gcdsprm.b_vtcm_partition_en) {
		cdsprm_compute_vtcm_set_partition_map(VTCM_PARTITION_SET);
	}

	if (gcdsprm.b_cx_limit_en) {
		reinit_completion(&gcdsprm.npu_activity_complete);
		reinit_completion(&gcdsprm.npu_corner_complete);
@@ -897,6 +994,25 @@ static int hvx_set_cur_state(struct thermal_cooling_device *cdev,
	return 0;
}

static int cdsprm_vtcm_partition_state_read(void *data, u64 *val)
{
	*val = gcdsprm.b_vtcm_partitioning;

	return 0;
}

static int cdsprm_vtcm_partition_state_write(void *data, u64 val)
{

	cdsprm_compute_vtcm_set_partition_map((unsigned int)val);

	if (gcdsprm.b_vtcm_partitioning != val)

		return -EINVAL;

	return 0;
}

static int cdsprm_compute_prio_read(void *data, u64 *val)
{
	*val = gcdsprm.compute_prio_idx;
@@ -916,6 +1032,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(cdsprm_debugfs_fops,
			cdsprm_compute_prio_write,
			"%llu\n");

DEFINE_DEBUGFS_ATTRIBUTE(cdsprmvtcm_debugfs_fops,
			cdsprm_vtcm_partition_state_read,
			cdsprm_vtcm_partition_state_write,
			"%llu\n");

static const struct thermal_cooling_device_ops hvx_cooling_ops = {
	.get_max_state = hvx_get_max_state,
	.get_cur_state = hvx_get_cur_state,
@@ -924,6 +1045,8 @@ static const struct thermal_cooling_device_ops hvx_cooling_ops = {

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;
@@ -953,10 +1076,11 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev)
			dev_err(dev,
			"Failed to create debugfs directory for cdsprm\n");
		} else {
			gcdsprm.debugfs_file = debugfs_create_file("priority",
			gcdsprm.debugfs_file_priority =
						debugfs_create_file("priority",
						0644, gcdsprm.debugfs_dir,
						NULL, &cdsprm_debugfs_fops);
			if (!gcdsprm.debugfs_file) {
			if (!gcdsprm.debugfs_file_priority) {
				debugfs_remove_recursive(gcdsprm.debugfs_dir);
				dev_err(dev,
					"Failed to create debugfs file\n");
@@ -972,16 +1096,141 @@ static int cdsp_rm_driver_probe(struct platform_device *pdev)
		tcdev = thermal_of_cooling_device_register(dev->of_node,
							"cdsp", NULL,
							&cdsp_cooling_ops);

		if (IS_ERR(tcdev)) {
			dev_err(dev,
				"CDSP thermal driver reg failed\n");
		}

		gcdsprm.cdsp_tcdev = tcdev;
		thermal_cdev_update(tcdev);
	}

	dev_dbg(dev, "CDSP request manager driver probe called\n");
	gcdsprm.b_qosinitdone = true;
	gcdsprm.b_vtcm_partition_en = of_property_read_bool(dev->of_node,
				"qcom,vtcm-partition-info");

	if (gcdsprm.b_vtcm_partition_en) {
		n = of_property_count_u32_elems(dev->of_node,
			"qcom,vtcm-partition-info");

		gcdsprm.vtcm_partition.num_partitions = (n / 3);

		if ((n % 3) != 0) {
			dev_err(dev,
			"Maps are expected to have %d elements each entry\n",
			 n/3);
			return -EINVAL;
		}

		for (i = 0; i < gcdsprm.vtcm_partition.num_partitions; i++) {
			ret = of_property_read_u32_index(dev->of_node,
				"qcom,vtcm-partition-info", i * 3, &p);

			if (ret) {
				dev_err(dev,
				"Error reading partition element %d :%d\n",
				 i, p);
				return ret;
			}

			gcdsprm.vtcm_partition.partitions[i].partition_id
			 = (unsigned char)p;

			if (gcdsprm.vtcm_partition.partitions[i].partition_id
			 >= (n/3)) {
				dev_err(dev,
				"partition id is invalid: %d\n", n/3);
				return -EINVAL;
			}

			ret = of_property_read_u32_index(dev->of_node,
				"qcom,vtcm-partition-info", i * 3 + 1, &p);

			if (ret) {
				dev_err(dev,
						"Error reading partition element %d :%d\n"
						, i, p);
				return ret;
			}

			gcdsprm.vtcm_partition.partitions[i].size
			 = (unsigned int)p;

			ret = of_property_read_u32_index(dev->of_node,
				"qcom,vtcm-partition-info", i * 3 + 2, &p);

			if (ret) {
				dev_err(dev,
						"Error reading partition element %d :%d\n",
						 i, p);
				return ret;
			}

			gcdsprm.vtcm_partition.partitions[i].flags
			= (unsigned int)p;
		}

		m = of_property_count_u32_elems(dev->of_node,
			"qcom,vtcm-partition-map");

		gcdsprm.vtcm_partition.num_app_id_maps = (m / 2);

		if ((m % 2) != 0) {
			dev_err(dev,
			"Maps to have %d elements each entry\n", m / 2);
			return -EINVAL;
		}

		for (i = 0; i < gcdsprm.vtcm_partition.num_app_id_maps; i++) {
			ret = of_property_read_u32_index(dev->of_node,
				"qcom,vtcm-partition-map", i * 2, &p);

			if (ret) {
				dev_err(dev,
				"Error reading map element %d :%d\n", i, p);
				return ret;
			}

			gcdsprm.vtcm_partition.app2partition[i].app_id
			 = (unsigned char)p;

			ret = of_property_read_u32_index(dev->of_node,
				"qcom,vtcm-partition-map", i * 2 + 1, &p);

			if (ret) {
				dev_err(dev,
				"Error reading map element %d :%d\n", i, p);
				return ret;
			}

			gcdsprm.vtcm_partition.app2partition[i].partition_id
			 = (unsigned char)p;
		}

		if (!gcdsprm.b_cx_limit_en || !gcdsprm.debugfs_dir)
			gcdsprm.debugfs_dir
			 = debugfs_create_dir("compute", NULL);

		if (!gcdsprm.debugfs_dir)
			dev_err(dev,
			"Failed to find debugfs directory for cdsprm\n");
		else {
			gcdsprm.debugfs_file_vtcm =
				debugfs_create_file("vtcm_partition_state",
				0644, gcdsprm.debugfs_dir,
				NULL, &cdsprmvtcm_debugfs_fops);
		}

		if (!gcdsprm.debugfs_file_vtcm
			&& !gcdsprm.debugfs_file_priority) {
			debugfs_remove_recursive(gcdsprm.debugfs_dir);
					dev_err(dev,
					"Failed to create debugfs file\n");
		}
	}

	dev_dbg(dev, "CDSP request manager driver probe called\n");

	return 0;
}
@@ -1231,7 +1480,8 @@ static void __exit cdsprm_exit(void)
	gcdsprm.b_hvxrm_devinit = false;
	gcdsprm.b_cdsprm_devinit = false;
	gcdsprm.debugfs_dir = NULL;
	gcdsprm.debugfs_file = NULL;
	gcdsprm.debugfs_file_priority = NULL;
	gcdsprm.debugfs_file_vtcm = NULL;
	gcdsprm.hvx_tcdev = NULL;
	gcdsprm.cdsp_tcdev = NULL;

+15 −0
Original line number Diff line number Diff line
@@ -39,4 +39,19 @@ void cdsprm_register_cdspl3gov(struct cdsprm_l3 *arg);
 */
void cdsprm_unregister_cdspl3gov(void);

/**
 * cdsprm_compute_vtcm_set_partition_map() - Send the vtcm partition and
 *                                           map data to cdsp via
 *                                           rpmsg channel
 * @arg: b_vtcm_partitioning 0 - disable VTCM partitioning
 *                           1 - enable VTCM partitioning
 *@return SUCCESS (0) if vtcm partition and map data is sent
 *         FAILURE (Non-zero) if vtcm partition and map sent fails
 * Note: VTCM partitioning should be defined in the device tree for
 *        the enable / disable request to go through.
 *
 */

int cdsprm_compute_vtcm_set_partition_map(unsigned int b_vtcm_partitioning);

#endif