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