From 777af0aef6268b7669a73f2741f34bc229bd5609 Mon Sep 17 00:00:00 2001 From: Sanghwa Park Date: Tue, 19 Feb 2019 16:59:05 +0900 Subject: [PATCH] [RAMEN9610-12328][9610] vipx: change DRAM address for cacheable configuration and add debugging methods Change-Id: I8c11914bc28bff84fb19884c38c00009e8eedd67 Signed-off-by: Sanghwa Park --- arch/arm64/boot/dts/exynos/exynos9610.dtsi | 2 +- drivers/vision/vipx/vipx-binary.c | 137 +------ drivers/vision/vipx/vipx-binary.h | 6 +- drivers/vision/vipx/vipx-compat-ioctl.c | 6 +- drivers/vision/vipx/vipx-context.c | 3 +- drivers/vision/vipx/vipx-core.c | 11 +- drivers/vision/vipx/vipx-debug.c | 419 +++++++++++++++++++-- drivers/vision/vipx/vipx-debug.h | 18 + drivers/vision/vipx/vipx-device.c | 3 +- drivers/vision/vipx/vipx-graph.c | 24 +- drivers/vision/vipx/vipx-graphmgr.c | 36 +- drivers/vision/vipx/vipx-interface.c | 59 ++- drivers/vision/vipx/vipx-ioctl.h | 2 + drivers/vision/vipx/vipx-kernel-binary.c | 21 +- drivers/vision/vipx/vipx-kernel-binary.h | 4 +- drivers/vision/vipx/vipx-mailbox.c | 47 +-- drivers/vision/vipx/vipx-memory.c | 49 ++- drivers/vision/vipx/vipx-memory.h | 11 +- drivers/vision/vipx/vipx-system.c | 16 +- drivers/vision/vipx/vipx-taskmgr.h | 69 ---- 20 files changed, 570 insertions(+), 373 deletions(-) diff --git a/arch/arm64/boot/dts/exynos/exynos9610.dtsi b/arch/arm64/boot/dts/exynos/exynos9610.dtsi index ef9ed3c8ad63..d4e64ba00688 100644 --- a/arch/arm64/boot/dts/exynos/exynos9610.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos9610.dtsi @@ -3026,7 +3026,7 @@ /* ranges; */ #dma-address-cells = <1>; #dma-size-cells = <1>; - dma-window = <0x30000000 0xB0000000>; + dma-window = <0x40000000 0xA0000000>; domain-clients = <&vipx>, <&vipx_vertex>; }; diff --git a/drivers/vision/vipx/vipx-binary.c b/drivers/vision/vipx/vipx-binary.c index 6b0617056f12..8dcb348e1568 100644 --- a/drivers/vision/vipx/vipx-binary.c +++ b/drivers/vision/vipx/vipx-binary.c @@ -9,92 +9,12 @@ */ #include -#include #include "vipx-log.h" #include "vipx-system.h" #include "vipx-binary.h" -static noinline_for_stack loff_t __vipx_binary_get_file_size(struct file *file) -{ - int ret; - struct kstat st; - unsigned int request_mask = (STATX_MODE | STATX_SIZE); - - vipx_enter(); - ret = vfs_getattr(&file->f_path, &st, request_mask, KSTAT_QUERY_FLAGS); - if (ret) { - vipx_err("vfs_getattr failed (%d)\n", ret); - goto p_err; - } - - if (!S_ISREG(st.mode)) { - ret = -EINVAL; - vipx_err("file mode is not S_ISREG\n"); - goto p_err; - } - - vipx_leave(); - return st.size; -p_err: - return (loff_t)ret; -} - -static int __vipx_binary_file_read(struct vipx_binary *bin, const char *path, - const char *name, void *target, size_t size) -{ - int ret; - mm_segment_t old_fs; - char fname[VIPX_FW_NAME_LEN]; - struct file *fp; - loff_t fsize, pos = 0; - ssize_t nread; - - vipx_enter(); - snprintf(fname, sizeof(fname), "%s/%s", path, name); - - old_fs = get_fs(); - set_fs(KERNEL_DS); - fp = filp_open(fname, O_RDONLY, 0); - if (IS_ERR(fp)) { - set_fs(old_fs); - ret = PTR_ERR(fp); - vipx_err("filp_open(%s) is failed (%d)\n", fname, ret); - goto p_err_open; - } - - fsize = __vipx_binary_get_file_size(fp); - if (fsize <= 0) { - ret = (int)fsize; - goto p_err_size; - } - - if (fsize > size) { - ret = -EIO; - vipx_err("file(%s) size is over (%lld > %zu)\n", - fname, fsize, size); - goto p_err_size; - } - - nread = kernel_read(fp, target, fsize, &pos); - filp_close(fp, current->files); - set_fs(old_fs); - - if (nread < 0) { - ret = (int)nread; - vipx_err("kernel_read(%s) is fail (%d)\n", fname, ret); - goto p_err_read; - } - - vipx_leave(); - return 0; -p_err_read: -p_err_size: -p_err_open: - return ret; -} - -static int __vipx_binary_firmware_load(struct vipx_binary *bin, +int vipx_binary_firmware_load(struct vipx_binary *bin, const char *name, void *target, size_t size) { int ret; @@ -132,61 +52,6 @@ p_err_target: return ret; } -int vipx_binary_read(struct vipx_binary *bin, const char *path, - const char *name, void *target, size_t size) -{ - int ret; - - vipx_enter(); - - if (path) - ret = __vipx_binary_file_read(bin, path, name, target, size); - else - ret = __vipx_binary_firmware_load(bin, name, target, size); - - vipx_leave(); - return ret; -} - -int vipx_binary_write(struct vipx_binary *bin, const char *path, - const char *name, void *target, size_t size) -{ - int ret; - char fname[VIPX_FW_NAME_LEN]; - mm_segment_t old_fs; - struct file *fp; - ssize_t nwrite; - loff_t pos = 0; - - vipx_enter(); - snprintf(fname, sizeof(fname), "%s/%s", path, name); - - old_fs = get_fs(); - set_fs(KERNEL_DS); - fp = filp_open(fname, O_RDWR | O_CREAT, 0); - if (IS_ERR(fp)) { - set_fs(old_fs); - ret = PTR_ERR(fp); - vipx_err("filp_open(%s) is fail (%d)\n", fname, ret); - goto p_err; - } - - nwrite = kernel_write(fp, target, size, &pos); - filp_close(fp, current->files); - set_fs(old_fs); - - if (nwrite < 0) { - ret = (int)nwrite; - vipx_err("kernel_write(%s) is fail (%d)\n", fname, ret); - goto p_err; - } - - vipx_leave(); - return 0; -p_err: - return ret; -} - int vipx_binary_init(struct vipx_system *sys) { struct vipx_binary *bin; diff --git a/drivers/vision/vipx/vipx-binary.h b/drivers/vision/vipx/vipx-binary.h index b1eef33f9180..5aad16d36053 100644 --- a/drivers/vision/vipx/vipx-binary.h +++ b/drivers/vision/vipx/vipx-binary.h @@ -28,10 +28,8 @@ struct vipx_binary { struct device *dev; }; -int vipx_binary_read(struct vipx_binary *bin, const char *path, - const char *name, void *target, size_t size); -int vipx_binary_write(struct vipx_binary *bin, const char *path, - const char *name, void *target, size_t size); +int vipx_binary_firmware_load(struct vipx_binary *bin, const char *name, + void *target, size_t size); int vipx_binary_init(struct vipx_system *sys); void vipx_binary_deinit(struct vipx_binary *bin); diff --git a/drivers/vision/vipx/vipx-compat-ioctl.c b/drivers/vision/vipx/vipx-compat-ioctl.c index 1e67dce18682..d64c318e9e60 100644 --- a/drivers/vision/vipx/vipx-compat-ioctl.c +++ b/drivers/vision/vipx/vipx-compat-ioctl.c @@ -117,6 +117,8 @@ struct vipx_ioc_load_kernel_binary32 { struct vipx_ioc_unload_kernel_binary32 { unsigned int size; unsigned int global_id; + int kernel_fd; + unsigned int kernel_size; int ret; struct compat_timespec timestamp[4]; int reserved[2]; @@ -568,7 +570,9 @@ static int __vipx_ioctl_get_unload_kernel_binary32( vipx_enter(); if (get_user(karg->size, &uarg->size) || - get_user(karg->global_id, &uarg->global_id)) { + get_user(karg->global_id, &uarg->global_id) || + get_user(karg->kernel_fd, &uarg->kernel_fd) || + get_user(karg->kernel_size, &uarg->kernel_size)) { ret = -EFAULT; vipx_err("Copy failed [Unload Kernel Binary(32)]\n"); goto p_err; diff --git a/drivers/vision/vipx/vipx-context.c b/drivers/vision/vipx/vipx-context.c index 685de26931dd..fee361aa1bd0 100644 --- a/drivers/vision/vipx/vipx-context.c +++ b/drivers/vision/vipx/vipx-context.c @@ -122,7 +122,8 @@ static int vipx_context_unload_kernel_binary(struct vipx_context *vctx, vipx_dbg("[%s] unload kernel binary (framework)\n", __func__); vipx_dbg("model_id : %#x\n", unload_kbin->global_id); - ret = vipx_kernel_binary_unload(vctx, unload_kbin->global_id); + ret = vipx_kernel_binary_unload(vctx, unload_kbin->global_id, + unload_kbin->kernel_fd, unload_kbin->kernel_size); if (ret) goto p_err; diff --git a/drivers/vision/vipx/vipx-core.c b/drivers/vision/vipx/vipx-core.c index 7de774f0e598..eb5d172ed96d 100644 --- a/drivers/vision/vipx/vipx-core.c +++ b/drivers/vision/vipx/vipx-core.c @@ -472,7 +472,11 @@ static int vipx_open(struct inode *inode, struct file *file) ret = vipx_device_open(vdev); if (ret) - goto p_err_device; + goto p_err_device_open; + + ret = vipx_device_start(vdev); + if (ret) + goto p_err_device_start; vctx = vipx_context_create(core); if (IS_ERR(vctx)) { @@ -498,8 +502,10 @@ static int vipx_open(struct inode *inode, struct file *file) return 0; p_err_graph: p_err_vctx: + vipx_device_stop(vdev); +p_err_device_start: vipx_device_close(vdev); -p_err_device: +p_err_device_open: mutex_unlock(&core->lock); vipx_err("Failed to open the vipx(count:%d)(%d)\n", vdev->open_count, ret); @@ -525,6 +531,7 @@ static int vipx_release(struct inode *inode, struct file *file) vipx_graph_destroy(vctx->graph); vipx_context_destroy(vctx); + vipx_device_stop(core->device); vipx_device_close(core->device); mutex_unlock(&core->lock); diff --git a/drivers/vision/vipx/vipx-debug.c b/drivers/vision/vipx/vipx-debug.c index 675225e1015f..b6d50c3a1457 100644 --- a/drivers/vision/vipx/vipx-debug.c +++ b/drivers/vision/vipx/vipx-debug.c @@ -9,57 +9,173 @@ */ #include +#include +#include #include "vipx-log.h" +#include "vipx-mailbox.h" #include "vipx-device.h" #include "vipx-pm.h" #include "vipx-debug.h" +#define VIPX_DEBUG_LOG_LINE_SIZE (128) +#define VIPX_DEBUG_LOG_TIME (10) + static struct vipx_device *debug_device; int vipx_debug_log_enable; -int vipx_debug_write_log_binary(void) +int vipx_debug_dump_debug_regs(void) { - int ret; struct vipx_system *sys; - struct vipx_binary *bin; vipx_enter(); sys = &debug_device->system; - bin = &sys->binary; - if (!sys->memory.debug.kvaddr) - return -ENOMEM; + sys->ctrl_ops->debug_dump(sys); + vipx_leave(); + return 0; +} - if (!current->fs) { - vipx_warn("Failed to write debug log as fs is invalid\n"); - return -ESRCH; - } +static int vipx_debug_mem_show(struct seq_file *file, void *unused) +{ + struct vipx_debug *debug; + struct vipx_memory *mem; - ret = vipx_binary_write(bin, VIPX_DEBUG_BIN_PATH, - "vipx_log.bin", - sys->memory.debug.kvaddr, - sys->memory.debug.size); - if (!ret) - vipx_info("%s/vipx_log.bin was created for debugging\n", - VIPX_DEBUG_BIN_PATH); + vipx_enter(); + debug = file->private; + mem = &debug->system->memory; + + seq_printf(file, "%15s : %zu KB\n", + mem->fw.name, mem->fw.size / SZ_1K); + seq_printf(file, "%15s : %zu KB (%zu Bytes used)\n", + mem->mbox.name, mem->mbox.size / SZ_1K, + sizeof(struct vipx_mailbox_ctrl)); + seq_printf(file, "%15s : %zu KB\n", + mem->heap.name, mem->heap.size / SZ_1K); + seq_printf(file, "%15s : %zu KB\n", + mem->log.name, mem->log.size / SZ_1K); vipx_leave(); - return ret; + return 0; } -int vipx_debug_dump_debug_regs(void) +static int vipx_debug_mem_open(struct inode *inode, struct file *filp) { - struct vipx_system *sys; + return single_open(filp, vipx_debug_mem_show, inode->i_private); +} + +static ssize_t vipx_debug_mem_write(struct file *filp, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + struct seq_file *file; + struct vipx_debug *debug; + struct vipx_memory *mem; + struct vipx_pm *pm; + char buf[128]; + int ret; + unsigned int fw, mbox, heap, log; + ssize_t len; vipx_enter(); - sys = &debug_device->system; + file = filp->private_data; + debug = file->private; + mem = &debug->system->memory; + pm = &debug->system->pm; + + if (count > sizeof(buf)) { + vipx_err("[debugfs] writing size(%zd) is larger than buffer\n", + count); + goto out; + } + + len = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count); + if (len <= 0) { + vipx_err("[debugfs] Failed to get user buf(%d)\n", len); + goto out; + } + + buf[len] = '\0'; + + ret = sscanf(buf, "%u %u %u %u\n", &fw, &mbox, &heap, &log); + if (ret != 4) { + vipx_err("[debugfs] Failed to get memory size(%d)\n", ret); + goto out; + } + + mutex_lock(&pm->lock); + if (vipx_pm_qos_active(pm)) { + vipx_warn("[debugfs] size can't be changed (power on)\n"); + mutex_unlock(&pm->lock); + goto out; + } + + fw = PAGE_ALIGN(fw * SZ_1K); + if (fw >= VIPX_CC_DRAM_BIN_SIZE && fw <= VIPX_MEMORY_MAX_SIZE) { + vipx_info("[debugfs] size of %s is changed (%zu KB -> %u KB)\n", + mem->fw.name, mem->fw.size / SZ_1K, + fw / SZ_1K); + mem->fw.size = fw; + } else { + vipx_warn("[debugfs] invalid size %u KB (%s, %u ~ %u)\n", + fw / SZ_1K, mem->fw.name, + VIPX_CC_DRAM_BIN_SIZE / SZ_1K, + VIPX_MEMORY_MAX_SIZE / SZ_1K); + } + + mbox = PAGE_ALIGN(mbox * SZ_1K); + if (mbox >= VIPX_MBOX_SIZE && mbox <= VIPX_MEMORY_MAX_SIZE) { + vipx_info("[debugfs] size of %s is changed (%zu KB -> %u KB)\n", + mem->mbox.name, mem->mbox.size / SZ_1K, + mbox / SZ_1K); + mem->mbox.size = mbox; + } else { + vipx_warn("[debugfs] invalid size %u KB (%s, %u ~ %u)\n", + mbox / SZ_1K, mem->mbox.name, + VIPX_MBOX_SIZE / SZ_1K, + VIPX_MEMORY_MAX_SIZE / SZ_1K); + } + + heap = PAGE_ALIGN(heap * SZ_1K); + if (heap >= VIPX_HEAP_SIZE && heap <= VIPX_MEMORY_MAX_SIZE) { + vipx_info("[debugfs] size of %s is changed (%zu KB -> %u KB)\n", + mem->heap.name, mem->heap.size / SZ_1K, + heap / SZ_1K); + mem->heap.size = heap; + } else { + vipx_warn("[debugfs] invalid size %u KB (%s, %u ~ %u)\n", + heap / SZ_1K, mem->heap.name, + VIPX_HEAP_SIZE / SZ_1K, + VIPX_MEMORY_MAX_SIZE / SZ_1K); + } + + log = PAGE_ALIGN(log * SZ_1K); + if (log >= VIPX_LOG_SIZE && log <= VIPX_MEMORY_MAX_SIZE) { + vipx_info("[debugfs] size of %s is changed (%zu KB -> %u KB)\n", + mem->log.name, mem->log.size / SZ_1K, + log / SZ_1K); + mem->log.size = log; + } else { + vipx_warn("[debugfs] invalid size %u KB (%s, %u ~ %u)\n", + log / SZ_1K, mem->log.name, + VIPX_LOG_SIZE / SZ_1K, + VIPX_MEMORY_MAX_SIZE / SZ_1K); + } + + mutex_unlock(&pm->lock); - sys->ctrl_ops->debug_dump(sys); vipx_leave(); - return 0; +out: + return count; } +static const struct file_operations vipx_debug_mem_fops = { + .open = vipx_debug_mem_open, + .read = seq_read, + .write = vipx_debug_mem_write, + .llseek = seq_lseek, + .release = single_release +}; + static int vipx_debug_dvfs_show(struct seq_file *file, void *unused) { #if defined(CONFIG_PM_DEVFREQ) @@ -282,9 +398,250 @@ static const struct file_operations vipx_debug_wait_time_fops = { .release = single_release }; +static int __vipx_debug_write_file(const char *name, void *kva) +{ + int ret; + mm_segment_t old_fs; + int fd; + struct file *fp; + loff_t pos = 0; + struct vipx_debug_log_area *area; + char head[40]; + int write_size; + int idx; + char line[134]; + + vipx_enter(); + if (!current->fs) { + vipx_warn("Failed to write %s as fs is invalid\n", name); + return -ESRCH; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + fd = sys_open(name, O_RDWR | O_CREAT | O_TRUNC, 0640); + if (fd < 0) { + ret = fd; + vipx_err("sys_open(%s) is fail(%d)\n", name, ret); + goto p_err; + } + + fp = fget(fd); + if (!fp) { + ret = -EFAULT; + vipx_err("fget(%s) is fail\n", name); + goto p_err; + } + + area = kva; + write_size = snprintf(head, sizeof(head), "%d/%d/%d/%d\n", + area->front, area->rear, + area->line_size, area->queue_size); + + vfs_write(fp, head, write_size, &pos); + + for (idx = 0; idx < area->queue_size; ++idx) { + write_size = snprintf(line, sizeof(line), "[%4d]%s", + idx, area->queue + (area->line_size * idx)); + if (write_size < 9) + continue; + + if (line[write_size - 1] != '\n') + line[write_size - 1] = '\n'; + + if (line[write_size] != '\0') + line[write_size] = '\0'; + + vfs_write(fp, line, write_size, &pos); + } + + fput(fp); + sys_close(fd); + set_fs(old_fs); + + vipx_leave(); + return 0; +p_err: + set_fs(old_fs); + return ret; +} + +int vipx_debug_write_log_binary(void) +{ + int ret; + struct vipx_system *sys; + char fname[30]; + + vipx_enter(); + sys = &debug_device->system; + + if (!sys->memory.log.kvaddr) + return -ENOMEM; + + snprintf(fname, sizeof(fname), "%s/%s", VIPX_DEBUG_BIN_PATH, + "vipx_log.bin"); + ret = __vipx_debug_write_file(fname, sys->memory.log.kvaddr); + if (!ret) + vipx_info("%s was created for debugging\n", fname); + + vipx_leave(); + return ret; +} + +static bool __vipx_debug_log_valid(struct vipx_debug_log *log) +{ + vipx_check(); + if (!log->area || + log->area->front >= log->area->queue_size || + log->area->rear >= log->area->queue_size) + return false; + else + return true; +} + +static bool __vipx_debug_log_empty(struct vipx_debug_log *log) +{ + vipx_check(); + return (log->area->front == log->area->rear); +} + +static void __vipx_debug_log_increase_front(struct vipx_debug_log *log) +{ + vipx_enter(); + log->area->front = (log->area->front + 1) % log->area->queue_size; + vipx_leave(); +} + +static void __vipx_debug_log_start(struct vipx_debug *debug) +{ + vipx_enter(); + add_timer(&debug->target_log.timer); + vipx_leave(); +} + +static void __vipx_debug_log_stop(struct vipx_debug *debug) +{ + vipx_enter(); + del_timer_sync(&debug->target_log.timer); + vipx_debug_log_flush(debug); + vipx_leave(); +} + +static void __vipx_debug_log_open(struct vipx_debug *debug) +{ + struct vipx_debug_log *log; + struct vipx_system *sys; + + vipx_enter(); + log = &debug->target_log; + sys = &debug_device->system; + + log->area = sys->memory.log.kvaddr; + log->area->front = -1; + log->area->rear = -1; + log->area->line_size = VIPX_DEBUG_LOG_LINE_SIZE; + log->area->queue_size = (sys->memory.log.size - 32) / + log->area->line_size; + vipx_leave(); +} + +static char *__vipx_debug_log_dequeue(struct vipx_debug *debug) +{ + struct vipx_debug_log *log; + int front; + char *buf; + + vipx_enter(); + log = &debug->target_log; + + if (__vipx_debug_log_empty(log)) + return NULL; + + if (!__vipx_debug_log_valid(log)) { + vipx_warn("debug log queue is broken(%d/%d)\n", + log->area->front, log->area->rear); + __vipx_debug_log_open(debug); + return NULL; + } + + front = (log->area->front + 1) % log->area->queue_size; + if (front < 0) { + vipx_warn("debug log queue has invalid value(%d/%d)\n", + log->area->front, log->area->rear); + return NULL; + } + + buf = log->area->queue + (log->area->line_size * front); + if (buf[log->area->line_size - 2] != '\0') + buf[log->area->line_size - 2] = '\n'; + buf[log->area->line_size - 1] = '\0'; + + vipx_leave(); + return buf; +} + +static void vipx_debug_log_print(unsigned long data) +{ + struct vipx_debug *debug; + struct vipx_debug_log *log; + char *line; + + vipx_enter(); + debug = (struct vipx_debug *)data; + log = &debug->target_log; + + while (true) { + line = __vipx_debug_log_dequeue(debug); + if (!line) + break; + vipx_info("[timer(%4d)] %s", + (log->area->front + 1) % log->area->queue_size, + line); + __vipx_debug_log_increase_front(log); + } + + mod_timer(&log->timer, jiffies + msecs_to_jiffies(VIPX_DEBUG_LOG_TIME)); + vipx_leave(); +} + +static void __vipx_debug_log_init(struct vipx_debug *debug) +{ + struct vipx_debug_log *log; + + vipx_enter(); + log = &debug->target_log; + + init_timer(&log->timer); + log->timer.expires = jiffies + msecs_to_jiffies(VIPX_DEBUG_LOG_TIME); + log->timer.data = (unsigned long)debug; + log->timer.function = vipx_debug_log_print; + vipx_leave(); +} + +void vipx_debug_log_flush(struct vipx_debug *debug) +{ + struct vipx_debug_log *log; + char *line; + + vipx_enter(); + log = &debug->target_log; + + while (true) { + line = __vipx_debug_log_dequeue(debug); + if (!line) + break; + vipx_info("[flush(%4d)] %s", + (log->area->front + 1) % log->area->queue_size, + line); + __vipx_debug_log_increase_front(log); + } + vipx_leave(); +} + int vipx_debug_start(struct vipx_debug *debug) { vipx_enter(); + __vipx_debug_log_start(debug); set_bit(VIPX_DEBUG_STATE_START, &debug->state); vipx_leave(); return 0; @@ -294,6 +651,7 @@ int vipx_debug_stop(struct vipx_debug *debug) { vipx_enter(); clear_bit(VIPX_DEBUG_STATE_START, &debug->state); + __vipx_debug_log_stop(debug); vipx_leave(); return 0; } @@ -301,6 +659,7 @@ int vipx_debug_stop(struct vipx_debug *debug) int vipx_debug_open(struct vipx_debug *debug) { vipx_enter(); + __vipx_debug_log_open(debug); vipx_leave(); return 0; } @@ -308,6 +667,7 @@ int vipx_debug_open(struct vipx_debug *debug) int vipx_debug_close(struct vipx_debug *debug) { vipx_enter(); + vipx_debug_log_flush(debug); if (debug->log_bin_enable) vipx_debug_write_log_binary(); vipx_leave(); @@ -330,6 +690,11 @@ int vipx_debug_probe(struct vipx_device *device) goto p_end; } + debug->mem = debugfs_create_file("mem", 0640, debug->root, debug, + &vipx_debug_mem_fops); + if (!debug->mem) + vipx_err("Failed to create mem debugfs file\n"); + debug->log = debugfs_create_u32("log", 0640, debug->root, &vipx_debug_log_enable); if (!debug->log) @@ -343,17 +708,19 @@ int vipx_debug_probe(struct vipx_device *device) debug->dvfs = debugfs_create_file("dvfs", 0640, debug->root, debug, &vipx_debug_dvfs_fops); if (!debug->dvfs) - vipx_err("Filed to create dvfs debugfs file\n"); + vipx_err("Failed to create dvfs debugfs file\n"); debug->clk = debugfs_create_file("clk", 0640, debug->root, debug, &vipx_debug_clk_fops); if (!debug->clk) - vipx_err("Filed to create clk debugfs file\n"); + vipx_err("Failed to create clk debugfs file\n"); debug->wait_time = debugfs_create_file("wait_time", 0640, debug->root, debug, &vipx_debug_wait_time_fops); if (!debug->wait_time) - vipx_err("Filed to create wait_time debugfs file\n"); + vipx_err("Failed to create wait_time debugfs file\n"); + + __vipx_debug_log_init(debug); vipx_leave(); p_end: diff --git a/drivers/vision/vipx/vipx-debug.h b/drivers/vision/vipx/vipx-debug.h index 015a54a403b2..70b2878b4ba8 100644 --- a/drivers/vision/vipx/vipx-debug.h +++ b/drivers/vision/vipx/vipx-debug.h @@ -22,12 +22,29 @@ enum vipx_debug_state { VIPX_DEBUG_STATE_START, }; +struct vipx_debug_log_area { + int front; + int rear; + int line_size; + int queue_size; + int reserved[4]; + char queue[0]; +}; + +struct vipx_debug_log { + struct timer_list timer; + struct vipx_debug_log_area *area; +}; + struct vipx_debug { unsigned long state; struct vipx_system *system; + struct vipx_debug_log target_log; + int log_bin_enable; struct dentry *root; + struct dentry *mem; struct dentry *log; struct dentry *log_bin; struct dentry *dvfs; @@ -39,6 +56,7 @@ extern int vipx_debug_log_enable; int vipx_debug_write_log_binary(void); int vipx_debug_dump_debug_regs(void); +void vipx_debug_log_flush(struct vipx_debug *debug); int vipx_debug_start(struct vipx_debug *debug); int vipx_debug_stop(struct vipx_debug *debug); diff --git a/drivers/vision/vipx/vipx-device.c b/drivers/vision/vipx/vipx-device.c index 65c0644dc218..d089dbc04c20 100644 --- a/drivers/vision/vipx/vipx-device.c +++ b/drivers/vision/vipx/vipx-device.c @@ -35,6 +35,7 @@ static int __attribute__((unused)) vipx_fault_handler( vipx_debug_dump_debug_regs(); vipx_mailbox_dump(mctrl); + vipx_debug_log_flush(&vdev->debug); return -EINVAL; } @@ -80,7 +81,6 @@ static int vipx_device_suspend(struct device *dev) mutex_lock(&vdev->open_lock); if (!vdev->open_count) { - vipx_warn("device is already closed\n"); mutex_unlock(&vdev->open_lock); return 0; } @@ -111,7 +111,6 @@ static int vipx_device_resume(struct device *dev) mutex_lock(&vdev->open_lock); if (!vdev->open_count) { - vipx_warn("device is already closed\n"); mutex_unlock(&vdev->open_lock); return 0; } diff --git a/drivers/vision/vipx/vipx-graph.c b/drivers/vision/vipx/vipx-graph.c index 975060aa3faf..920b75dc13f7 100644 --- a/drivers/vision/vipx/vipx-graph.c +++ b/drivers/vision/vipx/vipx-graph.c @@ -269,9 +269,9 @@ static int vipx_graph_queue(struct vipx_graph *graph, otcl->id = incl->id; } - taskmgr_e_barrier_irqs(tmgr, 0, flags); + spin_lock_irqsave(&tmgr->slock, flags); task = vipx_task_pick_fre_to_req(tmgr); - taskmgr_x_barrier_irqr(tmgr, 0, flags); + spin_unlock_irqrestore(&tmgr->slock, flags); if (!task) { ret = -ENOMEM; vipx_err("free task is not remained (%u)\n", graph->idx); @@ -361,9 +361,9 @@ static int vipx_graph_deque(struct vipx_graph *graph, if (task->incl || task->otcl) return 0; - taskmgr_e_barrier_irqs(tmgr, 0, flags); + spin_lock_irqsave(&tmgr->slock, flags); vipx_task_trans_com_to_fre(tmgr, task); - taskmgr_x_barrier_irqr(tmgr, 0, flags); + spin_unlock_irqrestore(&tmgr->slock, flags); vipx_leave(); return 0; @@ -449,9 +449,9 @@ static int vipx_graph_request(struct vipx_graph *graph, struct vipx_task *task) goto p_err; } - taskmgr_e_barrier_irqs(tmgr, 0, flags); + spin_lock_irqsave(&tmgr->slock, flags); vipx_task_trans_req_to_pre(tmgr, task); - taskmgr_x_barrier_irqr(tmgr, 0, flags); + spin_unlock_irqrestore(&tmgr->slock, flags); vipx_leave(); return 0; @@ -474,9 +474,9 @@ static int vipx_graph_process(struct vipx_graph *graph, struct vipx_task *task) goto p_err; } - taskmgr_e_barrier_irqs(tmgr, TASKMGR_IDX_0, flags); + spin_lock_irqsave(&tmgr->slock, flags); vipx_task_trans_pre_to_pro(tmgr, task); - taskmgr_x_barrier_irqr(tmgr, TASKMGR_IDX_0, flags); + spin_unlock_irqrestore(&tmgr->slock, flags); vipx_leave(); return 0; @@ -506,9 +506,9 @@ static int vipx_graph_cancel(struct vipx_graph *graph, struct vipx_task *task) goto p_err; } - taskmgr_e_barrier_irqs(tmgr, TASKMGR_IDX_0, flags); + spin_lock_irqsave(&tmgr->slock, flags); vipx_task_trans_pro_to_com(tmgr, task); - taskmgr_x_barrier_irqr(tmgr, TASKMGR_IDX_0, flags); + spin_unlock_irqrestore(&tmgr->slock, flags); graph->recent = task->id; graph->done_cnt++; @@ -547,9 +547,9 @@ static int vipx_graph_done(struct vipx_graph *graph, struct vipx_task *task) goto p_err; } - taskmgr_e_barrier_irqs(tmgr, TASKMGR_IDX_0, flags); + spin_lock_irqsave(&tmgr->slock, flags); vipx_task_trans_pro_to_com(tmgr, task); - taskmgr_x_barrier_irqr(tmgr, TASKMGR_IDX_0, flags); + spin_unlock_irqrestore(&tmgr->slock, flags); graph->recent = task->id; graph->done_cnt++; diff --git a/drivers/vision/vipx/vipx-graphmgr.c b/drivers/vision/vipx/vipx-graphmgr.c index daf0642a9196..b49b9e95c2d3 100644 --- a/drivers/vision/vipx/vipx-graphmgr.c +++ b/drivers/vision/vipx/vipx-graphmgr.c @@ -551,9 +551,9 @@ static void vipx_interface_thread(struct kthread_work *work) } /* itask cleanup */ - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_com_to_fre(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); break; case VIPX_TASK_PROCESS: taskdesc_index = itask->tdindex; @@ -569,9 +569,9 @@ static void vipx_interface_thread(struct kthread_work *work) taskdesc_index); /* itask cleanup */ - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_com_to_fre(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); break; } @@ -608,9 +608,9 @@ static void vipx_interface_thread(struct kthread_work *work) __vipx_taskdesc_trans_com_to_fre(gmgr, taskdesc); /* itask cleanup */ - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_com_to_fre(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); break; default: vipx_err("message of task is invalid (%d)\n", itask->message); @@ -775,9 +775,9 @@ static int __vipx_graphmgr_itf_load_graph(struct vipx_interface *itf, vipx_enter(); itaskmgr = &itf->taskmgr; - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); itask = vipx_task_pick_fre_to_req(itaskmgr); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); if (!itask) { ret = -ENOMEM; vipx_err("itask is NULL\n"); @@ -792,9 +792,9 @@ static int __vipx_graphmgr_itf_load_graph(struct vipx_interface *itf, gmodel->time[TIME_LOAD_GRAPH] = itask->time; - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_com_to_fre(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); if (ret) goto p_err_hw_load_graph; @@ -851,9 +851,9 @@ static int __vipx_graphmgr_itf_unload_graph(struct vipx_interface *itf, vipx_enter(); itaskmgr = &itf->taskmgr; - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); itask = vipx_task_pick_fre_to_req(itaskmgr); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); if (!itask) { ret = -ENOMEM; vipx_err("itask is NULL\n"); @@ -868,9 +868,9 @@ static int __vipx_graphmgr_itf_unload_graph(struct vipx_interface *itf, gmodel->time[TIME_UNLOAD_GRAPH] = itask->time; - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_com_to_fre(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); if (ret) goto p_err_hw_unload_graph; @@ -932,9 +932,9 @@ static int __vipx_graphmgr_itf_execute_graph(struct vipx_interface *itf, vipx_enter(); itaskmgr = &itf->taskmgr; - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); itask = vipx_task_pick_fre_to_req(itaskmgr); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); if (!itask) { ret = -ENOMEM; vipx_err("itask is NULL\n"); @@ -950,9 +950,9 @@ static int __vipx_graphmgr_itf_execute_graph(struct vipx_interface *itf, gmodel->time[TIME_EXECUTE_GRAPH] = itask->time; - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_com_to_fre(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); if (ret) goto p_err_hw_load_graph; diff --git a/drivers/vision/vipx/vipx-interface.c b/drivers/vision/vipx/vipx-interface.c index bbe5ec0f0a7e..2b7cddcc6f43 100644 --- a/drivers/vision/vipx/vipx-interface.c +++ b/drivers/vision/vipx/vipx-interface.c @@ -23,11 +23,6 @@ #include "vipx-system.h" #include "vipx-interface.h" -#define enter_request_barrier(task) mutex_lock(task->lock) -#define exit_request_barrier(task) mutex_unlock(task->lock) -#define enter_process_barrier(itf) spin_lock_irq(&itf->process_barrier) -#define exit_process_barrier(itf) spin_unlock_irq(&itf->process_barrier) - static inline void __vipx_interface_set_reply(struct vipx_interface *itf, unsigned int gidx) { @@ -181,7 +176,7 @@ static int __vipx_interface_send_mailbox(struct vipx_interface *itf, struct vipx_mailbox_ctrl *mctrl; void *msg; unsigned long size, type; - unsigned long flags; + unsigned long flags, process_flags; vipx_enter(); itaskmgr = &itf->taskmgr; @@ -191,7 +186,7 @@ static int __vipx_interface_send_mailbox(struct vipx_interface *itf, size = itask->param2; type = itask->param3; - enter_process_barrier(itf); + spin_lock_irqsave(&itf->process_barrier, process_flags); itf->process = itask; ret = vipx_mailbox_check_full(mctrl, type, MAILBOX_WAIT); @@ -216,33 +211,33 @@ static int __vipx_interface_send_mailbox(struct vipx_interface *itf, } vipx_time_get_timestamp(&itask->time, TIMESTAMP_START); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, process_flags); - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_req_to_pro(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); ret = __vipx_interface_wait_mailbox_reply(itf, itask); if (ret) vipx_mailbox_dump(mctrl); - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_pro_to_com(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); - enter_process_barrier(itf); + spin_lock_irqsave(&itf->process_barrier, process_flags); itf->process = NULL; - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, process_flags); vipx_leave(); return ret; p_err_process: - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_req_to_com(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); itf->process = NULL; - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, process_flags); return ret; } @@ -506,6 +501,7 @@ static void __vipx_interface_isr(void *data) struct work_struct *work_queue; struct vipx_work *work; struct vipx_d2h_message rsp; + unsigned long flags; vipx_enter(); itf = (struct vipx_interface *)data; @@ -550,10 +546,11 @@ static void __vipx_interface_isr(void *data) } break; } else if (rsp.head.msg_id == D2H_LOAD_GRAPH_RSP) { - enter_process_barrier(itf); + spin_lock_irqsave(&itf->process_barrier, flags); if (!itf->process) { vipx_err("process task is empty\n"); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, + flags); continue; } @@ -565,13 +562,14 @@ static void __vipx_interface_isr(void *data) TIMESTAMP_END); itf->process->message = VIPX_TASK_DONE; wake_up(&itf->reply_wq); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, flags); continue; } else if (rsp.head.msg_id == D2H_EXECUTE_RSP) { - enter_process_barrier(itf); + spin_lock_irqsave(&itf->process_barrier, flags); if (!itf->process) { vipx_err("process task is empty\n"); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, + flags); continue; } @@ -585,13 +583,14 @@ static void __vipx_interface_isr(void *data) TIMESTAMP_END); itf->process->message = VIPX_TASK_DONE; wake_up(&itf->reply_wq); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, flags); continue; } else if (rsp.head.msg_id == D2H_UNLOAD_GRAPH_RSP) { - enter_process_barrier(itf); + spin_lock_irqsave(&itf->process_barrier, flags); if (!itf->process) { vipx_err("process task is empty\n"); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, + flags); continue; } @@ -603,7 +602,7 @@ static void __vipx_interface_isr(void *data) TIMESTAMP_END); itf->process->message = VIPX_TASK_DONE; wake_up(&itf->reply_wq); - exit_process_barrier(itf); + spin_unlock_irqrestore(&itf->process_barrier, flags); continue; } work = __vipx_interface_work_list_dequeue_free(work_list); @@ -710,7 +709,7 @@ static void __vipx_interface_cleanup(struct vipx_interface *itf) /* TODO remove debug log */ vipx_task_print_all(&itf->taskmgr); - taskmgr_e_barrier_irqs(taskmgr, 0, flags); + spin_lock_irqsave(&taskmgr->slock, flags); for (idx = 1; idx < taskmgr->tot_cnt; ++idx) { task = &taskmgr->task[idx]; @@ -721,7 +720,7 @@ static void __vipx_interface_cleanup(struct vipx_interface *itf) task_count--; } - taskmgr_x_barrier_irqr(taskmgr, 0, flags); + spin_unlock_irqrestore(&taskmgr->slock, flags); } } @@ -817,9 +816,9 @@ static void vipx_interface_work_reply_func(struct work_struct *data) __vipx_interface_set_reply(itf, gidx); break; case VIPX_TASK_PROCESS: - taskmgr_e_barrier_irqs(itaskmgr, 0, flags); + spin_lock_irqsave(&itaskmgr->slock, flags); vipx_task_trans_pro_to_com(itaskmgr, itask); - taskmgr_x_barrier_irqr(itaskmgr, 0, flags); + spin_unlock_irqrestore(&itaskmgr->slock, flags); itask->param2 = 0; itask->param3 = 0; diff --git a/drivers/vision/vipx/vipx-ioctl.h b/drivers/vision/vipx/vipx-ioctl.h index 0ef11e42e382..e83e50160c23 100644 --- a/drivers/vision/vipx/vipx-ioctl.h +++ b/drivers/vision/vipx/vipx-ioctl.h @@ -37,6 +37,8 @@ struct vipx_ioc_load_kernel_binary { struct vipx_ioc_unload_kernel_binary { unsigned int size; unsigned int global_id; + int kernel_fd; + unsigned int kernel_size; int ret; struct timespec timestamp[4]; int reserved[2]; diff --git a/drivers/vision/vipx/vipx-kernel-binary.c b/drivers/vision/vipx/vipx-kernel-binary.c index 4565f9727b55..cb4aef712fb3 100644 --- a/drivers/vision/vipx/vipx-kernel-binary.c +++ b/drivers/vision/vipx/vipx-kernel-binary.c @@ -113,17 +113,30 @@ p_err: return ret; } -int vipx_kernel_binary_unload(struct vipx_context *vctx, unsigned int global_id) +int vipx_kernel_binary_unload(struct vipx_context *vctx, unsigned int id, + int fd, unsigned int size) { + unsigned int model_id, kid; struct vipx_kernel_binary *kbin, *temp; - unsigned int kid, mid; + bool found; vipx_enter(); - mid = GET_COMMON_GRAPH_MODEL_ID(global_id); + found = false; + model_id = GET_COMMON_GRAPH_MODEL_ID(id); list_for_each_entry_safe(kbin, temp, &vctx->binary_list, clist) { kid = GET_COMMON_GRAPH_MODEL_ID(kbin->global_id); - if (kid == mid) + if ((model_id == kid) && + (fd == kbin->buffer.m.fd) && + (size == kbin->buffer.size)) { vipx_kernel_binary_remove(kbin); + found = true; + break; + } + } + if (!found) { + vipx_err("There is no kernel binary to unload\n"); + vipx_leave(); + return -ENOENT; } vipx_leave(); return 0; diff --git a/drivers/vision/vipx/vipx-kernel-binary.h b/drivers/vision/vipx/vipx-kernel-binary.h index a5e18ad8ba04..148953519e7b 100644 --- a/drivers/vision/vipx/vipx-kernel-binary.h +++ b/drivers/vision/vipx/vipx-kernel-binary.h @@ -28,8 +28,8 @@ int vipx_kernel_binary_set_gmodel(struct vipx_context *vctx, struct vipx_graph_model *gmodel); int vipx_kernel_binary_add(struct vipx_context *vctx, unsigned int id, int fd, unsigned int size); -int vipx_kernel_binary_unload(struct vipx_context *vctx, - unsigned int global_id); +int vipx_kernel_binary_unload(struct vipx_context *vctx, unsigned int id, + int fd, unsigned int size); void vipx_kernel_binary_remove(struct vipx_kernel_binary *kbin); void vipx_kernel_binary_all_remove(struct vipx_context *vctx); diff --git a/drivers/vision/vipx/vipx-mailbox.c b/drivers/vision/vipx/vipx-mailbox.c index 0068a6720845..f36089595e6e 100644 --- a/drivers/vision/vipx/vipx-mailbox.c +++ b/drivers/vision/vipx/vipx-mailbox.c @@ -40,45 +40,22 @@ static void __vipx_mailbox_dump(struct vipx_mailbox_head *head, void *data) void vipx_mailbox_dump(struct vipx_mailbox_ctrl *mctrl) { - int ret; - vipx_enter(); - ret = __vipx_mailbox_is_empty(&mctrl->h2d_normal_head); - if (ret) { - vipx_info("h2d normal mailbox is empty\n"); - } else { - vipx_info("h2d normal mailbox dump\n"); - __vipx_mailbox_dump(&mctrl->h2d_normal_head, - mctrl->h2d_normal_data); - } + vipx_info("h2d normal mailbox dump\n"); + __vipx_mailbox_dump(&mctrl->h2d_normal_head, + mctrl->h2d_normal_data); - ret = __vipx_mailbox_is_empty(&mctrl->h2d_urgent_head); - if (ret) { - vipx_info("h2d urgent mailbox is empty\n"); - } else { - vipx_info("h2d urgent mailbox dump\n"); - __vipx_mailbox_dump(&mctrl->h2d_urgent_head, - &mctrl->h2d_urgent_data); - } + vipx_info("h2d urgent mailbox dump\n"); + __vipx_mailbox_dump(&mctrl->h2d_urgent_head, + &mctrl->h2d_urgent_data); - ret = __vipx_mailbox_is_empty(&mctrl->d2h_normal_head); - if (ret) { - vipx_info("d2h normal mailbox is empty\n"); - } else { - vipx_info("d2h normal mailbox dump\n"); - __vipx_mailbox_dump(&mctrl->d2h_normal_head, - &mctrl->d2h_normal_data); - } - - ret = __vipx_mailbox_is_empty(&mctrl->d2h_urgent_head); - if (ret) { - vipx_info("d2h urgent mailbox is empty\n"); - } else { - vipx_info("d2h urgent mailbox dump\n"); - __vipx_mailbox_dump(&mctrl->d2h_urgent_head, - &mctrl->d2h_urgent_data); - } + vipx_info("d2h normal mailbox dump\n"); + __vipx_mailbox_dump(&mctrl->d2h_normal_head, + &mctrl->d2h_normal_data); + vipx_info("d2h urgent mailbox dump\n"); + __vipx_mailbox_dump(&mctrl->d2h_urgent_head, + &mctrl->d2h_urgent_data); vipx_leave(); } diff --git a/drivers/vision/vipx/vipx-memory.c b/drivers/vision/vipx/vipx-memory.c index 99ffe946d6ce..dd1b89ab396b 100644 --- a/drivers/vision/vipx/vipx-memory.c +++ b/drivers/vision/vipx/vipx-memory.c @@ -278,8 +278,9 @@ static int __vipx_memory_alloc(struct vipx_memory *mem, } pmem->dvaddr = dvaddr; } - vipx_info("[%20s] memory is allocated(%#p,%#x,%zu)", - pmem->name, kvaddr, (int)pmem->dvaddr, pmem->size); + vipx_info("[%20s] memory is allocated(%#p,%#x,%zuKB)", + pmem->name, kvaddr, (int)pmem->dvaddr, + pmem->size / SZ_1K); vipx_leave(); return 0; @@ -323,6 +324,13 @@ int vipx_memory_open(struct vipx_memory *mem) if (ret) goto p_err_map; + if (mem->mbox.size < sizeof(struct vipx_mailbox_ctrl)) { + vipx_err("mailbox(%zu) is larger than allocated memory(%zu)\n", + sizeof(struct vipx_mailbox_ctrl), + mem->mbox.size); + goto p_err_mbox; + } + ret = __vipx_memory_alloc(mem, &mem->mbox); if (ret) goto p_err_mbox; @@ -331,7 +339,7 @@ int vipx_memory_open(struct vipx_memory *mem) if (ret) goto p_err_heap; - ret = __vipx_memory_alloc(mem, &mem->debug); + ret = __vipx_memory_alloc(mem, &mem->log); if (ret) goto p_err_debug; @@ -350,7 +358,7 @@ p_err_map: int vipx_memory_close(struct vipx_memory *mem) { vipx_enter(); - __vipx_memory_free(mem, &mem->debug); + __vipx_memory_free(mem, &mem->log); __vipx_memory_free(mem, &mem->heap); __vipx_memory_free(mem, &mem->mbox); __vipx_memory_free(mem, &mem->fw); @@ -365,7 +373,7 @@ int vipx_memory_probe(struct vipx_system *sys) struct vipx_priv_mem *fw; struct vipx_priv_mem *mbox; struct vipx_priv_mem *heap; - struct vipx_priv_mem *debug; + struct vipx_priv_mem *log; vipx_enter(); dev = sys->dev; @@ -379,9 +387,9 @@ int vipx_memory_probe(struct vipx_system *sys) fw = &mem->fw; mbox = &mem->mbox; heap = &mem->heap; - debug = &mem->debug; + log = &mem->log; - snprintf(fw->name, VIPX_PRIV_MEM_NAME_LEN, "vipx_cc_dram_bin"); + snprintf(fw->name, VIPX_PRIV_MEM_NAME_LEN, "CC_DRAM_BIN"); fw->size = PAGE_ALIGN(VIPX_CC_DRAM_BIN_SIZE); fw->flags = 0; fw->direction = DMA_TO_DEVICE; @@ -389,25 +397,28 @@ int vipx_memory_probe(struct vipx_system *sys) fw->dvaddr = VIPX_CC_DRAM_BIN_DVADDR; fw->fixed_dvaddr = true; - snprintf(mbox->name, VIPX_PRIV_MEM_NAME_LEN, "vipx_mbox"); - mbox->size = PAGE_ALIGN(sizeof(struct vipx_mailbox_ctrl)); + snprintf(mbox->name, VIPX_PRIV_MEM_NAME_LEN, "MBOX"); + mbox->size = PAGE_ALIGN(VIPX_MBOX_SIZE); mbox->flags = 0; mbox->direction = DMA_BIDIRECTIONAL; mbox->kmap = true; - mbox->fixed_dvaddr = false; + mbox->dvaddr = VIPX_MBOX_DVADDR; + mbox->fixed_dvaddr = true; - snprintf(heap->name, VIPX_PRIV_MEM_NAME_LEN, "vipx_heap"); + snprintf(heap->name, VIPX_PRIV_MEM_NAME_LEN, "HEAP"); heap->size = PAGE_ALIGN(VIPX_HEAP_SIZE); heap->flags = 0; heap->direction = DMA_FROM_DEVICE; - heap->fixed_dvaddr = false; - - snprintf(debug->name, VIPX_PRIV_MEM_NAME_LEN, "vipx_debug"); - debug->size = PAGE_ALIGN(VIPX_DEBUG_SIZE); - debug->flags = 0; - debug->direction = DMA_BIDIRECTIONAL; - debug->kmap = true; - debug->fixed_dvaddr = false; + heap->dvaddr = VIPX_HEAP_DVADDR; + heap->fixed_dvaddr = true; + + snprintf(log->name, VIPX_PRIV_MEM_NAME_LEN, "LOG"); + log->size = PAGE_ALIGN(VIPX_LOG_SIZE); + log->flags = 0; + log->direction = DMA_BIDIRECTIONAL; + log->kmap = true; + log->dvaddr = VIPX_LOG_DVADDR; + log->fixed_dvaddr = true; vipx_leave(); return 0; diff --git a/drivers/vision/vipx/vipx-memory.h b/drivers/vision/vipx/vipx-memory.h index 48b0b5fed32c..8301b3ac81b8 100644 --- a/drivers/vision/vipx/vipx-memory.h +++ b/drivers/vision/vipx/vipx-memory.h @@ -16,10 +16,15 @@ #include "vs4l.h" #include "vipx-common-type.h" -#define VIPX_CC_DRAM_BIN_DVADDR (0xB8000000) +#define VIPX_CC_DRAM_BIN_DVADDR (0x10000000) #define VIPX_CC_DRAM_BIN_SIZE (SZ_4M) +#define VIPX_MBOX_DVADDR (0x11000000) +#define VIPX_MBOX_SIZE (SZ_32K) +#define VIPX_HEAP_DVADDR (0x12000000) #define VIPX_HEAP_SIZE (SZ_1M) -#define VIPX_DEBUG_SIZE (SZ_16M) +#define VIPX_LOG_DVADDR (0x13000000) +#define VIPX_LOG_SIZE (SZ_1M) +#define VIPX_MEMORY_MAX_SIZE (SZ_16M) #define VIPX_PRIV_MEM_NAME_LEN (30) @@ -86,7 +91,7 @@ struct vipx_memory { struct vipx_priv_mem fw; struct vipx_priv_mem mbox; struct vipx_priv_mem heap; - struct vipx_priv_mem debug; + struct vipx_priv_mem log; }; int vipx_memory_open(struct vipx_memory *mem); diff --git a/drivers/vision/vipx/vipx-system.c b/drivers/vision/vipx/vipx-system.c index 09592d9adad5..3d49f453d44e 100644 --- a/drivers/vision/vipx/vipx-system.c +++ b/drivers/vision/vipx/vipx-system.c @@ -26,8 +26,8 @@ int vipx_system_fw_bootup(struct vipx_system *sys) unsigned int mbox_size; unsigned int heap_addr; unsigned int heap_size; - unsigned int debug_addr; - unsigned int debug_size; + unsigned int log_addr; + unsigned int log_size; } *shared_mem; vipx_enter(); @@ -36,12 +36,12 @@ int vipx_system_fw_bootup(struct vipx_system *sys) sys->ctrl_ops->reset(sys); - ret = vipx_binary_read(bin, NULL, VIPX_FW_DRAM_NAME, mem->fw.kvaddr, + ret = vipx_binary_firmware_load(bin, VIPX_FW_DRAM_NAME, mem->fw.kvaddr, mem->fw.size); if (ret) goto p_err; - ret = vipx_binary_read(bin, NULL, VIPX_FW_DTCM_NAME, sys->dtcm, + ret = vipx_binary_firmware_load(bin, VIPX_FW_DTCM_NAME, sys->dtcm, sys->dtcm_size); if (ret) goto p_err; @@ -51,11 +51,11 @@ int vipx_system_fw_bootup(struct vipx_system *sys) shared_mem->mbox_size = mem->mbox.size; shared_mem->heap_addr = mem->heap.dvaddr; shared_mem->heap_size = mem->heap.size; - shared_mem->debug_addr = mem->debug.dvaddr; - shared_mem->debug_size = mem->debug.size; + shared_mem->log_addr = mem->log.dvaddr; + shared_mem->log_size = mem->log.size; - ret = vipx_binary_read(bin, NULL, VIPX_FW_ITCM_NAME, - sys->itcm, sys->itcm_size); + ret = vipx_binary_firmware_load(bin, VIPX_FW_ITCM_NAME, sys->itcm, + sys->itcm_size); if (ret) goto p_err; diff --git a/drivers/vision/vipx/vipx-taskmgr.h b/drivers/vision/vipx/vipx-taskmgr.h index 96421bffb206..ebdf814085f4 100644 --- a/drivers/vision/vipx/vipx-taskmgr.h +++ b/drivers/vision/vipx/vipx-taskmgr.h @@ -16,75 +16,6 @@ #include "vipx-config.h" #include "vipx-time.h" -#define TASKMGR_IDX_0 (1 << 0) /* graphmgr thread */ -#define TASKMGR_IDX_1 (1 << 1) -#define TASKMGR_IDX_2 (1 << 2) -#define TASKMGR_IDX_3 (1 << 3) -#define TASKMGR_IDX_4 (1 << 4) -#define TASKMGR_IDX_5 (1 << 5) -#define TASKMGR_IDX_6 (1 << 6) -#define TASKMGR_IDX_7 (1 << 7) -#define TASKMGR_IDX_8 (1 << 8) -#define TASKMGR_IDX_9 (1 << 9) -#define TASKMGR_IDX_10 (1 << 10) -#define TASKMGR_IDX_11 (1 << 11) -#define TASKMGR_IDX_12 (1 << 12) -#define TASKMGR_IDX_13 (1 << 13) -#define TASKMGR_IDX_14 (1 << 14) -#define TASKMGR_IDX_15 (1 << 15) -#define TASKMGR_IDX_16 (1 << 16) -#define TASKMGR_IDX_17 (1 << 17) -#define TASKMGR_IDX_18 (1 << 18) -#define TASKMGR_IDX_19 (1 << 19) -#define TASKMGR_IDX_20 (1 << 20) -#define TASKMGR_IDX_21 (1 << 21) -#define TASKMGR_IDX_22 (1 << 22) -#define TASKMGR_IDX_23 (1 << 23) -#define TASKMGR_IDX_24 (1 << 24) -#define TASKMGR_IDX_25 (1 << 25) -#define TASKMGR_IDX_26 (1 << 26) -#define TASKMGR_IDX_27 (1 << 27) -#define TASKMGR_IDX_28 (1 << 28) -#define TASKMGR_IDX_29 (1 << 29) -#define TASKMGR_IDX_30 (1 << 30) -#define TASKMGR_IDX_31 (1 << 31) - -#define taskmgr_e_barrier_irqs(taskmgr, index, flag) \ - do { \ - taskmgr->sindex |= index; \ - spin_lock_irqsave(&taskmgr->slock, flag); \ - } while (0) - -#define taskmgr_x_barrier_irqr(taskmgr, index, flag) \ - do { \ - spin_unlock_irqrestore(&taskmgr->slock, flag); \ - taskmgr->sindex &= ~index; \ - } while (0) - -#define taskmgr_e_barrier_irq(taskmgr, index) \ - do { \ - taskmgr->sindex |= index; \ - spin_lock_irq(&taskmgr->slock); \ - } while (0) - -#define taskmgr_x_barrier_irq(taskmgr, index) \ - do { \ - spin_unlock_irq(&taskmgr->slock); \ - taskmgr->sindex &= ~index; \ - } while (0) - -#define taskmgr_e_barrier(taskmgr, index) \ - do { \ - taskmgr->sindex |= index; \ - spin_lock(&taskmgr->slock); \ - } while (0) - -#define taskmgr_x_barrier(taskmgr, index) \ - do { \ - spin_unlock(&taskmgr->slock); \ - taskmgr->sindex &= ~index; \ - } while (0) - enum vipx_task_state { VIPX_TASK_STATE_FREE = 1, VIPX_TASK_STATE_REQUEST, -- 2.20.1