summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuang Chaofan <chaofan.huang@nxp.com>2018-11-26 14:45:44 +0800
committerBryan O'Donoghue <bryan.odonoghue@linaro.org>2019-01-25 16:14:18 +0000
commit373ff085de1b1835dd45d915eb608fd62971913a (patch)
tree5a8f15ff7ccbbd3e0fe3931b7670d9ab3ba190fd
parent8abbb7693e99f19066cd6af8c8b36ba7ea6efd2a (diff)
MLK-20426 VPU: Adding more statistic info for debug
Adding more statistic info for debug Signed-off-by: Huang Chaofan <chaofan.huang@nxp.com> (cherry picked from commit ebef17b0a54a307a5f98d5912a7848b922bb863d)
-rw-r--r--drivers/mxc/vpu-decoder-b0/Makefile3
-rw-r--r--drivers/mxc/vpu-decoder-b0/vpu_b0.c82
-rw-r--r--drivers/mxc/vpu-decoder-b0/vpu_b0.h3
-rw-r--r--drivers/mxc/vpu-decoder-b0/vpu_debug_log.c133
-rw-r--r--drivers/mxc/vpu-decoder-b0/vpu_debug_log.h48
5 files changed, 267 insertions, 2 deletions
diff --git a/drivers/mxc/vpu-decoder-b0/Makefile b/drivers/mxc/vpu-decoder-b0/Makefile
index fc4c91ab4061..2c27d2f03e11 100644
--- a/drivers/mxc/vpu-decoder-b0/Makefile
+++ b/drivers/mxc/vpu-decoder-b0/Makefile
@@ -9,7 +9,8 @@ EXTRA_CFLAGS += $(DEFINES)
obj-y = vpu-decoder.o
vpu-decoder-objs = vpu_b0.o \
vpu_rpc.o \
- insert_startcode.o
+ insert_startcode.o \
+ vpu_debug_log.o
clean:
rm -rf $(vpu-decoder-objs)
diff --git a/drivers/mxc/vpu-decoder-b0/vpu_b0.c b/drivers/mxc/vpu-decoder-b0/vpu_b0.c
index 3687cb56917e..df95063ab2ef 100644
--- a/drivers/mxc/vpu-decoder-b0/vpu_b0.c
+++ b/drivers/mxc/vpu-decoder-b0/vpu_b0.c
@@ -48,9 +48,11 @@
#include "vpu_b0.h"
#include "insert_startcode.h"
+#include "vpu_debug_log.h"
unsigned int vpu_dbg_level_decoder = 1;
static int vpu_frm_depth = INVALID_FRAME_DEPTH;
+static int vpu_log_depth = 10;
/* Generic End of content startcodes to differentiate from those naturally in the stream/file */
#define EOS_GENERIC_HEVC 0x7c010000
@@ -972,6 +974,7 @@ static int v4l2_ioctl_streamoff(struct file *file,
vpu_dbg(LVL_INFO, "%s(): send VID_API_CMD_ABORT\n", __func__);
size = add_scode(ctx, 0, BUFABORT_PADDING_TYPE, false);
+ record_log_info(ctx, LOG_PADDING, 0, 0);
if (size < 0)
vpu_dbg(LVL_ERR, "%s(): failed to fill abort padding data\n", __func__);
v4l2_vpu_send_cmd(ctx, ctx->str_index, VID_API_CMD_ABORT, 1, &size);
@@ -1406,6 +1409,7 @@ static void v4l2_vpu_send_cmd(struct vpu_ctx *ctx, uint32_t idx, uint32_t cmdid,
{
vpu_log_cmd(cmdid, idx);
count_cmd(&ctx->statistic, cmdid);
+ record_log_info(ctx, LOG_COMMAND, cmdid, 0);
mutex_lock(&ctx->dev->cmd_mutex);
rpc_send_cmd_buf(&ctx->dev->shared_mem, idx, cmdid, cmdnum, local_cmddata);
mutex_unlock(&ctx->dev->cmd_mutex);
@@ -1586,6 +1590,7 @@ static int update_stream_addr(struct vpu_ctx *ctx, void *input_buffer, uint32_t
if (nfreespace - buffer_size - length < MIN_SPACE)
return 0;
+ record_log_info(ctx, LOG_UPDATE_STREAM, 0, buffer_size);
if (nfreespace >= buffer_size + length) {
if ((wptr == rptr) || (wptr > rptr)) {
if (end - wptr >= length) {
@@ -1677,6 +1682,7 @@ static void v4l2_update_stream_addr(struct vpu_ctx *ctx, uint32_t uStrBufIdx)
if (!ctx->firmware_stopped) {
vpu_dbg(LVL_EVENT, "ctx[%d]: insert eos directly\n", ctx->str_index);
if (add_scode(ctx, 0, EOS_PADDING_TYPE, true) >= 0) {
+ record_log_info(ctx, LOG_EOS, 0, 0);
ctx->eos_stop_received = false;
ctx->eos_stop_added = true;
}
@@ -1762,6 +1768,7 @@ static void vpu_api_event_handler(struct vpu_ctx *ctx, u_int32 uStrIdx, u_int32
vpu_log_event(uEvent, uStrIdx);
count_event(&ctx->statistic, uEvent);
+ record_log_info(ctx, LOG_EVENT, uEvent, 0);
if (ctx == NULL) {
vpu_dbg(LVL_ERR, "receive event: 0x%X after instance released, ignore it\n", uEvent);
@@ -2254,6 +2261,7 @@ static int release_hang_instance(struct vpu_dev *dev)
for (i = 0; i < VPU_MAX_NUM_STREAMS; i++)
if (dev->ctx[i]) {
remove_instance_file(dev->ctx[i]);
+ destroy_log_info_queue(dev->ctx[i]);
kfree(dev->ctx[i]);
dev->ctx[i] = NULL;
}
@@ -2725,6 +2733,58 @@ static ssize_t show_instance_buffer_info(struct device *dev,
return num;
}
+static ssize_t show_instance_log_info(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct vpu_ctx *ctx;
+ struct vpu_statistic *statistic;
+ struct vpu_log_info *vpu_info;
+ struct vpu_log_info *tem_info;
+ int num = 0;
+
+ ctx = container_of(attr, struct vpu_ctx, dev_attr_instance_flow);
+ statistic = &ctx->statistic;
+
+ num += snprintf(buf + num, PAGE_SIZE - num, "log info under depth: %d\n",
+ vpu_log_depth);
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->log_q))
+ goto exit;
+
+ list_for_each_entry_safe(vpu_info, tem_info, &ctx->log_q, list) {
+ switch (vpu_info->type) {
+ case LOG_EVENT:
+ num += snprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%26s\n", "event", event2str[vpu_info->log_info[vpu_info->type]]);
+ break;
+ case LOG_COMMAND:
+ num += snprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%26s\n", "command", cmd2str[vpu_info->log_info[vpu_info->type]]);
+ break;
+ case LOG_EOS:
+ num += snprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%26s\n", "add eos", "done");
+ break;
+ case LOG_PADDING:
+ num += snprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%26s\n", "add padding", "done");
+ break;
+ case LOG_UPDATE_STREAM:
+ num += snprintf(buf + num, PAGE_SIZE - num,
+ "\t%20s:%16s %16d\n", "update stream data", "stream size", vpu_info->data);
+ break;
+ default:
+ break;
+ }
+ }
+
+exit:
+ mutex_unlock(&ctx->instance_mutex);
+ return num;
+}
+
+
static int create_instance_command_file(struct vpu_ctx *ctx)
{
snprintf(ctx->command_name, sizeof(ctx->command_name) - 1,
@@ -2767,6 +2827,19 @@ static int create_instance_buffer_file(struct vpu_ctx *ctx)
return 0;
}
+static int create_instance_flow_file(struct vpu_ctx *ctx)
+{
+ snprintf(ctx->flow_name, sizeof(ctx->flow_name) - 1,
+ "instance%d_flow",
+ ctx->str_index);
+ ctx->dev_attr_instance_flow.attr.name = ctx->flow_name;
+ ctx->dev_attr_instance_flow.attr.mode = VERIFY_OCTAL_PERMISSIONS(0444);
+ ctx->dev_attr_instance_flow.show = show_instance_log_info;
+
+ device_create_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_flow);
+
+ return 0;
+}
static int create_instance_file(struct vpu_ctx *ctx)
{
if (!ctx || !ctx->dev || !ctx->dev->generic_dev)
@@ -2775,6 +2848,7 @@ static int create_instance_file(struct vpu_ctx *ctx)
create_instance_command_file(ctx);
create_instance_event_file(ctx);
create_instance_buffer_file(ctx);
+ create_instance_flow_file(ctx);
return 0;
}
@@ -2787,6 +2861,7 @@ static int remove_instance_file(struct vpu_ctx *ctx)
device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_command);
device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_event);
device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_buffer);
+ device_remove_file(ctx->dev->generic_dev, &ctx->dev_attr_instance_flow);
return 0;
}
@@ -2893,6 +2968,8 @@ static int v4l2_open(struct file *filp)
goto err_alloc_seq;
}
init_queue_data(ctx);
+ init_log_info_queue(ctx);
+ create_log_info_queue(ctx, vpu_log_depth);
init_waitqueue_head(&ctx->buffer_wq);
mutex_lock(&dev->dev_mutex);
if (!dev->fw_is_ready) {
@@ -2997,6 +3074,7 @@ static int v4l2_release(struct file *filp)
if (!ctx->hang_status) { // judge the path is hang or not, if hang, don't clear
remove_instance_file(ctx);
+ destroy_log_info_queue(ctx);
clear_bit(ctx->str_index, &dev->instance_mask);
dev->ctx[ctx->str_index] = NULL;
kfree(ctx);
@@ -3575,5 +3653,7 @@ MODULE_LICENSE("GPL");
module_param(vpu_dbg_level_decoder, int, 0644);
MODULE_PARM_DESC(vpu_dbg_level_decoder, "Debug level (0-2)");
module_param(vpu_frm_depth, int, 0644);
-MODULE_PARM_DESC(vpu_frm_depth, "maxium frame number in data pool");
+MODULE_PARM_DESC(vpu_frm_depth, "maximum frame number in data pool");
+module_param(vpu_log_depth, int, 0644);
+MODULE_PARM_DESC(vpu_log_depth, "maximum log number in queue");
diff --git a/drivers/mxc/vpu-decoder-b0/vpu_b0.h b/drivers/mxc/vpu-decoder-b0/vpu_b0.h
index aaafda059f39..0d614cc7b7f6 100644
--- a/drivers/mxc/vpu-decoder-b0/vpu_b0.h
+++ b/drivers/mxc/vpu-decoder-b0/vpu_b0.h
@@ -248,9 +248,12 @@ struct vpu_ctx {
char event_name[64];
struct device_attribute dev_attr_instance_buffer;
char buffer_name[64];
+ struct device_attribute dev_attr_instance_flow;
+ char flow_name[64];
struct v4l2_ctrl *ctrls[V4L2_MAX_CTRLS];
struct v4l2_ctrl_handler ctrl_handler;
bool ctrl_inited;
+ struct list_head log_q;
int str_index;
struct queue_data q_data[2];
diff --git a/drivers/mxc/vpu-decoder-b0/vpu_debug_log.c b/drivers/mxc/vpu-decoder-b0/vpu_debug_log.c
new file mode 100644
index 000000000000..47653439385e
--- /dev/null
+++ b/drivers/mxc/vpu-decoder-b0/vpu_debug_log.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file vpu-debug_log.c
+ *
+ * copyright here may be changed later
+ *
+ *
+ */
+#include "vpu_debug_log.h"
+
+int init_log_info_queue(struct vpu_ctx *ctx)
+{
+ if (!ctx)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+ INIT_LIST_HEAD(&ctx->log_q);
+ mutex_unlock(&ctx->instance_mutex);
+ return 0;
+}
+
+int create_log_info_queue(struct vpu_ctx *ctx, u_int32 vpu_log_depth)
+{
+ struct vpu_log_info *vpu_info = NULL;
+ u_int32 i;
+
+ if (!ctx)
+ return -EINVAL;
+
+ for (i = 0; i < vpu_log_depth; i++) {
+ vpu_info = kzalloc(sizeof(*vpu_info), GFP_KERNEL);
+ if (!vpu_info)
+ continue;
+
+ list_add_tail(&vpu_info->list, &ctx->log_q);
+ }
+
+ return 0;
+}
+
+int destroy_log_info_queue(struct vpu_ctx *ctx)
+{
+ struct vpu_log_info *vpu_info, *temp_info;
+ u_int32 ret = 0;
+
+ if (!ctx)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->log_q)) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ list_for_each_entry_safe(vpu_info, temp_info, &ctx->log_q, list)
+ if (!vpu_info)
+ list_del_init(&vpu_info->list);
+
+exit:
+ mutex_unlock(&ctx->instance_mutex);
+
+ return ret;
+}
+
+int put_log_info(struct vpu_ctx *ctx, struct vpu_log_info *vpu_info)
+{
+ if (!ctx || !vpu_info)
+ return -EINVAL;
+
+ mutex_lock(&ctx->instance_mutex);
+ list_add_tail(&vpu_info->list, &ctx->log_q);
+ mutex_unlock(&ctx->instance_mutex);
+
+ return 0;
+}
+
+struct vpu_log_info *pop_log_info(struct vpu_ctx *ctx)
+{
+ struct vpu_log_info *vpu_info = NULL;
+
+ if (!ctx)
+ return NULL;
+
+ mutex_lock(&ctx->instance_mutex);
+ if (list_empty(&ctx->log_q))
+ vpu_info = NULL;
+ vpu_info = list_first_entry(&ctx->log_q, struct vpu_log_info, list);
+ if (vpu_info)
+ list_del_init(&vpu_info->list);
+ mutex_unlock(&ctx->instance_mutex);
+ return vpu_info;
+}
+
+int set_log_info(struct vpu_log_info *vpu_info, enum ACTION_TYPE type, u_int32 info, u_int32 info_data)
+{
+ if (!vpu_info)
+ return -EINVAL;
+ if (type >= LOG_RESERVED)
+ return -EINVAL;
+
+ vpu_info->type = type;
+ vpu_info->log_info[type] = info;
+ vpu_info->data = info_data;
+ return 0;
+}
+
+int record_log_info(struct vpu_ctx *ctx, enum ACTION_TYPE type, u_int32 info, u_int32 info_data)
+{
+ struct vpu_log_info *vpu_info = NULL;
+
+ if (!ctx)
+ return -EINVAL;
+
+ vpu_info = pop_log_info(ctx);
+ if (!vpu_info)
+ return -EINVAL;
+ set_log_info(vpu_info, type, info, info_data);
+ put_log_info(ctx, vpu_info);
+
+ return 0;
+}
+
diff --git a/drivers/mxc/vpu-decoder-b0/vpu_debug_log.h b/drivers/mxc/vpu-decoder-b0/vpu_debug_log.h
new file mode 100644
index 000000000000..a42e9ea9a044
--- /dev/null
+++ b/drivers/mxc/vpu-decoder-b0/vpu_debug_log.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @file vpu_debug_log.h
+ *
+ * @brief VPU debug definition
+ *
+ */
+#ifndef _VPU_DEBUG_LOG_H_
+#define _VPU_DEBUG_LOG_H_
+#include "vpu_b0.h"
+enum ACTION_TYPE {
+ LOG_NULL = 0,
+ LOG_EVENT,
+ LOG_COMMAND,
+ LOG_PADDING,
+ LOG_EOS,
+ LOG_UPDATE_STREAM,
+ LOG_RESERVED,
+};
+
+struct vpu_log_info {
+ struct list_head list;
+ enum ACTION_TYPE type;
+ u_int32 log_info[LOG_RESERVED];
+ u_int32 data;
+};
+int init_log_info_queue(struct vpu_ctx *ctx);
+int create_log_info_queue(struct vpu_ctx *ctx, u_int32 vpu_log_depth);
+int destroy_log_info_queue(struct vpu_ctx *ctx);
+int put_log_info(struct vpu_ctx *ctx, struct vpu_log_info *vpu_info);
+struct vpu_log_info *pop_log_info(struct vpu_ctx *ctx);
+int set_log_info(struct vpu_log_info *vpu_info, enum ACTION_TYPE type, u_int32 info, u_int32 info_data);
+int record_log_info(struct vpu_ctx *ctx, enum ACTION_TYPE type, u_int32 info, u_int32 info_data);
+
+#endif
+