Pārlūkot izejas kodu

msm-mmrm: Adding support for noop request/response

Adding support for noop request/response to evaluate the msg queue roundtrip.

Change-Id: I5014714002e7d8c5df11a1b9ec71f8ad2cb297f5
Mark Bao 3 gadi atpakaļ
vecāks
revīzija
bbeb858667

+ 8 - 0
vm/fe/src/mmrm_vm_fe.h

@@ -22,6 +22,12 @@ struct mmrm_vm_fe_clk_src_set {
 	u32 count;
 };
 
+struct mmrm_vm_fe_msgq_rt_stats {
+	u64 register_total_us;
+	u64 looptest_total_us;
+	u32 count;
+};
+
 struct mmrm_vm_fe_priv {
 	struct device *dev;
 
@@ -34,6 +40,8 @@ struct mmrm_vm_fe_priv {
 	struct mutex msg_send_lock;
 	int  seq_no;
 	bool is_clk_scaling_supported;
+
+	struct mmrm_vm_fe_msgq_rt_stats msgq_rt_stats;
 };
 
 struct mmrm_vm_fe_pkt {

+ 27 - 0
vm/fe/src/mmrm_vm_fe_api.c

@@ -13,6 +13,8 @@
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/ktime.h>
+
 
 #include "mmrm_vm_fe.h"
 #include "mmrm_vm_interface.h"
@@ -50,6 +52,8 @@ int mmrm_fe_append_work_list(struct mmrm_vm_msg_q *msg_q, int msg_sz)
 
 	d_mpr_w("%s: seq no:%d\n", __func__, msg_pkt->msg.hd.seq_no);
 
+	msg_pkt->start_time_ns = ktime_get_ns();
+
 	mmrm_vm_fe_request_send(drv_vm_fe, msg_pkt, msg_sz);
 
 	waited_time_ms = wait_for_completion_timeout(&msg_q->complete,
@@ -291,3 +295,26 @@ skip_mmrm:
 	return false;
 }
 EXPORT_SYMBOL(mmrm_client_check_scaling_supported);
+
+int mmrm_client_msgq_roundtrip_measure(u32 val)
+{
+	int rc = 0;
+	struct mmrm_vm_api_request_msg *api_msg;
+	struct mmrm_vm_noop_request *reg_data;
+	struct mmrm_vm_msg_q *msg_q;
+
+	size_t msg_size = sizeof(api_msg->hd) + sizeof(*reg_data);
+
+	msg_q = get_msg_work();
+	api_msg = &msg_q->m_req->msg;
+	reg_data = &api_msg->data.lptest;
+
+	api_msg->hd.cmd_id = MMRM_VM_REQUEST_NOOP;
+	reg_data->client_id = val;
+
+	rc = mmrm_fe_append_work_list(msg_q, msg_size);
+
+	release_msg_work(msg_q);
+
+	return rc;
+}

+ 16 - 3
vm/fe/src/mmrm_vm_fe_frontend.c

@@ -6,6 +6,8 @@
 #include <linux/of.h>
 #include <linux/limits.h>
 
+#include <linux/timekeeping.h>
+
 #include "mmrm_vm_fe.h"
 #include "mmrm_vm_interface.h"
 #include "mmrm_vm_msgq.h"
@@ -18,7 +20,7 @@ void mmrm_vm_fe_recv(struct mmrm_vm_driver_data *mmrm_vm, void *data, size_t siz
 	struct mmrm_vm_api_response_msg *msg = data;
 	struct mmrm_vm_msg_q *node, *temp;
 	int rc = -1;
-	u64 kt2;
+	u64 kt2, interval;
 	struct mmrm_vm_fe_priv *fe_data = mmrm_vm->vm_pvt_data;
 
 	mutex_lock(&fe_data->resp_works_lock);
@@ -40,7 +42,7 @@ void mmrm_vm_fe_recv(struct mmrm_vm_driver_data *mmrm_vm, void *data, size_t siz
 	switch (msg->hd.cmd_id) {
 	case	MMRM_VM_RESPONSE_REGISTER:
 		node->m_resp->msg.data.reg.client_id = msg->data.reg.client_id;
-		d_mpr_e("%s: client_id:%u\n", __func__, msg->data.reg.client_id);
+		d_mpr_w("%s: client_id:%u\n", __func__, msg->data.reg.client_id);
 		break;
 	case	MMRM_VM_RESPONSE_SETVALUE:
 		node->m_resp->msg.data.setval.val = msg->data.setval.val;
@@ -54,13 +56,24 @@ void mmrm_vm_fe_recv(struct mmrm_vm_driver_data *mmrm_vm, void *data, size_t siz
 	case	MMRM_VM_RESPONSE_DEREGISTER:
 		node->m_resp->msg.data.dereg.ret_code = msg->data.dereg.ret_code;
 		break;
+	case	MMRM_VM_RESPONSE_NOOP:
+		kt2 = ktime_get_ns();
+		interval = kt2 - node->m_req->start_time_ns;
+		d_mpr_w("%s: looptest start:%lu end:%lu interval:%luns\n",
+			__func__,
+			node->m_req->start_time_ns, kt2,
+			interval);
+		fe_data->msgq_rt_stats.looptest_total_us += interval;
+		break;
+	case	MMRM_VM_RESPONSE_INVALID_PKT:
+		d_mpr_e("%s: invalid request code\n");
+		break;
 	default:
 		d_mpr_e("wrong response\n");
 		break;
 	};
 
 	complete(&node->complete);
-	kt2 = ktime_get_ns();
 }
 
 int mmrm_vm_fe_request_send(struct mmrm_vm_driver_data *mmrm_vm,

+ 42 - 0
vm/fe/src/mmrm_vm_fe_main.c

@@ -53,12 +53,54 @@ ssize_t msgq_send_trigger_store(struct device *dev, struct device_attribute *att
 	return ret ? ret : count;
 }
 
+extern int mmrm_client_msgq_roundtrip_measure(u32 val);
+
+ssize_t msgq_rt_test_store(struct device *dev, struct device_attribute *attr,
+	const char *buf, size_t count)
+{
+	int ret;
+	long sz, n;
+	struct mmrm_vm_fe_priv *fe_data;
+	struct mmrm_vm_fe_msgq_rt_stats *trip_time;
+
+	if (IS_ERR_OR_NULL(drv_vm_fe)) {
+		return -1;
+	}
+	ret = kstrtol(buf, 10, &sz);
+
+	if (ret) {
+		dev_err(dev, "invalid user input\n");
+		return -1;
+	}
+	if (sz) {
+		d_mpr_w("%s: loop count:%d\n", __func__, sz);
+
+		fe_data = drv_vm_fe->vm_pvt_data;
+		trip_time = &fe_data->msgq_rt_stats;
+		trip_time->looptest_total_us = 0;
+
+		n = sz;
+		while (n-- > 0) {
+			ret = mmrm_client_msgq_roundtrip_measure(0);
+			if (ret) {
+				d_mpr_e("%s:send msgq failed\n", __func__);
+				break;
+			};
+		}
+		if (n <= 0)
+			d_mpr_w("%s: aver: %d\n", __func__, trip_time->looptest_total_us / sz);
+	}
+	return ret ? ret : count;
+}
+
 static DEVICE_ATTR_RO(dump_clk_info);
 static DEVICE_ATTR_WO(msgq_send_trigger);
+static DEVICE_ATTR_WO(msgq_rt_test);
 
 static struct attribute *mmrm_vm_fe_fs_attrs[] = {
 	&dev_attr_dump_clk_info.attr,
 	&dev_attr_msgq_send_trigger.attr,
+	&dev_attr_msgq_rt_test.attr,
 	NULL,
 };