video: rockchip: rga3: Add dump_image

Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
Change-Id: Iaa12d959d2f1532bbab66a6d9aa480adb8cd2535
This commit is contained in:
Yu Qiaowei
2022-05-19 10:14:14 +08:00
committed by Tao Huang
parent 352bd73cac
commit 545047abb0
5 changed files with 204 additions and 1 deletions

View File

@@ -10,6 +10,8 @@
#ifndef _RGA_DEBUGGER_H_
#define _RGA_DEBUGGER_H_
#include "rga_drv.h"
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
extern int RGA_DEBUG_REG;
@@ -19,6 +21,7 @@ extern int RGA_DEBUG_INT_FLAG;
extern int RGA_DEBUG_MM;
extern int RGA_DEBUG_CHECK_MODE;
extern int RGA_DEBUG_NONUSE;
extern int RGA_DEBUG_DUMP_IMAGE;
#define DEBUGGER_EN(name) (unlikely(RGA_DEBUG_##name ? true : false))
@@ -131,6 +134,7 @@ static inline int rga_procfs_init(void)
void rga_cmd_print_debug_info(struct rga_req *req);
void rga_request_task_debug_info(struct seq_file *m, struct rga_req *req);
void rga_dump_external_buffer(struct rga_external_buffer *buffer);
void rga_dump_job_image(struct rga_job *dump_job);
#endif /* #ifndef _RGA_DEBUGGER_H_ */

View File

@@ -189,6 +189,9 @@ struct rga_internal_buffer {
/* physical address */
uint64_t phys_addr;
/* buffer size */
unsigned long size;
struct rga_memory_parm memory_parm;

View File

@@ -34,6 +34,9 @@ int RGA_DEBUG_MM;
int RGA_DEBUG_CHECK_MODE;
int RGA_DEBUG_NONUSE;
int RGA_DEBUG_DEBUG_MODE;
int RGA_DEBUG_DUMP_IMAGE;
static char g_dump_path[100] = "/data";
static int rga_debug_show(struct seq_file *m, void *data)
{
@@ -340,14 +343,76 @@ static int rga_request_manager_show(struct seq_file *m, void *data)
return 0;
}
static int rga_dump_path_show(struct seq_file *m, void *data)
{
seq_printf(m, "dump path: %s\n", g_dump_path);
struct rga_debugger_list rga_debugger_root_list[] = {
return 0;
}
static ssize_t rga_dump_path_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
char buf[100];
if (len > sizeof(buf) - 1)
return -EINVAL;
if (copy_from_user(buf, ubuf, len))
return -EFAULT;
buf[len - 1] = '\0';
snprintf(g_dump_path, sizeof(buf), "%s", buf);
pr_info("dump path change to: %s\n", g_dump_path);
return len;
}
static int rga_dump_image_show(struct seq_file *m, void *data)
{
seq_printf(m, "dump image count: %d\n", RGA_DEBUG_DUMP_IMAGE);
return 0;
}
static ssize_t rga_dump_image_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
int ret;
int dump_count = 0;
char buf[14];
if (len > sizeof(buf) - 1)
return -EINVAL;
if (copy_from_user(buf, ubuf, len))
return -EFAULT;
buf[len - 1] = '\0';
ret = kstrtoint(buf, 10, &dump_count);
if (ret) {
pr_err("Failed to parse str[%s]\n", buf);
return -EFAULT;
}
if (dump_count <= 0) {
pr_err("dump_image count is invalid [%d]!\n", dump_count);
return -EINVAL;
}
RGA_DEBUG_DUMP_IMAGE = dump_count;
pr_info("dump image %d\n", RGA_DEBUG_DUMP_IMAGE);
return len;
}
static struct rga_debugger_list rga_debugger_root_list[] = {
{"debug", rga_debug_show, rga_debug_write, NULL},
{"driver_version", rga_version_show, NULL, NULL},
{"load", rga_load_show, NULL, NULL},
{"scheduler_status", rga_scheduler_show, NULL, NULL},
{"mm_session", rga_mm_session_show, NULL, NULL},
{"request_manager", rga_request_manager_show, NULL, NULL},
{"dump_path", rga_dump_path_show, rga_dump_path_write, NULL},
{"dump_image", rga_dump_image_show, rga_dump_image_write, NULL},
};
static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf,
@@ -709,3 +774,118 @@ void rga_dump_external_buffer(struct rga_external_buffer *buffer)
rga_get_format_name(buffer->memory_parm.format),
buffer->memory_parm.size);
}
static int rga_dump_image_to_file(struct rga_internal_buffer *dump_buffer,
const char *channel_name,
int plane_id,
int core)
{
char file_name[100];
struct file *file;
size_t size = 0;
loff_t pos = 0;
void *kvaddr = NULL;
void *kvaddr_origin = NULL;
switch (dump_buffer->type) {
case RGA_DMA_BUFFER:
case RGA_DMA_BUFFER_PTR:
if (IS_ERR_OR_NULL(dump_buffer->dma_buffer->dma_buf)) {
pr_err("Failed to dump dma_buf 0x%px\n",
dump_buffer->dma_buffer->dma_buf);
return -EINVAL;
}
kvaddr = dma_buf_vmap(dump_buffer->dma_buffer->dma_buf);
if (!kvaddr) {
pr_err("can't vmap the dma buffer!\n");
return -EINVAL;
}
kvaddr_origin = kvaddr;
kvaddr += dump_buffer->dma_buffer->offset;
break;
case RGA_VIRTUAL_ADDRESS:
kvaddr = vmap(dump_buffer->virt_addr->pages, dump_buffer->virt_addr->page_count,
VM_MAP, pgprot_writecombine(PAGE_KERNEL));
if (!kvaddr) {
pr_err("dump_vaddr vmap error!, 0x%lx\n",
(unsigned long)dump_buffer->virt_addr->addr);
return -EFAULT;
}
kvaddr_origin = kvaddr;
kvaddr += dump_buffer->virt_addr->offset;
break;
case RGA_PHYSICAL_ADDRESS:
kvaddr = phys_to_virt(dump_buffer->phys_addr);
break;
default:
pr_err("unsupported memory type[%x]\n", dump_buffer->type);
return -EINVAL;
}
size = dump_buffer->size;
if (kvaddr == NULL) {
pr_err("dump addr is NULL!\n");
return -EFAULT;
}
if (size <= 0) {
pr_err("dump buffer size[%lx] is invalid!\n", (unsigned long)size);
return -EFAULT;
}
snprintf(file_name, 100, "%s/%d_core%d_%s_plane%d_%s_w%d_h%d_%s.bin",
g_dump_path,
RGA_DEBUG_DUMP_IMAGE, core, channel_name, plane_id,
rga_get_memory_type_str(dump_buffer->type),
dump_buffer->memory_parm.width,
dump_buffer->memory_parm.height,
rga_get_format_name(dump_buffer->memory_parm.format));
file = filp_open(file_name, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (!IS_ERR(file)) {
kernel_write(file, kvaddr, size, &pos);
pr_info("dump image to: %s\n", file_name);
fput(file);
} else {
pr_info("open %s failed\n", file_name);
}
switch (dump_buffer->type) {
case RGA_DMA_BUFFER:
case RGA_DMA_BUFFER_PTR:
dma_buf_vunmap(dump_buffer->dma_buffer->dma_buf, kvaddr_origin);
break;
case RGA_VIRTUAL_ADDRESS:
vunmap(kvaddr_origin);
break;
}
return 0;
}
static inline void rga_dump_channel_image(struct rga_job_buffer *job_buffer,
const char *channel_name,
int core)
{
if (job_buffer->y_addr)
rga_dump_image_to_file(job_buffer->y_addr, channel_name, 0, core);
if (job_buffer->uv_addr)
rga_dump_image_to_file(job_buffer->uv_addr, channel_name, 1, core);
if (job_buffer->v_addr)
rga_dump_image_to_file(job_buffer->v_addr, channel_name, 2, core);
}
void rga_dump_job_image(struct rga_job *dump_job)
{
rga_dump_channel_image(&dump_job->src_buffer, "src", dump_job->core);
rga_dump_channel_image(&dump_job->src1_buffer, "src1", dump_job->core);
rga_dump_channel_image(&dump_job->dst_buffer, "dst", dump_job->core);
rga_dump_channel_image(&dump_job->els_buffer, "els", dump_job->core);
if (RGA_DEBUG_DUMP_IMAGE > 0)
RGA_DEBUG_DUMP_IMAGE--;
}

View File

@@ -425,6 +425,9 @@ void rga_job_done(struct rga_scheduler_t *scheduler, int ret)
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
if (DEBUGGER_EN(DUMP_IMAGE))
rga_dump_job_image(job);
rga_job_finish_and_next(scheduler, job, ret);
}

View File

@@ -605,6 +605,8 @@ static int rga_mm_map_buffer(struct rga_external_buffer *external_buffer,
return ret;
}
internal_buffer->size = internal_buffer->dma_buffer->size -
internal_buffer->dma_buffer->offset;
internal_buffer->mm_flag |= RGA_MEM_NEED_USE_IOMMU;
break;
case RGA_VIRTUAL_ADDRESS:
@@ -616,12 +618,23 @@ static int rga_mm_map_buffer(struct rga_external_buffer *external_buffer,
return ret;
}
internal_buffer->size = internal_buffer->virt_addr->size -
internal_buffer->virt_addr->offset;
internal_buffer->mm_flag |= RGA_MEM_NEED_USE_IOMMU;
break;
case RGA_PHYSICAL_ADDRESS:
internal_buffer->type = RGA_PHYSICAL_ADDRESS;
internal_buffer->phys_addr = external_buffer->memory;
if (internal_buffer->memory_parm.size)
internal_buffer->size = internal_buffer->memory_parm.size;
else
internal_buffer->size =
rga_image_size_cal(internal_buffer->memory_parm.width,
internal_buffer->memory_parm.height,
internal_buffer->memory_parm.format,
NULL, NULL, NULL);
break;
default:
pr_err("Illegal external buffer!\n");