162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2020-2021 NXP
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/init.h>
762306a36Sopenharmony_ci#include <linux/device.h>
862306a36Sopenharmony_ci#include <linux/ioctl.h>
962306a36Sopenharmony_ci#include <linux/list.h>
1062306a36Sopenharmony_ci#include <linux/module.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/types.h>
1362306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1462306a36Sopenharmony_ci#include <media/v4l2-device.h>
1562306a36Sopenharmony_ci#include <linux/debugfs.h>
1662306a36Sopenharmony_ci#include "vpu.h"
1762306a36Sopenharmony_ci#include "vpu_defs.h"
1862306a36Sopenharmony_ci#include "vpu_core.h"
1962306a36Sopenharmony_ci#include "vpu_helpers.h"
2062306a36Sopenharmony_ci#include "vpu_cmds.h"
2162306a36Sopenharmony_ci#include "vpu_rpc.h"
2262306a36Sopenharmony_ci#include "vpu_v4l2.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct print_buf_desc {
2562306a36Sopenharmony_ci	u32 start_h_phy;
2662306a36Sopenharmony_ci	u32 start_h_vir;
2762306a36Sopenharmony_ci	u32 start_m;
2862306a36Sopenharmony_ci	u32 bytes;
2962306a36Sopenharmony_ci	u32 read;
3062306a36Sopenharmony_ci	u32 write;
3162306a36Sopenharmony_ci	char buffer[];
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic char *vb2_stat_name[] = {
3562306a36Sopenharmony_ci	[VB2_BUF_STATE_DEQUEUED] = "dequeued",
3662306a36Sopenharmony_ci	[VB2_BUF_STATE_IN_REQUEST] = "in_request",
3762306a36Sopenharmony_ci	[VB2_BUF_STATE_PREPARING] = "preparing",
3862306a36Sopenharmony_ci	[VB2_BUF_STATE_QUEUED] = "queued",
3962306a36Sopenharmony_ci	[VB2_BUF_STATE_ACTIVE] = "active",
4062306a36Sopenharmony_ci	[VB2_BUF_STATE_DONE] = "done",
4162306a36Sopenharmony_ci	[VB2_BUF_STATE_ERROR] = "error",
4262306a36Sopenharmony_ci};
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic char *vpu_stat_name[] = {
4562306a36Sopenharmony_ci	[VPU_BUF_STATE_IDLE] = "idle",
4662306a36Sopenharmony_ci	[VPU_BUF_STATE_INUSE] = "inuse",
4762306a36Sopenharmony_ci	[VPU_BUF_STATE_DECODED] = "decoded",
4862306a36Sopenharmony_ci	[VPU_BUF_STATE_READY] = "ready",
4962306a36Sopenharmony_ci	[VPU_BUF_STATE_SKIP] = "skip",
5062306a36Sopenharmony_ci	[VPU_BUF_STATE_ERROR] = "error",
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline const char *to_vpu_stat_name(int state)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	if (state <= VPU_BUF_STATE_ERROR)
5662306a36Sopenharmony_ci		return vpu_stat_name[state];
5762306a36Sopenharmony_ci	return "unknown";
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic int vpu_dbg_instance(struct seq_file *s, void *data)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	struct vpu_inst *inst = s->private;
6362306a36Sopenharmony_ci	char str[128];
6462306a36Sopenharmony_ci	int num;
6562306a36Sopenharmony_ci	struct vb2_queue *vq;
6662306a36Sopenharmony_ci	int i;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	if (!inst->fh.m2m_ctx)
6962306a36Sopenharmony_ci		return 0;
7062306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(inst->type));
7162306a36Sopenharmony_ci	if (seq_write(s, str, num))
7262306a36Sopenharmony_ci		return 0;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid);
7562306a36Sopenharmony_ci	if (seq_write(s, str, num))
7662306a36Sopenharmony_ci		return 0;
7762306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "state = %s\n", vpu_codec_state_name(inst->state));
7862306a36Sopenharmony_ci	if (seq_write(s, str, num))
7962306a36Sopenharmony_ci		return 0;
8062306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str),
8162306a36Sopenharmony_ci			"min_buffer_out = %d, min_buffer_cap = %d\n",
8262306a36Sopenharmony_ci			inst->min_buffer_out, inst->min_buffer_cap);
8362306a36Sopenharmony_ci	if (seq_write(s, str, num))
8462306a36Sopenharmony_ci		return 0;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
8762306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str),
8862306a36Sopenharmony_ci			"output (%2d, %2d): fmt = %c%c%c%c %d x %d, %d;",
8962306a36Sopenharmony_ci			vb2_is_streaming(vq),
9062306a36Sopenharmony_ci			vq->num_buffers,
9162306a36Sopenharmony_ci			inst->out_format.pixfmt,
9262306a36Sopenharmony_ci			inst->out_format.pixfmt >> 8,
9362306a36Sopenharmony_ci			inst->out_format.pixfmt >> 16,
9462306a36Sopenharmony_ci			inst->out_format.pixfmt >> 24,
9562306a36Sopenharmony_ci			inst->out_format.width,
9662306a36Sopenharmony_ci			inst->out_format.height,
9762306a36Sopenharmony_ci			vq->last_buffer_dequeued);
9862306a36Sopenharmony_ci	if (seq_write(s, str, num))
9962306a36Sopenharmony_ci		return 0;
10062306a36Sopenharmony_ci	for (i = 0; i < inst->out_format.mem_planes; i++) {
10162306a36Sopenharmony_ci		num = scnprintf(str, sizeof(str), " %d(%d)",
10262306a36Sopenharmony_ci				vpu_get_fmt_plane_size(&inst->out_format, i),
10362306a36Sopenharmony_ci				inst->out_format.bytesperline[i]);
10462306a36Sopenharmony_ci		if (seq_write(s, str, num))
10562306a36Sopenharmony_ci			return 0;
10662306a36Sopenharmony_ci	}
10762306a36Sopenharmony_ci	if (seq_write(s, "\n", 1))
10862306a36Sopenharmony_ci		return 0;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
11162306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str),
11262306a36Sopenharmony_ci			"capture(%2d, %2d): fmt = %c%c%c%c %d x %d, %d;",
11362306a36Sopenharmony_ci			vb2_is_streaming(vq),
11462306a36Sopenharmony_ci			vq->num_buffers,
11562306a36Sopenharmony_ci			inst->cap_format.pixfmt,
11662306a36Sopenharmony_ci			inst->cap_format.pixfmt >> 8,
11762306a36Sopenharmony_ci			inst->cap_format.pixfmt >> 16,
11862306a36Sopenharmony_ci			inst->cap_format.pixfmt >> 24,
11962306a36Sopenharmony_ci			inst->cap_format.width,
12062306a36Sopenharmony_ci			inst->cap_format.height,
12162306a36Sopenharmony_ci			vq->last_buffer_dequeued);
12262306a36Sopenharmony_ci	if (seq_write(s, str, num))
12362306a36Sopenharmony_ci		return 0;
12462306a36Sopenharmony_ci	for (i = 0; i < inst->cap_format.mem_planes; i++) {
12562306a36Sopenharmony_ci		num = scnprintf(str, sizeof(str), " %d(%d)",
12662306a36Sopenharmony_ci				vpu_get_fmt_plane_size(&inst->cap_format, i),
12762306a36Sopenharmony_ci				inst->cap_format.bytesperline[i]);
12862306a36Sopenharmony_ci		if (seq_write(s, str, num))
12962306a36Sopenharmony_ci			return 0;
13062306a36Sopenharmony_ci	}
13162306a36Sopenharmony_ci	if (seq_write(s, "\n", 1))
13262306a36Sopenharmony_ci		return 0;
13362306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "crop: (%d, %d) %d x %d\n",
13462306a36Sopenharmony_ci			inst->crop.left,
13562306a36Sopenharmony_ci			inst->crop.top,
13662306a36Sopenharmony_ci			inst->crop.width,
13762306a36Sopenharmony_ci			inst->crop.height);
13862306a36Sopenharmony_ci	if (seq_write(s, str, num))
13962306a36Sopenharmony_ci		return 0;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
14262306a36Sopenharmony_ci	for (i = 0; i < vq->num_buffers; i++) {
14362306a36Sopenharmony_ci		struct vb2_buffer *vb = vq->bufs[i];
14462306a36Sopenharmony_ci		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci		if (vb->state == VB2_BUF_STATE_DEQUEUED)
14762306a36Sopenharmony_ci			continue;
14862306a36Sopenharmony_ci		num = scnprintf(str, sizeof(str),
14962306a36Sopenharmony_ci				"output [%2d] state = %10s, %8s\n",
15062306a36Sopenharmony_ci				i, vb2_stat_name[vb->state],
15162306a36Sopenharmony_ci				to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
15262306a36Sopenharmony_ci		if (seq_write(s, str, num))
15362306a36Sopenharmony_ci			return 0;
15462306a36Sopenharmony_ci	}
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
15762306a36Sopenharmony_ci	for (i = 0; i < vq->num_buffers; i++) {
15862306a36Sopenharmony_ci		struct vb2_buffer *vb = vq->bufs[i];
15962306a36Sopenharmony_ci		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci		if (vb->state == VB2_BUF_STATE_DEQUEUED)
16262306a36Sopenharmony_ci			continue;
16362306a36Sopenharmony_ci		num = scnprintf(str, sizeof(str),
16462306a36Sopenharmony_ci				"capture[%2d] state = %10s, %8s\n",
16562306a36Sopenharmony_ci				i, vb2_stat_name[vb->state],
16662306a36Sopenharmony_ci				to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
16762306a36Sopenharmony_ci		if (seq_write(s, str, num))
16862306a36Sopenharmony_ci			return 0;
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
17262306a36Sopenharmony_ci	if (seq_write(s, str, num))
17362306a36Sopenharmony_ci		return 0;
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	if (inst->use_stream_buffer) {
17662306a36Sopenharmony_ci		num = scnprintf(str, sizeof(str), "stream_buffer = %d / %d, <%pad, 0x%x>\n",
17762306a36Sopenharmony_ci				vpu_helper_get_used_space(inst),
17862306a36Sopenharmony_ci				inst->stream_buffer.length,
17962306a36Sopenharmony_ci				&inst->stream_buffer.phys,
18062306a36Sopenharmony_ci				inst->stream_buffer.length);
18162306a36Sopenharmony_ci		if (seq_write(s, str, num))
18262306a36Sopenharmony_ci			return 0;
18362306a36Sopenharmony_ci	}
18462306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&inst->msg_fifo));
18562306a36Sopenharmony_ci	if (seq_write(s, str, num))
18662306a36Sopenharmony_ci		return 0;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "flow :\n");
18962306a36Sopenharmony_ci	if (seq_write(s, str, num))
19062306a36Sopenharmony_ci		return 0;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	mutex_lock(&inst->core->cmd_lock);
19362306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(inst->flows); i++) {
19462306a36Sopenharmony_ci		u32 idx = (inst->flow_idx + i) % (ARRAY_SIZE(inst->flows));
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci		if (!inst->flows[idx])
19762306a36Sopenharmony_ci			continue;
19862306a36Sopenharmony_ci		num = scnprintf(str, sizeof(str), "\t[%s] %s\n",
19962306a36Sopenharmony_ci				inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C",
20062306a36Sopenharmony_ci				vpu_id_name(inst->flows[idx]));
20162306a36Sopenharmony_ci		if (seq_write(s, str, num)) {
20262306a36Sopenharmony_ci			mutex_unlock(&inst->core->cmd_lock);
20362306a36Sopenharmony_ci			return 0;
20462306a36Sopenharmony_ci		}
20562306a36Sopenharmony_ci	}
20662306a36Sopenharmony_ci	mutex_unlock(&inst->core->cmd_lock);
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	i = 0;
20962306a36Sopenharmony_ci	while (true) {
21062306a36Sopenharmony_ci		num = call_vop(inst, get_debug_info, str, sizeof(str), i++);
21162306a36Sopenharmony_ci		if (num <= 0)
21262306a36Sopenharmony_ci			break;
21362306a36Sopenharmony_ci		if (seq_write(s, str, num))
21462306a36Sopenharmony_ci			return 0;
21562306a36Sopenharmony_ci	}
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	return 0;
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_cistatic int vpu_dbg_core(struct seq_file *s, void *data)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	struct vpu_core *core = s->private;
22362306a36Sopenharmony_ci	struct vpu_shared_addr *iface = core->iface;
22462306a36Sopenharmony_ci	char str[128];
22562306a36Sopenharmony_ci	int num;
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(core->type));
22862306a36Sopenharmony_ci	if (seq_write(s, str, num))
22962306a36Sopenharmony_ci		return 0;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "boot_region  = <%pad, 0x%x>\n",
23262306a36Sopenharmony_ci			&core->fw.phys, core->fw.length);
23362306a36Sopenharmony_ci	if (seq_write(s, str, num))
23462306a36Sopenharmony_ci		return 0;
23562306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "rpc_region   = <%pad, 0x%x> used = 0x%x\n",
23662306a36Sopenharmony_ci			&core->rpc.phys, core->rpc.length, core->rpc.bytesused);
23762306a36Sopenharmony_ci	if (seq_write(s, str, num))
23862306a36Sopenharmony_ci		return 0;
23962306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "fwlog_region = <%pad, 0x%x>\n",
24062306a36Sopenharmony_ci			&core->log.phys, core->log.length);
24162306a36Sopenharmony_ci	if (seq_write(s, str, num))
24262306a36Sopenharmony_ci		return 0;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "power %s\n",
24562306a36Sopenharmony_ci			vpu_iface_get_power_state(core) ? "on" : "off");
24662306a36Sopenharmony_ci	if (seq_write(s, str, num))
24762306a36Sopenharmony_ci		return 0;
24862306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
24962306a36Sopenharmony_ci	if (seq_write(s, str, num))
25062306a36Sopenharmony_ci		return 0;
25162306a36Sopenharmony_ci	if (core->state == VPU_CORE_DEINIT)
25262306a36Sopenharmony_ci		return 0;
25362306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "fw version = %d.%d.%d\n",
25462306a36Sopenharmony_ci			(core->fw_version >> 16) & 0xff,
25562306a36Sopenharmony_ci			(core->fw_version >> 8) & 0xff,
25662306a36Sopenharmony_ci			core->fw_version & 0xff);
25762306a36Sopenharmony_ci	if (seq_write(s, str, num))
25862306a36Sopenharmony_ci		return 0;
25962306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "instances = %d/%d (0x%02lx), %d\n",
26062306a36Sopenharmony_ci			hweight32(core->instance_mask),
26162306a36Sopenharmony_ci			core->supported_instance_count,
26262306a36Sopenharmony_ci			core->instance_mask,
26362306a36Sopenharmony_ci			core->request_count);
26462306a36Sopenharmony_ci	if (seq_write(s, str, num))
26562306a36Sopenharmony_ci		return 0;
26662306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&core->msg_fifo));
26762306a36Sopenharmony_ci	if (seq_write(s, str, num))
26862306a36Sopenharmony_ci		return 0;
26962306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str),
27062306a36Sopenharmony_ci			"cmd_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
27162306a36Sopenharmony_ci			iface->cmd_desc->start,
27262306a36Sopenharmony_ci			iface->cmd_desc->end,
27362306a36Sopenharmony_ci			iface->cmd_desc->wptr,
27462306a36Sopenharmony_ci			iface->cmd_desc->rptr);
27562306a36Sopenharmony_ci	if (seq_write(s, str, num))
27662306a36Sopenharmony_ci		return 0;
27762306a36Sopenharmony_ci	num = scnprintf(str, sizeof(str),
27862306a36Sopenharmony_ci			"msg_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
27962306a36Sopenharmony_ci			iface->msg_desc->start,
28062306a36Sopenharmony_ci			iface->msg_desc->end,
28162306a36Sopenharmony_ci			iface->msg_desc->wptr,
28262306a36Sopenharmony_ci			iface->msg_desc->rptr);
28362306a36Sopenharmony_ci	if (seq_write(s, str, num))
28462306a36Sopenharmony_ci		return 0;
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	return 0;
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_cistatic int vpu_dbg_fwlog(struct seq_file *s, void *data)
29062306a36Sopenharmony_ci{
29162306a36Sopenharmony_ci	struct vpu_core *core = s->private;
29262306a36Sopenharmony_ci	struct print_buf_desc *print_buf;
29362306a36Sopenharmony_ci	int length;
29462306a36Sopenharmony_ci	u32 rptr;
29562306a36Sopenharmony_ci	u32 wptr;
29662306a36Sopenharmony_ci	int ret = 0;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	if (!core->log.virt || core->state == VPU_CORE_DEINIT)
29962306a36Sopenharmony_ci		return 0;
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	print_buf = core->log.virt;
30262306a36Sopenharmony_ci	rptr = print_buf->read;
30362306a36Sopenharmony_ci	wptr = print_buf->write;
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	if (rptr == wptr)
30662306a36Sopenharmony_ci		return 0;
30762306a36Sopenharmony_ci	else if (rptr < wptr)
30862306a36Sopenharmony_ci		length = wptr - rptr;
30962306a36Sopenharmony_ci	else
31062306a36Sopenharmony_ci		length = print_buf->bytes + wptr - rptr;
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	if (s->count + length >= s->size) {
31362306a36Sopenharmony_ci		s->count = s->size;
31462306a36Sopenharmony_ci		return 0;
31562306a36Sopenharmony_ci	}
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	if (rptr + length >= print_buf->bytes) {
31862306a36Sopenharmony_ci		int num = print_buf->bytes - rptr;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci		if (seq_write(s, print_buf->buffer + rptr, num))
32162306a36Sopenharmony_ci			ret = -1;
32262306a36Sopenharmony_ci		length -= num;
32362306a36Sopenharmony_ci		rptr = 0;
32462306a36Sopenharmony_ci	}
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	if (length) {
32762306a36Sopenharmony_ci		if (seq_write(s, print_buf->buffer + rptr, length))
32862306a36Sopenharmony_ci			ret = -1;
32962306a36Sopenharmony_ci		rptr += length;
33062306a36Sopenharmony_ci	}
33162306a36Sopenharmony_ci	if (!ret)
33262306a36Sopenharmony_ci		print_buf->read = rptr;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	return 0;
33562306a36Sopenharmony_ci}
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cistatic int vpu_dbg_inst_open(struct inode *inode, struct file *filp)
33862306a36Sopenharmony_ci{
33962306a36Sopenharmony_ci	return single_open(filp, vpu_dbg_instance, inode->i_private);
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cistatic ssize_t vpu_dbg_inst_write(struct file *file,
34362306a36Sopenharmony_ci				  const char __user *user_buf, size_t size, loff_t *ppos)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci	struct seq_file *s = file->private_data;
34662306a36Sopenharmony_ci	struct vpu_inst *inst = s->private;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	vpu_session_debug(inst);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	return size;
35162306a36Sopenharmony_ci}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_cistatic ssize_t vpu_dbg_core_write(struct file *file,
35462306a36Sopenharmony_ci				  const char __user *user_buf, size_t size, loff_t *ppos)
35562306a36Sopenharmony_ci{
35662306a36Sopenharmony_ci	struct seq_file *s = file->private_data;
35762306a36Sopenharmony_ci	struct vpu_core *core = s->private;
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	pm_runtime_resume_and_get(core->dev);
36062306a36Sopenharmony_ci	mutex_lock(&core->lock);
36162306a36Sopenharmony_ci	if (vpu_iface_get_power_state(core) && !core->request_count) {
36262306a36Sopenharmony_ci		dev_info(core->dev, "reset\n");
36362306a36Sopenharmony_ci		if (!vpu_core_sw_reset(core)) {
36462306a36Sopenharmony_ci			vpu_core_set_state(core, VPU_CORE_ACTIVE);
36562306a36Sopenharmony_ci			core->hang_mask = 0;
36662306a36Sopenharmony_ci		}
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci	mutex_unlock(&core->lock);
36962306a36Sopenharmony_ci	pm_runtime_put_sync(core->dev);
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	return size;
37262306a36Sopenharmony_ci}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_cistatic int vpu_dbg_core_open(struct inode *inode, struct file *filp)
37562306a36Sopenharmony_ci{
37662306a36Sopenharmony_ci	return single_open(filp, vpu_dbg_core, inode->i_private);
37762306a36Sopenharmony_ci}
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cistatic int vpu_dbg_fwlog_open(struct inode *inode, struct file *filp)
38062306a36Sopenharmony_ci{
38162306a36Sopenharmony_ci	return single_open(filp, vpu_dbg_fwlog, inode->i_private);
38262306a36Sopenharmony_ci}
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_cistatic const struct file_operations vpu_dbg_inst_fops = {
38562306a36Sopenharmony_ci	.owner = THIS_MODULE,
38662306a36Sopenharmony_ci	.open = vpu_dbg_inst_open,
38762306a36Sopenharmony_ci	.release = single_release,
38862306a36Sopenharmony_ci	.read = seq_read,
38962306a36Sopenharmony_ci	.write = vpu_dbg_inst_write,
39062306a36Sopenharmony_ci};
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistatic const struct file_operations vpu_dbg_core_fops = {
39362306a36Sopenharmony_ci	.owner = THIS_MODULE,
39462306a36Sopenharmony_ci	.open = vpu_dbg_core_open,
39562306a36Sopenharmony_ci	.release = single_release,
39662306a36Sopenharmony_ci	.read = seq_read,
39762306a36Sopenharmony_ci	.write = vpu_dbg_core_write,
39862306a36Sopenharmony_ci};
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_cistatic const struct file_operations vpu_dbg_fwlog_fops = {
40162306a36Sopenharmony_ci	.owner = THIS_MODULE,
40262306a36Sopenharmony_ci	.open = vpu_dbg_fwlog_open,
40362306a36Sopenharmony_ci	.release = single_release,
40462306a36Sopenharmony_ci	.read = seq_read,
40562306a36Sopenharmony_ci};
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ciint vpu_inst_create_dbgfs_file(struct vpu_inst *inst)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	struct vpu_dev *vpu;
41062306a36Sopenharmony_ci	char name[64];
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	if (!inst || !inst->core || !inst->core->vpu)
41362306a36Sopenharmony_ci		return -EINVAL;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	vpu = inst->core->vpu;
41662306a36Sopenharmony_ci	if (!vpu->debugfs)
41762306a36Sopenharmony_ci		return -EINVAL;
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	if (inst->debugfs)
42062306a36Sopenharmony_ci		return 0;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	scnprintf(name, sizeof(name), "instance.%d.%d", inst->core->id, inst->id);
42362306a36Sopenharmony_ci	inst->debugfs = debugfs_create_file((const char *)name,
42462306a36Sopenharmony_ci					    VERIFY_OCTAL_PERMISSIONS(0644),
42562306a36Sopenharmony_ci					    vpu->debugfs,
42662306a36Sopenharmony_ci					    inst,
42762306a36Sopenharmony_ci					    &vpu_dbg_inst_fops);
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci	return 0;
43062306a36Sopenharmony_ci}
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ciint vpu_inst_remove_dbgfs_file(struct vpu_inst *inst)
43362306a36Sopenharmony_ci{
43462306a36Sopenharmony_ci	if (!inst)
43562306a36Sopenharmony_ci		return 0;
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	debugfs_remove(inst->debugfs);
43862306a36Sopenharmony_ci	inst->debugfs = NULL;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	return 0;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ciint vpu_core_create_dbgfs_file(struct vpu_core *core)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	struct vpu_dev *vpu;
44662306a36Sopenharmony_ci	char name[64];
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	if (!core || !core->vpu)
44962306a36Sopenharmony_ci		return -EINVAL;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	vpu = core->vpu;
45262306a36Sopenharmony_ci	if (!vpu->debugfs)
45362306a36Sopenharmony_ci		return -EINVAL;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	if (!core->debugfs) {
45662306a36Sopenharmony_ci		scnprintf(name, sizeof(name), "core.%d", core->id);
45762306a36Sopenharmony_ci		core->debugfs = debugfs_create_file((const char *)name,
45862306a36Sopenharmony_ci						    VERIFY_OCTAL_PERMISSIONS(0644),
45962306a36Sopenharmony_ci						    vpu->debugfs,
46062306a36Sopenharmony_ci						    core,
46162306a36Sopenharmony_ci						    &vpu_dbg_core_fops);
46262306a36Sopenharmony_ci	}
46362306a36Sopenharmony_ci	if (!core->debugfs_fwlog) {
46462306a36Sopenharmony_ci		scnprintf(name, sizeof(name), "fwlog.%d", core->id);
46562306a36Sopenharmony_ci		core->debugfs_fwlog = debugfs_create_file((const char *)name,
46662306a36Sopenharmony_ci							  VERIFY_OCTAL_PERMISSIONS(0444),
46762306a36Sopenharmony_ci							  vpu->debugfs,
46862306a36Sopenharmony_ci							  core,
46962306a36Sopenharmony_ci							  &vpu_dbg_fwlog_fops);
47062306a36Sopenharmony_ci	}
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	return 0;
47362306a36Sopenharmony_ci}
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ciint vpu_core_remove_dbgfs_file(struct vpu_core *core)
47662306a36Sopenharmony_ci{
47762306a36Sopenharmony_ci	if (!core)
47862306a36Sopenharmony_ci		return 0;
47962306a36Sopenharmony_ci	debugfs_remove(core->debugfs);
48062306a36Sopenharmony_ci	core->debugfs = NULL;
48162306a36Sopenharmony_ci	debugfs_remove(core->debugfs_fwlog);
48262306a36Sopenharmony_ci	core->debugfs_fwlog = NULL;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	return 0;
48562306a36Sopenharmony_ci}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_civoid vpu_inst_record_flow(struct vpu_inst *inst, u32 flow)
48862306a36Sopenharmony_ci{
48962306a36Sopenharmony_ci	if (!inst)
49062306a36Sopenharmony_ci		return;
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	inst->flows[inst->flow_idx] = flow;
49362306a36Sopenharmony_ci	inst->flow_idx = (inst->flow_idx + 1) % (ARRAY_SIZE(inst->flows));
49462306a36Sopenharmony_ci}
495