vipx_fw_code_rmem: vipx_fw_rmem@0xB8000000 {
compatible = "exynos,vipx_fw_code_rmem";
- reg = <0x0 0xb8000000 0x2000000>;
+ reg = <0x0 0xb8000000 0x300000>;
};
};
};
#size-cells = <1>;
ranges;
- domain-clients = <&vipx>;
+ domain-clients = <>;
};
iommu-domain_abox {
available_stop_owner = <PANIC_HANDLE CAMERA_DRIVER MODEM_IF ITMON_HANDLE>;
buff_size = <0x100000>;
};
-
- vipx: vipx@10D60000 {
- compatible = "samsung,exynos-vipx";
- id = <0>;
- reg = <0x0 0x10D60000 0x10000>, /* VIPX_CPU_SS1 */
- <0x0 0x10F60000 0x10000>, /* VIPX_CPU_SS2 */
- <0x0 0x10D90000 0x2000>, /* ITCM(8K) */
- <0x0 0x10DA0000 0x4000>; /* DTCM(16K) */
- pinctrl-names = "default","release";
- pinctrl-0 = <>;
- pinctrl-1 = <>;
- clocks = <&clock UMUX_CLKCMU_VIPX1_BUS>,
- <&clock GATE_VIPX1_QCH>,
- <&clock UMUX_CLKCMU_VIPX2_BUS>,
- <&clock GATE_VIPX2_QCH>,
- <&clock GATE_VIPX2_QCH_LOCAL>;
- clock-names = "UMUX_CLKCMU_VIPX1_BUS",
- "GATE_VIPX1_QCH",
- "UMUX_CLKCMU_VIPX2_BUS",
- "GATE_VIPX2_QCH",
- "GATE_VIPX2_QCH_LOCAL";
-
- /*samsung,power-domain = <&pd_vipx2>;*/
- interrupts = <0 129 0>,
- <0 130 0>;
- iommus = <&sysmmu_vipx1>, <&sysmmu_vipx2>;
- status = "ok";
- };
-
};
CONFIG_SECURITY_SELINUX=y
CONFIG_CRYPTO_DISKCIPHER=y
CONFIG_EXYNOS_FMP=y
-CONFIG_VISION_SUPPORT=y
-CONFIG_VISION_CORE=y
-CONFIG_EXYNOS_VIPX=y
-CONFIG_EXYNOS_VIPX_PLATFORM=y
-CONFIG_EXYNOS_VIPX_EXYNOS9610=y
-CONFIG_EXYNOS_VIPX_INTERFACE=y
-CONFIG_EXYNOS_VIPX_HARDWARE=y
-CONFIG_EXYNOS_VIPX_MBOX=n
source "drivers/gud/Kconfig"
source "drivers/ccic/Kconfig"
-
-source "drivers/vision/Kconfig"
-
endmenu
obj-$(CONFIG_TRUSTONIC_TEE) += gud/
obj-$(CONFIG_USBPD_CORE) += ccic/
-
-obj-$(CONFIG_VISION_SUPPORT) += vision/
-
+++ /dev/null
-menuconfig VISION_SUPPORT
- bool "Vision Support"
- select VISION_CORE
- help
- If you want to use hardware acceleration for vision
- enable this option and other options below.
-
-if VISION_SUPPORT
-source "drivers/vision/vision-core/Kconfig"
-source "drivers/vision/vipx/Kconfig"
-endif # VISION_SUPPORT
+++ /dev/null
-obj-$(CONFIG_VISION_CORE) += vision-core/
-obj-$(CONFIG_EXYNOS_VIPX) += vipx/
+++ /dev/null
-/* include/media/videobuf2-ion.h
- *
- * Copyright 2011-2012 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * Definition of Android ION memory allocator for videobuf2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _MEDIA_VIDEOBUF2_ION_H
-#define _MEDIA_VIDEOBUF2_ION_H
-
-#include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
-//#include <linux/ion.h>
-//#include <linux/exynos_ion.h>
-#include <linux/err.h>
-#include <linux/dma-buf.h>
-
-/* flags to vb2_ion_create_context
- * These flags are dependet upon heap flags in ION.
- *
- * bit 0 ~ ION_NUM_HEAPS: ion heap flags
- * bit ION_NUM_HEAPS+1 ~ 20: non-ion flags (cached, iommu)
- * bit 21 ~ BITS_PER_INT - 1: ion specific flags
- */
-
-/* DMA of the client device is coherent with CPU */
-#define VB2ION_CTX_COHERENT_DMA (1 << (ION_NUM_HEAPS + 3))
-/* DMA should read from memory instead of CPU cache even if DMA is coherent */
-#define VB2ION_CTX_UNCACHED_READ_DMA (1 << (ION_NUM_HEAPS + 4))
-
-#define VB2ION_CONTIG_ID_NUM 16
-#define VB2ION_NUM_HEAPS 8
-/* below 6 is the above vb2-ion flags (ION_NUM_HEAPS + 1 ~ 6) */
-
-
-struct device;
-struct vb2_buffer;
-
-/* - vb2_ion_set_noncoherent_dma_read(): Forces the DMA to read from system
- * memory even though it is capable of snooping CPU caches.
- */
-void vb2_ion_set_noncoherent_dma_read(struct device *dev, bool noncoherent);
-
-/* Data type of the cookie returned by vb2_plane_cookie() function call.
- * The drivers do not need the definition of this structure. The only reason
- * why it is defined outside of videobuf2-ion.c is to make some functions
- * inline.
- */
-struct vb2_ion_cookie {
- dma_addr_t ioaddr;
- dma_addr_t paddr;
- struct sg_table *sgt;
- off_t offset;
-};
-
-/* vb2_ion_buffer_offset - return the mapped offset of the buffer
- * - cookie: pointer returned by vb2_plane_cookie()
- *
- * Returns offset value that the mapping starts from.
- */
-
-static inline off_t vb2_ion_buffer_offset(void *cookie)
-{
- return IS_ERR_OR_NULL(cookie) ?
- -EINVAL : ((struct vb2_ion_cookie *)cookie)->offset;
-}
-
-/* vb2_ion_phys_address - returns the physical address of the given buffer
- * - cookie: pointer returned by vb2_plane_cookie()
- * - phys_addr: pointer to the store of the physical address of the buffer
- * specified by cookie.
- *
- * Returns -EINVAL if the buffer does not have nor physically contiguous memory.
- */
-static inline int vb2_ion_phys_address(void *cookie, phys_addr_t *phys_addr)
-{
- struct vb2_ion_cookie *vb2cookie = cookie;
-
- if (WARN_ON(!phys_addr || IS_ERR_OR_NULL(cookie)))
- return -EINVAL;
-
- if (vb2cookie->paddr) {
- *phys_addr = vb2cookie->paddr;
- } else {
- if (vb2cookie->sgt && vb2cookie->sgt->nents == 1) {
- *phys_addr = sg_phys(vb2cookie->sgt->sgl) +
- vb2cookie->offset;
- } else {
- *phys_addr = 0;
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-/* vb2_ion_dma_address - returns the DMA address that device can see
- * - cookie: pointer returned by vb2_plane_cookie()
- * - dma_addr: pointer to the store of the address of the buffer specified
- * by cookie. It can be either IO virtual address or physical address
- * depending on the specification of allocation context which allocated
- * the buffer.
- *
- * Returns -EINVAL if the buffer has neither IO virtual address nor physically
- * contiguous memory
- */
-static inline int vb2_ion_dma_address(void *cookie, dma_addr_t *dma_addr)
-{
- struct vb2_ion_cookie *vb2cookie = cookie;
-
- if (WARN_ON(!dma_addr || IS_ERR_OR_NULL(cookie)))
- return -EINVAL;
-
- if (vb2cookie->ioaddr == 0)
- return vb2_ion_phys_address(cookie, (phys_addr_t *)dma_addr);
-
- *dma_addr = vb2cookie->ioaddr;
-
- return 0;
-}
-
-/* vb2_ion_get_sg - returns scatterlist of the given cookie.
- * - cookie: pointer returned by vb2_plane_cookie()
- * - nents: pointer to the store of number of elements in the returned
- * scatterlist
- *
- * Returns the scatterlist of the buffer specified by cookie.
- * If the arguments are not correct, returns NULL.
- */
-static inline struct scatterlist *vb2_ion_get_sg(void *cookie, int *nents)
-{
- struct vb2_ion_cookie *vb2cookie = cookie;
-
- if (WARN_ON(!nents || IS_ERR_OR_NULL(cookie)))
- return NULL;
-
- *nents = vb2cookie->sgt->nents;
- return vb2cookie->sgt->sgl;
-}
-
-/* vb2_ion_get_dmabuf - returns dmabuf of the given cookie
- * - cookie: pointer returned by vb2_plane_cookie()
- *
- * Returns dma-buf descriptor with a reference held.
- * NULL if the cookie is invalid or the buffer is not dmabuf.
- * The caller must put the dmabuf when it is no longer need the dmabuf
- */
-struct dma_buf *vb2_ion_get_dmabuf(void *cookie);
-
-/***** Cache mainatenance operations *****/
-void vb2_ion_sync_for_device(void *cookie, off_t offset, size_t size,
- enum dma_data_direction dir);
-void vb2_ion_sync_for_cpu(void *cookie, off_t offset, size_t size,
- enum dma_data_direction dir);
-int vb2_ion_buf_prepare(struct vb2_buffer *vb);
-void vb2_ion_buf_finish(struct vb2_buffer *vb);
-int vb2_ion_buf_prepare_exact(struct vb2_buffer *vb);
-int vb2_ion_buf_finish_exact(struct vb2_buffer *vb);
-
-extern const struct vb2_mem_ops vb2_ion_memops;
-extern struct ion_device *ion_exynos; /* drivers/gpu/ion/exynos/exynos-ion.c */
-
-#endif /* _MEDIA_VIDEOBUF2_ION_H */
+++ /dev/null
-/*
- * Samsung Exynos SoC series VPU driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VISION_BUFFER_H_
-#define VISION_BUFFER_H_
-
-#include <linux/mm_types.h>
-#include <linux/mutex.h>
-#include <linux/poll.h>
-#include <linux/dma-buf.h>
-#include <linux/time.h>
-
-#include <media/videobuf2-core.h>
-#if defined(CONFIG_VIDEOBUF2_CMA_PHYS)
-#include <media/videobuf2-cma-phys.h>
-#elif defined(CONFIG_VIDEOBUF2_DMA_SG)
-//#include <media/videobuf2-dma-sg.h>
-#endif
-
-#include "vision-config.h"
-#include "vs4l.h"
-
-#define VB_MAX_BUFFER VISION_MAX_BUFFER
-#define VB_MAX_PLANES VISION_MAX_PLANE
-
-struct vb_queue;
-
-struct vb_fmt {
- char *name;
- u32 colorspace;
- u32 planes;
- u32 bitsperpixel[VB_MAX_PLANES];
-};
-
-struct vb_format {
- u32 target;
- struct vb_fmt *fmt;
- u32 colorspace;
- u32 plane;
- u32 width;
- u32 height;
- u32 size[VB_MAX_PLANES];
-};
-
-struct vb_format_list {
- u32 count;
- struct vb_format *formats;
-};
-
-struct vb_buffer {
- struct vs4l_roi roi;
- union {
- unsigned long userptr;
- __s32 fd;
- } m;
- struct dma_buf *dbuf;
- void *mem_priv;
- void *cookie;
- void *kvaddr;
- dma_addr_t dvaddr;
- ulong reserved;
-#if 1 // MODERN_ION
- struct dma_buf *dma_buf;
- struct dma_buf_attachment *attachment;
- struct sg_table *sgt;
- dma_addr_t daddr;
- void *vaddr;
- size_t size;
-#endif
-};
-
-struct vb_container {
- u32 type;
- u32 target;
- u32 memory;
- u32 reserved[4];
- u32 count;
- struct vb_buffer *buffers;
- struct vb_format *format;
-};
-
-struct vb_container_list {
- u32 direction;
- u32 id;
- u32 index;
- unsigned long flags;
- struct timeval timestamp[6];
- u32 count;
- u32 user_params[_MAX_NUM_OF_USER_PARAMS];
- struct vb_container *containers;
-};
-
-enum vb_bundle_state {
- VB_BUF_STATE_DEQUEUED,
- VB_BUF_STATE_QUEUED,
- VB_BUF_STATE_PROCESS,
- VB_BUF_STATE_DONE,
-};
-
-struct vb_bundle {
- /* this flag is for internal state */
- unsigned long flags;
- enum vb_bundle_state state;
- struct list_head queued_entry;
- struct list_head process_entry;
- struct list_head done_entry;
-
- struct vb_container_list clist;
-};
-
-struct vb_ops {
- int (*buf_prepare)(struct vb_queue *q, struct vb_container_list *clist);
- int (*buf_unprepare)(struct vb_queue *q, struct vb_container_list *clist);
-};
-
-enum vb_queue_state {
- VB_QUEUE_STATE_FORMAT,
- VB_QUEUE_STATE_START
-};
-
-struct vb_queue {
- u32 direction;
- const char *name;
- unsigned long state;
- unsigned int streaming:1;
- struct mutex *lock;
-
- struct list_head queued_list;
- atomic_t queued_count;
- struct list_head process_list;
- atomic_t process_count;
- struct list_head done_list;
- atomic_t done_count;
-
- spinlock_t done_lock;
- wait_queue_head_t done_wq;
-
- struct vb_format_list format;
- struct vb_bundle *bufs[VB_MAX_BUFFER];
- unsigned int num_buffers;
-
- void *alloc_dev;
- const struct vb2_mem_ops *mem_ops;
- const struct vb_ops *ops;
- void *private_data;
-};
-
-int vb_queue_init(struct vb_queue *q, void *alloc_ctx, const struct vb2_mem_ops *mem_ops, const struct vb_ops *ops, struct mutex *lock, u32 direction);
-int vb_queue_s_format(struct vb_queue *q, struct vs4l_format_list *f);
-int vb_queue_start(struct vb_queue *q);
-int vb_queue_stop(struct vb_queue *q);
-int vb_queue_qbuf(struct vb_queue *q, struct vs4l_container_list *c);
-int vb_queue_dqbuf(struct vb_queue *q, struct vs4l_container_list *c, bool nonblocking);
-void vb_queue_process(struct vb_queue *q, struct vb_bundle *vb);
-void vb_queue_done(struct vb_queue *q, struct vb_bundle *vb);
-
-#define call_memop(q, op, args...) (((q)->mem_ops->op) ? ((q)->mem_ops->op(args)) : 0)
-#define call_op(q, op, args...) (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VPU driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VISION_CONFIG_H_
-#define VISION_CONFIG_H_
-
-#define VISION_MAX_BUFFER 16
-#define VISION_MAX_PLANE 3
-#define VISION_MAP_KVADDR
-
-/*
-#define probe_info(fmt, ...) pr_info("[V]" fmt, ##__VA_ARGS__)
-#define probe_warn(fmt, args...) pr_warning("[V][WRN]" fmt, ##args)
-#define probe_err(fmt, args...) pr_err("[V][ERR]%s:%d:" fmt, __func__, __LINE__, ##args)
-*/
-#define DISABLE_VISION_LOG 1
-
-#if DISABLE_VISION_LOG
-#define vision_err_target(fmt, ...)
-#define vision_warn_target(fmt, ...)
-#define vision_info_target(fmt, ...)
-#define vision_dbg_target(fmt, ...)
-
-#else
-
-#ifdef DEBUG_LOG_MEMORY
-#define vision_err_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#define vision_warn_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#define vision_info_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#define vision_dbg_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#else
-#define vision_err_target(fmt, ...) pr_err(fmt, ##__VA_ARGS__)
-#define vision_warn_target(fmt, ...) pr_warning(fmt, ##__VA_ARGS__)
-#define vision_info_target(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
-#define vision_dbg_target(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
-#endif
-
-#endif
-#define vision_err(fmt, args...) \
- vision_err_target("[V][ERR]%s:%d:" fmt, __func__, __LINE__, ##args)
-
-#define vision_info(fmt, args...) \
- vision_info_target("[V]" fmt, ##args)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VPU driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VISION_DEV_H_
-#define VISION_DEV_H_
-
-#include <linux/fs.h>
-#include <linux/device.h>
-
-#define VISION_NUM_DEVICES 256
-#define VISION_MAJOR 82
-#define VISION_NAME "vision4linux"
-
-enum VISION_DEVICE_TYPE {
- VISION_DEVICE_TYPE_VERTEX
-};
-
-struct vision_file_ops {
- struct module *owner;
- int (*open) (struct file *);
- int (*release) (struct file *);
- unsigned int (*poll) (struct file *, struct poll_table_struct *);
- long (*ioctl) (struct file *, unsigned int, unsigned long);
- long (*compat_ioctl)(struct file *file, unsigned int, unsigned long);
-};
-
-enum VISION_FLAGS {
- VISION_FL_REGISTERED
-};
-
-struct vision_device {
- int minor;
- char name[32];
- unsigned long flags;
- int index;
- u32 type;
-
- /* device ops */
- const struct vision_file_ops *fops;
-
- /* sysfs */
- struct device dev;
- struct cdev *cdev;
- struct device *parent;
-
- /* vb2_queue associated with this device node. May be NULL. */
- //struct vb2_queue *queue;
-
-
- int debug; /* Activates debug level*/
-
- /* callbacks */
- void (*release)(struct vision_device *vdev);
-
- /* ioctl callbacks */
- const struct vertex_ioctl_ops *ioctl_ops;
- //DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
-
- /* serialization lock */
- //DECLARE_BITMAP(disable_locking, BASE_VIDIOC_PRIVATE);
- struct mutex *lock;
-};
-
-struct vision_device *vision_devdata(struct file *file);
-int vision_register_device(struct vision_device *vdev, int minor, struct module *owner);
-
-#endif
\ No newline at end of file
+++ /dev/null
-/*
- * Samsung Exynos SoC series VPU driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "vs4l.h"
-
-#ifndef VISION_IOCTL_H_
-#define VISION_IOCTL_H_
-
-struct vertex_ioctl_ops {
- int (*vertexioc_s_graph)(struct file *file, struct vs4l_graph *graph);
- int (*vertexioc_s_format)(struct file *file, struct vs4l_format_list *flist);
- int (*vertexioc_s_param)(struct file *file, struct vs4l_param_list *plist);
- int (*vertexioc_s_ctrl)(struct file *file, struct vs4l_ctrl *ctrl);
- int (*vertexioc_qbuf)(struct file *file, struct vs4l_container_list *clist);
- int (*vertexioc_dqbuf)(struct file *file, struct vs4l_container_list *clist);
- int (*vertexioc_streamon)(struct file *file);
- int (*vertexioc_streamoff)(struct file *file);
-};
-
-long vertex_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-long vertex_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg);
-
-#endif
-
+++ /dev/null
-/*
- * Samsung Exynos SoC series VPU driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VISION_FOR_LINUX_H_
-#define VISION_FOR_LINUX_H_
-
-#define VS4L_VERSION 5
-#define VS4L_TARGET_SC 0xFFFF
-#define VS4L_TARGET_SC_SHIFT 16
-#define VS4L_TARGET_PU 0xFFFF
-#define VS4L_TARGET_PU_SHIFT 0
-#define _MAX_NUM_OF_USER_PARAMS 80
-
-
-enum vs4l_graph_flag {
- VS4L_GRAPH_FLAG_FIXED,
- VS4L_GRAPH_FLAG_SHARED_AMONG_SUBCHAINS,
- VS4L_GRAPH_FLAG_SHARING_AMONG_SUBCHAINS_PREFERRED,
- VS4L_GRAPH_FLAG_SHARED_AMONG_TASKS,
- VS4L_GRAPH_FLAG_SHARING_AMONG_TASKS_PREFERRED,
- VS4L_GRAPH_FLAG_DSBL_LATENCY_BALANCING,
- VS4L_STATIC_ALLOC_LARGE_MPRB_INSTEAD_SMALL_FLAG,
- VS4L_STATIC_ALLOC_PU_INSTANCE_LSB,
- VS4L_GRAPH_FLAG_PRIMITIVE,
- VS4L_GRAPH_FLAG_EXCLUSIVE,
- VS4L_GRAPH_FLAG_PERIODIC,
- VS4L_GRAPH_FLAG_ROUTING,
- VS4L_GRAPH_FLAG_BYPASS,
- VS4L_GRAPH_FLAG_END
-};
-
-struct vs4l_graph {
- __u32 id;
- __u32 priority;
- __u32 time; /* in millisecond */
- __u32 flags;
- __u32 size;
- unsigned long addr;
-};
-
-struct vs4l_format {
- __u32 target;
- __u32 format;
- __u32 plane;
- __u32 width;
- __u32 height;
-};
-
-struct vs4l_format_list {
- __u32 direction;
- __u32 count;
- struct vs4l_format *formats;
-};
-
-struct vs4l_param {
- __u32 target;
- unsigned long addr;
- __u32 offset;
- __u32 size;
-};
-
-struct vs4l_param_list {
- __u32 count;
- struct vs4l_param *params;
-};
-
-struct vs4l_ctrl {
- __u32 ctrl;
- __u32 value;
-};
-
-struct vs4l_roi {
- __u32 x;
- __u32 y;
- __u32 w;
- __u32 h;
-};
-
-struct vs4l_buffer {
- struct vs4l_roi roi;
- union {
- unsigned long userptr;
- __s32 fd;
- } m;
- unsigned long reserved;
-};
-
-enum vs4l_buffer_type {
- VS4L_BUFFER_LIST,
- VS4L_BUFFER_ROI,
- VS4L_BUFFER_PYRAMID
-};
-
-enum vs4l_memory {
- VS4L_MEMORY_USERPTR = 1,
- VS4L_MEMORY_VIRTPTR,
- VS4L_MEMORY_DMABUF
-};
-
-struct vs4l_container {
- __u32 type;
- __u32 target;
- __u32 memory;
- __u32 reserved[4];
- __u32 count;
- struct vs4l_buffer *buffers;
-};
-
-enum vs4l_direction {
- VS4L_DIRECTION_IN = 1,
- VS4L_DIRECTION_OT
-};
-
-enum vs4l_cl_flag {
- VS4L_CL_FLAG_TIMESTAMP,
- VS4L_CL_FLAG_PREPARE = 8,
- VS4L_CL_FLAG_INVALID,
- VS4L_CL_FLAG_DONE
-};
-
-struct vs4l_container_list {
- __u32 direction;
- __u32 id;
- __u32 index;
- __u32 flags;
- struct timeval timestamp[6];
- __u32 count;
- __u32 user_params[_MAX_NUM_OF_USER_PARAMS];
- struct vs4l_container *containers;
-};
-
-/*
- * F O U R C C C O D E S F O R V I S I O N
- *
- */
-
-#define VS4L_DF_IMAGE(a, b, c, d) ((a) | (b << 8) | (c << 16) | (d << 24))
-#define VS4L_DF_IMAGE_RGB VS4L_DF_IMAGE('R', 'G', 'B', '2')
-#define VS4L_DF_IMAGE_RGBX VS4L_DF_IMAGE('R', 'G', 'B', 'A')
-#define VS4L_DF_IMAGE_NV12 VS4L_DF_IMAGE('N', 'V', '1', '2')
-#define VS4L_DF_IMAGE_NV21 VS4L_DF_IMAGE('N', 'V', '2', '1')
-#define VS4L_DF_IMAGE_YV12 VS4L_DF_IMAGE('Y', 'V', '1', '2')
-#define VS4L_DF_IMAGE_I420 VS4L_DF_IMAGE('I', '4', '2', '0')
-#define VS4L_DF_IMAGE_I422 VS4L_DF_IMAGE('I', '4', '2', '2')
-#define VS4L_DF_IMAGE_YUYV VS4L_DF_IMAGE('Y', 'U', 'Y', 'V')
-#define VS4L_DF_IMAGE_YUV4 VS4L_DF_IMAGE('Y', 'U', 'V', '4')
-#define VS4L_DF_IMAGE_U8 VS4L_DF_IMAGE('U', '0', '0', '8')
-#define VS4L_DF_IMAGE_U16 VS4L_DF_IMAGE('U', '0', '1', '6')
-#define VS4L_DF_IMAGE_U32 VS4L_DF_IMAGE('U', '0', '3', '2')
-#define VS4L_DF_IMAGE_S16 VS4L_DF_IMAGE('S', '0', '1', '6')
-#define VS4L_DF_IMAGE_S32 VS4L_DF_IMAGE('S', '0', '3', '2')
-
-/*
- * I O C T L C O D E S F O R V E R T E X D E V I C E
- *
- */
-
-#define VS4L_VERTEXIOC_S_GRAPH _IOW('V', 0, struct vs4l_graph)
-#define VS4L_VERTEXIOC_S_FORMAT _IOW('V', 1, struct vs4l_format_list)
-#define VS4L_VERTEXIOC_S_PARAM _IOW('V', 2, struct vs4l_param_list)
-#define VS4L_VERTEXIOC_S_CTRL _IOW('V', 3, struct vs4l_ctrl)
-#define VS4L_VERTEXIOC_STREAM_ON _IO('V', 4)
-#define VS4L_VERTEXIOC_STREAM_OFF _IO('V', 5)
-#define VS4L_VERTEXIOC_QBUF _IOW('V', 6, struct vs4l_container_list)
-#define VS4L_VERTEXIOC_DQBUF _IOW('V', 7, struct vs4l_container_list)
-
-#endif
+++ /dev/null
-menuconfig EXYNOS_VIPX
- bool "Exynos VIPx driver"
- select EXYNOS_VIPX_PLATFORM
- select EXYNOS_VIPX_INTERFACE
- help
- This is a vision image processing unit
-
-if EXYNOS_VIPX
-
-source "drivers/vision/vipx/platform/Kconfig"
-source "drivers/vision/vipx/interface/Kconfig"
-
-endif
+++ /dev/null
-obj-y += vipx-debug.o
-obj-y += vipx-binary.o
-obj-y += vipx-time.o
-obj-y += vipx-taskmgr.o
-obj-y += vipx-graph.o
-obj-y += vipx-graphmgr.o
-obj-y += vipx-queue.o
-obj-y += vipx-vertex.o
-obj-y += vipx-device.o
-obj-y += vipx-memory.o
-obj-y += vipx-system.o
-obj-y += vipx-io.o
-obj-$(CONFIG_EXYNOS_VIPX_INTERFACE) += interface/
-obj-$(CONFIG_EXYNOS_VIPX_PLATFORM) += platform/
-
-EXTRA_CFLAGS += -Idrivers/vision/include -Idrivers/vision/vipx/include
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/*
- * Version history
- * 2017.06.27 : Initial draft
- * 2017.08.25 : Released
- * 2017.10.12 : Add BOOTUP_RSP
- */
-
-#ifndef AP_VIP_IF_H_
-#define AP_VIP_IF_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// temp for previous host ver
-#if 0
-#define AP_FOCAL_ZONE_SETTING 0
-#else
-#define AP_FOCAL_ZONE_SETTING 1
-#endif
-/**
- Typedefs
-*/
-typedef u32 dram_addr_t;
-typedef u32 graph_id_t;
-typedef u32 job_id_t;
-
-/**
- Message type
-*/
-enum
-{
- BOOTUP_RSP = 1,
- INIT_REQ,
- INIT_RSP,
- CREATE_GRAPH_REQ,
- CREATE_GRAPH_RSP,
- SET_GRAPH_REQ,
- SET_GRAPH_RSP,
- INVOKE_GRAPH_REQ,
- INVOKE_GRAPH_ACK,
- INVOKE_GRAPH_RSP,
- DESTROY_GRAPH_REQ,
- DESTROY_GRAPH_RSP,
- ABORT_GRAPH_REQ,
- ABORT_GRAPH_RSP,
- POWER_DOWN_REQ,
- POWER_DOWN_RSP,
- MAX_MSG_TYPE,
-};
-
-typedef u32 vipx_msgid_e;
-
-/**
- Constants
-*/
-enum
-{
-// temp for previous host ver
-#if 0
-MAX_NUM_OF_INPUTS = 16,
-#else
- MAX_NUM_OF_INPUTS = 24,
-#endif
-#if 0
- MAX_NUM_OF_OUTPUTS = 12,
-#else
- MAX_NUM_OF_OUTPUTS = 8,
-#endif
-// temp for previous host ver
-#if 0
- MAX_NUM_OF_USER_PARAMS = 8,
-#else
- MAX_NUM_OF_USER_PARAMS = 80,
-#endif
-};
-
-/**
- Error indications
-*/
-enum
-{
- SUCCESS = 0,
- ERROR_INVALID_GRAPH_ID = -1,
- ERROR_EXEC_PARAM_CORRUPTION = -2,
- ERROR_GRAPH_DATA_CORRUPTION = -3,
- ERROR_COMPILED_GRAPH_ENABLED = -4,
- ERROR_INVALID_MSG_TYPE = -5,
- ERROR_UNKNOWN = -6,
- ERROR_INVALID = -7,
- ERROR_MBX_BUSY = -8,
-};
-
-
-typedef s32 vipx_error_e;
-
-/**
- Predefined builtin algorithms.
-*/
-
-enum
-{
- SCENARIO_DE = 1,
- SCENARIO_SDOF_FULL,
- SCENARIO_DE_SDOF,
-// temp for previous host ver
-// SCENARIO_ENF,
- SCENARIO_DE_CAPTURE,
- SCENARIO_SDOF_CAPTURE,
- SCENARIO_DE_SDOF_CAPTURE,
- SCENARIO_GDC,
- SCENARIO_ENF,
- SCENARIO_ENF_UV,
- SCENARIO_BLEND,
- SCENARIO_AP_MAX,
-};
-
-#define SCENARIO_MAX SCENARIO_AP_MAX
-
-typedef u32 vipx_builtin_graph_id_e;
-
-typedef struct
-{
- vipx_error_e error;
-} __attribute__((__packed__)) vipx_bootup_rsp_t;
-
-typedef struct
-{
- dram_addr_t p_cc_heap; //< pointer to CC heap region
- u32 sz_cc_heap; //< size of CC heap region
-} __attribute__((__packed__)) vipx_init_req_t;
-
-typedef struct
-{
- vipx_error_e error;
-} __attribute__((__packed__)) vipx_init_rsp_t;
-
-typedef struct
-{
- dram_addr_t p_graph; //< pointer to compiled graph
- u32 sz_graph; //< size of compiled graph
-} __attribute__((__packed__)) vipx_create_graph_req_t;
-
-typedef struct
-{
- vipx_error_e error;
- graph_id_t graph_id; //< graph id that should be used for invocation
-} __attribute__((__packed__)) vipx_create_graph_rsp_t;
-
-typedef struct
-{
- graph_id_t graph_id;
-
- dram_addr_t p_lll_bin; //< pointer to VIP binary in DRAM
- u32 sz_lll_bin; //< size of VIP binary in DRAM
-
- int num_inputs; //< number of inputs for the graph
- int num_outputs; //< number of outputs for the graph
-
- u32 input_width[MAX_NUM_OF_INPUTS]; //< array of input width sizes
- u32 input_height[MAX_NUM_OF_INPUTS]; //< array of input height sizes
- u32 input_depth[MAX_NUM_OF_INPUTS]; //< array of input depth sizes
-
- u32 output_width[MAX_NUM_OF_OUTPUTS]; //< array of output width sizes
- u32 output_height[MAX_NUM_OF_OUTPUTS]; //< array of output height sizes
- u32 output_depth[MAX_NUM_OF_OUTPUTS]; //< array of output depth sizes
-
- dram_addr_t p_temp; //< pointer to DRAM area for temporary buffers
- u32 sz_temp; //< size of temporary buffer area
-} __attribute__((__packed__)) vipx_set_graph_req_t;
-
-typedef struct
-{
- vipx_error_e error;
-} __attribute__((__packed__)) vipx_set_graph_rsp_t;
-
-typedef struct
-{
- graph_id_t graph_id; //< graph id that should be used for invocation
- int num_inputs; //< number of inputs for the graph
- int num_outputs; //< number of outputs for the graph
- dram_addr_t p_input[MAX_NUM_OF_INPUTS]; //< array of input buffers
- dram_addr_t p_output[MAX_NUM_OF_OUTPUTS]; //< array of output buffers
-#if AP_FOCAL_ZONE_SETTING
- u32 user_params[MAX_NUM_OF_USER_PARAMS]; //< array of user parameters
-#endif
-} __attribute__((__packed__)) vipx_invoke_graph_req_t;
-
-typedef struct
-{
- vipx_error_e error;
- job_id_t job_id;
-} __attribute__((__packed__)) vipx_invoke_graph_ack_t;
-
-typedef struct
-{
- vipx_error_e error;
- job_id_t job_id;
-} __attribute__((__packed__)) vipx_invoke_graph_rsp_t;
-
-typedef struct
-{
- job_id_t job_id;
-} __attribute__((__packed__)) vipx_abort_graph_req_t;
-
-typedef struct
-{
- vipx_error_e error;
-} __attribute__((__packed__)) vipx_abort_graph_rsp_t;
-
-typedef struct
-{
- graph_id_t graph_id;
-} __attribute__((__packed__)) vipx_destroy_graph_req_t;
-
-typedef struct
-{
- vipx_error_e error;
-} __attribute__((__packed__)) vipx_destroy_graph_rsp_t;
-
-typedef struct
-{
- uint32_t valid;
-} __attribute__((__packed__)) vipx_powerdown_req_t;
-
-typedef struct
-{
- vipx_error_e error;
-} __attribute__((__packed__)) vipx_powerdown_rsp_t;
-
-
-union __attribute__((__packed__)) vipx_messages_u
-{
- vipx_bootup_rsp_t bootup_rsp;
- vipx_init_req_t init_req;
- vipx_init_rsp_t init_rsp;
- vipx_create_graph_req_t create_graph_req;
- vipx_create_graph_rsp_t create_graph_rsp;
- vipx_set_graph_req_t set_graph_req;
- vipx_set_graph_rsp_t set_graph_rsp;
- vipx_invoke_graph_req_t invoke_graph_req;
- vipx_invoke_graph_ack_t invoke_graph_ack;
- vipx_invoke_graph_rsp_t invoke_graph_rsp;
- vipx_destroy_graph_req_t destroy_graph_req;
- vipx_destroy_graph_rsp_t destroy_graph_rsp;
- vipx_abort_graph_req_t abort_graph_req;
- vipx_abort_graph_rsp_t abort_graph_rsp;
- vipx_powerdown_req_t powerdown_req;
- vipx_powerdown_rsp_t powerdown_rsp;
-};
-
-typedef struct
-{
- // TODO: valid flag to be removed.
- uint32_t valid;
- uint32_t transId;
- vipx_msgid_e type;
- union vipx_messages_u msg_u;
-} __attribute__((__packed__)) vipx_msg_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // AP_VIP_IF_H_
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_BINARY_H_
-#define VIPX_BINARY_H_
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-
-#define VIPX_FW_PATH1 "/data/"
-#define VIPX_FW_PATH2 "/vendor/firmware/"
-
-#define VIPX_FW_DRAM_NAME "CC_DRAM_CODE_FLASH.bin"
-#define VIPX_FW_ITCM_NAME "CC_ITCM_CODE_FLASH.bin"
-#define VIPX_FW_DTCM_NAME "CC_DTCM_CODE_FLASH.bin"
-
-#define VIPX_FW_NAME_LEN 100
-#define VIPX_VERSION_SIZE 42
-
-struct vipx_binary {
- struct device *dev;
-};
-
-int vipx_binary_init(struct vipx_binary *binary, struct device *dev);
-
-int vipx_binary_read(struct vipx_binary *binary,
- char *path,
- char *name,
- void *target,
- size_t target_size);
-int vipx_binary_write(struct vipx_binary *binary,
- char *path,
- char *name,
- void *target,
- size_t target_size);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_CONFIG_H_
-#define VIPX_CONFIG_H_
-
-/*
- * =================================================================================================
- * CONFIG - GLOBAL OPTIONS
- * =================================================================================================
- */
-
-#define VIPX_MAX_BUFFER 16
-#define VIPX_MAX_PLANE 3
-
-#define VIPX_MAX_GRAPH 32
-#define VIPX_MAX_TASK VIPX_MAX_BUFFER
-
-/* this macro determines schedule period, the unit is mile second */
-#define VIPX_TIME_TICK 5
-/*
- * =================================================================================================
- * CONFIG -PLATFORM CONFIG
- * =================================================================================================
- */
-#define VIPX_AHB_BASE_ADDR 0x20200000
-#define VIPX_STOP_WAIT_COUNT 200
-
-
-/*
- * =================================================================================================
- * CONFIG - FEATURE ENABLE
- * =================================================================================================
- */
-
-/* #define VIPX_DYNAMIC_RESOURCE */
-
-/*
- * =================================================================================================
- * CONFIG - DEBUG OPTIONS
- * =================================================================================================
- */
-
-/* #define DBG_STREAMING */
-#define DBG_HISTORY
-/* #define DBG_INTERFACE_ISR */
-/* #define DBG_TIMEMEASURE */
-#define DBG_MAP_KVADDR
-/* #define DBG_RESOURCE */
-#define DBG_MARKING
-/* #define DBG_HW_SFR */
-/* #define DBG_PRINT_TASK */
-/* #define DBG_VERBOSE_IO */
-
-//#define DUMP_DEBUG_LOG_REGION
-#define DEBUG_LOG_MEMORY
-//#define PRINT_DBG
-
-#define DISABLE_VIPX_LOG 0
-
-#if DISABLE_VIPX_LOG
-#define probe_info(fmt, ...)
-#define probe_warn(fmt, args...)
-#define probe_err(fmt, args...)
-#define vipx_err_target(fmt, ...)
-#define vipx_warn_target(fmt, ...)
-#define vipx_info_target(fmt, ...)
-#define vipx_dbg_target(fmt, ...)
-
-#else
-
-#define probe_info(fmt, ...) pr_info("[V]" fmt, ##__VA_ARGS__)
-#define probe_warn(fmt, args...) pr_warning("[V][WRN]" fmt, ##args)
-#define probe_err(fmt, args...) pr_err("[V][ERR]%s:%d:" fmt, __func__, __LINE__, ##args)
-
-#ifdef DEBUG_LOG_MEMORY
-#define vipx_err_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#define vipx_warn_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#define vipx_info_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#ifdef PRINT_DBG
-#define vipx_dbg_target(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#else
-#define vipx_dbg_target(fmt, ...)
-#endif
-#else
-#define vipx_err_target(fmt, ...) pr_err(fmt, ##__VA_ARGS__)
-#define vipx_warn_target(fmt, ...) pr_warning(fmt, ##__VA_ARGS__)
-#define vipx_info_target(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
-#define vipx_dbg_target(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
-#endif
-
-#endif // DISABLE_ALL_LOG
-
-
-#define vipx_err(fmt, args...) \
- vipx_err_target("[V][ERR]%s:%d:" fmt, __func__, __LINE__, ##args)
-
-#define vipx_ierr(fmt, vctx, args...) \
- vipx_err_target("[V][I%d][ERR]%s:%d:" fmt, vctx->idx, __func__, __LINE__, ##args)
-
-#define vipx_irerr(fmt, vctx, task, args...) \
- vipx_err_target("[V][I%d][F%d][ERR]%s:%d:" fmt, vctx->idx, task->id, __func__, __LINE__, ##args)
-
-#define vipx_warn(fmt, args...) \
- vipx_warn_target("[V][WRN]%s:%d:" fmt, __func__, __LINE__, ##args)
-
-#define vipx_iwarn(fmt, vctx, args...) \
- vipx_warn_target("[V][I%d][WRN]%s:%d:" fmt, vctx->idx, __func__, __LINE__, ##args)
-
-#define vipx_irwarn(fmt, vctx, task, args...) \
- vipx_warn_target("[V][I%d][F%d][WRN]%s:%d:" fmt, vctx->idx, task->id, __func__, __LINE__, ##args)
-
-#define vipx_info(fmt, args...) \
- vipx_info_target("[V]%s:%d:" fmt, __func__, __LINE__, ##args)
-
-#define vipx_iinfo(fmt, vctx, args...) \
- vipx_info_target("[V][I%d]" fmt, vctx->idx, ##args)
-
-#define vipx_irinfo(fmt, vctx, task, args...) \
- vipx_info_target("[V][I%d][F%d]" fmt, vctx->idx, task->id, ##args)
-
-#define vipx_dbg(fmt, args...) \
- vipx_dbg_target("[V]" fmt, ##args)
-
-#define vipx_idbg(fmt, vctx, args...) \
- vipx_dbg_target("[V][I%d]" fmt, vctx->idx, ##args)
-
-#define vipx_irdbg(fmt, vctx, task, args...) \
- vipx_dbg_target("[V][I%d][F%d]" fmt, vctx->idx, task->id, ##args)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_CONTROL_H_
-#define VIPX_CONTROL_H_
-
-#define VISION_CTRL_VIPX_BASE 0x00010000
-
-#define VIPX_CTRL_DUMP (VISION_CTRL_VIPX_BASE + 1)
-#define VIPX_CTRL_MODE (VISION_CTRL_VIPX_BASE + 2)
-#define VIPX_CTRL_TEST (VISION_CTRL_VIPX_BASE + 3)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_DEBUG_H_
-#define VIPX_DEBUG_H_
-
-#include <linux/types.h>
-#include <linux/timer.h>
-
-#include "vipx-config.h"
-
-#define DEBUG_SENTENCE_MAX 300
-#define DEBUG_MONITORING_PERIOD (HZ * 5)
-
-struct vipx_debug_imgdump {
- struct dentry *file;
- u32 target_graph;
- u32 target_chain;
- u32 target_pu;
- u32 target_index;
- void *kvaddr;
- void *cookie;
- size_t length;
- size_t offset;
-};
-
-struct vipx_debug_monitor {
- struct timer_list timer;
- u32 time_cnt;
- u32 tick_cnt;
- u32 sched_cnt;
- u32 done_cnt;
-};
-
-enum vipx_debug_state {
- VIPX_DEBUG_STATE_START
-};
-
-struct vipx_debug {
- unsigned long state;
-
- struct dentry *root;
- struct dentry *logfile;
- struct dentry *grpfile;
- struct dentry *buffile;
-
- /* graph */
- void *graphmgr_data;
- void *system_data;
-
- struct vipx_debug_imgdump imgdump;
- struct vipx_debug_monitor monitor;
-};
-
-struct vipx_debug_log {
- size_t dsentence_pos;
- char dsentence[DEBUG_SENTENCE_MAX];
-};
-
-s32 atoi(const char *psz_buf);
-int bitmap_scnprintf(char *buf, unsigned int buflen,
- const unsigned long *maskp, int nmaskbits);
-
-int vipx_debug_probe(struct vipx_debug *debug, void *graphmgr_data, void *interface_data);
-int vipx_debug_open(struct vipx_debug *debug);
-int vipx_debug_close(struct vipx_debug *debug);
-int vipx_debug_start(struct vipx_debug *debug);
-int vipx_debug_stop(struct vipx_debug *debug);
-
-void vipx_dmsg_concate(struct vipx_debug_log *log, const char *fmt, ...);
-char * vipx_dmsg_print(struct vipx_debug_log *log);
-int vipx_debug_memdump8(u8 *start, u8 *end);
-int vipx_debug_memdump16(u16 *start, u16 *end);
-int vipx_debug_memdump32(u32 *start, u32 *end);
-
-#ifdef DBG_HISTORY
-#define DLOG_INIT() struct vipx_debug_log vipx_debug_log = { .dsentence_pos = 0 }
-#define DLOG(fmt, ...) vipx_dmsg_concate(&vipx_debug_log, fmt, ##__VA_ARGS__)
-#define DLOG_OUT() vipx_dmsg_print(&vipx_debug_log)
-#else
-#define DLOG_INIT()
-#define DLOG(fmt, ...)
-#define DLOG_OUT() "FORBIDDEN HISTORY"
-#endif
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPX driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_EXYNOS_H_
-#define VIPX_EXYNOS_H_
-
-#include <linux/clk.h>
-#include <linux/device.h>
-
-struct vipx_exynos;
-
-enum {
- VIPX_REG_CPU_SS1 = 0,
- VIPX_REG_CPU_SS2 = 1,
- VIPX_REG_MAX_CNT,
-};
-
-struct vipx_regblock {
- unsigned int offset;
- unsigned int blocks;
- char *name;
-};
-
-enum regdata_type {
- /* read write */
- RW = 0,
- /* read only */
- RO = 1,
- /* write only */
- WO = 2,
- /* write input */
- WI = 2,
- /* clear after read */
- RAC = 3,
- /* write 1 -> clear */
- W1C = 4,
- /* write read input */
- WRI = 5,
- /* write input */
- RWI = 5,
- /* only scaler */
- R_W = 6,
- /* read & write for clear */
- RWC = 7,
- /* read & write as dual setting */
- RWS
-};
-
-struct vipx_reg {
- unsigned int offset;
- char *name;
-};
-
-struct vipx_field {
- char *name;
- unsigned int bit_start;
- unsigned int bit_width;
- enum regdata_type type;
-};
-
-struct vipx_clk {
- const char *name;
- struct clk *clk;
-};
-
-struct vipx_clk_ops {
- int (*clk_cfg)(struct vipx_exynos *exynos);
- int (*clk_on)(struct vipx_exynos *exynos);
- int (*clk_off)(struct vipx_exynos *exynos);
- int (*clk_dump)(struct vipx_exynos *exynos);
-};
-
-struct vipx_ctl_ops {
- int (*ctl_reset)(struct vipx_exynos *exynos, bool hold);
- int (*ctl_dump)(struct vipx_exynos *exynos, u32 instance);
- void * (*ctl_remap)(struct vipx_exynos *exynos, u32 instance);
- int (*ctl_unmap)(struct vipx_exynos *exynos, u32 instance, void *base);
- int (*ctl_trigger)(struct vipx_exynos *exynos, u32 chain_id);
- int (*ctl_start)(struct vipx_exynos *exynos, u32 chain_id);
-};
-
-struct vipx_exynos {
- struct device *dev;
- void **regbase;
- void *ram0base;
- void *ram1base;
- struct pinctrl *pinctrl;
- const struct vipx_clk_ops *clk_ops;
- const struct vipx_ctl_ops *ctl_ops;
-};
-
-int vipx_exynos_probe(struct vipx_exynos *exynos, struct device *dev,
- void **regs, void *ram0, void *ram1);
-
-void vipx_readl(void __iomem *base_addr, struct vipx_reg *reg, u32 *val);
-void vipx_writel(void __iomem *base_addr, struct vipx_reg *reg, u32 val);
-
-#define CLK_OP(exynos, op) (exynos->clk_ops ? exynos->clk_ops->op(exynos) : 0)
-#define CTL_OP(exynos, op, ...) (exynos->ctl_ops ? exynos->ctl_ops->op(exynos, ##__VA_ARGS__) : 0)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_INTERFACE_H_
-#define VIPX_INTERFACE_H_
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-
-#include "vipx-taskmgr.h"
-#include "vipx-slab.h"
-
-#define VIPX_WORK_MAX_COUNT 20
-#define VIPX_WORK_MAX_DATA 24
-#define VIPX_COMMAND_TIMEOUT (3 * HZ)
-
-typedef enum {
- VIPX_WORK_MTYPE_BLK,
- VIPX_WORK_MTYPE_NBLK,
-} vipx_work_msg_t;
-
-struct vipx_work {
- struct list_head list;
- u32 valid:1;
- u32 id;
- vipx_work_msg_t message;
- u32 work_param0;
- u32 work_param1;
- u32 work_param2;
- u32 work_param3;
- u8 data[VIPX_WORK_MAX_DATA];
-};
-
-struct vipx_work_list {
- struct vipx_work work[VIPX_WORK_MAX_COUNT];
- spinlock_t slock;
- struct list_head free_head;
- u32 free_cnt;
- struct list_head reply_head;
- u32 reply_cnt;
- wait_queue_head_t wait_queue;
-};
-
-enum vipx_interface_state {
- VIPX_ITF_STATE_OPEN,
- VIPX_ITF_STATE_BOOTUP,
- VIPX_ITF_STATE_ENUM,
- VIPX_ITF_STATE_START
-};
-
-struct vipx_interface {
- void *mbox;
- size_t mbox_size;
- void __iomem *regs;
- resource_size_t regs_size;
- unsigned long state;
-
- struct vipx_slab_allocator slab;
- struct vipx_taskmgr taskmgr;
- void *cookie;
- u32 done_cnt;
-
- struct vipx_task *request[VIPX_MAX_GRAPH];
- struct mutex request_barrier;
- struct vipx_work reply[VIPX_MAX_GRAPH];
- wait_queue_head_t reply_queue;
- struct vipx_task *process;
- spinlock_t process_barrier;
-
- struct vipx_work_list work_list;
- struct work_struct work_queue;
-
-#if defined(CONFIG_EXYNOS_EMUL_MBOX)
- struct timer_list timer;
-#endif
- void *private_data;
-};
-
-int vipx_interface_probe(struct vipx_interface *interface,
- struct device *dev,
- void __iomem *regs,
- resource_size_t regs_size,
- u32 irq0, u32 irq1);
-int vipx_interface_open(struct vipx_interface *interface,
- void *mbox, size_t mbox_size);
-int vipx_interface_close(struct vipx_interface *interface);
-int vipx_interface_start(struct vipx_interface *interface);
-int vipx_interface_stop(struct vipx_interface *interface);
-void vipx_interface_print(struct vipx_interface *interface);
-
-int vipx_hw_wait_bootup(struct vipx_interface *interface);
-
-int vipx_hw_enum(struct vipx_interface *interface);
-int vipx_hw_init(struct vipx_interface *interface, struct vipx_task *itask);
-int vipx_hw_deinit(struct vipx_interface *interface, struct vipx_task *itask);
-int vipx_hw_create(struct vipx_interface *interface, struct vipx_task *itask);
-int vipx_hw_destroy(struct vipx_interface *interface, struct vipx_task *itask);
-int vipx_hw_config(struct vipx_interface *interface, struct vipx_task *itask);
-int vipx_hw_process(struct vipx_interface *interface, struct vipx_task *itask);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __VIPX_IO_H__
-#define __VIPX_IO_H__
-
-#include <linux/io.h>
-#include "vipx-config.h"
-
-#define IOR8(port) readb((const volatile void *)&port)
-#define IOR16(port) readw((const volatile void *)&port)
-#define IOR32(port) readl((const volatile void *)&port)
-#define IOR64(port) readq((const volatile void *)&port)
-
-#ifdef DBG_VERBOSE_IO
-#define IOW8(port, val) \
- do { pr_info("ADDR: %p, VAL: 0x%02x\r\n", \
- &port, val); writeb(val, &port);\
- } while (0)
-#define IOW16(port, val) \
- do { pr_info("ADDR: %p, VAL: 0x%04x\r\n", \
- &port, val); writew(val, &port);\
- } while (0)
-#define IOW32(port, val) \
- do { pr_info("ADDR: %p, VAL: 0x%08x\r\n", \
- &port, val); writel(val, &port);\
- } while (0)
-#define IOW64(port, val) \
- do { pr_info("ADDR: %p, VAL: 0x%016llx\r\n", \
- &port, val); writeq(val, &port);\
- } while (0)
-
-#else /* not VERBOSE_WRITE */
-#define IOW8(port, val) writeb(val, &port)
-#define IOW16(port, val) writew(val, &port)
-#define IOW32(port, val) writel(val, &port)
-#define IOW64(port, val) writeq(val, &port)
-#endif /* not VERBOSE_WRITE */
-
-void *mem2iocpy(void *dst,void *src, u32 size);
-void *io2memcpy(void *dst,void *src, u32 size);
-
-#endif /* __VIPXL_IO_H__ */
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_MAILBOX_H_
-#define VIPX_MAILBOX_H_
-
-#include <interface/ap_vip_if.h>
-
-#define VIPX_MAILBOX_SIGNATURE1 0xCAFE
-#define VIPX_MAILBOX_SIGNATURE2 0xEFAC
-#define VIPX_MAILBOX_BASEOFFSET 16
-
-#define VIPX_CMD_SIGNATURE 0x1234
-#define VIPX_DUM_SIGNATURE 0x5678
-
-#define MAX_MESSAGE_CNT 8
-
-#define DMESG() printk("[%s:%d]\n", __func__, __LINE__)
-
-enum {
- VIPX_MTYPE_H2F_NORMAL = 0,
- VIPX_MTYPE_H2F_URGENT = 1,
- VIPX_MTYPE_F2H_NORMAL = 0,
- VIPX_MTYPE_F2H_URGENT = 1,
- VIPX_MTYPE_MAX,
-};
-
-struct vipx_mailbox_h2f {
- volatile u32 wmsg_idx; /* Host permission is RW */
- volatile u32 rmsg_idx; /* Host permission is R_ONLY */
- vipx_msg_t msg[MAX_MESSAGE_CNT];
-};
-
-struct vipx_mailbox_f2h {
- volatile u32 wmsg_idx; /* Host permission is R_ONLY */
- volatile u32 rmsg_idx; /* Host permission is RW */
- vipx_msg_t msg[MAX_MESSAGE_CNT];
-};
-
-struct vipx_mailbox_stack {
- struct vipx_mailbox_h2f h2f;
- struct vipx_mailbox_f2h f2h;
-};
-
-struct vipx_mailbox_ctrl {
- struct vipx_mailbox_stack *stack;
- struct vipx_mailbox_stack *urgent_stack;
-};
-
-struct vipx_mailbox_stack * vipx_mbox_g_stack(void *mbox, u32 mbox_size);
-struct vipx_mailbox_stack * vipx_mbox_g_urgent_stack(void *mbox, u32 mbox_size);
-int vipx_mbox_ready(struct vipx_mailbox_ctrl *mctrl, size_t size, u32 type);
-int vipx_mbox_wait_reply(struct vipx_mailbox_ctrl *mctrl, u32 cmd, u32 type);
-int vipx_mbox_write(struct vipx_mailbox_ctrl *mctrl,
- void *payload, size_t size, u32 type, u32 gid, u32 cmd, u32 cid);
-int vipx_mbox_read(struct vipx_mailbox_ctrl *mctrl,
- void *payload, u32 type, void *debug_data);
-
-int emul_mbox_handler(struct vipx_mailbox_ctrl *mctrl);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos5 SoC series VIPx driver
- *
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_MEM_H
-#define VIPX_MEM_H
-
-#include <linux/platform_device.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-sg.h>
-#include <linux/dma-buf.h>
-#include <linux/ion_exynos.h>
-
-
-#include "vipx-binary.h"
-
-/*
- * TEMP for test
- */
-#define VIPX_CM7_DRAM_BIN_SIZE (1024 * 1024 * 3)
-#define VIPX_MBOX_SIZE (1024 * 24)
-#define VIPX_DEBUG_SIZE (1024 * 1024 * 16)
-#define VIPX_CM7_HEAP_SIZE_PREVIEW (1024 * 1024 * 16)
-#define VIPX_CM7_HEAP_SIZE_ENF (1024 * 1024 * 64)
-#define VIPX_CM7_HEAP_SIZE_CAPTURE (1024 * 1024 * 128)
-
-#define VIPX_IOVA_DRAM_FIRMWARE 0xB8000000
-#define VIPX_IOVA_DRAM_MBOX 0xA9000000
-
-struct vipx_vb2_buf;
-struct vipx_vb2_buf_ops {
- ulong (*plane_kvaddr)(struct vipx_vb2_buf *vbuf, u32 plane);
- ulong (*plane_cookie)(struct vipx_vb2_buf *vbuf, u32 plane);
- dma_addr_t (*plane_dvaddr)(struct vipx_vb2_buf *vbuf, u32 plane);
- void (*plane_prepare)(struct vipx_vb2_buf *vbuf, u32 plane,
- bool exact);
- void (*plane_finish)(struct vipx_vb2_buf *vbuf, u32 plane,
- bool exact);
- void (*buf_prepare)(struct vipx_vb2_buf *vbuf, bool exact);
- void (*buf_finish)(struct vipx_vb2_buf *vbuf, bool exact);
-};
-
-enum vipx_vbuf_cache_state {
- VIPX_VBUF_CACHE_INVALIDATE,
-};
-
-struct vipx_vb2_buf {
- struct vb2_v4l2_buffer vb;
- ulong kva[VIDEO_MAX_PLANES];
- dma_addr_t dva[VIDEO_MAX_PLANES];
-
- /* for cache operation */
- unsigned long cache_state;
- struct list_head cache_flush_list;
-
- const struct vipx_vb2_buf_ops *ops;
-};
-
-struct vipx_priv_buf;
-struct vipx_priv_buf_ops {
- void (*free)(struct vipx_priv_buf *pbuf);
- void *(*kvaddr)(struct vipx_priv_buf *pbuf);
- dma_addr_t (*dvaddr)(struct vipx_priv_buf *pbuf);
- phys_addr_t (*phaddr)(struct vipx_priv_buf *pbuf);
- void (*sync_for_device)(struct vipx_priv_buf *pbuf,
- off_t offset, size_t size,
- enum dma_data_direction dir);
- void (*sync_for_cpu)(struct vipx_priv_buf *pbuf,
- off_t offset, size_t size,
- enum dma_data_direction dir);
-};
-
-struct vipx_priv_buf {
- size_t size;
- size_t align;
- void *ctx;
- void *kvaddr;
-
- const struct vipx_priv_buf_ops *ops;
- void *priv;
- struct dma_buf *dma_buf;
- struct dma_buf_attachment *attachment;
- enum dma_data_direction direction;
- void *kva;
- dma_addr_t iova;
- struct sg_table *sgt;
-};
-
-#define vb_to_vipx_vb2_buf(x) \
- container_of(x, struct vipx_vb2_buf, vb)
-
-#define CALL_BUFOP(buf, op, args...) \
- ((buf)->ops->op ? (buf)->ops->op(args) : 0)
-
-#define CALL_PTR_BUFOP(buf, op, args...) \
- ((buf)->ops->op ? (buf)->ops->op(args) : NULL)
-
-#define CALL_VOID_BUFOP(buf, op, args...) \
- do { \
- if ((buf)->ops->op) \
- (buf)->ops->op(args); \
- } while (0)
-
-#define call_buf_op(buf, op, args...) \
- ((buf)->ops->op ? (buf)->ops->op((buf), args) : 0)
-
-struct vipx_mem_ops {
- void *(*init)(struct device *dev);
- void (*cleanup)(void *ctx);
- int (*resume)(void *ctx);
- void (*suspend)(void *ctx);
- void (*set_cached)(void *ctx, bool cacheable);
- int (*set_alignment)(void *ctx, size_t alignment);
- struct vipx_priv_buf *(*alloc)(void *ctx, size_t size, size_t align);
-};
-
-struct vipx_ion_ctx {
- struct device *dev;
- unsigned long alignment;
- long flags;
-
- /* protects iommu_active_cnt and protected */
- struct mutex lock;
- int iommu_active_cnt;
-};
-
-struct vipx_minfo {
- struct vipx_priv_buf *pb_debug;
- struct vipx_priv_buf *pb_heap;
-
- ulong kvaddr_debug_cnt;
-
- dma_addr_t paddr_fw;
- dma_addr_t dvaddr_fw;
- void *kvaddr_fw;
-
- dma_addr_t paddr_mbox;
- dma_addr_t dvaddr_mbox;
- void *kvaddr_mbox;
-
- dma_addr_t paddr_debug;
- dma_addr_t dvaddr_debug;
- void *kvaddr_debug;
-
- dma_addr_t paddr_heap;
- dma_addr_t dvaddr_heap;
- void *kvaddr_heap;
-};
-
-struct vipx_memory {
- struct device *dev;
- struct vipx_ion_ctx *default_ctx;
- struct vipx_ion_ctx *phcontig_ctx;
- const struct vipx_mem_ops *vipx_mem_ops;
- const struct vb2_mem_ops *vb2_mem_ops;
- const struct vipx_vb2_buf_ops *vipx_vb2_buf_ops;
- struct iommu_domain *iommu_domain;
-
- struct vipx_minfo info;
- void *priv;
- struct vipx_priv_buf *(*kmalloc)(size_t size, size_t align);
-};
-
-#define CALL_MEMOP(mem, op, args...) \
- ((mem)->vipx_mem_ops->op ? \
- (mem)->vipx_mem_ops->op(args) : 0)
-
-#define CALL_PTR_MEMOP(mem, op, args...) \
- ((mem)->vipx_mem_ops->op ? \
- (mem)->vipx_mem_ops->op(args) : NULL)
-
-#define CALL_VOID_MEMOP(mem, op, args...) \
- do { \
- if ((mem)->vipx_mem_ops->op) \
- (mem)->vipx_mem_ops->op(args); \
- } while (0)
-
-int vipx_memory_probe(struct vipx_memory *mem, struct device *dev);
-int vipx_memory_open(struct vipx_memory *mem);
-int vipx_memory_close(struct vipx_memory *mem);
-dma_addr_t vipx_allocate_heap(struct vipx_memory *mem, u32 size);
-void vipx_free_heap(struct vipx_memory *mem, struct vipx_binary *binary, u32 heap_size);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_SLAB_H_
-#define VIPX_SLAB_H_
-
-#include <interface/ap_vip_if.h>
-
-#define VIPX_SLAB_MAX_LEVEL 1
-
-struct vipx_slab_allocator {
- u32 cache_size[VIPX_SLAB_MAX_LEVEL];
- struct kmem_cache *cache[VIPX_SLAB_MAX_LEVEL];
-};
-
-int vipx_slab_init(struct vipx_slab_allocator *allocator);
-int vipx_slab_alloc(struct vipx_slab_allocator *allocator, void **target, size_t size);
-int vipx_slab_free(struct vipx_slab_allocator *allocator, void *target, size_t size);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_TASKMGR_H_
-#define VIPX_TASKMGR_H_
-
-#include <linux/types.h>
-#include <linux/kthread.h>
-
-#include "vipx-config.h"
-#include "vipx-time.h"
-#include "vs4l.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) \
- taskmgr->sindex |= index; spin_lock_irqsave(&taskmgr->slock, flag)
-#define taskmgr_x_barrier_irqr(taskmgr, index, flag) \
- spin_unlock_irqrestore(&taskmgr->slock, flag); taskmgr->sindex &= ~index
-#define taskmgr_e_barrier_irq(taskmgr, index) \
- taskmgr->sindex |= index; spin_lock_irq(&taskmgr->slock)
-#define taskmgr_x_barrier_irq(taskmgr, index) \
- spin_unlock_irq(&taskmgr->slock); taskmgr->sindex &= ~index
-#define taskmgr_e_barrier(taskmgr, index) \
- taskmgr->sindex |= index; spin_lock(&taskmgr->slock)
-#define taskmgr_x_barrier(taskmgr, index) \
- spin_unlock(&taskmgr->slock); taskmgr->sindex &= ~index
-
-enum vipx_task_state {
- VIPX_TASK_STATE_FREE = 1,
- VIPX_TASK_STATE_REQUEST,
- VIPX_TASK_STATE_PREPARE,
- VIPX_TASK_STATE_PROCESS,
- VIPX_TASK_STATE_COMPLETE,
- VIPX_TASK_STATE_INVALID
-};
-
-enum vipx_task_flag {
- VIPX_TASK_FLAG_IOCPY = 16
-};
-
-enum vipx_task_message {
- VIPX_TASK_INIT = 1,
- VIPX_TASK_DEINIT,
- VIPX_TASK_CREATE,
- VIPX_TASK_DESTROY,
- VIPX_TASK_ALLOCATE,
- VIPX_TASK_PROCESS,
- VIPX_TASK_REQUEST = 10,
- VIPX_TASK_DONE,
- VIPX_TASK_NDONE
-};
-
-enum vipx_control_message {
- VIPX_CTRL_NONE = 100,
- VIPX_CTRL_STOP,
- VIPX_CTRL_STOP_DONE
-};
-
-struct vipx_task {
- struct list_head list;
- struct kthread_work work;
- u32 state;
-
- u32 message;
- ulong param0;
- ulong param1;
- ulong param2;
- ulong param3;
-
- struct vb_container_list *incl;
- struct vb_container_list *otcl;
- ulong flags;
-
- u32 id;
- struct mutex *lock;
- u32 index;
- u32 findex;
- u32 tdindex;
- void *owner;
-
- struct vipx_time time[VIPX_TMP_COUNT];
-};
-
-struct vipx_taskmgr {
- u32 id;
- u32 sindex;
- spinlock_t slock;
- struct vipx_task task[VIPX_MAX_TASK];
-
- struct list_head fre_list;
- struct list_head req_list;
- struct list_head pre_list;
- struct list_head pro_list;
- struct list_head com_list;
-
- u32 tot_cnt;
- u32 fre_cnt;
- u32 req_cnt;
- u32 pre_cnt;
- u32 pro_cnt;
- u32 com_cnt;
-};
-
-void vipx_task_s_free(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_g_free(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_free_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_free_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_print_free_list(struct vipx_taskmgr *taskmgr);
-
-void vipx_task_s_request(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_g_request(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_request_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_request_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_print_request_list(struct vipx_taskmgr *taskmgr);
-
-void vipx_task_s_prepare(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_g_prepare(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_prepare_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_prepare_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_print_prepare_list(struct vipx_taskmgr *taskmgr);
-
-void vipx_task_s_process(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_g_process(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_process_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_process_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_print_process_list(struct vipx_taskmgr *taskmgr);
-
-void vipx_task_s_complete(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_g_complete(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_complete_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_complete_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_print_complete_list(struct vipx_taskmgr *taskmgr);
-
-void vipx_task_trans_fre_to_req(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_req_to_pre(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_req_to_pro(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_req_to_com(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_req_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_pre_to_pro(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_pre_to_com(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_pre_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_pro_to_com(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_pro_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_com_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-void vipx_task_trans_any_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task);
-
-void vipx_task_pick_fre_to_req(struct vipx_taskmgr *taskmgr, struct vipx_task **task);
-void vipx_task_print_all(struct vipx_taskmgr *taskmgr);
-
-int vipx_task_init(struct vipx_taskmgr *taskmgr, void *owner);
-int vipx_task_deinit(struct vipx_taskmgr *taskmgr);
-void vipx_task_flush(struct vipx_taskmgr *taskmgr);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/ktime.h>
-#include <linux/timekeeping.h>
-
-enum vipx_time_measure_point {
- VIPX_TMP_QUEUE,
- VIPX_TMP_REQUEST,
- VIPX_TMP_RESOURCE,
- VIPX_TMP_PROCESS,
- VIPX_TMP_DONE,
- VIPX_TMP_COUNT
-};
-
-struct vipx_time {
- struct timeval time;
-};
-
-void vipx_get_timestamp(struct vipx_time *time);
-
-#define VIPX_TIME_IN_US(v) ((v).time.tv_sec * 1000000 + (v).time.tv_usec)
+++ /dev/null
-config EXYNOS_VIPX_INTERFACE
- bool "Select Interface"
- help
- This is VIPx interface
-
-config EXYNOS_VIPX_HARDWARE
- bool "Use Hardware"
- depends on EXYNOS_VIPX_INTERFACE
- help
- This is hardware device
-
-choice
- prompt "Select Message box type"
- depends on EXYNOS_VIPX_INTERFACE
- help
- Select VIP(x) message box type.
-
-config EXYNOS_VIPX_MBOX
- bool "Use VIPX MBOX"
- depends on EXYNOS_VIPX_INTERFACE
- help
- This is message box device
-
-config EXYNOS_EMUL_MBOX
- bool "Use EMUL MBOX"
- depends on EXYNOS_VIPX_INTERFACE
- help
- This is message box emulator
-endchoice
+++ /dev/null
-obj-$(CONFIG_EXYNOS_VIPX_HARDWARE) += hardware/
-obj-$(CONFIG_EXYNOS_VIPX_HARDWARE) += vipx-slab.o
-
-EXTRA_CFLAGS += -Idrivers/vision/include -Idrivers/vision/vipx/include
+++ /dev/null
-obj-y += vipx-interface.o
-obj-$(CONFIG_EXYNOS_VIPX_MBOX) += vipx-mailbox.o
-obj-$(CONFIG_EXYNOS_EMUL_MBOX) += emul-mailbox.o
-EXTRA_CFLAGS += -Idrivers/vision/include -Idrivers/vision/vipx/include
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/random.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#include "vipx-config.h"
-#include "vipx-io.h"
-#include "vipx-mailbox.h"
-#include "vipx-interface.h"
-
-#include <interface/ap_vip_if.h>
-
-#define INDEX(x) (x % MAX_MESSAGE_CNT)
-
-struct vipx_mailbox_stack * vipx_mbox_g_stack(void *mbox, u32 mbox_size)
-{
- vipx_info("sizeof mbox stack (%lx) %p\n", sizeof(struct vipx_mailbox_stack), mbox);
- return (struct vipx_mailbox_stack *)mbox;
-}
-
-struct vipx_mailbox_stack * vipx_mbox_g_urgent_stack(void *mbox, u32 mbox_size)
-{
- vipx_info("%p\n", ((char *)mbox + sizeof(struct vipx_mailbox_stack)));
- return (struct vipx_mailbox_stack *)((char *)mbox + sizeof(struct vipx_mailbox_stack));
-}
-
-static u32 __vipx_mbox_g_freesize(struct vipx_mailbox_h2f *mbox)
-{
- u32 wmsg_idx = 0;
- u32 rmsg_idx = 0;
- u32 free_size = 0;
-
- BUG_ON(!mbox);
-
- wmsg_idx = mbox->wmsg_idx;
- rmsg_idx = mbox->rmsg_idx;
-
- free_size = MAX_MESSAGE_CNT - (wmsg_idx - rmsg_idx);
-
- BUG_ON(free_size < 0);
-
- return free_size;
-}
-
-int vipx_mbox_ready(struct vipx_mailbox_ctrl *mctrl,
- size_t size, u32 type)
-{
- u32 try_count;
- struct vipx_mailbox_h2f *mbox;
- u16 free_size16;
-
- BUG_ON(!mctrl);
- BUG_ON(!IS_ALIGNED(size, 2));
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->h2f;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->h2f;
- } else {
- vipx_err("invalid type(%d)\n", type);
- return -EINVAL;
- }
- try_count = 1000;
-
- free_size16 = __vipx_mbox_g_freesize(mbox);
- while (--try_count && (free_size16 == 0)) {
- vipx_warn("mbox is not ready(freesize %d)...(%d)\n",
- free_size16, try_count);
- udelay(10);
- free_size16 = __vipx_mbox_g_freesize(mbox);
- }
-
- if (try_count)
- return 0;
- else
- return -EBUSY;
-}
-
-int vipx_mbox_wait_reply(struct vipx_mailbox_ctrl *mctrl,
- u32 cmd, u32 type)
-{
- int ret = 0;
- struct vipx_mailbox_f2h *mbox;
- int try_count;
-
- if (type == VIPX_MTYPE_F2H_NORMAL) {
- mbox = &mctrl->stack->f2h;
- } else if (type == VIPX_MTYPE_F2H_URGENT) {
- mbox = &mctrl->urgent_stack->f2h;
- } else {
- vipx_err("cmd(%d) has invalid type(%d)\n", cmd, type);
- ret = -EINVAL;
- goto p_err;
- }
-
- try_count = 1000;
- while (--try_count && (mbox->wmsg_idx == mbox->rmsg_idx)) {
- vipx_info("waiting vipx reply(%d, %d)...(%d)\n", mbox->wmsg_idx, mbox->rmsg_idx, try_count);
- msleep(1);
- }
-
- if (try_count <= 0) {
- vipx_err("waiting vipx reply is timeout\n");
- ret = -EINVAL;
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_mbox_write(struct vipx_mailbox_ctrl *mctrl,
- void *payload, size_t size, u32 type, u32 gid, u32 cmd, u32 cid)
-{
- int ret = 0;
- struct vipx_mailbox_h2f *mbox;
- u32 wmsg_idx;
- u32 *wptr;
-
- BUG_ON(!mctrl);
- BUG_ON(!payload);
- BUG_ON(!IS_ALIGNED(size, 2));
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->h2f;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->h2f;
- } else {
- vipx_err("invalid type(%d)\n", type);
- ret = -EINVAL;
- goto p_err;
- }
- wmsg_idx = mbox->wmsg_idx;
- wptr = (void *)&mbox->msg[wmsg_idx % MAX_MESSAGE_CNT];
-
- mem2iocpy(wptr, payload, size);
-
-#ifdef DBG_MAILBOX_CORE
- vipx_info("[I%d][MBOX][H2F] %d command(%d, %d, %d)\n", gid,
- cmd, cid, wmsg_idx, mbox->rmsg_idx);
-#endif
-
- /* increment actual write pointer */
- mbox->wmsg_idx++;
-
-p_err:
- return ret;
-}
-
-int vipx_mbox_read(struct vipx_mailbox_ctrl *mctrl,
- void *payload, u32 type, void *debug_data)
-{
- int ret = 0;
- struct vipx_mailbox_f2h *mbox;
- u32 rmsg_idx;
- u32 *rptr;
-
- BUG_ON(!mctrl);
- BUG_ON(!payload);
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->f2h;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->f2h;
- } else {
- vipx_err("invalid type(%d)\n", type);
- ret = -EINVAL;
- goto p_err;
- }
- rmsg_idx = mbox->rmsg_idx;
- rptr = (void *)&mbox->msg[rmsg_idx % MAX_MESSAGE_CNT];
-
- io2memcpy(payload, rptr, sizeof(vipx_msg_t));
-
- mbox->rmsg_idx++;
-
-p_err:
- return ret;
-}
-
-/* emul mbox */
-
-static u32 __emul_mbox_g_freesize(struct vipx_mailbox_f2h *mbox)
-{
- u32 wmsg_idx = 0;
- u32 rmsg_idx = 0;
- u32 free_size = 0;
-
- BUG_ON(!mbox);
-
- wmsg_idx = mbox->wmsg_idx;
- rmsg_idx = mbox->rmsg_idx;
-
- free_size = MAX_MESSAGE_CNT - (wmsg_idx - rmsg_idx);
-
- BUG_ON(free_size < 0);
-
- return free_size;
-}
-
-int emul_mbox_ready(struct vipx_mailbox_ctrl *mctrl, u32 type)
-{
- u32 try_count;
- struct vipx_mailbox_f2h *mbox;
- u32 free_size;
-
- BUG_ON(!mctrl);
-
- vipx_info("________ %d\n", type);
-
- if (type == VIPX_MTYPE_F2H_NORMAL) {
- mbox = &mctrl->stack->f2h;
- } else if (type == VIPX_MTYPE_F2H_URGENT) {
- mbox = &mctrl->urgent_stack->f2h;
- } else {
- vipx_err("invalid type(%d)\n", type);
- return -EINVAL;
- }
- try_count = 1000;
-
- free_size = __emul_mbox_g_freesize(mbox);
- while (--try_count && (free_size == 0)) {
- vipx_warn("mbox is not ready(freesize %d)...(%d)\n",
- free_size, try_count);
- udelay(10);
- free_size = __emul_mbox_g_freesize(mbox);
- }
-
- if (try_count)
- return 0;
- else
- return -EBUSY;
-}
-
-int emul_mbox_check_message_from_host(struct vipx_mailbox_ctrl *mctrl, u32 type)
-{
- int ret = 0;
- u32 wmsg_idx, rmsg_idx;
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- wmsg_idx = mctrl->stack->h2f.wmsg_idx;
- rmsg_idx = mctrl->stack->h2f.rmsg_idx;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- wmsg_idx = mctrl->urgent_stack->h2f.wmsg_idx;
- rmsg_idx = mctrl->urgent_stack->h2f.rmsg_idx;
- } else {
- vipx_err("invalid type(%d)\n", type);
- ret = -EINVAL;
- goto p_err;
- }
-
- if ((wmsg_idx == rmsg_idx)) {
- ret = -EINVAL;
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int emul_mbox_write(struct vipx_mailbox_ctrl *mctrl,
- void *payload, size_t size, u32 type)
-{
- struct vipx_mailbox_f2h *mbox;
- u32 wmsg_idx;
- u32 *wptr;
-
- BUG_ON(!mctrl);
- BUG_ON(!payload);
- BUG_ON(!IS_ALIGNED(size, 2));
-
- if (type == VIPX_MTYPE_F2H_NORMAL) {
- mbox = &mctrl->stack->f2h;
- } else if (type == VIPX_MTYPE_F2H_URGENT) {
- mbox = &mctrl->urgent_stack->f2h;
- } else {
- vipx_err("invalid type(%d)\n", type);
- return -EINVAL;
- }
- wmsg_idx = mbox->wmsg_idx;
- wptr = (void *)&mbox->msg[wmsg_idx % MAX_MESSAGE_CNT];
-
- mem2iocpy(wptr, payload, size);
-
- /* increment actual write pointer */
- mbox->wmsg_idx++;
-
- return 0;
-}
-
-int emul_mbox_read(struct vipx_mailbox_ctrl *mctrl, void *payload, u32 type)
-{
- int ret = 0;
- struct vipx_mailbox_h2f *mbox;
- u32 rmsg_idx;
- u32 *rptr;
-
- BUG_ON(!mctrl);
- BUG_ON(!payload);
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->h2f;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->h2f;
- } else {
- vipx_err("invalid type(%d)\n", type);
- ret = -EINVAL;
- goto p_err;
- }
- rmsg_idx = mbox->rmsg_idx;
- rptr = (void *)&mbox->msg[rmsg_idx % MAX_MESSAGE_CNT];
-
- io2memcpy(payload, rptr, sizeof(vipx_msg_t));
-
- mbox->rmsg_idx++;
-
-p_err:
- return ret;
-}
-
-int emul_mbox_handler(struct vipx_mailbox_ctrl *mctrl)
-{
- int ret = 0;
- int has_urgent = 0;
- int has_normal = 0;
-
- vipx_msg_t payload;
-
- /*
- * Handle urgent
- */
-
- /* read h2f mbox */
- ret = emul_mbox_check_message_from_host(mctrl, VIPX_MTYPE_H2F_URGENT);
- if (ret)
- goto p_normal;
-
- ret = emul_mbox_read(mctrl, &payload, VIPX_MTYPE_H2F_URGENT);
-
- /* handle message */
-
- /* write f2h mbox */
- ret = emul_mbox_ready(mctrl, VIPX_MTYPE_F2H_URGENT);
- if (ret) {
- vipx_err("emul_mbox_ready is failed(%d)\n", ret);
- goto p_normal;
- }
-
- ret = emul_mbox_write(mctrl, &payload, sizeof(vipx_msg_t), VIPX_MTYPE_F2H_URGENT);
- if (ret) {
- vipx_err("emul_mbox_write is failed(%d)\n", ret);
- goto p_normal;
- }
-
- has_urgent = 1;
-
-p_normal:
- /*
- * Handle normal
- */
-
- /* read h2f mbox */
- ret = emul_mbox_check_message_from_host(mctrl, VIPX_MTYPE_H2F_NORMAL);
- if (ret)
- goto p_err;
-
- ret = emul_mbox_read(mctrl, &payload, VIPX_MTYPE_H2F_NORMAL);
-
- /* handle message */
-
- /* write f2h mbox */
- ret = emul_mbox_ready(mctrl, VIPX_MTYPE_F2H_NORMAL);
- if (ret) {
- vipx_err("emul_mbox_ready is failed(%d)\n", ret);
- goto p_err;
- }
-
- ret = emul_mbox_write(mctrl, &payload, sizeof(vipx_msg_t), VIPX_MTYPE_F2H_NORMAL);
- if (ret) {
- vipx_err("emul_mbox_write is failed(%d)\n", ret);
- goto p_err;
- }
-
- has_normal = 1;
-
-p_err:
- if (has_urgent || has_normal) {
- vipx_info("________ %d %d exit\n", has_urgent, has_normal);
- }
-
- return (has_urgent || has_normal) ? 0 : -1;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/random.h>
-#include <linux/slab.h>
-
-#include "vipx-config.h"
-#include "vipx-interface.h"
-#include "vipx-memory.h"
-#include "vipx-mailbox.h"
-#include "vipx-io.h"
-#include "../vipx-graphmgr.h"
-#include "../vipx-device.h"
-
-#include <interface/ap_vip_if.h>
-
-#define TURN_AROUND_TIME (HZ/20)
-
-#define enter_request_barrier(task) mutex_lock(task->lock);
-#define exit_request_barrier(task) mutex_unlock(task->lock);
-#define init_process_barrier(itf) spin_lock_init(&itf->process_barrier);
-#define enter_process_barrier(itf) spin_lock_irq(&itf->process_barrier);
-#define exit_process_barrier(itf) spin_unlock_irq(&itf->process_barrier);
-
-#ifdef DBG_INTERFACE_ISR
-#define DEBUG_ISR vipx_info
-#else
-#define DEBUG_ISR vipx_dbg
-#endif
-
-/* #define NON_BLOCK_INVOKE */
-
-atomic_t checker;
-
-int __get_size_from(struct vipx_format *format, unsigned int plane, int *width, int *height)
-{
- int ret = 0;
-
- switch (format->format) {
- case VS4L_DF_IMAGE_U8:
- case VS4L_DF_IMAGE_U16:
- case VS4L_DF_IMAGE_RGB:
- case VS4L_DF_IMAGE_U32:
- *width = format->width;
- *height = format->height;
- break;
- case VS4L_DF_IMAGE_NV21:
- if (plane == 0) {
- *width = format->width;
- *height = format->height;
- } else if (plane == 1) {
- *width = format->width;
- *height = format->height / 2;
- } else {
- vipx_err("Invalid plane(%d) for NV21 format\n", plane);
- ret = -1;
- }
- break;
- case VS4L_DF_IMAGE_YV12:
- case VS4L_DF_IMAGE_I420:
- if (plane == 0) {
- *width = format->width;
- *height = format->height;
- } else if (plane == 1) {
- *width = format->width / 2;
- *height = format->height / 2;
- } else if (plane == 2) {
- *width = format->width / 2;
- *height = format->height / 2;
- } else {
- vipx_err("Invalid plane(%d) for YV12/I420 format\n", plane);
- ret = -1;
- }
- break;
- case VS4L_DF_IMAGE_I422:
- if (plane == 0) {
- *width = format->width;
- *height = format->height;
- } else if (plane == 1) {
- *width = format->width / 2;
- *height = format->height;
- } else if (plane == 2) {
- *width = format->width / 2;
- *height = format->height;
- } else {
- vipx_err("Invalid plane(%d) for YV12/I422 format\n", plane);
- ret = -1;
- }
- break;
- default:
- vipx_err("invalid format(%d)\n", format->format);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-static void WORK_TO_FREE(struct vipx_work_list *work_list, struct vipx_work *work)
-{
- unsigned long flags;
-
- BUG_ON(!work_list);
- BUG_ON(!work);
-
- spin_lock_irqsave(&work_list->slock, flags);
- list_add_tail(&work->list, &work_list->free_head);
- work_list->free_cnt++;
- spin_unlock_irqrestore(&work_list->slock, flags);
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static void WORK_FR_FREE(struct vipx_work_list *work_list, struct vipx_work **work)
-{
- unsigned long flags;
-
- BUG_ON(!work_list);
- BUG_ON(!work);
-
- spin_lock_irqsave(&work_list->slock, flags);
- if (work_list->free_cnt) {
- *work = container_of(work_list->free_head.next, struct vipx_work, list);
- list_del(&(*work)->list);
- work_list->free_cnt--;
- } else {
- *work = NULL;
- }
- spin_unlock_irqrestore(&work_list->slock, flags);
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static void WORK_TO_REPLY(struct vipx_work_list *work_list, struct vipx_work *work)
-{
- unsigned long flags;
-
- BUG_ON(!work_list);
- BUG_ON(!work);
-
- spin_lock_irqsave(&work_list->slock, flags);
- list_add_tail(&work->list, &work_list->reply_head);
- work_list->reply_cnt++;
- spin_unlock_irqrestore(&work_list->slock, flags);
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static void WORK_FR_REPLY(struct vipx_work_list *work_list, struct vipx_work **work)
-{
- unsigned long flags;
-
- BUG_ON(!work_list);
- BUG_ON(!work);
-
- spin_lock_irqsave(&work_list->slock, flags);
- if (work_list->reply_cnt) {
- *work = container_of(work_list->reply_head.next, struct vipx_work, list);
- list_del(&(*work)->list);
- work_list->reply_cnt--;
- } else {
- *work = NULL;
- }
- spin_unlock_irqrestore(&work_list->slock, flags);
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static void INIT_WORK_LIST(struct vipx_work_list *work_list, u32 count)
-{
- u32 i;
-
- work_list->free_cnt = 0;
- work_list->reply_cnt = 0;
- INIT_LIST_HEAD(&work_list->free_head);
- INIT_LIST_HEAD(&work_list->reply_head);
- spin_lock_init(&work_list->slock);
- init_waitqueue_head(&work_list->wait_queue);
- for (i = 0; i < count; ++i)
- WORK_TO_FREE(work_list, &work_list->work[i]);
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static inline void __set_reply(struct vipx_interface *interface, u32 graph_idx)
-{
- BUG_ON(graph_idx >= VIPX_MAX_GRAPH);
- interface->reply[graph_idx].valid = 1;
- wake_up(&interface->reply_queue);
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static inline void __clr_reply(struct vipx_interface *interface, u32 graph_idx)
-{
- BUG_ON(graph_idx >= VIPX_MAX_GRAPH);
- interface->reply[graph_idx].valid = 0;
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static int __wait_reply(struct vipx_interface *interface, u32 graph_idx)
-{
- int ret = 0;
- int remain_time;
- u32 cmd, type;
-
- BUG_ON(!interface);
- BUG_ON(graph_idx >= VIPX_MAX_GRAPH);
- BUG_ON(!interface->request[graph_idx]);
-
- cmd = interface->request[graph_idx]->message;
- type = interface->request[graph_idx]->param3;
-
-#ifdef NON_BLOCK_INVOKE
- remain_time = wait_event_timeout(interface->reply_queue,
- interface->reply[graph_idx].valid, VIPX_COMMAND_TIMEOUT);
-#else
- remain_time = wait_event_timeout(interface->reply_queue,
- interface->reply[graph_idx].valid, VIPX_COMMAND_TIMEOUT * 2);
-#endif
- if (!remain_time) {
- vipx_err("[GID:%d] %d command[type: %d] : reply is timeout\n", graph_idx, cmd, type);
- ret = -ETIME;
- goto p_err;
- }
-
-p_err:
-
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static void __send_interrupt(struct vipx_interface *interface)
-{
-#ifndef CONFIG_EXYNOS_EMUL_MBOX
- u32 try_count;
- u32 type, offset, val;
-
- BUG_ON(!interface);
- BUG_ON(!interface->process);
-
- type = interface->process->param3;
- offset = (type == VIPX_MTYPE_H2F_NORMAL) ? 0x10 : 0x0C;
-
-
- /* Check interrupt clear */
- try_count = 100;
- val = readl(interface->regs + offset);
- while (--try_count && val) {
- vipx_warn("waiting interrupt clear(%d)...(%d)\n", val, try_count);
- val = readl(interface->regs + offset);
- }
-
- DEBUG_ISR("[DEBUG ISR] interrupt generate (%x)\n", offset);
-
- /* Raise interrupt */
- writel(0x100, interface->regs + offset);
-#endif
-
- vipx_dbg("%s:\n", __func__);
-}
-
-static int __vipx_set_cmd(struct vipx_interface *interface,
- struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_mailbox_ctrl *mctrl;
- void *payload;
- u32 cmd, gidx, cid, size, type;
- ulong flag;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
- BUG_ON(!itask->lock);
- BUG_ON(itask->param1 >= VIPX_MAX_GRAPH);
-
- itaskmgr = &interface->taskmgr;
- mctrl = interface->private_data;
- cmd = itask->message;
- payload = (void *)itask->param0;
- gidx = itask->param1;
- size = itask->param2;
- type = itask->param3;
- cid = itask->index;
-
- enter_request_barrier(itask);
- interface->request[gidx] = itask;
-
- enter_process_barrier(interface);
- interface->process = itask;
-
- ret = vipx_mbox_ready(mctrl, size, type);
- if (ret) {
- interface->process = NULL;
- exit_process_barrier(interface);
- interface->request[gidx] = NULL;
- exit_request_barrier(itask);
- vipx_err("vipx_mbox_ready is fail(%d)", ret);
- goto p_err;
- }
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_req_to_pro(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- ret = vipx_mbox_write(mctrl, payload, size, type, gidx, cmd, cid);
- if (ret) {
- interface->process = NULL;
- exit_process_barrier(interface);
- interface->request[gidx] = NULL;
- exit_request_barrier(itask);
- pr_err("vipx_mbox_write_request fail (%d)\n", ret);
- goto p_err;
- }
-
- atomic_inc(&checker);
-
- __send_interrupt(interface);
-
- DEBUG_ISR("[I%ld][MBOX] CMD : %d, ID : %d\n", itask->param1, cmd, cid);
-
- interface->process = NULL;
- exit_process_barrier(interface);
-
- ret = __wait_reply(interface, gidx);
- if (ret) {
- interface->request[gidx] = NULL;
- exit_request_barrier(itask);
- vipx_err("%d command is timeout", cmd);
- ret = -ETIME;
- goto p_err;
- }
-
- if (interface->reply[gidx].work_param1) {
- interface->request[gidx] = NULL;
- exit_request_barrier(itask);
- vipx_err("%d command is error(%d)\n", cmd, interface->reply[gidx].work_param1);
- ret = interface->reply[gidx].work_param1;
- goto p_err;
- }
-
- __clr_reply(interface, gidx);
-
- interface->request[gidx] = NULL;
- exit_request_barrier(itask);
-
-p_err:
-
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-
-#ifdef NON_BLOCK_INVOKE
-static int __vipx_set_cmd_nblk(struct vipx_interface *interface,
- struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_mailbox_ctrl *mctrl;
- void *payload;
- u32 cmd, gidx, cid, size, type;
- ulong flag;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
- mctrl = interface->private_data;
- cmd = itask->message;
- payload = (void *)itask->param0;
- gidx = itask->param1;
- size = itask->param2;
- type = itask->param3;
- cid = itask->index;
-
- enter_process_barrier(interface);
- interface->process = itask;
-
- ret = vipx_mbox_ready(mctrl, size, type);
- if (ret) {
- interface->process = NULL;
- exit_process_barrier(interface);
- vipx_err("vipx_mbox_ready is fail(%d)", ret);
- goto p_err;
- }
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_req_to_pro(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- ret = vipx_mbox_write(mctrl, payload, size, type, gidx, cmd, cid);
- if (ret) {
- interface->process = NULL;
- exit_process_barrier(interface);
- pr_err("vipx_mbox_write_request fail (%d)\n", ret);
- goto p_err;
- }
-
- atomic_inc(&checker);
-
- __send_interrupt(interface);
-
- DEBUG_ISR("[I%ld][MBOX] CMD : %d, ID : %d\n", itask->param1, cmd, cid);
-
- interface->process = NULL;
- exit_process_barrier(interface);
-
-p_err:
-
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-#endif
-
-static int __vipx_interface_cleanup(struct vipx_interface *interface)
-{
- int ret = 0;
- struct vipx_taskmgr *taskmgr;
- struct vipx_task *task;
- ulong flags;
- u32 i;
-
- taskmgr = &interface->taskmgr;
-
- if (taskmgr->req_cnt) {
- vipx_err("[ITF] request count is NOT zero(%d)\n", taskmgr->req_cnt);
- ret += taskmgr->req_cnt;
- }
-
- if (taskmgr->pro_cnt) {
- vipx_err("[ITF] process count is NOT zero(%d)\n", taskmgr->pro_cnt);
- ret += taskmgr->pro_cnt;
- }
-
- if (taskmgr->com_cnt) {
- vipx_err("[ITF] complete count is NOT zero(%d)\n", taskmgr->com_cnt);
- ret += taskmgr->com_cnt;
- }
-
- if (ret) {
- taskmgr_e_barrier_irqs(taskmgr, 0, flags);
-
- for (i = 1; i < taskmgr->tot_cnt; ++i) {
- task = &taskmgr->task[i];
- if (task->state == VIPX_TASK_STATE_FREE)
- continue;
-
- vipx_task_trans_any_to_fre(taskmgr, task);
- ret--;
- }
-
- taskmgr_x_barrier_irqr(taskmgr, 0, flags);
- }
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-void vipx_interface_print(struct vipx_interface *interface)
-{
- DLOG_INIT();
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask, *itemp;
-
- BUG_ON(!interface);
-
- itaskmgr = &interface->taskmgr;
-
- DLOG("REQUEST LIST(%d) :", itaskmgr->req_cnt);
- list_for_each_entry_safe(itask, itemp, &itaskmgr->req_list, list) {
- DLOG(" %d(%d, %d)", itask->index, itask->param1, itask->message);
- }
- vipx_info("%s\n", DLOG_OUT());
-
- DLOG("PROCESS LIST(%d) :", itaskmgr->pro_cnt);
- list_for_each_entry_safe(itask, itemp, &itaskmgr->pro_list, list) {
- DLOG(" %d(%d, %d)", itask->index, itask->param1, itask->message);
- }
- vipx_info("%s\n", DLOG_OUT());
-
- DLOG("COMPLETE LIST(%d) :", itaskmgr->com_cnt);
- list_for_each_entry_safe(itask, itemp, &itaskmgr->com_list, list) {
- DLOG(" %d(%d, %d)", itask->index, itask->param1, itask->message);
- }
- vipx_info("%s\n", DLOG_OUT());
-}
-
-static irqreturn_t interface_isr(int irq, void *data)
-{
- int ret = 0;
- struct vipx_interface *interface;
- struct vipx_mailbox_ctrl *mctrl;
- struct vipx_mailbox_f2h *mbox;
- struct work_struct *work_queue;
- struct vipx_work_list *work_list;
- struct vipx_work *work;
- vipx_msg_t msg_rsp;
-
- interface = (struct vipx_interface *)data;
- mctrl = interface->private_data;
- work_queue = &interface->work_queue;
- work_list = &interface->work_list;
-
- mbox = &mctrl->urgent_stack->f2h;
- DEBUG_ISR("[DEBUG_ISR] status of urgent mbox w(%d) r(%d)\n", mbox->wmsg_idx, mbox->rmsg_idx);
- while (mbox->wmsg_idx != mbox->rmsg_idx) {
- ret = vipx_mbox_read(mctrl, &msg_rsp, VIPX_MTYPE_H2F_URGENT, data);
- if (ret) {
- vipx_err("vipx_mbox_read is fail(%d)\n", ret);
- break;
- }
- DEBUG_ISR("[DEBUG_ISR] read urgent mbox transid %d\n", msg_rsp.transId);
-
- if (msg_rsp.type == BOOTUP_RSP) {
- if (msg_rsp.msg_u.bootup_rsp.error == 0) {
- vipx_info("CM7 bootup complete %d\n", msg_rsp.transId);
- set_bit(VIPX_ITF_STATE_BOOTUP, &interface->state);
- }
- break;
- }
-
- atomic_dec(&checker);
-
- WORK_FR_FREE(work_list, &work);
- if (work) {
- /* TODO */
- work->id = msg_rsp.transId;
- work->message = 0;
- work->work_param0 = 0;
- work->work_param1 = 0;
- work->work_param2 = 0;
- work->work_param3 = 0;
-
- WORK_TO_REPLY(work_list, work);
- if (!work_pending(work_queue))
- schedule_work(work_queue);
- } else {
- vipx_err("free work is empty\n");
- break;
- }
- break;
- }
-
- mbox = &mctrl->stack->f2h;
- DEBUG_ISR("[DEBUG_ISR] status of normal mbox w(%d) r(%d)\n", mbox->wmsg_idx, mbox->rmsg_idx);
- while (mbox->wmsg_idx != mbox->rmsg_idx) {
- ret = vipx_mbox_read(mctrl, &msg_rsp, VIPX_MTYPE_H2F_NORMAL, data);
- if (ret) {
- vipx_err("vipx_mbox_read is fail(%d)\n", ret);
- break;
- }
- DEBUG_ISR("[DEBUG_ISR] read normal mbox transid %d\n", msg_rsp.transId);
-
- atomic_dec(&checker);
-
- WORK_FR_FREE(work_list, &work);
- if (work) {
- /* TODO */
- work->id = msg_rsp.transId;
- work->message = 0;
- work->work_param0 = 0;
- work->work_param1 = 0;
- work->work_param2 = 0;
- work->work_param3 = 0;
-
- WORK_TO_REPLY(work_list, work);
- if (!work_pending(work_queue))
- schedule_work(work_queue);
- } else {
- vipx_err("free work is empty\n");
- break;
- }
- break;
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t interface_isr0(int irq, void *data)
-{
- struct vipx_interface *interface = (struct vipx_interface *)data;
- u32 val;
-
- val = readl(interface->regs + 0x8);
- if (val & 0x1) {
- val &= ~(0x1);
- writel(val, interface->regs + 0x8);
- interface_isr(irq, data);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t interface_isr1(int irq, void *data)
-{
- struct vipx_interface *interface = (struct vipx_interface *)data;
- u32 val;
-
- val = readl(interface->regs + 0x8);
- if (val & (0x1 << 0x1)) {
- val &= ~(0x1 << 0x1);
- writel(val, interface->regs + 0x8);
- interface_isr(irq, data);
- }
-
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_EXYNOS_EMUL_MBOX
-static void interface_timer(unsigned long data)
-{
- struct vipx_interface *interface = (struct vipx_interface *)data;
- struct vipx_mailbox_ctrl *mctrl;
- int ret = 0;
- u32 random;
-
- mctrl = interface->private_data;
-
- if (!test_bit(VIPX_ITF_STATE_START, &interface->state))
- goto exit;
-
- ret = emul_mbox_handler(mctrl);
- if (ret)
- {
- if (atomic_read(&checker) != 0) {
- vipx_info("nothing to handle, checker %d\n", atomic_read(&checker));
- }
- goto exit;
- }
-
- interface_isr(0, (void *)data);
-
-exit:
- get_random_bytes(&random, sizeof(random));
- random = random % TURN_AROUND_TIME;
- mod_timer(&interface->timer, jiffies + random);
-}
-#endif
-
-static void vipx_wq_func(struct work_struct *data)
-{
- struct vipx_interface *interface;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
- struct vipx_work_list *work_list;
- struct vipx_work *work;
- u32 graph_idx;
- ulong flags;
-
- interface = container_of(data, struct vipx_interface, work_queue);
- itaskmgr = &interface->taskmgr;
- work_list = &interface->work_list;
-
- WORK_FR_REPLY(work_list, &work);
- while (work) {
- if (work->id >= VIPX_MAX_TASK) {
- vipx_err("work id is invalid(%d)\n", work->id);
- break;
- }
- itask = &itaskmgr->task[work->id];
-
- if (itask->state != VIPX_TASK_STATE_PROCESS) {
- vipx_err("task(%d, %d, %ld) state is invalid(%d), work(%d, %d, %d)\n",
- itask->message, itask->index, itask->param1, itask->state,
- work->id, work->work_param0, work->work_param1);
- vipx_interface_print(interface);
- BUG();
- }
-
- switch (itask->message) {
- case VIPX_TASK_INIT:
- case VIPX_TASK_DEINIT:
- case VIPX_TASK_CREATE:
- case VIPX_TASK_DESTROY:
- case VIPX_TASK_ALLOCATE:
- case VIPX_TASK_REQUEST:
- graph_idx = itask->param1;
- interface->reply[graph_idx] = *work;
- DEBUG_ISR("[DEBUG_ISR] set reply graph idx(%d)\n", graph_idx);
- __set_reply(interface, graph_idx);
- break;
- case VIPX_TASK_PROCESS:
- DEBUG_ISR("[DEBUG_ISR] TASK PROCESS\n");
-
-#ifdef NON_BLOCK_INVOKE
-#else
- graph_idx = itask->param1;
- interface->reply[graph_idx] = *work;
- __set_reply(interface, graph_idx);
-#endif
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_trans_pro_to_com(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- itask->param2 = 0;
- itask->param3 = 0;
- vipx_graphmgr_queue(interface->cookie, itask);
- interface->done_cnt++;
- break;
- default:
- vipx_err("unresolved message(%d) have arrived\n", work->message);
- break;
- }
-
- WORK_TO_FREE(work_list, work);
- WORK_FR_REPLY(work_list, &work);
- }
-}
-
-int vipx_interface_probe(struct vipx_interface *interface,
- struct device *dev,
- void __iomem *regs,
- resource_size_t regs_size,
- u32 irq0, u32 irq1)
-{
- int ret = 0;
- struct vipx_device *device;
- struct vipx_system *system;
- struct vipx_taskmgr *taskmgr;
-
- BUG_ON(!interface);
- BUG_ON(!dev);
- BUG_ON(!regs);
-
- system = container_of(interface, struct vipx_system, interface);
- device = container_of(system, struct vipx_device, system);
-
- init_process_barrier(interface);
- init_waitqueue_head(&interface->reply_queue);
-
- interface->regs = regs;
- interface->regs_size = regs_size;
- interface->cookie = (void *)&device->graphmgr;
- clear_bit(VIPX_ITF_STATE_OPEN, &interface->state);
- clear_bit(VIPX_ITF_STATE_BOOTUP, &interface->state);
- clear_bit(VIPX_ITF_STATE_ENUM, &interface->state);
- clear_bit(VIPX_ITF_STATE_START, &interface->state);
- interface->private_data = kmalloc(sizeof(struct vipx_mailbox_ctrl), GFP_KERNEL);
- if (!interface->private_data) {
- probe_err("kmalloc is fail\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- ret = devm_request_irq(dev, irq0, interface_isr0, 0, dev_name(dev), interface);
- if (ret) {
- probe_err("devm_request_irq(0) is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = devm_request_irq(dev, irq1, interface_isr1, 0, dev_name(dev), interface);
- if (ret) {
- probe_err("devm_request_irq(1) is fail(%d)\n", ret);
- goto p_err;
- }
-
- taskmgr = &interface->taskmgr;
- taskmgr->id = VIPX_MAX_GRAPH;
- taskmgr->sindex = 0;
- spin_lock_init(&taskmgr->slock);
-
- ret = vipx_task_init(taskmgr, interface);
- if (ret) {
- probe_err("vipx_task_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_slab_init(&interface->slab);
- if (ret) {
- probe_err("vipx_slab_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- INIT_WORK(&interface->work_queue, vipx_wq_func);
- INIT_WORK_LIST(&interface->work_list, VIPX_WORK_MAX_COUNT);
-
-p_err:
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_interface_open(struct vipx_interface *interface,
- void *mbox, size_t mbox_size)
-{
- struct vipx_mailbox_ctrl *mctrl;
- int ret = 0;
- u32 i;
-
- BUG_ON(!interface);
- BUG_ON(!mbox);
-
- interface->mbox = mbox;
- interface->mbox_size = mbox_size;
- memset(interface->mbox, 0x0, interface->mbox_size);
-
- mctrl = interface->private_data;
- mctrl->stack = vipx_mbox_g_stack(mbox, mbox_size);
- mctrl->urgent_stack = vipx_mbox_g_urgent_stack(mbox, mbox_size);
-
- ret = vipx_graphmgr_itf_register(interface->cookie, interface);
- if (ret) {
- vipx_err("vipx_graphmgr_itf_register is fail(%d)\n", ret);
- goto p_err;
- }
-
- atomic_set(&checker, 0);
-
- interface->process = NULL;
- for (i = 0; i < VIPX_MAX_GRAPH; ++i) {
- interface->request[i] = NULL;
- interface->reply[i].valid = 0;
- }
-
- interface->done_cnt = 0;
- set_bit(VIPX_ITF_STATE_OPEN, &interface->state);
- clear_bit(VIPX_ITF_STATE_BOOTUP, &interface->state);
- clear_bit(VIPX_ITF_STATE_ENUM, &interface->state);
- clear_bit(VIPX_ITF_STATE_START, &interface->state);
-
-p_err:
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_interface_close(struct vipx_interface *interface)
-{
- int ret = 0;
-
- BUG_ON(!interface);
-
- ret = __vipx_interface_cleanup(interface);
- if (ret)
- vipx_err("__vipx_interface_cleanup is fail(%d)\n", ret);
-
- ret = vipx_graphmgr_itf_unregister(interface->cookie, interface);
- if (ret)
- vipx_err("vipx_graphmgr_itf_unregister is fail(%d)\n", ret);
-
- interface->mbox = 0;
- interface->mbox_size = 0;
-
- clear_bit(VIPX_ITF_STATE_OPEN, &interface->state);
- clear_bit(VIPX_ITF_STATE_BOOTUP, &interface->state);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_interface_start(struct vipx_interface *interface)
-{
- int ret = 0;
-
- set_bit(VIPX_ITF_STATE_START, &interface->state);
-
-#ifdef CONFIG_EXYNOS_EMUL_MBOX
- init_timer(&interface->timer);
- interface->timer.expires = jiffies + TURN_AROUND_TIME;
- interface->timer.data = (unsigned long)interface;
- interface->timer.function = interface_timer;
- add_timer(&interface->timer);
-#endif
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_interface_stop(struct vipx_interface *interface)
-{
- int errcnt = 0;
- struct vipx_taskmgr *itaskmgr;
- u32 retry;
-
- itaskmgr = &interface->taskmgr;
-
- retry = VIPX_STOP_WAIT_COUNT;
- while (--retry && itaskmgr->req_cnt) {
- vipx_warn("waiting %d request completion...(%d)\n", itaskmgr->req_cnt, retry);
- msleep(10);
- }
-
- if (!retry) {
- vipx_err("request completion is fail\n");
- vipx_interface_print(interface);
- errcnt++;
- }
-
- retry = VIPX_STOP_WAIT_COUNT;
- while (--retry && itaskmgr->pro_cnt) {
- vipx_warn("waiting %d process completion...(%d)\n", itaskmgr->pro_cnt, retry);
- msleep(10);
- }
-
- if (!retry) {
- vipx_err("process completion is fail\n");
- vipx_interface_print(interface);
- errcnt++;
- }
-
- retry = VIPX_STOP_WAIT_COUNT;
- while (--retry && itaskmgr->com_cnt) {
- vipx_warn("waiting %d complete completion...(%d)\n", itaskmgr->com_cnt, retry);
- msleep(10);
- }
-
- if (!retry) {
- vipx_err("complete completion is fail\n");
- vipx_interface_print(interface);
- errcnt++;
- }
-
-#ifdef CONFIG_EXYNOS_EMUL_MBOX
- del_timer(&interface->timer);
-#endif
- clear_bit(VIPX_ITF_STATE_START, &interface->state);
-
- vipx_info("%s:\n", __func__);
- return 0;
-}
-
-int vipx_hw_wait_bootup(struct vipx_interface *interface)
-{
- int ret = 0;
- int try_cnt = 10;
- struct vipx_system *system = container_of(interface, struct vipx_system, interface);
- struct vipx_binary *binary = &system->binary;
-
- BUG_ON(!interface);
-
- while (try_cnt && !test_bit(VIPX_ITF_STATE_BOOTUP, &interface->state)) {
- msleep(5);
- try_cnt--;
- vipx_info("%s(): wait CM7 bootup\n",__func__);
- }
-
- vipx_info("debug kva(0x%p), dva(0x%x), size(%ld)\n", system->memory.info.kvaddr_debug, (u32)system->memory.info.dvaddr_debug, system->memory.info.pb_debug->size);
-
- if (try_cnt == 0)
- {
- if (!IS_ERR_OR_NULL(system->memory.info.kvaddr_debug)) {
- ret = vipx_binary_write(binary, VIPX_FW_PATH1, "vipx_log.bin",
- system->memory.info.kvaddr_debug, VIPX_DEBUG_SIZE);
- if (ret)
- vipx_err("vipx_binary_write is fail(%d)\n", ret);
- }
- ret = -EINVAL;
- }
-
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_hw_enum(struct vipx_interface *interface)
-{
- int ret = 0;
-
- BUG_ON(!interface);
-
- set_bit(VIPX_ITF_STATE_ENUM, &interface->state);
-
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-/* Init Req */
-int vipx_hw_init(struct vipx_interface *interface, struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- ulong flag;
- vipx_msg_t payload;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
-
- payload.transId = itask->index;
- payload.type = INIT_REQ;
-
- /* TODO */
- /* fill init_req */
-#if 0
- payload.msg_u.init_req.p_vip_core_bin = 0;
- payload.msg_u.init_req.sz_vip_core_bin = 0;
- payload.msg_u.init_req.p_cc_log = 0;
- payload.msg_u.init_req.sz_cc_log = 0;
-#endif
-
- payload.msg_u.init_req.p_cc_heap = 0;
- payload.msg_u.init_req.sz_cc_heap = 0;
-
- itask->param0 = (ulong)&payload;
- /* Do not update param1. param1 is graph_idx */
- /* itask->param1 = 0; */
- itask->param2 = sizeof(vipx_msg_t);
- itask->param3 = VIPX_MTYPE_H2F_URGENT;
-
- ret = __vipx_set_cmd(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_any_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-/* Power doen Req */
-int vipx_hw_deinit(struct vipx_interface *interface, struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- ulong flag;
- vipx_msg_t payload;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
-
- /* TODO */
- payload.transId = itask->index;
- payload.type = POWER_DOWN_REQ;
-
- /* fill powerdown_graph_req */
- payload.msg_u.powerdown_req.valid = 1;
-
- itask->param0 = (ulong)&payload;
- /* Do not update param1. param1 is graph_idx */
- /* itask->param1 = 0; */
- itask->param2 = sizeof(vipx_msg_t);
- itask->param3 = VIPX_MTYPE_H2F_URGENT;
-
- ret = __vipx_set_cmd(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_any_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-/* Create graph */
-int vipx_hw_create(struct vipx_interface *interface, struct vipx_task *itask)
-{
- int ret = 0;
-
- struct vipx_taskmgr *itaskmgr;
- ulong flag;
- vipx_msg_t payload;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
-
- /* TODO */
- payload.transId = itask->index;
- payload.type = CREATE_GRAPH_REQ;
-
- /* fill create_graph_req */
- payload.msg_u.create_graph_req.p_graph = 0;
- payload.msg_u.create_graph_req.sz_graph = 0;
-
- itask->param0 = (ulong)&payload;
- /* Do not update param1. param1 is graph_idx */
- /* itask->param1 = 0; */
- itask->param2 = sizeof(vipx_msg_t);
- itask->param3 = VIPX_MTYPE_H2F_NORMAL;
-
- ret = __vipx_set_cmd(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_any_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- vipx_info("%s:%d\n", __func__, ret);
-
- return ret;
-}
-
-/* Destroy graph */
-int vipx_hw_destroy(struct vipx_interface *interface, struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_system *system = container_of(interface, struct vipx_system, interface);
- ulong flag;
- vipx_msg_t payload;
- u32 heap_size;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
-
- /* TODO */
- payload.transId = itask->index;
- payload.type = DESTROY_GRAPH_REQ;
-
- /* fill destroy_graph_req */
- payload.msg_u.destroy_graph_req.graph_id = itask->param0;
- vipx_dbg("[%s] graph_id(%d)\n", __func__, payload.msg_u.destroy_graph_req.graph_id);
-
- itask->param0 = (ulong)&payload;
- /* Do not update param1. param1 is graph_idx */
- /* itask->param1 = 0; */
- itask->param2 = sizeof(vipx_msg_t);
- itask->param3 = VIPX_MTYPE_H2F_NORMAL;
-
- ret = __vipx_set_cmd(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd is fail(%d)\n", ret);
- goto p_err;
- }
-
- if (payload.msg_u.destroy_graph_req.graph_id < SCENARIO_DE_CAPTURE)
- heap_size = VIPX_CM7_HEAP_SIZE_PREVIEW;
- else if (payload.msg_u.destroy_graph_req.graph_id == SCENARIO_ENF)
- heap_size = VIPX_CM7_HEAP_SIZE_ENF;
- else
- heap_size = VIPX_CM7_HEAP_SIZE_CAPTURE;
-
- vipx_free_heap(&system->memory, &system->binary, heap_size);
-
- vipx_info("checker %d\n", atomic_read(&checker));
-
-p_err:
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_any_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_hw_config(struct vipx_interface *interface, struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_system *system = container_of(interface, struct vipx_system, interface);
- ulong flag;
- vipx_msg_t payload;
- int i = 0, j = 0;
- int num_inputs = 0;
- int num_outputs = 0;
- int cur_width = 0;
- int cur_height = 0;
- dma_addr_t dvaddr_heap = 0;
- u32 heap_size;
-
- struct vipx_format_list *in_list;
- struct vipx_format_list *out_list;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
- in_list = (void *)itask->param2;
- out_list = (void *)itask->param3;
-
- payload.transId = itask->index;
- payload.type = SET_GRAPH_REQ;
-
- /* fill set_graph_req */
- payload.msg_u.set_graph_req.graph_id = itask->param0;
- vipx_dbg("[%s] graph_id(%d)\n", __func__, payload.msg_u.set_graph_req.graph_id);
-
- /* TODO : How to update depth field */
- for (i = 0; i < in_list->count; i++) {
- vipx_info("in-buf[%d], fmt %d, plane %d, size: %dx%d\n",
- i, in_list->formats[i].format,
- in_list->formats[i].plane,
- in_list->formats[i].width,
- in_list->formats[i].height);
- for (j = 0; j < in_list->formats[i].plane; j++) {
- ret = __get_size_from(&in_list->formats[i], j, &cur_width, &cur_height);
- if (ret) {
- vipx_err("__get_size_from fail (%d)\n", ret);
- goto p_err;
- }
- payload.msg_u.set_graph_req.input_width[num_inputs] = cur_width;
- payload.msg_u.set_graph_req.input_height[num_inputs] = cur_height;
- payload.msg_u.set_graph_req.input_depth[num_inputs] = 0;
- vipx_info("input[%d] WxH(%dx%d), depth(%d)\n", num_inputs,
- payload.msg_u.set_graph_req.input_width[num_inputs],
- payload.msg_u.set_graph_req.input_height[num_inputs],
- payload.msg_u.set_graph_req.input_depth[num_inputs]
- );
- num_inputs++;
- }
- }
-
- for (i = 0; i < out_list->count; i++) {
- vipx_info("out-buf[%d], fmt %d, plane %d, size: %dx%d\n",
- i, out_list->formats[i].format,
- out_list->formats[i].plane,
- out_list->formats[i].width,
- out_list->formats[i].height);
- for (j = 0; j < out_list->formats[i].plane; j++) {
- ret = __get_size_from(&out_list->formats[i], j, &cur_width, &cur_height);
- if (ret) {
- vipx_err("__get_size_from fail (%d)\n", ret);
- goto p_err;
- }
- payload.msg_u.set_graph_req.output_width[num_outputs] = cur_width;
- payload.msg_u.set_graph_req.output_height[num_outputs] = cur_height;
- payload.msg_u.set_graph_req.output_depth[num_outputs] = 0;
- vipx_info("output[%d] WxH(%dx%d), depth(%d)\n", num_outputs,
- payload.msg_u.set_graph_req.output_width[num_outputs],
- payload.msg_u.set_graph_req.output_height[num_outputs],
- payload.msg_u.set_graph_req.output_depth[num_outputs]
- );
- num_outputs++;
- }
- }
- // Allocate and assign heap
- if (payload.msg_u.set_graph_req.graph_id < SCENARIO_DE_CAPTURE)
- heap_size = VIPX_CM7_HEAP_SIZE_PREVIEW;
- else if (payload.msg_u.destroy_graph_req.graph_id == SCENARIO_ENF_UV ||
- payload.msg_u.destroy_graph_req.graph_id == SCENARIO_ENF)
- heap_size = VIPX_CM7_HEAP_SIZE_ENF;
- else
- heap_size = VIPX_CM7_HEAP_SIZE_CAPTURE;
- dvaddr_heap = vipx_allocate_heap(&system->memory, heap_size);
-
- payload.msg_u.set_graph_req.p_temp = dvaddr_heap;
- payload.msg_u.set_graph_req.sz_temp = heap_size;
- vipx_info("CC heap dva(0x%x), size(%d)\n", (u32)dvaddr_heap, heap_size);
-
- payload.msg_u.set_graph_req.num_inputs = num_inputs;
- payload.msg_u.set_graph_req.num_outputs = num_outputs;
- vipx_info("input cnt(%d), output cnt(%d)\n", num_inputs, num_outputs);
-
- itask->param0 = (ulong)&payload;
- /* Do not update param1. param1 is graph_idx */
- /* itask->param1 = 0; */
- itask->param2 = sizeof(vipx_msg_t);
- itask->param3 = VIPX_MTYPE_H2F_NORMAL;
-
- ret = __vipx_set_cmd(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_any_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_hw_process(struct vipx_interface *interface, struct vipx_task *itask)
-{
- int ret = 0;
- struct vipx_taskmgr *itaskmgr;
- ulong flag;
- vipx_msg_t payload;
- int i = 0, j = 0;
- int num_inputs = 0;
- int num_outputs = 0;
- int num_user_params = 0;
-
- struct vb_container_list *incl;
- struct vb_container_list *otcl;
-
- BUG_ON(!interface);
- BUG_ON(!itask);
-
- itaskmgr = &interface->taskmgr;
- incl = itask->incl;
- otcl = itask->otcl;
-
- payload.transId = itask->index;
- payload.type = INVOKE_GRAPH_REQ;
-
- /* use itask->incl and itask->otcl */
- payload.msg_u.invoke_graph_req.graph_id = itask->param0;
- vipx_dbg("[%s] graph_id(%d)\n", __func__, payload.msg_u.invoke_graph_req.graph_id);
-
- /* TODO : We need to consider to support multi plain buffer */
- for (i = 0; i < incl->count; i++) {
- for (j = 0; j < incl->containers[i].count; j++) {
- payload.msg_u.invoke_graph_req.p_input[num_inputs] = incl->containers[i].buffers[j].dvaddr;
- vipx_dbg("input[%d] buffer dvaddr(%x)\n", num_inputs,
- payload.msg_u.invoke_graph_req.p_input[num_inputs]);
- num_inputs++;
- }
- }
- for (i = 0; i < otcl->count; i++) {
- for (j = 0; j < otcl->containers[i].count; j++) {
- payload.msg_u.invoke_graph_req.p_output[num_outputs] = otcl->containers[i].buffers[j].dvaddr;
- vipx_dbg("output[%d] buffer dvaddr(%x)\n", num_outputs,
- payload.msg_u.invoke_graph_req.p_output[num_outputs]);
- num_outputs++;
- }
- }
- for (num_user_params = 0; num_user_params < MAX_NUM_OF_USER_PARAMS; num_user_params++) {
- payload.msg_u.invoke_graph_req.user_params[num_user_params] = incl->user_params[num_user_params];
- vipx_dbg("user_params[%d] = (%d)\n", num_user_params,
- payload.msg_u.invoke_graph_req.user_params[num_user_params]);
- }
-
- payload.msg_u.invoke_graph_req.num_inputs = num_inputs;
- payload.msg_u.invoke_graph_req.num_outputs = num_outputs;
- vipx_dbg("input cnt(%d), output cnt(%d)\n", num_inputs, num_outputs);
-
- itask->param0 = (ulong)&payload;
- /* Do not update param1. param1 is graph_idx */
- /* itask->param1 = 0; */
- itask->param2 = sizeof(vipx_msg_t);
- itask->param3 = VIPX_MTYPE_H2F_NORMAL;
-
-#ifdef NON_BLOCK_INVOKE
- ret = __vipx_set_cmd_nblk(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd_nblk is fail(%d)\n", ret);
- goto p_err;
- }
-#else
- ret = __vipx_set_cmd(interface, itask);
- if (ret) {
- vipx_err("__vipx_set_cmd is fail(%d)\n", ret);
- goto p_err;
- }
-#endif
-
- vipx_dbg("%s:%d\n", __func__, ret);
- return 0;
-
-p_err:
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_any_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
-
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/random.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#include "vipx-config.h"
-#include "vipx-io.h"
-#include "vipx-mailbox.h"
-#include "vipx-interface.h"
-
-#include <interface/ap_vip_if.h>
-
-#define INDEX(x) (x % MAX_MESSAGE_CNT)
-
-struct vipx_mailbox_stack * vipx_mbox_g_stack(void *mbox, u32 mbox_size)
-{
- vipx_info("sizeof mbox stack (%lx) address of normal mbox (%p)\n",
- sizeof(struct vipx_mailbox_stack), mbox);
- return (struct vipx_mailbox_stack *)mbox;
-}
-
-struct vipx_mailbox_stack * vipx_mbox_g_urgent_stack(void *mbox, u32 mbox_size)
-{
- vipx_info("address of urgent mbox (%p)\n", ((char *)mbox + sizeof(struct vipx_mailbox_stack)));
- return (struct vipx_mailbox_stack *)((char *)mbox + sizeof(struct vipx_mailbox_stack));
-}
-
-static u32 __vipx_mbox_g_freesize(struct vipx_mailbox_h2f *mbox)
-{
- u32 wmsg_idx = 0;
- u32 rmsg_idx = 0;
- u32 free_size = 0;
-
- BUG_ON(!mbox);
-
- wmsg_idx = mbox->wmsg_idx;
- rmsg_idx = mbox->rmsg_idx;
-
- free_size = MAX_MESSAGE_CNT - (wmsg_idx - rmsg_idx);
-
- BUG_ON(free_size < 0);
-
- return free_size;
-}
-
-int vipx_mbox_ready(struct vipx_mailbox_ctrl *mctrl,
- size_t size, u32 type)
-{
- u32 try_count;
- struct vipx_mailbox_h2f *mbox;
- u16 free_size16;
-
- BUG_ON(!mctrl);
- BUG_ON(!IS_ALIGNED(size, 2));
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->h2f;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->h2f;
- } else {
- vipx_err("invalid type(%d)\n", type);
- return -EINVAL;
- }
- try_count = 1000;
-
- free_size16 = __vipx_mbox_g_freesize(mbox);
- while (--try_count && (free_size16 == 0)) {
- vipx_warn("mbox is not ready(freesize %d)...(%d)\n",
- free_size16, try_count);
- udelay(10);
- free_size16 = __vipx_mbox_g_freesize(mbox);
- }
-
- if (try_count)
- return 0;
- else
- return -EBUSY;
-}
-
-int vipx_mbox_wait_reply(struct vipx_mailbox_ctrl *mctrl,
- u32 cmd, u32 type)
-{
- int ret = 0;
- struct vipx_mailbox_f2h *mbox;
- int try_count;
-
- if (type == VIPX_MTYPE_F2H_NORMAL) {
- mbox = &mctrl->stack->f2h;
- } else if (type == VIPX_MTYPE_F2H_URGENT) {
- mbox = &mctrl->urgent_stack->f2h;
- } else {
- vipx_err("cmd(%d) has invalid type(%d)\n", cmd, type);
- ret = -EINVAL;
- goto p_err;
- }
-
- try_count = 1000;
- while (--try_count && (mbox->wmsg_idx == mbox->rmsg_idx)) {
- vipx_warn("waiting vipx reply(%d, %d)...(%d)\n", mbox->wmsg_idx, mbox->rmsg_idx, try_count);
- msleep(10);
- }
-
- if (try_count <= 0) {
- vipx_err("waiting vipx reply is timeout\n");
- ret = -EINVAL;
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_mbox_write(struct vipx_mailbox_ctrl *mctrl,
- void *payload, size_t size, u32 type, u32 gid, u32 cmd, u32 cid)
-{
- int ret = 0;
- struct vipx_mailbox_h2f *mbox;
- u32 *wptr;
-
- BUG_ON(!mctrl);
- BUG_ON(!payload);
- BUG_ON(!IS_ALIGNED(size, 2));
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->h2f;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->h2f;
- } else {
- vipx_err("invalid type(%d)\n", type);
- ret = -EINVAL;
- goto p_err;
- }
- wptr = (void *)&mbox->msg[mbox->wmsg_idx % MAX_MESSAGE_CNT];
-
- mem2iocpy(wptr, payload, size);
-
- /* increment actual write pointer */
- mbox->wmsg_idx++;
-
-#ifdef DBG_INTERFACE_ISR
- vipx_info("[I%d][MBOX][H2F] %d command(type: %d, cid: %d, wmsg_idx: %d, rmsg_idx: %d)\n", gid,
- cmd, type, cid, mbox->wmsg_idx, mbox->rmsg_idx);
-#endif
-
-p_err:
- return ret;
-}
-
-int vipx_mbox_read(struct vipx_mailbox_ctrl *mctrl,
- void *payload, u32 type, void *debug_data)
-{
- int ret = 0;
- struct vipx_mailbox_f2h *mbox;
- u32 *rptr;
-
- BUG_ON(!mctrl);
- BUG_ON(!payload);
-
- if (type == VIPX_MTYPE_H2F_NORMAL) {
- mbox = &mctrl->stack->f2h;
- } else if (type == VIPX_MTYPE_H2F_URGENT) {
- mbox = &mctrl->urgent_stack->f2h;
- } else {
- vipx_err("invalid type(%d)\n", type);
- ret = -EINVAL;
- goto p_err;
- }
- rptr = (void *)&mbox->msg[mbox->rmsg_idx % MAX_MESSAGE_CNT];
-
- io2memcpy(payload, rptr, sizeof(vipx_msg_t));
-
- /* increment actual read pointer */
- mbox->rmsg_idx++;
-
-p_err:
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/random.h>
-#include <linux/slab.h>
-
-#include "vipx-config.h"
-#include "vipx-slab.h"
-
-int vipx_slab_init(struct vipx_slab_allocator *allocator)
-{
- int ret = 0, i;
- char name[100];
- size_t size;
-
- allocator->cache_size[0] = sizeof(vipx_msg_t);
-
- for (i = 0; i < VIPX_SLAB_MAX_LEVEL; ++i) {
- size = allocator->cache_size[i];
- snprintf(name, sizeof(name), "vipx=size-%zd", size);
-
- allocator->cache[i] = kmem_cache_create(name, size,
- ARCH_KMALLOC_MINALIGN, SLAB_POISON | SLAB_PANIC, NULL);
- if (!allocator->cache[i]) {
- probe_err("kmem_cache_create(%zd) is fail\n", size);
- ret = -ENOMEM;
- goto p_err;
- }
- }
-
-p_err:
- return ret;
-}
-
-int vipx_slab_alloc(struct vipx_slab_allocator *allocator, void **target, size_t size)
-{
- int ret = 0, i;
-
- for (i = 0; i < VIPX_SLAB_MAX_LEVEL; ++i) {
- if (size <= allocator->cache_size[i])
- break;
- }
-
- if (i >= VIPX_SLAB_MAX_LEVEL) {
- vipx_err("alloc size is invalid(%zd)\n", size);
- ret= -EINVAL;
- goto p_err;
- }
-
- *target = kmem_cache_alloc(allocator->cache[i], GFP_KERNEL);
- if (!(*target)) {
- vipx_err("kmem_cache_alloc is fail\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_slab_free(struct vipx_slab_allocator *allocator, void *target, size_t size)
-{
- int ret = 0, i;
-
- for (i = 0; i < VIPX_SLAB_MAX_LEVEL; ++i) {
- if (size <= allocator->cache_size[i])
- break;
- }
-
- if (i >= VIPX_SLAB_MAX_LEVEL) {
- vipx_err("alloc size is invalid(%zd)\n", size);
- BUG();
- }
-
- kmem_cache_free(allocator->cache[i], target);
-
- return ret;
-}
+++ /dev/null
-config EXYNOS_VIPX_PLATFORM
- bool "Select Platform"
- help
- This is a selection of platform
-
-config EXYNOS_VIPX_EXYNOS9610
- bool "Use Exynos9610 platform"
- depends on EXYNOS_VIPX_PLATFORM
- help
- This is a exynos9610 platform
+++ /dev/null
-obj-y += vipx-exynos.o
-obj-$(CONFIG_EXYNOS_VIPX_EXYNOS9610) += exynos9610/
-
-EXTRA_CFLAGS += -Idrivers/vision/vipx/include
+++ /dev/null
-obj-y += vipx-exynos9610.o
-
-EXTRA_CFLAGS += -Idrivers/vision/vipx/include
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPX driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include "vipx-config.h"
-#include "vipx-exynos.h"
-#include "vipx-exynos9610.h"
-#include "vipx-debug.h"
-
-#define CLK_INDEX(name) VIPX_##name
-#define REGISTER_CLK(name) [CLK_INDEX(name)] = {#name, NULL}
-
-extern int vipx_clk_set_rate(struct device *dev, u32 index, ulong frequency);
-extern ulong vipx_clk_get_rate(struct device *dev, u32 index);
-extern int vipx_clk_enable(struct device *dev, u32 index);
-extern int vipx_clk_disable(struct device *dev, u32 index);
-
-enum vipx_clk_index {
- CLK_INDEX(UMUX_CLKCMU_VIPX1_BUS),
- CLK_INDEX(GATE_VIPX1_QCH),
- CLK_INDEX(UMUX_CLKCMU_VIPX2_BUS),
- CLK_INDEX(GATE_VIPX2_QCH),
- CLK_INDEX(GATE_VIPX2_QCH_LOCAL)
-};
-
-struct vipx_clk vipx_clk_array[] = {
- REGISTER_CLK(UMUX_CLKCMU_VIPX1_BUS),
- REGISTER_CLK(GATE_VIPX1_QCH),
- REGISTER_CLK(UMUX_CLKCMU_VIPX2_BUS),
- REGISTER_CLK(GATE_VIPX2_QCH),
- REGISTER_CLK(GATE_VIPX2_QCH_LOCAL)
-};
-
-const u32 vipx_clk_array_size = ARRAY_SIZE(vipx_clk_array);
-
-int vipx_exynos_clk_cfg(struct vipx_exynos *exynos)
-{
- return 0;
-}
-
-int vipx_exynos_clk_on(struct vipx_exynos *exynos)
-{
- vipx_clk_enable(exynos->dev, CLK_INDEX(UMUX_CLKCMU_VIPX1_BUS));
- vipx_clk_get_rate(exynos->dev, CLK_INDEX(UMUX_CLKCMU_VIPX1_BUS));
-
- vipx_clk_enable(exynos->dev, CLK_INDEX(GATE_VIPX1_QCH));
- vipx_clk_get_rate(exynos->dev, CLK_INDEX(GATE_VIPX1_QCH));
-
- vipx_clk_enable(exynos->dev, CLK_INDEX(UMUX_CLKCMU_VIPX2_BUS));
- vipx_clk_get_rate(exynos->dev, CLK_INDEX(UMUX_CLKCMU_VIPX2_BUS));
-
- vipx_clk_enable(exynos->dev, CLK_INDEX(GATE_VIPX2_QCH));
- vipx_clk_get_rate(exynos->dev, CLK_INDEX(GATE_VIPX2_QCH));
-
- vipx_clk_enable(exynos->dev, CLK_INDEX(GATE_VIPX2_QCH_LOCAL));
- vipx_clk_get_rate(exynos->dev, CLK_INDEX(GATE_VIPX2_QCH_LOCAL));
-
- vipx_info("[%s]\n", __func__);
- return 0;
-}
-
-int vipx_exynos_clk_off(struct vipx_exynos *exynos)
-{
- vipx_clk_disable(exynos->dev, CLK_INDEX(UMUX_CLKCMU_VIPX1_BUS));
- vipx_clk_disable(exynos->dev, CLK_INDEX(GATE_VIPX1_QCH));
- vipx_clk_disable(exynos->dev, CLK_INDEX(UMUX_CLKCMU_VIPX2_BUS));
- vipx_clk_disable(exynos->dev, CLK_INDEX(GATE_VIPX2_QCH));
- vipx_clk_disable(exynos->dev, CLK_INDEX(GATE_VIPX2_QCH_LOCAL));
-
- vipx_info("[%s]\n", __func__);
- return 0;
-}
-
-int vipx_exynos_clk_dump(struct vipx_exynos *exynos)
-{
- int ret = 0;
-
- return ret;
-}
-
-int dummy_vipx_exynos_clk_cfg(struct vipx_exynos *exynos) { return 0; }
-int dummy_vipx_exynos_clk_on(struct vipx_exynos *exynos) { return 0; }
-int dummy_vipx_exynos_clk_off(struct vipx_exynos *exynos) { return 0; }
-int dummy_vipx_exynos_clk_dump(struct vipx_exynos *exynos) { return 0; }
-
-const struct vipx_clk_ops vipx_clk_ops = {
-#ifdef CONFIG_EXYNOS_VIPX_HARDWARE
- .clk_cfg = vipx_exynos_clk_cfg,
- .clk_on = vipx_exynos_clk_on,
- .clk_off = vipx_exynos_clk_off,
- .clk_dump = vipx_exynos_clk_dump
-#else
- .clk_cfg = dummy_vipx_exynos_clk_cfg,
- .clk_on = dummy_vipx_exynos_clk_on,
- .clk_off = dummy_vipx_exynos_clk_off,
- .clk_dump = dummy_vipx_exynos_clk_dump
-#endif
-};
-
-int vipx_exynos_ctl_reset(struct vipx_exynos *exynos, bool hold)
-{
- u32 val;
-
- vipx_readl(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_GLOBAL_CTRL], &val);
- val = val | 0xF1;
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_GLOBAL_CTRL], val);
- mdelay(1);
-
- vipx_readl(exynos->regbase[VIPX_REG_CPU_SS2], &vipx_regs_cpu_ss2[VIPX_CPU_SS2_GLOBAL_CTRL], &val);
- val = val | 0xF1;
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS2], &vipx_regs_cpu_ss2[VIPX_CPU_SS2_GLOBAL_CTRL], val);
- mdelay(1);
-
- vipx_readl(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_CPU_CTRL], &val);
- val = val | 0x1;
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_CPU_CTRL], val);
- mdelay(1);
-
- vipx_readl(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_CORTEX_CONTROL], &val);
- val = val | 0x1;
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_CORTEX_CONTROL], val);
- mdelay(1);
-
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_CPU_CTRL], 0x0);
- mdelay(1);
-
- /* QACTIVE */
- vipx_readl(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_QCHANNEL], &val);
- val = val | 0x1;
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_QCHANNEL], val);
- mdelay(1);
-
- vipx_readl(exynos->regbase[VIPX_REG_CPU_SS2], &vipx_regs_cpu_ss2[VIPX_CPU_SS2_QCHANNEL], &val);
- val = val | 0x1;
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS2], &vipx_regs_cpu_ss2[VIPX_CPU_SS2_QCHANNEL], val);
- mdelay(1);
-
- vipx_info("hold(%d)\n", hold);
- return 0;
-}
-
-int vipx_exynos_ctl_dump(struct vipx_exynos *exynos, u32 instance)
-{
-
- vipx_info("instance(%d)\n", instance);
- return 0;
-}
-
-void *vipx_exynos_ctl_remap(struct vipx_exynos *exynos, u32 instance)
-{
- BUG_ON(!exynos);
- BUG_ON(instance >= VIPX_REG_MAX_CNT);
-
- vipx_info("instance(%d)\n", instance);
- return exynos->regbase[instance];
-}
-
-int vipx_exynos_ctl_unmap(struct vipx_exynos *exynos, u32 instance, void *base)
-{
- BUG_ON(!exynos);
- BUG_ON(!base);
- BUG_ON(instance >= VIPX_REG_MAX_CNT);
-
- vipx_info("instance(%d)\n", instance);
- return 0;
-}
-
-int vipx_exynos_ctl_trigger(struct vipx_exynos *exynos, u32 chain_id)
-{
-
- vipx_info("chain_id(%d)\n", chain_id);
- return 0;
-}
-
-int vipx_exynos_ctl_start(struct vipx_exynos *exynos, u32 chain_id)
-{
- vipx_writel(exynos->regbase[VIPX_REG_CPU_SS1], &vipx_regs_cpu_ss1[VIPX_CPU_SS1_CORTEX_CONTROL], 0x0);
-
- vipx_info("chain_id(%d) %x %x\n", chain_id,exynos->regbase[VIPX_REG_CPU_SS1],exynos->regbase[VIPX_REG_CPU_SS2]);
- return 0;
-}
-
-int dummy_vipx_exynos_ctl_reset(struct vipx_exynos *exynos, bool hold) { return 0; }
-int dummy_vipx_exynos_ctl_dump(struct vipx_exynos *exynos, u32 instance) { return 0; }
-void *dummy_vipx_exynos_ctl_remap(struct vipx_exynos *exynos, u32 instance) { return NULL; }
-int dummy_vipx_exynos_ctl_unmap(struct vipx_exynos *exynos, u32 instance, void *base) { return 0; }
-int dummy_vipx_exynos_ctl_trigger(struct vipx_exynos *exynos, u32 chain_id) { return 0; }
-int dummy_vipx_exynos_ctl_start(struct vipx_exynos *exynos, u32 chain_id) { return 0; }
-
-const struct vipx_ctl_ops vipx_ctl_ops = {
-#ifdef CONFIG_EXYNOS_VIPX_HARDWARE
- .ctl_reset = vipx_exynos_ctl_reset,
- .ctl_dump = vipx_exynos_ctl_dump,
- .ctl_remap = vipx_exynos_ctl_remap,
- .ctl_unmap = vipx_exynos_ctl_unmap,
- .ctl_trigger = vipx_exynos_ctl_trigger,
- .ctl_start = vipx_exynos_ctl_start,
-#else
- .ctl_reset = dummy_vipx_exynos_ctl_reset,
- .ctl_dump = dummy_vipx_exynos_ctl_dump,
- .ctl_remap = dummy_vipx_exynos_ctl_remap,
- .ctl_unmap = dummy_vipx_exynos_ctl_unmap,
- .ctl_trigger = dummy_vipx_exynos_ctl_trigger,
- .ctl_start = dummy_vipx_exynos_ctl_start,
-#endif
-};
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPX driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_EXYNOS9610_H_
-#define VIPX_EXYNOS9610_H_
-
-enum vipx_reg_cpu_ss1_name {
- VIPX_CPU_SS1_VERSION_ID,
- VIPX_CPU_SS1_QCHANNEL,
- VIPX_CPU_SS1_IRQ_VIP_TO_HOST,
- VIPX_CPU_SS1_IRQ0_HOST_TO_VIP,
- VIPX_CPU_SS1_IRQ1_HOST_TO_VIP,
- VIPX_CPU_SS1_GLOBAL_CTRL,
- VIPX_CPU_SS1_CORTEX_CONTROL,
- VIPX_CPU_SS1_CPU_CTRL,
-};
-
-enum vipx_reg_cpu_ss2_name {
- VIPX_CPU_SS2_QCHANNEL,
- VIPX_CPU_SS2_GLOBAL_CTRL,
-};
-
-struct vipx_reg vipx_regs_cpu_ss1[] = {
- {0x00000, "VERSION_ID"},
- {0x00004, "SS1_QCHANNEL"},
- {0x00008, "SS1_IRQ_VIP_TO_HOST"},
- {0x0000C, "SS1_IRQ0_HOST_TO_VIP"},
- {0x00010, "SS1_IRQ1_HOST_TO_VIP"},
- {0x00014, "SS1_GLOBAL_CTRL"},
- {0x00018, "SS1_CORTEX_CONTROL"},
- {0x0001C, "SS1_CPU_CTRL"},
-};
-
-struct vipx_reg vipx_regs_cpu_ss2[] = {
- {0x00000, "SS2_QCHANNEL"},
- {0x00004, "SS2_GLOBAL_CTRL"},
-};
-
-#endif
+++ /dev/null
-#include <linux/io.h>
-#include <linux/pinctrl/consumer.h>
-
-#include "vipx-config.h"
-#include "vipx-exynos.h"
-
-extern struct vipx_clk vipx_clk_array[];
-extern const u32 vipx_clk_array_size;
-extern const struct vipx_clk_ops vipx_clk_ops;
-extern const struct vipx_ctl_ops vipx_ctl_ops;
-
-int vipx_clk_set_rate(struct device *dev, u32 index, ulong frequency)
-{
- int ret = 0;
- struct clk *clk;
-
- if (index >= vipx_clk_array_size) {
- vipx_err("index is invalid(%d >= %d)\n", index, vipx_clk_array_size);
- ret = -EINVAL;
- goto p_err;
- }
-
- clk= vipx_clk_array[index].clk;
- if (IS_ERR_OR_NULL(clk)) {
- vipx_err("clk is NULL(%d)\n", index);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = clk_set_rate(clk, frequency);
- if (ret) {
- vipx_err("clk_set_rate is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-ulong vipx_clk_get_rate(struct device *dev, u32 index)
-{
- ulong frequency;
- struct clk *clk;
-
- if (index >= vipx_clk_array_size) {
- vipx_err("index is invalid(%d >= %d)\n", index, vipx_clk_array_size);
- frequency = -EINVAL;
- goto p_err;
- }
-
- clk = vipx_clk_array[index].clk;
- if (IS_ERR_OR_NULL(clk)) {
- vipx_err("clk is NULL(%d)\n", index);
- frequency = -EINVAL;
- goto p_err;
- }
-
- frequency = clk_get_rate(clk);
-
-p_err:
- vipx_info("%s : %ldMhz\n", vipx_clk_array[index].name, frequency/1000000);
- return frequency;
-}
-
-int vipx_clk_enable(struct device *dev, u32 index)
-{
- int ret = 0;
- struct clk *clk;
-
- if (index >= vipx_clk_array_size) {
- vipx_err("index is invalid(%d >= %d)\n", index, vipx_clk_array_size);
- ret = -EINVAL;
- goto p_err;
- }
-
- clk = vipx_clk_array[index].clk;
- if (IS_ERR_OR_NULL(clk)) {
- vipx_err("clk is NULL(%d)\n", index);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = clk_prepare_enable(clk);
- if (ret) {
- vipx_err("clk_prepare_enable is fail(%s)\n", vipx_clk_array[index].name);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_clk_disable(struct device *dev, u32 index)
-{
- int ret = 0;
- struct clk *clk;
-
- if (index >= vipx_clk_array_size) {
- vipx_err("index is invalid(%d >= %d)\n", index, vipx_clk_array_size);
- ret = -EINVAL;
- goto p_err;
- }
-
- clk = vipx_clk_array[index].clk;
- if (IS_ERR_OR_NULL(clk)) {
- vipx_err("clk is NULL(%d)\n", index);
- ret = -EINVAL;
- goto p_err;
- }
-
- clk_disable_unprepare(clk);
-
-p_err:
- return ret;
-}
-
-static int vipx_exynos_clk_init(struct device *dev)
-{
- int ret = 0;
- const char *name;
- struct clk *clk;
- u32 index;
-
- for (index = 0; index < vipx_clk_array_size; ++index) {
- name = vipx_clk_array[index].name;
- if (!name) {
- probe_err("name is NULL\n");
- ret = -EINVAL;
- break;
- }
-
- clk = clk_get(dev, name);
- if (IS_ERR_OR_NULL(clk)) {
- probe_err("%s clk is not found\n", name);
- ret = -EINVAL;
- break;
- }
-
- vipx_clk_array[index].clk = clk;
- }
-
- return ret;
-}
-
-int vipx_exynos_probe(struct vipx_exynos *exynos, struct device *dev,
- void **regs, void *ram0, void *ram1)
-{
- int ret = 0;
-
- BUG_ON(!exynos);
- BUG_ON(!dev);
-
- exynos->regbase = regs;
- exynos->ram0base = ram0;
- exynos->ram1base = ram1;
- exynos->clk_ops = &vipx_clk_ops;
- exynos->ctl_ops = &vipx_ctl_ops;
- exynos->pinctrl = devm_pinctrl_get(dev);
- if (IS_ERR_OR_NULL(exynos->pinctrl)) {
- probe_err("devm_pinctrl_get is fail");
- ret = PTR_ERR(exynos->pinctrl);
- goto p_err;
- }
-
- ret = vipx_exynos_clk_init(dev);
- if (ret) {
- probe_err("vipx_exynos_clk_init is fail(%d)", ret);
- goto p_err;
- }
-
-p_err:
- probe_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-void vipx_readl(void __iomem *base_addr, struct vipx_reg *reg, u32 *val)
-{
- *val = readl(base_addr + reg->offset);
-
-#ifdef DBG_HW_SFR
- vipx_info("[REG][%s][0x%04X], val(R):[0x%08X]\n", reg->name, reg->offset, *val);
-#endif
-}
-
-void vipx_writel(void __iomem *base_addr, struct vipx_reg *reg, u32 val)
-{
-#ifdef DBG_HW_SFR
- vipx_info("[REG][%s][0x%04X], val(W):[0x%08X]\n", reg->name, reg->offset, val);
-#endif
-
- writel(val, base_addr + reg->offset);
-}
-
-void vipx_readf(void __iomem *base_addr, struct vipx_reg *reg, struct vipx_field *field, u32 *val)
-{
- *val = (readl(base_addr + reg->offset) >> (field->bit_start)) & ((1 << (field->bit_width)) - 1);
-
-#ifdef DBG_HW_SFR
- vipx_info("[REG][%s][%s][0x%04X], val(R):[0x%08X]\n", reg->name, field->name, reg->offset, *val);
-#endif
-}
-
-void vipx_writef(void __iomem *base_addr, struct vipx_reg *reg, struct vipx_field *field, u32 val)
-{
- u32 mask, temp;
-
- mask = ((1 << field->bit_width) - 1);
- temp = readl(base_addr + reg->offset) & ~(mask << field->bit_start);
- temp |= (val & mask) << (field->bit_start);
-
-#ifdef DBG_HW_SFR
- vipx_info("[REG][%s][%s][0x%04X], val(W):[0x%08X]\n", reg->name, field->name, reg->offset, val);
-#endif
-
- writel(temp, base_addr + reg->offset);
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/syscalls.h>
-#include <linux/vmalloc.h>
-
-#include "vipx-config.h"
-#include "vipx-binary.h"
-#include "vipx-memory.h"
-
-static noinline_for_stack long __get_file_size(struct file *file)
-{
- struct kstat st;
- u32 request_mask = (STATX_MODE | STATX_SIZE);
-
- if (vfs_getattr(&file->f_path, &st, request_mask, KSTAT_QUERY_FLAGS))
- return -1;
- if (!S_ISREG(st.mode))
- return -1;
- if (st.size != (long)st.size)
- return -1;
-
- return st.size;
-}
-
-int vipx_binary_init(struct vipx_binary *binary, struct device *dev)
-{
- int ret = 0;
-
- BUG_ON(!binary);
- BUG_ON(!dev);
-
- binary->dev = dev;
-
- return ret;
-}
-
-int vipx_binary_read(struct vipx_binary *binary,
- char *path,
- char *name,
- void *target,
- size_t target_size)
-{
- int ret = 0;
- loff_t pos = 0;
- const struct firmware *fw_blob;
- u8 *buf = NULL;
- struct file *fp;
- mm_segment_t old_fs;
- long fsize, nread;
- char fname[VIPX_FW_NAME_LEN];
-
- BUG_ON(!binary);
-
- 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_OR_NULL(fp)) {
- set_fs(old_fs);
- goto request_fw;
- }
-
- fsize = __get_file_size(fp);
- if (fsize <= 0) {
- vipx_err("__get_file_size is fail(%ld)\n", fsize);
- ret = -EBADF;
- goto p_err;
- }
-
- buf = vmalloc(fsize);
- if (!buf) {
- vipx_err("vmalloc is fail\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- nread = kernel_read(fp, buf, fsize, &pos);
- if (nread != fsize) {
- vipx_err("kernel_read is fail(%ld != %ld)\n", nread, fsize);
- ret = -EIO;
- goto p_err;
- }
-
- if (fsize > target_size) {
- vipx_err("image size is over(%ld > %ld)\n", fsize, target_size);
- ret = -EIO;
- goto p_err;
- }
-
- /* no cache operation, because target is sram of vipx */
-#ifdef CONFIG_EXYNOS_VIPX_HARDWARE
- memcpy(target, (void *)buf, fsize);
-#endif
- vipx_info("FW(%s, %ld) were applied successfully.\n", fname, fsize);
-
-p_err:
- if (buf)
- vfree(buf);
-
- filp_close(fp, current->files);
- set_fs(old_fs);
-
- return ret;
-
-request_fw:
- ret = request_firmware(&fw_blob, name, binary->dev);
- if (ret) {
- vipx_err("request_firmware(%s) is fail(%d)", name, ret);
- ret = -EINVAL;
- goto request_err;
- }
-
- if (!fw_blob) {
- vipx_err("fw_blob is NULL\n");
- ret = -EINVAL;
- goto request_err;
- }
-
- if (!fw_blob->data) {
- vipx_err("fw_blob->data is NULL\n");
- ret = -EINVAL;
- goto request_err;
- }
-
- if (fw_blob->size > target_size) {
- vipx_err("image size is over(%ld > %ld)\n", fw_blob->size, target_size);
- ret = -EIO;
- goto request_err;
- }
-
-#ifdef CONFIG_EXYNOS_VIPX_HARDWARE
- memcpy(target, fw_blob->data, fw_blob->size);
-#endif
- vipx_info("Binay(%s, %ld) were applied successfully.\n", name, fw_blob->size);
-
-request_err:
- release_firmware(fw_blob);
- return ret;
-}
-
-int vipx_binary_write(struct vipx_binary *binary,
- char *path,
- char *name,
- void *target,
- size_t target_size)
-{
- int ret = 0;
- struct file *fp;
- mm_segment_t old_fs;
- long nwrite;
- loff_t pos = 0;
- char fname[VIPX_FW_NAME_LEN];
-
- BUG_ON(!binary);
-
- 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_OR_NULL(fp)) {
- set_fs(old_fs);
- vipx_err("filp_open is fail(%p)\n", fp);
- ret = -EBADF;
- goto p_err;
- }
-
- vipx_info("debug kva(0x%p), size(%ld)\n", target, target_size);
-
-
- nwrite = kernel_write(fp, target, target_size, &pos);
- if (nwrite != target_size) {
- filp_close(fp, current->files);
- set_fs(old_fs);
- vipx_err("kernel_write is fail(%ld != %ld)\n", nwrite, target_size);
- ret = -EIO;
- goto p_err;
- }
-
- vipx_info("Binay(%s, %ld) were applied successfully.\n", fname, target_size);
-
- filp_close(fp, current->files);
- set_fs(old_fs);
-
-p_err:
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-#include <media/videobuf2-dma-sg.h>
-#include <linux/dma-buf.h>
-#include <linux/ion_exynos.h>
-
-#include "vipx-config.h"
-#include "vipx-debug.h"
-#include "vipx-graphmgr.h"
-#include "vipx-graph.h"
-#include "vipx-system.h"
-
-#define DEBUG_FS_ROOT_NAME "vipx"
-#define DEBUG_FS_LOGFILE_NAME "fw-msg"
-#define DEBUG_FS_IMGFILE_NAME "dump-img"
-#define DEBUG_FS_GRPFILE_NAME "graph"
-#define DEBUG_FS_BUFFILE_NAME "buffer"
-
-#define CHUNKSZ 32
-
-s32 atoi(const char *psz_buf)
-{
- const char *pch = psz_buf;
- s32 base = 0;
-
- while (isspace(*pch))
- pch++;
-
- if (*pch == '-' || *pch == '+') {
- base = 10;
- pch++;
- } else if (*pch && tolower(pch[strlen(pch) - 1]) == 'h') {
- base = 16;
- }
-
- return simple_strtoul(pch, NULL, base);
-}
-
-int bitmap_scnprintf(char *buf, unsigned int buflen,
- const unsigned long *maskp, int nmaskbits)
-{
- int i, word, bit, len = 0;
- unsigned long val;
- const char *sep = "";
- int chunksz;
- u32 chunkmask;
-
- chunksz = nmaskbits & (CHUNKSZ - 1);
- if (chunksz == 0)
- chunksz = CHUNKSZ;
-
- i = ALIGN(nmaskbits, CHUNKSZ) - CHUNKSZ;
- for (; i >= 0; i -= CHUNKSZ) {
- chunkmask = ((1ULL << chunksz) - 1);
- word = i / BITS_PER_LONG;
- bit = i % BITS_PER_LONG;
- val = (maskp[word] >> bit) & chunkmask;
- len += scnprintf(buf+len, buflen-len, "%s%0*lx", sep,
- (chunksz+3)/4, val);
- chunksz = CHUNKSZ;
- sep = ",";
- }
- return len;
-}
-
-void vipx_dmsg_concate(struct vipx_debug_log *log, const char *fmt, ...)
-{
- va_list ap;
- char term[50];
- u32 copy_len;
-
- va_start(ap, fmt);
- vsnprintf(term, sizeof(term), fmt, ap);
- va_end(ap);
-
- if (log->dsentence_pos >= DEBUG_SENTENCE_MAX) {
- vipx_err("debug message(%zd) over max\n", log->dsentence_pos);
- return;
- }
-
- copy_len = min((DEBUG_SENTENCE_MAX - log->dsentence_pos - 1), strlen(term));
- strncpy(log->dsentence + log->dsentence_pos, term, copy_len);
- log->dsentence_pos += copy_len;
- log->dsentence[log->dsentence_pos] = 0;
-}
-
-char * vipx_dmsg_print(struct vipx_debug_log *log)
-{
- log->dsentence_pos = 0;
- return log->dsentence;
-}
-
-int vipx_debug_memdump8(u8 *start, u8 *end)
-{
- int ret = 0;
- u8 *cur;
- u32 items, offset;
- char term[50], sentence[250];
-
- cur = start;
- items = 0;
- offset = 0;
-
- memset(sentence, 0, sizeof(sentence));
- snprintf(sentence, sizeof(sentence), "[V] Memory Dump8(%p ~ %p)", start, end);
-
- while (cur < end) {
- if ((items % 16) == 0) {
-#ifdef DEBUG_LOG_MEMORY
- printk(KERN_DEBUG "%s\n", sentence);
-#else
- printk(KERN_INFO "%s\n", sentence);
-#endif
- offset = 0;
- snprintf(term, sizeof(term), "[V] %p: ", cur);
- snprintf(&sentence[offset], sizeof(sentence) - offset, "%s", term);
- offset += strlen(term);
- items = 0;
- }
-
- snprintf(term, sizeof(term), "%02X ", *cur);
- snprintf(&sentence[offset], sizeof(sentence) - offset, "%s", term);
- offset += strlen(term);
- cur++;
- items++;
- }
-
- if (items) {
-#ifdef DEBUG_LOG_MEMORY
- printk(KERN_DEBUG "%s\n", sentence);
-#else
- printk(KERN_INFO "%s\n", sentence);
-#endif
- }
-
- ret = cur - end;
-
- return ret;
-}
-
-
-int vipx_debug_memdump16(u16 *start, u16 *end)
-{
- int ret = 0;
- u16 *cur;
- u32 items, offset;
- char term[50], sentence[250];
-
- cur = start;
- items = 0;
- offset = 0;
-
- memset(sentence, 0, sizeof(sentence));
- snprintf(sentence, sizeof(sentence), "[V] Memory Dump16(%p ~ %p)", start, end);
-
- while (cur < end) {
- if ((items % 16) == 0) {
-#ifdef DEBUG_LOG_MEMORY
- printk(KERN_DEBUG "%s\n", sentence);
-#else
- printk(KERN_INFO "%s\n", sentence);
-#endif
- offset = 0;
- snprintf(term, sizeof(term), "[V] %p: ", cur);
- snprintf(&sentence[offset], sizeof(sentence) - offset, "%s", term);
- offset += strlen(term);
- items = 0;
- }
-
- snprintf(term, sizeof(term), "0x%04X ", *cur);
- snprintf(&sentence[offset], sizeof(sentence) - offset, "%s", term);
- offset += strlen(term);
- cur++;
- items++;
- }
-
- if (items) {
-#ifdef DEBUG_LOG_MEMORY
- printk(KERN_DEBUG "%s\n", sentence);
-#else
- printk(KERN_INFO "%s\n", sentence);
-#endif
- }
-
- ret = cur - end;
-
- return ret;
-}
-
-int vipx_debug_memdump32(u32 *start, u32 *end)
-{
- int ret = 0;
- u32 *cur;
- u32 items, offset;
- char term[50], sentence[250];
-
- cur = start;
- items = 0;
- offset = 0;
-
- memset(sentence, 0, sizeof(sentence));
- snprintf(sentence, sizeof(sentence), "[V] Memory Dump32(%p ~ %p)", start, end);
-
- while (cur < end) {
- if ((items % 8) == 0) {
-#ifdef DEBUG_LOG_MEMORY
- printk(KERN_DEBUG "%s\n", sentence);
-#else
- printk(KERN_INFO "%s\n", sentence);
-#endif
- offset = 0;
- snprintf(term, sizeof(term), "[V] %p: ", cur);
- snprintf(&sentence[offset], sizeof(sentence) - offset, "%s", term);
- offset += strlen(term);
- items = 0;
- }
-
- snprintf(term, sizeof(term), "0x%08X ", *cur);
- snprintf(&sentence[offset], sizeof(sentence) - offset, "%s", term);
- offset += strlen(term);
- cur++;
- items++;
- }
-
- if (items) {
-#ifdef DEBUG_LOG_MEMORY
- printk(KERN_DEBUG "%s\n", sentence);
-#else
- printk(KERN_INFO "%s\n", sentence);
-#endif
- }
-
- ret = cur - end;
-
- return ret;
-}
-
-static int vipx_debug_log_open(struct inode *inode, struct file *file)
-{
- if (inode->i_private)
- file->private_data = inode->i_private;
-
- return 0;
-}
-
-static ssize_t vipx_debug_log_read(struct file *file, char __user *user_buf,
- size_t buf_len, loff_t *ppos)
-{
- int ret = 0;
- int size = 0;
-
- struct vipx_debug *debug;
- struct vipx_system *system;
-
- debug = file->private_data;
- if (debug == NULL) {
- vipx_err("Cannot find private data\n");
- return 0;
- }
-
- system = debug->system_data;
- if (system == NULL) {
- vipx_err("Cannot find system data\n");
- return 0;
- }
-
- if (buf_len > VIPX_DEBUG_SIZE)
- size = VIPX_DEBUG_SIZE;
- else
- size = buf_len;
-
- if (system->memory.info.kvaddr_debug == 0) {
- vipx_err("Cannot find debug region\n");
- return 0;
- }
-
- ret = copy_to_user(user_buf, system->memory.info.kvaddr_debug, size);
- if (ret) {
- vipx_err("copy_from_user is fail(%d)\n", ret);
- memcpy(user_buf, system->memory.info.kvaddr_debug, size);
- ret = 0;
- // return 0;
- }
-
- return size;
-}
-
-static int vipx_debug_img_open(struct inode *inode, struct file *file)
-{
- if (inode->i_private)
- file->private_data = inode->i_private;
-
- return 0;
-}
-
-static ssize_t vipx_debug_img_read(struct file *file, char __user *user_buf,
- size_t len, loff_t *ppos)
-{
- size_t size = 0;
- struct vipx_debug *debug;
- struct vipx_debug_imgdump *imgdump;
- int ret = 0;
-
- debug = file->private_data;
- imgdump = &debug->imgdump;
-
- if (!imgdump->kvaddr) {
- vipx_err("kvaddr is NULL\n");
- return 0;
- }
-
- if (!imgdump->cookie) {
- vipx_err("cookie is NULL\n");
- return 0;
- }
-
- if (len <= imgdump->length)
- size = len;
- else
- size = imgdump->length;
-
- if (!size) {
- imgdump->cookie = NULL;
- imgdump->kvaddr = NULL;
- imgdump->length = 0;
- imgdump->offset = 0;
- goto p_err;
- }
-
- /* HACK for test */
- memset(imgdump->kvaddr, 0x88, size / 2);
- //vb2_ion_sync_for_device(imgdump->cookie, imgdump->offset, size, DMA_FROM_DEVICE);
- ret = copy_to_user(user_buf, imgdump->kvaddr, size);
- if (ret) {
- vipx_err("copy_from_user is fail(%d)\n", ret);
- memcpy(user_buf, imgdump->kvaddr, size);
- ret = 0;
- // return 0;
-
- }
-
- vipx_info("DUMP : %p, SIZE : %zd\n", imgdump->kvaddr, size);
-
- imgdump->offset += size;
- imgdump->length -= size;
- imgdump->kvaddr = (char *)imgdump->kvaddr + size;
-
-p_err:
- return size;
-}
-
-static ssize_t vipx_debug_img_write(struct file *file, const char __user *user_buf,
- size_t len, loff_t *ppos)
-{
- return len;
-}
-
-static int vipx_debug_grp_show(struct seq_file *s, void *unused)
-{
- u32 i;
- struct vipx_debug *debug = s->private;
- struct vipx_graphmgr *graphmgr = debug->graphmgr_data;
- struct vipx_graph *graph;
-
- seq_printf(s, "------------------------------------------"
- "----------------------------------------"
- "--------------------------------------\n");
- seq_printf(s, "%7.s %7.s %7.s %7.s %7.s %7.s %7.s\n",
- "graph", "prio", "period", "input", "done", "cancel", "recent");
- seq_printf(s, "------------------------------------------"
- "----------------------------------------"
- "--------------------------------------\n");
-
- mutex_lock(&graphmgr->mlock);
- for (i = 0; i < VIPX_MAX_GRAPH; ++i) {
- graph = graphmgr->graph[i];
-
- if (!graph)
- continue;
-
- seq_printf(s, "%2d(%3d) %7d %7d %7d %7d %7d\n",
- graph->idx, graph->uid, graph->priority,
- graph->input_cnt, graph->done_cnt, graph->cancel_cnt, graph->recent);
- }
- mutex_unlock(&graphmgr->mlock);
-
- seq_printf(s, "------------------------------------------"
- "----------------------------------------"
- "--------------------------------------\n");
- return 0;
-}
-
-static int vipx_debug_grp_open(struct inode *inode, struct file *file)
-{
- return single_open(file, vipx_debug_grp_show, inode->i_private);
-}
-
-static int vipx_debug_buf_show(struct seq_file *s, void *unused)
-{
- return 0;
-}
-
-static int vipx_debug_buf_open(struct inode *inode, struct file *file)
-{
- return single_open(file, vipx_debug_buf_show, inode->i_private);
-}
-
-static const struct file_operations vipx_debug_log_fops = {
- .open = vipx_debug_log_open,
- .read = vipx_debug_log_read,
- .llseek = default_llseek
-};
-
-static const struct file_operations vipx_debug_img_fops = {
- .open = vipx_debug_img_open,
- .read = vipx_debug_img_read,
- .write = vipx_debug_img_write,
- .llseek = default_llseek
-};
-
-static const struct file_operations vipx_debug_grp_fops = {
- .open = vipx_debug_grp_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release
-};
-
-static const struct file_operations vipx_debug_buf_fops = {
- .open = vipx_debug_buf_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release
-};
-
-static void vipx_debug_monitor_fn(unsigned long data)
-{
- struct vipx_debug_monitor *monitor = (struct vipx_debug_monitor *)data;
- struct vipx_debug *debug = container_of(monitor, struct vipx_debug, monitor);
- struct vipx_graphmgr *graphmgr = debug->graphmgr_data;
- struct vipx_system *system = debug->system_data;
- struct vipx_interface *interface = &system->interface;
-
- if (!test_bit(VIPX_DEBUG_STATE_START, &debug->state))
- return;
-
- if (monitor->tick_cnt == graphmgr->tick_cnt)
- vipx_err("timer thread is stuck(%d, %d)\n", monitor->tick_cnt, graphmgr->tick_pos);
-
- if (monitor->sched_cnt == graphmgr->sched_cnt) {
- struct vipx_graph *graph;
- u32 i;
-
- vipx_info("GRAPH--------------------------------------------------------------\n");
- for (i = 0; i < VIPX_MAX_GRAPH; i++) {
- graph = graphmgr->graph[i];
- if (!graph)
- continue;
-
- vipx_graph_print(graph);
- }
-
- vipx_info("GRAPH-MGR----------------------------------------------------------\n");
- vipx_taskdesc_print(graphmgr);
-
- vipx_info("INTERFACE-MGR------------------------------------------------------\n");
- vipx_interface_print(interface);
-
- vipx_info("-------------------------------------------------------------------\n");
- vipx_err("graph thread is stuck(%d, %d)\n", monitor->sched_cnt, graphmgr->sched_pos);
- }
-
- monitor->tick_cnt = graphmgr->tick_cnt;
- monitor->sched_cnt = graphmgr->sched_cnt;
- monitor->done_cnt = interface->done_cnt;
- vipx_info("TIME %d(%d, %d, %d)\n", monitor->time_cnt, monitor->sched_cnt, monitor->tick_cnt, monitor->done_cnt);
-
- monitor->time_cnt++;
- mod_timer(&monitor->timer, jiffies + DEBUG_MONITORING_PERIOD);
-}
-
-int __vipx_debug_stop(struct vipx_debug *debug)
-{
- int ret = 0;
- struct vipx_debug_monitor *monitor = &debug->monitor;
-
- if (!test_bit(VIPX_DEBUG_STATE_START, &debug->state))
- goto p_err;
-
- del_timer(&monitor->timer);
- clear_bit(VIPX_DEBUG_STATE_START, &debug->state);
-
-p_err:
- return ret;
-}
-
-int vipx_debug_probe(struct vipx_debug *debug, void *graphmgr_data, void *system_data)
-{
- debug->graphmgr_data = graphmgr_data;
- debug->system_data = system_data;
-
- debug->root = debugfs_create_dir(DEBUG_FS_ROOT_NAME, NULL);
- if (debug->root)
- probe_info("%s is created\n", DEBUG_FS_ROOT_NAME);
-
- debug->logfile = debugfs_create_file(DEBUG_FS_LOGFILE_NAME, S_IRUSR,
- debug->root, debug, &vipx_debug_log_fops);
- if (debug->logfile)
- probe_info("%s is created\n", DEBUG_FS_LOGFILE_NAME);
-
- debug->imgdump.file = debugfs_create_file(DEBUG_FS_IMGFILE_NAME, S_IRUSR,
- debug->root, debug, &vipx_debug_img_fops);
- if (debug->imgdump.file)
- probe_info("%s is created\n", DEBUG_FS_IMGFILE_NAME);
-
- debug->grpfile = debugfs_create_file(DEBUG_FS_GRPFILE_NAME, S_IRUSR,
- debug->root, debug, &vipx_debug_grp_fops);
- if (debug->grpfile)
- probe_info("%s is created\n", DEBUG_FS_GRPFILE_NAME);
-
- debug->grpfile = debugfs_create_file(DEBUG_FS_BUFFILE_NAME, S_IRUSR,
- debug->root, debug, &vipx_debug_buf_fops);
- if (debug->buffile)
- probe_info("%s is created\n", DEBUG_FS_BUFFILE_NAME);
-
- clear_bit(VIPX_DEBUG_STATE_START, &debug->state);
-
- return 0;
-}
-
-int vipx_debug_open(struct vipx_debug *debug)
-{
- return 0;
-}
-
-int vipx_debug_close(struct vipx_debug *debug)
-{
- int ret = 0;
-
- ret = __vipx_debug_stop(debug);
- if (ret)
- vipx_err("__vipx_debug_stop is fail(%d)\n", ret);
-
- return ret;
-}
-
-int vipx_debug_start(struct vipx_debug *debug)
-{
- int ret = 0;
- struct vipx_debug_monitor *monitor = &debug->monitor;
- struct vipx_graphmgr *graphmgr = debug->graphmgr_data;
- struct vipx_system *system = debug->system_data;
- struct vipx_interface *interface = &system->interface;
-
- monitor->tick_cnt = graphmgr->tick_cnt;
- monitor->sched_cnt = graphmgr->sched_cnt;
- monitor->done_cnt = interface->done_cnt;
- monitor->time_cnt = 0;
-
- set_bit(VIPX_DEBUG_STATE_START, &debug->state);
-
- init_timer(&monitor->timer);
- monitor->timer.expires = jiffies + DEBUG_MONITORING_PERIOD;
- monitor->timer.data = (unsigned long)monitor;
- monitor->timer.function = vipx_debug_monitor_fn;
- add_timer(&monitor->timer);
-
- return ret;
-}
-
-int vipx_debug_stop(struct vipx_debug *debug)
-{
- int ret = 0;
-
- ret = __vipx_debug_stop(debug);
- if (ret)
- vipx_err("__vipx_debug_stop is fail(%d)\n", ret);
-
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-#include <linux/exynos_iovmm.h>
-#include <linux/pm_runtime.h>
-#include <linux/memblock.h>
-#include <linux/of_reserved_mem.h>
-
-#include "vipx-config.h"
-#include "vipx-device.h"
-#include "vipx-graph.h"
-#include "vipx-vertex.h"
-#include "vipx-graphmgr.h"
-
-static struct reserved_mem *vipx_fw_code_rmem;
-void *vipx_fw_code_rmem_base;
-
-static int vipx_device_runtime_suspend(struct device *dev);
-static int vipx_device_runtime_resume(struct device *dev);
-
-static int __init vipx_fw_code_rmem_setup(struct reserved_mem *rmem)
-{
- pr_info("%s: base=%pa, size=%pa\n", __func__, &rmem->base, &rmem->size);
-
- vipx_fw_code_rmem = rmem;
-
- return 0;
-}
-
-RESERVEDMEM_OF_DECLARE(vipx_fw_code_rmem, "exynos,vipx_fw_code_rmem", vipx_fw_code_rmem_setup);
-
-void __vipx_fault_handler(struct vipx_device *device) {
-#if 0
- struct vipx_system *system;
- struct vipx_memory *memory;
- struct vipx_graphmgr *graphmgr;
- struct vipx_graph *graph;
- struct vipxo_pu *pu, *temp;
- struct vb_container *container;
- struct vb_buffer *buffer;
- u32 i, j, k;
-
- system = &device->system;
- memory = &system->memory;
- graphmgr = &device->graphmgr;
-
- /* 1. Internal Memory Infomation */
- vipx_info("internal memory : 0x%llX\n", memory->info.dvaddr);
-
- /* 2. Buffer Memroy Information */
- for (i = 0; i < VIPX_MAX_GRAPH; ++i) {
- graph = graphmgr->graph[i];
- if (!graph)
- continue;
-
- vipx_info("=================================================\n");
- vipx_info("GRAPH : %d(%d)\n", graph->id, graph->uid);
- vipx_info("INPUT--------------------------------------------\n");
- list_for_each_entry_safe(pu, temp, &graph->inleaf_list, gleaf_entry) {
- vipx_info("PU : %d\n", pu->id);
- vipx_info("-------------------------------------------------\n");
- for (j = 0; j < VIPX_MAX_BUFFER; ++j) {
- container = pu->container[j];
- if (!container)
- continue;
-
- if (j == 0) {
- vipx_info("TYPE : %d\n", container->type);
- vipx_info("RESOLUTION : %d x %d\n", container->format->width, container->format->height);
- vipx_info("SIZE : %d\n", container->format->size[container->format->plane]);
- vipx_info("-------------------------------------------------\n");
- }
-
- for (k = 0; k < container->count; ++k) {
- buffer = &container->buffers[k];
- vipx_info("[%d][%d]DVADDR : %llx\n", j, k, buffer->dvaddr);
- vipx_info("[%d][%d]KVADDR : %p\n", j, k, buffer->kvaddr);
- }
-
- vipx_info("-------------------------------------------------\n");
- }
- }
-
- vipx_info("OUTPUT-------------------------------------------\n");
- list_for_each_entry_safe(pu, temp, &graph->otleaf_list, gleaf_entry) {
- vipx_info("PU : %d\n", pu->id);
- vipx_info("-------------------------------------------------\n");
- for (j = 0; j < VIPX_MAX_BUFFER; ++j) {
- container = pu->container[j];
- if (!container)
- continue;
-
- if (j == 0) {
- vipx_info("TYPE : %d\n", container->type);
- vipx_info("RESOLUTION : %d x %d\n", container->format->width, container->format->height);
- vipx_info("SIZE : %d\n", container->format->size[container->format->plane]);
- vipx_info("-------------------------------------------------\n");
- }
-
- for (k = 0; k < container->count; ++k) {
- buffer = &container->buffers[k];
- vipx_info("[%d][%d]DVADDR : %llx\n", j, k, buffer->dvaddr);
- vipx_info("[%d][%d]KVADDR : %p\n", j, k, buffer->kvaddr);
- }
-
- vipx_info("-------------------------------------------------\n");
- }
- }
-
- vipx_graph_print(graph);
- }
-#endif
-}
-
-static int __attribute__((unused)) vipx_fault_handler(struct iommu_domain *domain,
- struct device *dev,
- unsigned long fault_addr,
- int fault_flag,
- void *token)
-{
- struct vipx_device *device;
-
- pr_err("<VIPX FAULT HANDLER>\n");
- pr_err("Device virtual(0x%X) is invalid access\n", (u32)fault_addr);
-
- device = dev_get_drvdata(dev);
-
- __vipx_fault_handler(device);
-
- return -EINVAL;
-}
-
-static int __vipx_device_start(struct vipx_device *device)
-{
- int ret = 0;
-
- if (test_bit(VIPX_DEVICE_STATE_START, &device->state)) {
- vipx_err("already started\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_system_start(&device->system);
- if (ret) {
- vipx_err("vipx_system_start is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_debug_start(&device->debug);
- if (ret) {
- vipx_err("vipx_debug_start is fail(%d)\n", ret);
- goto p_err;
- }
-
- set_bit(VIPX_DEVICE_STATE_START, &device->state);
-
-p_err:
- return ret;
-}
-
-static int __vipx_device_stop(struct vipx_device *device)
-{
- int ret = 0;
-
- if (!test_bit(VIPX_DEVICE_STATE_START, &device->state))
- goto p_err;
-
- ret = vipx_debug_stop(&device->debug);
- if (ret)
- vipx_err("vipx_debug_stop is fail(%d)\n", ret);
-
- ret = vipx_system_stop(&device->system);
- if (ret)
- vipx_err("vipx_system_stop is fail(%d)\n", ret);
-
- clear_bit(VIPX_DEVICE_STATE_START, &device->state);
-
-p_err:
- return ret;
-}
-
-static int __vipx_device_power_on(struct vipx_device *device)
-{
- int ret = 0;
-
- ret = pm_runtime_get_sync(device->dev);
- if (ret)
- vipx_err("runtime resume is fail(%d)", ret);
-
- return ret;
-}
-
-static int __vipx_device_power_off(struct vipx_device *device)
-{
- int ret = 0;
-
- ret = pm_runtime_put_sync(device->dev);
- if (ret)
- vipx_err("runtime resume is fail(%d)", ret);
-
- return ret;
-}
-
-static int vipx_device_probe(struct platform_device *pdev)
-{
- int ret = 0;
- struct device *dev;
- struct vipx_device *device;
-
- BUG_ON(!pdev);
-
- dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
-
- dev = &pdev->dev;
-
- device = devm_kzalloc(dev, sizeof(struct vipx_device), GFP_KERNEL);
- if (!device) {
- probe_err("device is NULL");
- ret = -ENOMEM;
- goto p_err;
- }
-
- ret = vipx_system_probe(&device->system, pdev);
- if (ret) {
- probe_err("vipx_system_probe is fail(%d)\n", ret);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_vertex_probe(&device->vertex, dev);
- if (ret) {
- probe_err("vipx_vertex_probe is fail(%d)\n", ret);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_graphmgr_probe(&device->graphmgr);
- if (ret) {
- probe_err("vipx_graphmgr_probe is fail(%d)\n", ret);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_debug_probe(&device->debug, &device->graphmgr, &device->system);
- if (ret) {
- probe_err("vipx_debug_probe is fail(%d)\n", ret);
- ret = -EINVAL;
- goto p_err;
- }
-
- iovmm_set_fault_handler(dev, vipx_fault_handler, NULL);
- pm_runtime_enable(dev);
-
- device->dev = dev;
- device->mode = VIPX_DEVICE_MODE_NORMAL;
- clear_bit(VIPX_DEVICE_STATE_OPEN, &device->state);
- clear_bit(VIPX_DEVICE_STATE_START, &device->state);
- dev_set_drvdata(dev, device);
-
- vipx_fw_code_rmem_base = phys_to_virt(vipx_fw_code_rmem->base);
-
-p_err:
-
- probe_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_device_open(struct vipx_device *device)
-{
- int ret = 0;
-
- BUG_ON(!device);
-
- if (test_bit(VIPX_DEVICE_STATE_OPEN, &device->state)) {
- vipx_err("device is already opened\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_system_open(&device->system);
- if (ret) {
- vipx_err("vipx_system_open is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_debug_open(&device->debug);
- if (ret) {
- vipx_err("vipx_debug_open is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_graphmgr_open(&device->graphmgr);
- if (ret) {
- vipx_err("vipx_graphmgr_open is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = __vipx_device_power_on(device);
- if (ret) {
- vipx_err("__vipx_device_power_on is fail(%d)\n", ret);
- goto p_err;
- }
-
- set_bit(VIPX_DEVICE_STATE_OPEN, &device->state);
-
-p_err:
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_device_close(struct vipx_device *device)
-{
- int ret = 0;
-
- BUG_ON(!device);
-
- if (!test_bit(VIPX_DEVICE_STATE_OPEN, &device->state)) {
- vipx_err("device is already closed\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = __vipx_device_stop(device);
- if (ret)
- vipx_err("__vipx_device_stop is fail(%d)\n", ret);
-
- ret = vipx_graphmgr_close(&device->graphmgr);
- if (ret)
- vipx_err("vipx_graphmgr_close is fail(%d)\n", ret);
-
- ret = vipx_system_close(&device->system);
- if (ret)
- vipx_err("vipx_system_close is fail(%d)\n", ret);
-
- ret = vipx_debug_close(&device->debug);
- if (ret)
- vipx_err("vipx_debug_close is fail(%d)\n", ret);
-
- ret = __vipx_device_power_off(device);
- if (ret)
- vipx_err("__vipx_device_power_off is fail(%d)\n", ret);
-
- clear_bit(VIPX_DEVICE_STATE_OPEN, &device->state);
-
-p_err:
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_device_start(struct vipx_device *device)
-{
- int ret = 0;
-
- BUG_ON(!device);
-
- ret = __vipx_device_start(device);
- if (ret)
- vipx_err("__vipx_device_start is fail(%d)\n", ret);
-
- vipx_info("%s():%d\n", __func__, ret);
-
- return ret;
-}
-
-int vipx_device_stop(struct vipx_device *device)
-{
- int ret = 0;
-
- BUG_ON(!device);
-
- ret = __vipx_device_stop(device);
- if (ret)
- vipx_err("__vipx_device_stop is fail(%d)\n", ret);
-
- vipx_info("%s():%d\n", __func__, ret);
-
- return ret;
-}
-
-static int vipx_device_remove(struct platform_device *pdev)
-{
- return 0;
-}
-
-static int vipx_device_suspend(struct device *dev)
-{
- return 0;
-}
-
-static int vipx_device_resume(struct device *dev)
-{
- return 0;
-}
-
-static int vipx_device_runtime_suspend(struct device *dev)
-{
- int ret = 0;
- struct vipx_device *device;
-
- device = dev_get_drvdata(dev);
-
- ret = vipx_system_suspend(&device->system);
- if (ret)
- vipx_err("vipx_system_suspend is fail(%d)\n", ret);
-
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-static int vipx_device_runtime_resume(struct device *dev)
-{
- int ret = 0;
- struct vipx_device *device;
-
- device = dev_get_drvdata(dev);
-
- ret = vipx_system_resume(&device->system, device->mode);
- if (ret) {
- vipx_err("vipx_system_resume is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-static const struct dev_pm_ops vipx_pm_ops = {
- .suspend = vipx_device_suspend,
- .resume = vipx_device_resume,
- .runtime_suspend = vipx_device_runtime_suspend,
- .runtime_resume = vipx_device_runtime_resume,
-};
-
-static const struct of_device_id exynos_vipx_match[] = {
- {
- .compatible = "samsung,exynos-vipx",
- },
- {}
-};
-MODULE_DEVICE_TABLE(of, exynos_vipx_match);
-
-static struct platform_driver vipx_driver = {
- .probe = vipx_device_probe,
- .remove = vipx_device_remove,
- .driver = {
- .name = "exynos-vipx",
- .owner = THIS_MODULE,
- .pm = &vipx_pm_ops,
- .of_match_table = of_match_ptr(exynos_vipx_match)
- }
-};
-
-static int __init vipx_device_init(void)
-{
- int ret = platform_driver_register(&vipx_driver);
- if (ret)
- probe_err("platform_driver_register is fail():%d\n", ret);
-
- probe_info("vipx device init is loaded");
-
- return ret;
-}
-late_initcall(vipx_device_init);
-
-static void __exit vipx_device_exit(void)
-{
- platform_driver_unregister(&vipx_driver);
-}
-module_exit(vipx_device_exit);
-
-MODULE_AUTHOR("Scott Choi<hyeon.choi@samsung.com>");
-MODULE_DESCRIPTION("Exynos VIPx driver");
-MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_DEVICE_H_
-#define VIPX_DEVICE_H_
-
-#include "vipx-graphmgr.h"
-#include "vipx-system.h"
-#include "vipx-vertex.h"
-#include "vipx-debug.h"
-
-enum vipx_device_state {
- VIPX_DEVICE_STATE_OPEN,
- VIPX_DEVICE_STATE_START
-};
-
-enum vipx_device_mode {
- VIPX_DEVICE_MODE_NORMAL,
- VIPX_DEVICE_MODE_TEST
-};
-
-struct vipx_device {
- struct device *dev;
- unsigned long state;
- u32 mode;
-
- struct vipx_graphmgr graphmgr;
- struct vipx_system system;
- struct vipx_vertex vertex;
- struct vipx_debug debug;
-};
-
-int vipx_device_open(struct vipx_device *device);
-int vipx_device_close(struct vipx_device *device);
-int vipx_device_start(struct vipx_device *device);
-int vipx_device_stop(struct vipx_device *device);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include "vipx-graphmgr.h"
-#include "vipx-graph.h"
-#include "vipx-debug.h"
-#include "vs4l.h"
-
-const struct vipx_graph_ops vipx_graph_ops;
-
-static int __vipx_graph_start(struct vipx_graph *graph)
-{
- int ret = 0;
- BUG_ON(!graph);
-
- if (test_bit(VIPX_GRAPH_STATE_START, &graph->state))
- return 0;
-
- ret = vipx_graphmgr_grp_start(graph->cookie, graph);
- if (ret) {
- vipx_ierr("vipx_graphmgr_grp_start is fail(%d)\n", graph, ret);
- goto p_err;
- }
-
- set_bit(VIPX_GRAPH_STATE_START, &graph->state);
-
-p_err:
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int __vipx_graph_stop(struct vipx_graph *graph)
-{
- int ret = 0, errcnt = 0;
- u32 retry, timeout;
- struct vipx_taskmgr *taskmgr;
- struct vipx_task *control;
-
- if (!test_bit(VIPX_GRAPH_STATE_START, &graph->state))
- return 0;
-
- taskmgr = &graph->taskmgr;
- if (taskmgr->req_cnt + taskmgr->pre_cnt) {
- control = &graph->control;
- control->message = VIPX_CTRL_STOP;
- vipx_graphmgr_queue(graph->cookie, control);
- timeout = wait_event_timeout(graph->control_wq,
- control->message == VIPX_CTRL_STOP_DONE, VIPX_GRAPH_STOP_TIMEOUT);
- if (!timeout) {
- vipx_ierr("wait_event_timeout is expired\n", graph);
- errcnt++;
- }
- }
-
- retry = VIPX_STOP_WAIT_COUNT;
- while (--retry && taskmgr->req_cnt) {
- vipx_iwarn("waiting %d request cancel...(%d)\n", graph, taskmgr->req_cnt, retry);
- msleep(10);
- }
-
- if (!retry) {
- vipx_ierr("request cancel is fail\n", graph);
- errcnt++;
- }
-
- retry = VIPX_STOP_WAIT_COUNT;
- while (--retry && taskmgr->pre_cnt) {
- vipx_iwarn("waiting %d prepare cancel...(%d)\n", graph, taskmgr->pre_cnt, retry);
- msleep(10);
- }
-
- if (!retry) {
- vipx_ierr("prepare cancel is fail\n", graph);
- errcnt++;
- }
-
- retry = VIPX_STOP_WAIT_COUNT;
- while (--retry && taskmgr->pro_cnt) {
- vipx_iwarn("waiting %d process done...(%d)\n", graph, taskmgr->pro_cnt, retry);
- msleep(10);
- }
-
- if (!retry) {
- vipx_ierr("process done is fail\n", graph);
- errcnt++;
- }
-
- ret = vipx_graphmgr_grp_stop(graph->cookie, graph);
- if (ret) {
- vipx_ierr("vipx_graphmgr_grp_stop is fail(%d)\n", graph, ret);
- errcnt++;
- }
-
- vipx_task_flush(taskmgr);
- clear_bit(VIPX_GRAPH_STATE_START, &graph->state);
-
- vipx_info("%s:%d\n", __func__, ret);
- return errcnt;
-}
-
-static int __vipx_graph_unmap(struct vipx_graph *graph)
-{
- int ret = 0;
-
- clear_bit(VIPX_GRAPH_STATE_MMAPPED, &graph->state);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int __vipx_graph_map(struct vipx_graph *graph)
-{
- int ret = 0;
-
- set_bit(VIPX_GRAPH_STATE_MMAPPED, &graph->state);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int __vipx_graph_alloc(struct vipx_graph *graph)
-{
- int ret = 0;
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int __vipx_graph_free(struct vipx_graph *graph)
-{
- int ret = 0;
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int __vipx_graph_parse(struct vipx_graph *graph)
-{
- int ret = 0;
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-void vipx_graph_task_print(struct vipx_graph *graph)
-{
- vipx_info("%s:\n", __func__);
-}
-
-void vipx_graph_print(struct vipx_graph *graph)
-{
-
- vipx_info("%s:\n", __func__);
-}
-
-int vipx_graph_create(struct vipx_graph **graph, void *cookie, void *memory)
-{
- int ret = 0;
- u32 i;
- struct vipx_taskmgr *taskmgr;
-
- BUG_ON(!cookie);
-
- *graph = kzalloc(sizeof(struct vipx_graph), GFP_KERNEL);
- if (*graph == NULL) {
- vipx_err("kzalloc is fail");
- ret = -ENOMEM;
- goto p_err;
- }
-
- ret = vipx_graphmgr_grp_register(cookie, *graph);
- if (ret) {
- vipx_err("vipx_graphmgr_grp_register is fail(%d)\n", ret);
- kfree(*graph);
- goto p_err;
- }
-
- (*graph)->control.message = VIPX_CTRL_NONE;
- (*graph)->cookie = cookie;
- (*graph)->memory = memory;
- (*graph)->gops = &vipx_graph_ops;
- mutex_init(&(*graph)->local_lock);
-
- /* task manager init */
- taskmgr = &(*graph)->taskmgr;
- taskmgr->id = (*graph)->idx;
- taskmgr->sindex = 0;
- spin_lock_init(&taskmgr->slock);
-
- for (i = 0; i < VIPX_MAX_TASK; ++i) {
- (*graph)->inhash[i] = VIPX_MAX_TASK;
- (*graph)->othash[i] = VIPX_MAX_TASK;
- }
-
- (*graph)->control.owner = *graph;
- init_waitqueue_head(&(*graph)->control_wq);
- ret = vipx_task_init(taskmgr, *graph);
- if (ret) {
- vipx_err("vipx_task_init is fail(%d)\n", ret);
- kfree(*graph);
- goto p_err;
- }
-
- (*graph)->informat_list.count = 0;
- (*graph)->informat_list.formats = 0;
- (*graph)->otformat_list.count = 0;
- (*graph)->otformat_list.formats = 0;
-
-p_err:
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_graph_destroy(struct vipx_graph *graph)
-{
- int ret = 0;
-
- BUG_ON(!graph);
-
- ret = __vipx_graph_stop(graph);
- if (ret)
- vipx_ierr("__vipx_graph_stop is fail(%d)\n", graph, ret);
-
- ret = vipx_graphmgr_grp_unregister(graph->cookie, graph);
- if (ret)
- vipx_ierr("vipx_graphmgr_grp_unregister is fail(%d)\n", graph, ret);
-
- ret = __vipx_graph_unmap(graph);
- if (ret)
- vipx_ierr("__vipx_graph_unmap is fail(%d)\n", graph, ret);
-
- ret = __vipx_graph_free(graph);
- if (ret)
- vipx_ierr("__vipx_graph_free is fail(%d)\n", graph, ret);
-
- if (graph->informat_list.formats)
- kfree(graph->informat_list.formats);
- graph->informat_list.formats = 0;
- graph->informat_list.count = 0;
-
- if (graph->otformat_list.formats)
- kfree(graph->otformat_list.formats);
- graph->otformat_list.count = 0;
-
- kfree(graph);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_graph_config(struct vipx_graph *graph, struct vs4l_graph *info)
-{
- int ret = 0;
-
- BUG_ON(!graph);
- BUG_ON(!graph->cookie);
- BUG_ON(!info);
-
- if (test_bit(VIPX_GRAPH_STATE_CONFIG, &graph->state)) {
- vipx_ierr("graph is already configured\n", graph);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (info->priority > VIPX_GRAPH_MAX_PRIORITY) {
- vipx_iwarn("graph priority is over(%d)\n", graph, info->priority);
- info->priority = VIPX_GRAPH_MAX_PRIORITY;
- }
-
- graph->uid = info->id;
- graph->flags = info->flags;
- graph->priority = info->priority;
-
- /* 2. graph allocation */
- ret = __vipx_graph_alloc(graph);
- if (ret) {
- vipx_ierr("__vipx_graph_alloc is fail(%d)\n", graph, ret);
- goto p_err;
- }
-
- /* 3. parsing */
- ret = __vipx_graph_parse(graph);
- if (ret) {
- vipx_ierr("__vipx_graph_parse is fail(%d)\n", graph, ret);
- goto p_err;
- }
-
- /* 4. Buffer Mapping */
- ret = __vipx_graph_map(graph);
- if (ret) {
- vipx_ierr("__vipx_graph_map is fail(%d)\n", graph, ret);
- goto p_err;
- }
-
- set_bit(VIPX_GRAPH_STATE_CONFIG, &graph->state);
-
-p_err:
- vipx_iinfo("%s(%d, %d, %X):%d\n", graph, __func__, info->id, info->priority, info->flags, ret);
- return ret;
-}
-
-int vipx_graph_param(struct vipx_graph *graph, struct vs4l_param_list *plist)
-{
- int ret = 0;
-
- set_bit(VIPX_GRAPH_FLAG_UPDATE_PARAM, &graph->flags);
-
- vipx_iinfo("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-static int vipx_graph_prepare(struct vb_queue *q, struct vb_container_list *clist)
-{
- int ret = 0;
-
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int vipx_graph_unprepare(struct vb_queue *q, struct vb_container_list *clist)
-{
- int ret = 0;
-
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-
-const struct vb_ops vb_ops = {
- .buf_prepare = vipx_graph_prepare,
- .buf_unprepare = vipx_graph_unprepare
-};
-
-int vipx_graph_start(struct vipx_queue *queue)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx;
- struct vipx_graph *graph;
-
- BUG_ON(!queue);
-
- vctx = container_of(queue, struct vipx_vertex_ctx, queue);
- graph = container_of(vctx, struct vipx_graph, vctx);
-
- ret = __vipx_graph_start(graph);
- if (ret)
- vipx_ierr("__vipx_graph_start is fail(%d)\n", graph, ret);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_graph_stop(struct vipx_queue *queue)
-{
- int ret = 0;
- struct vipx_graph *graph;
- struct vipx_vertex_ctx *vctx;
-
- BUG_ON(!queue);
-
- vctx = container_of(queue, struct vipx_vertex_ctx, queue);
- graph = container_of(vctx, struct vipx_graph, vctx);
-
- ret = __vipx_graph_stop(graph);
- if (ret)
- vipx_ierr("__vipx_graph_stop is fail(%d)\n", graph, ret);
-
- vipx_info("%s:%d\n", __func__, ret);
- return ret;
-}
-
-/* Description of flist elements
- * tartget : We done need this field. Ignore.
- * format : Fourcc name. Converting to char pointer.
- * plane : Num of planes.
- * width, height
- */
-int vipx_graph_format(struct vipx_queue *queue, struct vs4l_format_list *flist)
-{
- int ret = 0;
- struct vipx_graph *graph;
- struct vipx_vertex_ctx *vctx;
- struct vipx_format_list *in_list;
- struct vipx_format_list *ot_list;
- int cnt = 0;
-
- BUG_ON(!queue);
- BUG_ON(!flist);
-
- vctx = container_of(queue, struct vipx_vertex_ctx, queue);
- graph = container_of(vctx, struct vipx_graph, vctx);
- in_list = &graph->informat_list;
- ot_list = &graph->otformat_list;
-
- if (flist->direction == VS4L_DIRECTION_IN) {
- if (in_list->count != flist->count) {
- if (in_list->formats)
- kfree(in_list->formats);
-
- in_list->count = flist->count;
- in_list->formats = kzalloc(in_list->count * sizeof(struct vipx_format), GFP_KERNEL);
- if (!in_list->formats) {
- ret = -ENOMEM;
- goto p_err;
- }
-
- for (cnt = 0; cnt < in_list->count; cnt++) {
- vipx_info("[%d] size (%dx%d), format(%d), plane(%d)\n", cnt,
- flist->formats[cnt].width,
- flist->formats[cnt].height,
- flist->formats[cnt].format,
- flist->formats[cnt].plane);
-
- in_list->formats[cnt].width = flist->formats[cnt].width;
- in_list->formats[cnt].height = flist->formats[cnt].height;
- in_list->formats[cnt].format = flist->formats[cnt].format;
- in_list->formats[cnt].plane = flist->formats[cnt].plane;
- }
- }
- } else if (flist->direction == VS4L_DIRECTION_OT) {
- if (ot_list->count != flist->count) {
- if (ot_list->formats)
- kfree(ot_list->formats);
-
- ot_list->count = flist->count;
- ot_list->formats = kzalloc(ot_list->count * sizeof(struct vipx_format), GFP_KERNEL);
- if (!ot_list->formats) {
- ret = -ENOMEM;
- goto p_err;
- }
-
- for (cnt = 0; cnt < ot_list->count; cnt++) {
- vipx_info("[%d] size (%dx%d), format(%d), plane(%d)\n", cnt,
- flist->formats[cnt].width,
- flist->formats[cnt].height,
- flist->formats[cnt].format,
- flist->formats[cnt].plane);
-
- ot_list->formats[cnt].width = flist->formats[cnt].width;
- ot_list->formats[cnt].height = flist->formats[cnt].height;
- ot_list->formats[cnt].format = flist->formats[cnt].format;
- ot_list->formats[cnt].plane = flist->formats[cnt].plane;
- }
- }
- } else {
- vipx_err("invalid direction(%d)\n", flist->direction);
- ret = -EINVAL;
- goto p_err;
- }
-
- vipx_info("%s:%d, count in/out (%d/%d)\n", __func__, ret,
- graph->informat_list.count,
- graph->otformat_list.count);
- return ret;
-
-p_err:
- if (in_list->formats)
- kfree(in_list->formats);
- in_list->formats = 0;
-
- if (ot_list->formats)
- kfree(ot_list->formats);
- ot_list->formats = 0;
-
- return ret;
-}
-
-static int vipx_graph_queue(struct vipx_queue *queue, struct vb_container_list *incl, struct vb_container_list *otcl)
-{
- int ret = 0;
- unsigned long flag;
- struct vipx_graph *graph;
- struct vipx_vertex_ctx *vctx;
- struct vipx_taskmgr *taskmgr;
- struct vipx_task *task;
- int i = 0, j = 0;
-
- BUG_ON(!queue);
- BUG_ON(!incl);
- vipx_warn("ASDFASDFASDF : %d, %d\n",incl->index, otcl->index);
- //BUG_ON(incl->index < VIPX_MAX_TASK);
- BUG_ON(!otcl);
- //BUG_ON(otcl->index < VIPX_MAX_TASK);
-
- vctx = container_of(queue, struct vipx_vertex_ctx, queue);
- graph = container_of(vctx, struct vipx_graph, vctx);
- taskmgr = &graph->taskmgr;
-
- if (!test_bit(VIPX_GRAPH_STATE_START, &graph->state)) {
- vipx_ierr("graph is NOT start\n", graph);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (incl->id != otcl->id) {
- vipx_warn("buffer id is incoincidence(%d, %d)\n", incl->id, otcl->id);
- otcl->id = incl->id;
- }
-
- taskmgr_e_barrier_irqs(taskmgr, 0, flag);
- vipx_task_pick_fre_to_req(taskmgr, &task);
- taskmgr_x_barrier_irqr(taskmgr, 0, flag);
-
- if (!task) {
- vipx_ierr("task is lack\n", graph);
- vipx_task_print_all(taskmgr);
- ret = -ENOMEM;
- goto p_err;
- }
-
- graph->inhash[incl->index] = task->index;
- graph->othash[otcl->index] = task->index;
- graph->input_cnt++;
-
- vipx_dbg("in-container list: dir(%d), id(%d), index(%d), flags(%lx), count(%d)\n",
- incl->direction, incl->id, incl->index, incl->flags, incl->count);
- for (i = 0; i < incl->count; i++) {
- vipx_dbg("in-containers[%d] type(%d), target(%d), memory(%d), count(%d)\n", i,
- incl->containers[i].type, incl->containers[i].target,
- incl->containers[i].memory, incl->containers[i].count);
-
- for (j = 0; j < incl->containers[i].count; j++) {
- vipx_dbg("in-buffer[%d] fd(%d), kvaddr(%p), dvaddr(%p)\n", j,
- incl->containers[i].buffers[j].m.fd,
- incl->containers[i].buffers[j].kvaddr,
- (void *)incl->containers[i].buffers[j].dvaddr);
- }
- }
-
- vipx_dbg("out-container list: dir(%d), id(%d), index(%d), flags(%lx), count(%d)\n",
- otcl->direction, otcl->id, otcl->index, otcl->flags, otcl->count);
- for (i = 0; i < otcl->count; i++) {
- vipx_dbg("out-containers[%d] type(%d), target(%d), memory(%d), count(%d)\n", i,
- otcl->containers[i].type, otcl->containers[i].target,
- otcl->containers[i].memory, otcl->containers[i].count);
-
- for (j = 0; j < otcl->containers[i].count; j++) {
- vipx_dbg("out-buffer[%d] fd(%d), kvaddr(%p), dvaddr(%p)\n", j,
- otcl->containers[i].buffers[j].m.fd,
- otcl->containers[i].buffers[j].kvaddr,
- (void *)otcl->containers[i].buffers[j].dvaddr);
- }
- }
-
- task->id = incl->id;
- task->incl = incl;
- task->otcl = otcl;
- task->message = VIPX_TASK_REQUEST;
- task->param0 = 0;
- task->param1 = 0;
- task->param2 = 0;
- task->param3 = 0;
- clear_bit(VS4L_CL_FLAG_TIMESTAMP, &task->flags);
-
- if ((incl->flags & (1 << VS4L_CL_FLAG_TIMESTAMP)) ||
- (otcl->flags & (1 << VS4L_CL_FLAG_TIMESTAMP))) {
- set_bit(VS4L_CL_FLAG_TIMESTAMP, &task->flags);
- vipx_get_timestamp(&task->time[VIPX_TMP_QUEUE]);
- }
-
- vipx_graphmgr_queue(graph->cookie, task);
-
-p_err:
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-
-static int vipx_graph_deque(struct vipx_queue *queue, struct vb_container_list *clist)
-{
- int ret = 0;
- u32 findex;
- unsigned long flags;
- struct vipx_graph *graph;
- struct vipx_vertex_ctx *vctx;
- struct vipx_taskmgr *taskmgr;
- struct vipx_task *task;
-
- BUG_ON(!queue);
- BUG_ON(!clist);
- //BUG_ON(clist->index < VIPX_MAX_TASK);
-
- vctx = container_of(queue, struct vipx_vertex_ctx, queue);
- graph = container_of(vctx, struct vipx_graph, vctx);
- taskmgr = &graph->taskmgr;
-
- if (!test_bit(VIPX_GRAPH_STATE_START, &graph->state)) {
- vipx_ierr("graph is NOT start\n", graph);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (clist->direction == VS4L_DIRECTION_IN)
- findex = graph->inhash[clist->index];
- else
- findex = graph->othash[clist->index];
-
- if (findex >= VIPX_MAX_TASK) {
- vipx_ierr("task index(%d) invalid\n", graph, findex);
- BUG();
- }
-
- task = &taskmgr->task[findex];
- if (task->state != VIPX_TASK_STATE_COMPLETE) {
- vipx_ierr("task state(%d) is invalid\n", graph, task->state);
- BUG();
- }
-
- if (clist->direction == VS4L_DIRECTION_IN) {
- if (task->incl != clist) {
- vipx_ierr("incl ptr is invalid(%p != %p)\n", graph, task->incl, clist);
- BUG();
- }
-
- graph->inhash[clist->index] = VIPX_MAX_TASK;
- task->incl = NULL;
- } else {
- if (task->otcl != clist) {
- vipx_ierr("otcl ptr is invalid(%p != %p)\n", graph, task->otcl, clist);
- BUG();
- }
-
- graph->othash[clist->index] = VIPX_MAX_TASK;
- task->otcl = NULL;
- }
-
- if (task->incl || task->otcl)
- goto p_err;
-
- taskmgr_e_barrier_irqs(taskmgr, 0, flags);
- vipx_task_trans_com_to_fre(taskmgr, task);
- taskmgr_x_barrier_irqr(taskmgr, 0, flags);
-
-p_err:
- vipx_dbg("%s:%d\n", __func__, ret);
- return ret;
-}
-
-const struct vipx_queue_ops vipx_queue_ops = {
- .start = vipx_graph_start,
- .stop = vipx_graph_stop,
- .format = vipx_graph_format,
- .queue = vipx_graph_queue,
- .deque = vipx_graph_deque
-};
-
-static int vipx_graph_control(struct vipx_graph *graph, struct vipx_task *task)
-{
- int ret = 0;
- struct vipx_taskmgr *taskmgr;
-
- BUG_ON(!graph);
- BUG_ON(!task);
-
- taskmgr = &graph->taskmgr;
-
- if (&graph->control != task) {
- vipx_ierr("control task is invalid(%p == %p)\n", graph, &graph->control, task);
- BUG();
- }
-
- switch (task->message) {
- case VIPX_CTRL_STOP:
- graph->control.message = VIPX_CTRL_STOP_DONE;
- wake_up(&graph->control_wq);
- break;
- default:
- vipx_ierr("unresolved message(%d)\n", graph, task->message);
- vipx_task_print_all(taskmgr);
- BUG();
- break;
- }
-
- vipx_iinfo("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-static int vipx_graph_request(struct vipx_graph *graph, struct vipx_task *task)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *taskmgr;
-
- BUG_ON(!graph);
- BUG_ON(!task);
-
- taskmgr = &graph->taskmgr;
-
- if (task->state != VIPX_TASK_STATE_REQUEST) {
- vipx_ierr("task state(%d) is invalid\n", graph, task->state);
- BUG();
- }
-
- taskmgr_e_barrier_irqs(taskmgr, 0, flags);
- vipx_task_trans_req_to_pre(taskmgr, task);
- taskmgr_x_barrier_irqr(taskmgr, 0, flags);
-
- if (test_bit(VS4L_CL_FLAG_TIMESTAMP, &task->flags))
- vipx_get_timestamp(&task->time[VIPX_TMP_REQUEST]);
-
- vipx_idbg("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-static int vipx_graph_process(struct vipx_graph *graph, struct vipx_task *task)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *taskmgr;
-
- BUG_ON(!graph);
- BUG_ON(!task);
-
- taskmgr = &graph->taskmgr;
-
- if (task->state != VIPX_TASK_STATE_PREPARE) {
- vipx_ierr("task state(%d) is invalid\n", graph, task->state);
- BUG();
- }
-
- taskmgr_e_barrier_irqs(taskmgr, TASKMGR_IDX_0, flags);
- vipx_task_trans_pre_to_pro(taskmgr, task);
- taskmgr_x_barrier_irqr(taskmgr, TASKMGR_IDX_0, flags);
-
-#ifdef DBG_STREAMING
- vipx_iinfo("PROCESS(%d, %d)\n", graph, task->index, task->id);
-#endif
-
- if (test_bit(VS4L_CL_FLAG_TIMESTAMP, &task->flags))
- vipx_get_timestamp(&task->time[VIPX_TMP_PROCESS]);
-
- vipx_idbg("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-static int vipx_graph_cancel(struct vipx_graph *graph, struct vipx_task *task)
-{
- int ret = 0;
- unsigned long flags;
- unsigned long result;
- struct vipx_taskmgr *taskmgr;
- struct vipx_queue *queue;
- struct vb_container_list *incl, *otcl;
-
- BUG_ON(!graph);
- BUG_ON(!task);
-
- taskmgr = &graph->taskmgr;
- queue = &graph->vctx.queue;
- incl = task->incl;
- otcl = task->otcl;
- result = 0;
-
- if (!test_bit(VIPX_GRAPH_STATE_START, &graph->state)) {
- vipx_ierr("graph is NOT start\n", graph);
- BUG();
- }
-
- if (task->state != VIPX_TASK_STATE_PROCESS) {
- vipx_ierr("task state(%d) is invalid\n", graph, task->state);
- BUG();
- }
-
- if (test_bit(VS4L_CL_FLAG_TIMESTAMP, &task->flags)) {
- vipx_get_timestamp(&task->time[VIPX_TMP_DONE]);
-
- if (incl->flags & (1 << VS4L_CL_FLAG_TIMESTAMP))
- memcpy(incl->timestamp, task->time, sizeof(task->time));
-
- if (otcl->flags & (1 << VS4L_CL_FLAG_TIMESTAMP))
- memcpy(otcl->timestamp, task->time, sizeof(task->time));
-
-#ifdef DBG_TIMEMEASURE
- vipx_irinfo("[TM] G%d : QR(%ld), RR(%ld), RP(%ld), PD(%ld)\n", graph, task, graph->uid,
- VIPX_TIME_IN_US(task->time[VIPX_TMP_REQUEST]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_QUEUE]),
- VIPX_TIME_IN_US(task->time[VIPX_TMP_RESOURCE]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_REQUEST]),
- VIPX_TIME_IN_US(task->time[VIPX_TMP_PROCESS]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_RESOURCE]),
- VIPX_TIME_IN_US(task->time[VIPX_TMP_DONE]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_PROCESS]));
-#endif
- }
-
-#ifdef DBG_STREAMING
- vipx_iinfo("NDONE(%d, %d)\n", graph, task->index, task->id);
-#endif
- set_bit(VS4L_CL_FLAG_DONE, &result);
- set_bit(VS4L_CL_FLAG_INVALID, &result);
-
- taskmgr_e_barrier_irqs(taskmgr, TASKMGR_IDX_0, flags);
- vipx_task_trans_pro_to_com(taskmgr, task);
- taskmgr_x_barrier_irqr(taskmgr, TASKMGR_IDX_0, flags);
-
- graph->recent = task->id;
- graph->done_cnt++;
- vipx_queue_done(queue, incl, otcl, result);
-
- vipx_iinfo("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-static int vipx_graph_done(struct vipx_graph *graph, struct vipx_task *task)
-{
- int ret = 0;
- unsigned long flags;
- unsigned long result;
- struct vipx_taskmgr *taskmgr;
- struct vipx_queue *queue;
- struct vb_container_list *incl, *otcl;
-
- BUG_ON(!graph);
- BUG_ON(!task);
-
- taskmgr = &graph->taskmgr;
- queue = &graph->vctx.queue;
- incl = task->incl;
- otcl = task->otcl;
- result = 0;
-
- if (!test_bit(VIPX_GRAPH_STATE_START, &graph->state)) {
- vipx_ierr("graph is NOT start\n", graph);
- BUG();
- }
-
- if (task->state != VIPX_TASK_STATE_PROCESS) {
- vipx_ierr("task state(%d) is invalid\n", graph, task->state);
- BUG();
- }
-
- if (test_bit(VS4L_CL_FLAG_TIMESTAMP, &task->flags)) {
- vipx_get_timestamp(&task->time[VIPX_TMP_DONE]);
-
- if (incl->flags & (1 << VS4L_CL_FLAG_TIMESTAMP))
- memcpy(incl->timestamp, task->time, sizeof(task->time));
-
- if (otcl->flags & (1 << VS4L_CL_FLAG_TIMESTAMP))
- memcpy(otcl->timestamp, task->time, sizeof(task->time));
-
-#ifdef DBG_TIMEMEASURE
- vipx_irinfo("[TM] G%d : QR(%ld), RR(%ld), RP(%ld), PD(%ld)\n", graph, task, graph->uid,
- VIPX_TIME_IN_US(task->time[VIPX_TMP_REQUEST]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_QUEUE]),
- VIPX_TIME_IN_US(task->time[VIPX_TMP_RESOURCE]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_REQUEST]),
- VIPX_TIME_IN_US(task->time[VIPX_TMP_PROCESS]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_RESOURCE]),
- VIPX_TIME_IN_US(task->time[VIPX_TMP_DONE]) -
- VIPX_TIME_IN_US(task->time[VIPX_TMP_PROCESS]));
-#endif
- }
-
- if (task->param0) {
-#ifdef DBG_STREAMING
- vipx_iinfo("NDONE(%d, %d)\n", graph, task->index, task->id);
-#endif
- set_bit(VS4L_CL_FLAG_DONE, &result);
- set_bit(VS4L_CL_FLAG_INVALID, &result);
- } else {
-#ifdef DBG_STREAMING
- vipx_iinfo("DONE(%d, %d)\n", graph, task->index, task->id);
-#endif
- set_bit(VS4L_CL_FLAG_DONE, &result);
- }
-
- taskmgr_e_barrier_irqs(taskmgr, TASKMGR_IDX_0, flags);
- vipx_task_trans_pro_to_com(taskmgr, task);
- taskmgr_x_barrier_irqr(taskmgr, TASKMGR_IDX_0, flags);
-
- graph->recent = task->id;
- graph->done_cnt++;
- vipx_queue_done(queue, incl, otcl, result);
-
- vipx_idbg("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-static int vipx_graph_update_param(struct vipx_graph *graph, struct vipx_task *task)
-{
- int ret = 0;
-
- vipx_iinfo("%s:%d\n", graph, __func__, ret);
- return ret;
-}
-
-const struct vipx_graph_ops vipx_graph_ops = {
- .control = vipx_graph_control,
- .request = vipx_graph_request,
- .process = vipx_graph_process,
- .cancel = vipx_graph_cancel,
- .done = vipx_graph_done,
- .update_param = vipx_graph_update_param
-};
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_GRAPH_H_
-#define VIPX_GRAPH_H_
-
-#include <linux/types.h>
-
-#include "vs4l.h"
-#include "vipx-taskmgr.h"
-#include "vipx-vertex.h"
-#include "vipx-interface.h"
-
-#define VIPX_GRAPH_MAX_VERTEX 20
-#define VIPX_GRAPH_MAX_PRIORITY 20
-#define VIPX_GRAPH_MAX_INTERMEDIATE 64
-#define VIPX_GRAPH_MAX_LEVEL 20
-#define VIPX_GRAPH_STOP_TIMEOUT (3 * HZ)
-
-struct vipx_graph;
-
-enum vipx_graph_state {
- VIPX_GRAPH_STATE_CONFIG,
- VIPX_GRAPH_STATE_HENROLL,
- VIPX_GRAPH_STATE_HMAPPED,
- VIPX_GRAPH_STATE_MMAPPED,
- VIPX_GRAPH_STATE_START,
-};
-
-enum vipx_graph_flag {
- VIPX_GRAPH_FLAG_UPDATE_PARAM = VS4L_GRAPH_FLAG_END
-};
-
-struct vipx_format {
- u32 format;
- u32 plane;
- u32 width;
- u32 height;
-};
-
-struct vipx_format_list {
- u32 count;
- struct vipx_format *formats;
-};
-
-struct vipx_graph_ops {
- int (*control)(struct vipx_graph *graph, struct vipx_task *task);
- int (*request)(struct vipx_graph *graph, struct vipx_task *task);
- int (*process)(struct vipx_graph *graph, struct vipx_task *task);
- int (*cancel)(struct vipx_graph *graph, struct vipx_task *task);
- int (*done)(struct vipx_graph *graph, struct vipx_task *task);
- int (*update_param)(struct vipx_graph *graph, struct vipx_task *task);
-};
-
-struct vipx_graph_intermediate {
- u32 buffer_index;
- u32 *buffer;
- void *handle;
- int fd;
-};
-
-struct vipx_graph {
- u32 idx;
- u32 uid;
- unsigned long state;
- unsigned long flags;
- u32 priority;
- struct mutex local_lock;
- struct mutex *global_lock;
-
- /* for debugging */
- u32 input_cnt;
- u32 cancel_cnt;
- u32 done_cnt;
- u32 recent;
-
- const struct vipx_graph_ops *gops;
-
- void *cookie;
- void *memory;
- struct vipx_pipe *pipe;
- struct vipx_vertex_ctx vctx;
-
- struct vipx_format_list informat_list;
- struct vipx_format_list otformat_list;
-
- u32 inhash[VIPX_MAX_TASK];
- u32 othash[VIPX_MAX_TASK];
- struct vipx_taskmgr taskmgr;
- struct vipx_task control;
- wait_queue_head_t control_wq;
-};
-
-void vipx_graph_print(struct vipx_graph *graph);
-int vipx_graph_create(struct vipx_graph **graph, void *cookie, void *memory);
-int vipx_graph_destroy(struct vipx_graph *graph);
-int vipx_graph_config(struct vipx_graph *graph, struct vs4l_graph *info);
-int vipx_graph_param(struct vipx_graph *graph, struct vs4l_param_list *plist);
-
-#define CALL_GOPS(g, op, ...) (((g)->gops->op) ? ((g)->gops->op(g, ##__VA_ARGS__)) : 0)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/sched/types.h>
-#include <linux/sched/rt.h>
-#include <linux/bug.h>
-#include <linux/scatterlist.h>
-
-
-#include "vipx-taskmgr.h"
-#include "vipx-device.h"
-#include "vipx-graphmgr.h"
-
-/*
- * task trans
- */
-
-static void __vipx_taskdesc_s_free(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
-
- taskdesc->state = VIPX_TASKDESC_STATE_FREE;
-
- list_add_tail(&taskdesc->list, &graphmgr->tdfre_list);
- graphmgr->tdfre_cnt++;
-}
-
-static void __vipx_taskdesc_free_head(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc **taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
-
- if (graphmgr->tdfre_cnt)
- *taskdesc = container_of(graphmgr->tdfre_list.next, struct vipx_taskdesc, list);
- else
- *taskdesc = NULL;
-}
-
-static void __vipx_taskdesc_s_ready(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
-
- taskdesc->state = VIPX_TASKDESC_STATE_FREE;
-
- list_add_tail(&taskdesc->list, &graphmgr->tdrdy_list);
- graphmgr->tdrdy_cnt++;
-}
-
-static void __vipx_taskdesc_g_ready(struct vipx_graphmgr *graphmgr,
- struct vipx_taskdesc **taskdesc)
-{
- if (graphmgr->tdrdy_cnt &&
- (*taskdesc = container_of(graphmgr->tdrdy_list.next, struct vipx_taskdesc, list))) {
- list_del(&(*taskdesc)->list);
- graphmgr->tdrdy_cnt--;
- (*taskdesc)->state = VIPX_TASK_STATE_INVALID;
- } else {
- *taskdesc = NULL;
- }
-}
-
-static void __vipx_taskdesc_s_request(struct vipx_graphmgr *graphmgr,
- struct vipx_taskdesc *prev,
- struct vipx_taskdesc *taskdesc,
- struct vipx_taskdesc *next)
-{
- taskdesc->state = VIPX_TASKDESC_STATE_REQUEST;
-
- if (prev && next) {
- next->list.prev = &taskdesc->list;
- taskdesc->list.next = &next->list;
- taskdesc->list.prev = &prev->list;
- prev->list.next = &taskdesc->list;
- } else if (prev) {
- list_add_tail(&taskdesc->list, &graphmgr->tdreq_list);
- } else {
- list_add(&taskdesc->list, &graphmgr->tdreq_list);
- }
-
- graphmgr->tdreq_cnt++;
-}
-
-static void __vipx_taskdesc_s_alloc(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- taskdesc->state = VIPX_TASKDESC_STATE_ALLOC;
- list_add_tail(&taskdesc->list, &graphmgr->tdalc_list);
- graphmgr->tdalc_cnt++;
-}
-
-void __vipx_taskdesc_s_process(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
-
- taskdesc->state = VIPX_TASKDESC_STATE_PROCESS;
- list_add_tail(&taskdesc->list, &graphmgr->tdpro_list);
- graphmgr->tdpro_cnt++;
-}
-
-static void __vipx_taskdesc_s_complete(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
-
- taskdesc->state = VIPX_TASKDESC_STATE_COMPLETE;
- list_add_tail(&taskdesc->list, &graphmgr->tdcom_list);
- graphmgr->tdcom_cnt++;
-}
-
-void __vipx_taskdesc_trans_fre_to_rdy(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdfre_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_FREE);
-
- list_del(&taskdesc->list);
- graphmgr->tdfre_cnt--;
- __vipx_taskdesc_s_ready(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_rdy_to_fre(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdrdy_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_READY);
-
- list_del(&taskdesc->list);
- graphmgr->tdrdy_cnt--;
- __vipx_taskdesc_s_free(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_req_to_alc(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdreq_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_REQUEST);
-
- list_del(&taskdesc->list);
- graphmgr->tdreq_cnt--;
- __vipx_taskdesc_s_alloc(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_req_to_pro(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdreq_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_REQUEST);
-
- list_del(&taskdesc->list);
- graphmgr->tdreq_cnt--;
- __vipx_taskdesc_s_process(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_req_to_fre(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdreq_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_REQUEST);
-
- list_del(&taskdesc->list);
- graphmgr->tdreq_cnt--;
- __vipx_taskdesc_s_free(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_alc_to_pro(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdalc_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_ALLOC);
-
- list_del(&taskdesc->list);
- graphmgr->tdalc_cnt--;
- __vipx_taskdesc_s_process(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_alc_to_fre(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdalc_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_ALLOC);
-
- list_del(&taskdesc->list);
- graphmgr->tdalc_cnt--;
- __vipx_taskdesc_s_free(graphmgr, taskdesc);
-}
-
-static void __vipx_taskdesc_trans_pro_to_com(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdpro_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_PROCESS);
-
- list_del(&taskdesc->list);
- graphmgr->tdpro_cnt--;
- __vipx_taskdesc_s_complete(graphmgr, taskdesc);
-}
-
-void __vipx_taskdesc_trans_pro_to_fre(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdpro_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_PROCESS);
-
- list_del(&taskdesc->list);
- graphmgr->tdpro_cnt--;
- __vipx_taskdesc_s_free(graphmgr, taskdesc);
-}
-
-static void __vipx_taskdesc_trans_com_to_fre(struct vipx_graphmgr *graphmgr, struct vipx_taskdesc *taskdesc)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!taskdesc);
- BUG_ON(!graphmgr->tdcom_cnt);
- BUG_ON(taskdesc->state != VIPX_TASKDESC_STATE_COMPLETE);
-
- list_del(&taskdesc->list);
- graphmgr->tdcom_cnt--;
- __vipx_taskdesc_s_free(graphmgr, taskdesc);
-}
-
-/*
- * task trans END
- */
-
-void vipx_taskdesc_print(struct vipx_graphmgr *graphmgr)
-{
-}
-
-#ifdef USE_TASK_TIMER
-static int vipx_time_thread(void *data)
-{
- int ret = 0;
-
- return ret;
-}
-#endif
-
-static int __vipx_itf_init(struct vipx_interface *interface,
- struct vipx_graph *graph)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
-
- BUG_ON(!interface);
- BUG_ON(!graph);
-
- itaskmgr = &interface->taskmgr;
-
- ret = vipx_hw_enum(interface);
- if (ret) {
- vipx_err("vipx_hw_enum is fail(%d)\n", ret);
- goto p_err;
- }
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_pick_fre_to_req(itaskmgr, &itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- if (!itask) {
- vipx_err("itask is NULL\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- itask->id = 0;
- itask->lock = &graph->local_lock;
- itask->findex = VIPX_MAX_TASK;
- itask->tdindex = VIPX_MAX_TASKDESC;
- itask->message = VIPX_TASK_INIT;
- itask->param0 = graph->uid;
- itask->param1 = graph->idx;
- itask->param2 = 0;
- itask->param3 = 0;
-
- ret = vipx_hw_init(interface, itask);
- if (ret) {
- vipx_err("vipx_hw_init is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_info("%s:\n", __func__);
- return ret;
-}
-
-static int __vipx_itf_deinit(struct vipx_interface *interface,
- struct vipx_graph *graph)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
-
- BUG_ON(!interface);
- BUG_ON(!graph);
-
- itaskmgr = &interface->taskmgr;
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_pick_fre_to_req(itaskmgr, &itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- if (!itask) {
- vipx_err("itask is NULL\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- itask->id = 0;
- itask->lock = &graph->local_lock;
- itask->findex = VIPX_MAX_TASK;
- itask->tdindex = VIPX_MAX_TASKDESC;
- itask->message = VIPX_TASK_DEINIT;
- itask->param0 = graph->uid;
- itask->param1 = graph->idx;
- itask->param2 = 0;
- itask->param3 = 0;
-
- ret = vipx_hw_deinit(interface, itask);
- if (ret) {
- vipx_err("vipx_hw_deinit is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_info("%s:\n", __func__);
- return ret;
-}
-
-int __vipx_itf_create(struct vipx_interface *interface,
- struct vipx_graph *graph)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
-
- BUG_ON(!interface);
- BUG_ON(!graph);
-
- itaskmgr = &interface->taskmgr;
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_pick_fre_to_req(itaskmgr, &itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- if (!itask) {
- vipx_err("itask is NULL\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
-#ifdef DBG_TIMEMEASURE
- vipx_get_timestamp(&itask->time[VIPX_TMP_REQUEST]);
-#endif
-
- itask->id = 0;
- itask->lock = &graph->local_lock;
- itask->findex = VIPX_MAX_TASK;
- itask->tdindex = VIPX_MAX_TASKDESC;
- itask->message = VIPX_TASK_CREATE;
- itask->param0 = graph->uid;
- itask->param1 = graph->idx;
- itask->param2 = (ulong)0;
- itask->param3 = (ulong)0;
-
- ret = vipx_hw_create(interface, itask);
- if (ret) {
- vipx_err("vipx_hw_create is fail(%d)\n", ret);
- goto p_err;
- }
-
-#ifdef DBG_TIMEMEASURE
- vipx_iinfo("[TM] C : %ldus, %ldus\n", graph,
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_PROCESS]) -
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_REQUEST]),
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_DONE]) -
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_PROCESS]));
-#endif
-
-p_err:
- vipx_info("%s:\n", __func__);
- return ret;
-}
-
-static int __vipx_itf_destroy(struct vipx_interface *interface,
- struct vipx_graph *graph)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
-
- BUG_ON(!interface);
- BUG_ON(!graph);
-
- itaskmgr = &interface->taskmgr;
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_pick_fre_to_req(itaskmgr, &itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- if (!itask) {
- vipx_err("itask is NULL\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
-#ifdef DBG_TIMEMEASURE
- vipx_get_timestamp(&itask->time[VIPX_TMP_REQUEST]);
-#endif
-
- itask->id = 0;
- itask->lock = &graph->local_lock;
- itask->findex = VIPX_MAX_TASK;
- itask->tdindex = VIPX_MAX_TASKDESC;
- itask->message = VIPX_TASK_DESTROY;
- itask->param0 = graph->uid;
- itask->param1 = graph->idx;
- itask->param2 = 0;
- itask->param3 = 0;
-
- ret = vipx_hw_destroy(interface, itask);
- if (ret) {
- vipx_err("vipx_hw_destory is fail(%d)\n", ret);
- goto p_err;
- }
-
-#ifdef DBG_TIMEMEASURE
- vipx_iinfo("[TM] D : %ldus, %ldus\n", graph,
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_PROCESS]) -
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_REQUEST]),
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_DONE]) -
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_PROCESS]));
-#endif
-
-p_err:
- vipx_info("%s:\n", __func__);
- return ret;
-}
-
-static int __vipx_itf_config(struct vipx_interface *interface,
- struct vipx_graph *graph)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
-
- BUG_ON(!interface);
- BUG_ON(!graph);
-
- itaskmgr = &interface->taskmgr;
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_pick_fre_to_req(itaskmgr, &itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- if (!itask) {
- vipx_err("itask is NULL\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
-#ifdef DBG_TIMEMEASURE
- vipx_get_timestamp(&itask->time[VIPX_TMP_REQUEST]);
-#endif
-
- itask->id = 0;
- itask->lock = &graph->local_lock;
- itask->findex = VIPX_MAX_TASK;
- itask->tdindex = VIPX_MAX_TASKDESC;
- itask->message = VIPX_TASK_ALLOCATE;
- itask->param0 = graph->uid;
- itask->param1 = graph->idx;
- itask->param2 = (ulong)&graph->informat_list;
- itask->param3 = (ulong)&graph->otformat_list;
-
- ret = vipx_hw_config(interface, itask);
- if (ret) {
- vipx_err("vipx_hw_config is fail(%d)\n", ret);
- goto p_err;
- }
-
-#ifdef DBG_TIMEMEASURE
- vipx_iinfo("[TM] A : %ldus, %ldus\n", graph,
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_PROCESS]) -
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_REQUEST]),
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_DONE]) -
- VIPX_TIME_IN_US(itask->time[VIPX_TMP_PROCESS]));
-#endif
-
-p_err:
- vipx_info("%s:\n", __func__);
- return ret;
-}
-
-static int __vipx_itf_process(struct vipx_interface *interface,
- struct vipx_graph *graph,
- struct vipx_task *task)
-{
- int ret = 0;
- unsigned long flags;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *itask;
-
- BUG_ON(!interface);
- BUG_ON(!graph);
- BUG_ON(!task);
-
- itaskmgr = &interface->taskmgr;
-
- taskmgr_e_barrier_irqs(itaskmgr, 0, flags);
- vipx_task_pick_fre_to_req(itaskmgr, &itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flags);
-
- if (!itask) {
- vipx_err("itask is NULL\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- if (test_bit(VIPX_GRAPH_FLAG_UPDATE_PARAM, &graph->flags)) {
- ret = CALL_GOPS(graph, update_param, task);
- if (ret) {
- vipx_err("GOPS(update_param) is fail(%d)\n", ret);
- goto p_err;
- }
-
- clear_bit(VIPX_GRAPH_FLAG_UPDATE_PARAM, &graph->flags);
- }
-
- itask->id = task->id;
- itask->lock = &graph->local_lock;
- itask->findex = task->index;
- itask->tdindex = task->tdindex;
- itask->message = VIPX_TASK_PROCESS;
- itask->param0 = graph->uid;
- itask->param1 = graph->idx;
- itask->param2 = (ulong)0; /* return : DONE or NDONE */
- itask->param3 = 0; /* return : error code if param2 is NDONE */
- itask->flags = task->flags;
- itask->incl = task->incl;
- itask->otcl = task->otcl;
-
- ret = CALL_GOPS(graph, process, task);
- if (ret) {
- vipx_err("GOPS(process) is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_hw_process(interface, itask);
- if (ret) {
- vipx_err("vipx_hw_process is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_dbg("%s:\n", __func__);
- return ret;
-}
-
-static void __vipx_graphmgr_sched(struct vipx_graphmgr *graphmgr)
-{
- int ret = 0;
- struct vipx_graph *graph;
- struct vipx_task *task;
- struct vipx_taskdesc *ready, *request, *process, *prev, *next, *temp;
- struct vipx_interface *interface;
-
- interface = graphmgr->interface;
- ready = NULL;
- request = NULL;
- prev = NULL;
- next = NULL;
-
- mutex_lock(&graphmgr->tdlock);
-
- /* 1. priority order */
- while (1) {
- __vipx_taskdesc_g_ready(graphmgr, &ready);
- if (!ready)
- break;
-
- list_for_each_entry_safe(next, temp, &graphmgr->tdreq_list, list) {
- if (ready->priority > next->priority)
- break;
-
- prev = next;
- next = NULL;
- }
-
- __vipx_taskdesc_s_request(graphmgr, prev, ready, next);
- }
-
- /* 2. */
- list_for_each_entry_safe(request, temp, &graphmgr->tdreq_list, list) {
- graph = request->graph;
- task = request->task;
-
- __vipx_taskdesc_trans_req_to_pro(graphmgr, request);
- }
-
- mutex_unlock(&graphmgr->tdlock);
-
- /* 3. process graph */
- list_for_each_entry_safe(process, temp, &graphmgr->tdpro_list, list) {
- graph = process->graph;
- task = process->task;
-
- ret = __vipx_itf_process(interface, graph, task);
- if (ret) {
- vipx_err("__vipx_itf_process is fail(%d)\n", ret);
-
- ret = CALL_GOPS(graph, cancel, task);
- if (ret) {
- vipx_err("CALL_GOPS(cancel) is fail(%d)\n", ret);
- BUG();
- }
-
- process->graph = NULL;
- process->task = NULL;
- __vipx_taskdesc_trans_pro_to_fre(graphmgr, process);
- continue;
- }
-
- __vipx_taskdesc_trans_pro_to_com(graphmgr, process);
- }
-
- graphmgr->sched_cnt++;
- vipx_dbg("[%s:%d]\n", __func__, __LINE__);
-}
-
-static void vipx_graph_thread(struct kthread_work *work)
-{
- int ret = 0;
- struct vipx_graphmgr *graphmgr;
- struct vipx_graph *graph;
- struct vipx_task *task;
- struct vipx_taskdesc *taskdesc, * temp;
-
- BUG_ON(!work);
-
- task = container_of(work, struct vipx_task, work);
- graph = task->owner;
- graphmgr = graph->cookie;
-
- switch (task->message) {
- case VIPX_TASK_REQUEST:
- ret = CALL_GOPS(graph, request, task);
- if (ret) {
- vipx_err("CALL_GOPS(request) is fail(%d)\n", ret);
- BUG();
- }
-
- __vipx_taskdesc_free_head(graphmgr, &taskdesc);
- if (!taskdesc) {
- vipx_err("taskdesc is NULL\n");
- BUG();
- }
-
- task->tdindex = taskdesc->index;
- taskdesc->graph = graph;
- taskdesc->task = task;
- taskdesc->priority = graph->priority;
- __vipx_taskdesc_trans_fre_to_rdy(graphmgr, taskdesc);
- break;
- case VIPX_CTRL_STOP:
- list_for_each_entry_safe(taskdesc, temp, &graphmgr->tdrdy_list, list) {
- if (taskdesc->graph->idx != graph->idx)
- continue;
-
- ret = CALL_GOPS(graph, cancel, taskdesc->task);
- if (ret) {
- vipx_err("CALL_GOPS(cancel) is fail(%d)\n", ret);
- BUG();
- }
-
- taskdesc->graph = NULL;
- taskdesc->task = NULL;
- __vipx_taskdesc_trans_rdy_to_fre(graphmgr, taskdesc);
- }
-
- mutex_lock(&graphmgr->tdlock);
-
- list_for_each_entry_safe(taskdesc, temp, &graphmgr->tdreq_list, list) {
- if (taskdesc->graph->idx != graph->idx)
- continue;
-
- ret = CALL_GOPS(graph, cancel, taskdesc->task);
- if (ret) {
- vipx_err("CALL_GOPS(cancel) is fail(%d)\n", ret);
- BUG();
- }
-
- taskdesc->graph = NULL;
- taskdesc->task = NULL;
- __vipx_taskdesc_trans_req_to_fre(graphmgr, taskdesc);
- }
-
- mutex_unlock(&graphmgr->tdlock);
-
- ret = CALL_GOPS(graph, control, task);
- if (ret) {
- vipx_err("CALL_GOPS(control) is fail(%d)\n", ret);
- BUG();
- }
- return;
- default:
- BUG();
- break;
- }
-
- __vipx_graphmgr_sched(graphmgr);
- vipx_dbg("[%s:%d]\n", __func__, __LINE__);
-}
-
-static void vipx_interface_thread(struct kthread_work *work)
-{
- int ret = 0;
- u32 task_index;
- u32 taskdesc_index;
- unsigned long flag;
- struct vipx_graphmgr *graphmgr;
- struct vipx_graph *graph;
- struct vipx_taskmgr *itaskmgr;
- struct vipx_task *task, *itask;
- struct vipx_taskdesc *taskdesc;
- struct vipx_interface *interface;
-
- BUG_ON(!work);
-
- itask = container_of(work, struct vipx_task, work);
- interface = itask->owner;
- itaskmgr = &interface->taskmgr;
- graphmgr = interface->cookie;
-
- switch (itask->message) {
- case VIPX_TASK_ALLOCATE:
- task_index = itask->findex;
- taskdesc_index = itask->tdindex;
-
- if (taskdesc_index >= VIPX_MAX_TASKDESC) {
- vipx_err("taskdesc index(%d) is invalid\n", taskdesc_index);
- BUG();
- }
-
- if (task_index >= VIPX_MAX_TASK) {
- vipx_err("task index(%d) is invalid\n", task_index);
- BUG();
- }
-
- taskdesc = &graphmgr->taskdesc[taskdesc_index];
- if (taskdesc->state != VIPX_TASKDESC_STATE_ALLOC) {
- vipx_err("taskdesc state is invalid(%d)\n", taskdesc->state);
- vipx_taskdesc_print(graphmgr);
- BUG();
- }
-
- graph = taskdesc->graph;
- if (!graph) {
- vipx_err("graph is NULL(%d)\n", taskdesc_index);
- BUG();
- }
-
- task = taskdesc->task;
- if (!task) {
- vipx_err("task is NULL(%d)\n", taskdesc_index);
- BUG();
- }
-
- task->message = itask->message;
- task->param0 = itask->param2;
- task->param1 = itask->param3;
-
- /* return status check */
- if (task->param0) {
- vipx_err("allocation is fail(%ld, %ld)\n", task->param0, task->param1);
-
- ret = CALL_GOPS(graph, cancel, task);
- if (ret) {
- vipx_err("CALL_GOPS(cancel) is fail(%d)\n", ret);
- BUG();
- }
-
- /* taskdesc cleanup */
- mutex_lock(&graphmgr->tdlock);
- taskdesc->graph = NULL;
- taskdesc->task = NULL;
- __vipx_taskdesc_trans_alc_to_fre(graphmgr, taskdesc);
- mutex_unlock(&graphmgr->tdlock);
- } else {
- /* taskdesc transition */
- mutex_lock(&graphmgr->tdlock);
- __vipx_taskdesc_trans_alc_to_pro(graphmgr, taskdesc);
- mutex_unlock(&graphmgr->tdlock);
- }
-
- /* itask cleanup */
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_com_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
- break;
- case VIPX_TASK_PROCESS:
- task_index = itask->findex;
- taskdesc_index = itask->tdindex;
-
- if (taskdesc_index >= VIPX_MAX_TASKDESC) {
- vipx_err("taskdesc index(%d) is invalid\n", taskdesc_index);
- BUG();
- }
-
- if (task_index >= VIPX_MAX_TASK) {
- vipx_err("task index(%d) is invalid\n", task_index);
- BUG();
- }
-
- taskdesc = &graphmgr->taskdesc[taskdesc_index];
- if (taskdesc->state == VIPX_TASKDESC_STATE_FREE) {
- vipx_err("taskdesc state is FREE(%d)\n", taskdesc->state);
- vipx_taskdesc_print(graphmgr);
-
- /* itask cleanup */
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_com_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
- break;
- }
-
- if (taskdesc->state != VIPX_TASKDESC_STATE_COMPLETE) {
- vipx_err("taskdesc state is invalid(%d)\n", taskdesc->state);
- vipx_taskdesc_print(graphmgr);
- BUG();
- }
-
- graph = taskdesc->graph;
- if (!graph) {
- vipx_err("graph is NULL(%d)\n", taskdesc_index);
- BUG();
- }
-
- task = taskdesc->task;
- if (!task) {
- vipx_err("task is NULL(%d)\n", taskdesc_index);
- BUG();
- }
-
- task->message = itask->message;
- task->tdindex = VIPX_MAX_TASKDESC;
- task->param0 = itask->param2;
- task->param1 = itask->param3;
-
- ret = CALL_GOPS(graph, done, task);
- if (ret) {
- vipx_err("CALL_GOPS(done) is fail(%d)\n", ret);
- BUG();
- }
-
- /* taskdesc cleanup */
- taskdesc->graph = NULL;
- taskdesc->task = NULL;
- __vipx_taskdesc_trans_com_to_fre(graphmgr, taskdesc);
-
- /* itask cleanup */
- taskmgr_e_barrier_irqs(itaskmgr, 0, flag);
- vipx_task_trans_com_to_fre(itaskmgr, itask);
- taskmgr_x_barrier_irqr(itaskmgr, 0, flag);
- break;
- default:
- BUG();
- break;
- }
-
- __vipx_graphmgr_sched(graphmgr);
- vipx_dbg("[%s:%d]\n", __func__, __LINE__);
-}
-
-int vipx_graphmgr_grp_register(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph)
-{
- int ret = 0;
- u32 index;
-
- BUG_ON(!graphmgr);
- BUG_ON(!graph);
-
- mutex_lock(&graphmgr->mlock);
- for (index = 0; index < VIPX_MAX_GRAPH; index++) {
- if (!graphmgr->graph[index]) {
- graphmgr->graph[index] = graph;
- graph->idx = index;
- break;
- }
- }
- mutex_unlock(&graphmgr->mlock);
-
- if (index >= VIPX_MAX_GRAPH) {
- vipx_err("graph slot is lack\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- kthread_init_work(&graph->control.work, vipx_graph_thread);
- for (index = 0; index < VIPX_MAX_TASK; ++index)
- kthread_init_work(&graph->taskmgr.task[index].work, vipx_graph_thread);
-
- graph->global_lock = &graphmgr->mlock;
- atomic_inc(&graphmgr->active_cnt);
-
-p_err:
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_grp_unregister(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph)
-{
- int ret = 0;
-
- BUG_ON(!graphmgr);
- BUG_ON(!graph);
-
- mutex_lock(&graphmgr->mlock);
- graphmgr->graph[graph->idx] = NULL;
- mutex_unlock(&graphmgr->mlock);
-
- atomic_dec(&graphmgr->active_cnt);
-
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_grp_start(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph)
-{
- int ret = 0;
-
- mutex_lock(&graphmgr->mlock);
- if (test_bit(VIPX_GRAPHMGR_ENUM, &graphmgr->state)) {
- mutex_unlock(&graphmgr->mlock);
- goto p_skip_hw_init;
- }
-
- ret = __vipx_itf_init(graphmgr->interface, graph);
- if (ret) {
- mutex_unlock(&graphmgr->mlock);
- vipx_err("__vipx_itf_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- set_bit(VIPX_GRAPHMGR_ENUM, &graphmgr->state);
- mutex_unlock(&graphmgr->mlock);
-
-p_skip_hw_init:
-#if 0
- ret = __vipx_itf_create(graphmgr->interface, graph);
- if (ret) {
- vipx_err("__vipx_itf_create is fail(%d)\n", ret);
- goto p_err;
- }
-#endif
- ret = __vipx_itf_config(graphmgr->interface, graph);
- if (ret) {
- vipx_err("__vipx_itf_config is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_grp_stop(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph)
-{
- int ret = 0;
-
- ret = __vipx_itf_destroy(graphmgr->interface, graph);
- if (ret) {
- vipx_err("__vipx_itf_destroy is fail(%d)\n", ret);
- goto p_err;
- }
-
- mutex_lock(&graphmgr->mlock);
- if (test_bit(VIPX_GRAPHMGR_ENUM, &graphmgr->state) &&
- atomic_read(&graphmgr->active_cnt) == 1) {
- ret = __vipx_itf_deinit(graphmgr->interface, graph);
- if (ret) {
- mutex_unlock(&graphmgr->mlock);
- vipx_err("__vipx_itf_deinit is fail(%d)\n", ret);
- goto p_err;
- }
-
- clear_bit(VIPX_GRAPHMGR_ENUM, &graphmgr->state);
- }
- mutex_unlock(&graphmgr->mlock);
-
-p_err:
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_itf_register(struct vipx_graphmgr *graphmgr, struct vipx_interface *interface)
-{
- int ret = 0;
- u32 index;
-
- BUG_ON(!graphmgr);
- BUG_ON(!interface);
-
- graphmgr->interface = interface;
- for (index = 0; index < VIPX_MAX_TASK; ++index)
- kthread_init_work(&interface->taskmgr.task[index].work, vipx_interface_thread);
-
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_itf_unregister(struct vipx_graphmgr *graphmgr, struct vipx_interface *interface)
-{
- int ret = 0;
- BUG_ON(!graphmgr);
- BUG_ON(!interface);
-
- graphmgr->interface = NULL;
-
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-void vipx_graphmgr_queue(struct vipx_graphmgr *graphmgr, struct vipx_task *task)
-{
- BUG_ON(!graphmgr);
- BUG_ON(!task);
-
- kthread_queue_work(&graphmgr->worker, &task->work);
- vipx_dbg("[%s:%d]\n", __func__, __LINE__);
-}
-
-int vipx_graphmgr_probe(struct vipx_graphmgr *graphmgr)
-{
- int ret = 0;
- u32 index;
- struct vipx_device *device = container_of(graphmgr, struct vipx_device, graphmgr);
-
- BUG_ON(!graphmgr);
- BUG_ON(!device);
-
- graphmgr->tick_cnt = 0;
- graphmgr->tick_pos = 0;
- graphmgr->sched_cnt = 0;
- graphmgr->sched_pos = 0;
- graphmgr->task_graph = NULL;
-#ifdef USE_TASK_TIMER
- graphmgr->task_timer = NULL;
-#endif
- atomic_set(&graphmgr->active_cnt, 0);
- mutex_init(&graphmgr->mlock);
- mutex_init(&graphmgr->tdlock);
- clear_bit(VIPX_GRAPHMGR_OPEN, &graphmgr->state);
- clear_bit(VIPX_GRAPHMGR_ENUM, &graphmgr->state);
-
- for (index = 0; index < VIPX_MAX_GRAPH; ++index)
- graphmgr->graph[index] = NULL;
-
- INIT_LIST_HEAD(&graphmgr->tdfre_list);
- INIT_LIST_HEAD(&graphmgr->tdrdy_list);
- INIT_LIST_HEAD(&graphmgr->tdreq_list);
- INIT_LIST_HEAD(&graphmgr->tdalc_list);
- INIT_LIST_HEAD(&graphmgr->tdpro_list);
- INIT_LIST_HEAD(&graphmgr->tdcom_list);
-
- graphmgr->tdfre_cnt = 0;
- graphmgr->tdrdy_cnt = 0;
- graphmgr->tdreq_cnt = 0;
- graphmgr->tdalc_cnt = 0;
- graphmgr->tdpro_cnt = 0;
- graphmgr->tdcom_cnt = 0;
-
- for (index = 0; index < VIPX_MAX_TASKDESC; ++index) {
- graphmgr->taskdesc[index].index = index;
- graphmgr->taskdesc[index].graph = NULL;
- graphmgr->taskdesc[index].task = NULL;
- graphmgr->taskdesc[index].state = VIPX_TASKDESC_STATE_INVALID;
- __vipx_taskdesc_s_free(graphmgr, &graphmgr->taskdesc[index]);
- }
-
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_open(struct vipx_graphmgr *graphmgr)
-{
- int ret = 0;
- char name[30];
- struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
-
- BUG_ON(!graphmgr);
-
- kthread_init_worker(&graphmgr->worker);
- snprintf(name, sizeof(name), "vipx_graph");
- graphmgr->task_graph = kthread_run(kthread_worker_fn, &graphmgr->worker, name);
- if (IS_ERR_OR_NULL(graphmgr->task_graph)) {
- vipx_err("kthread_run is fail\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = sched_setscheduler_nocheck(graphmgr->task_graph, SCHED_FIFO, ¶m);
- if (ret) {
- vipx_err("sched_setscheduler_nocheck is fail(%d)\n", ret);
- goto p_err;
- }
-
-#ifdef USE_TASK_TIMER
- snprintf(name, sizeof(name), "vipx_timer");
- graphmgr->task_timer = kthread_run(vipx_time_thread, graphmgr, name);
- if (IS_ERR_OR_NULL(graphmgr->task_timer)) {
- vipx_err("kthread_run is fail\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = sched_setscheduler_nocheck(graphmgr->task_timer, SCHED_FIFO, ¶m);
- if (ret) {
- vipx_err("sched_setscheduler_nocheck is fail(%d)\n", ret);
- goto p_err;
- }
-#endif
-
- set_bit(VIPX_GRAPHMGR_OPEN, &graphmgr->state);
-
-p_err:
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
-
-int vipx_graphmgr_close(struct vipx_graphmgr *graphmgr)
-{
- int ret = 0;
-
-#ifdef USE_TASK_TIMER
- kthread_stop(graphmgr->task_timer);
-#endif
- kthread_stop(graphmgr->task_graph);
-
- clear_bit(VIPX_GRAPHMGR_OPEN, &graphmgr->state);
- clear_bit(VIPX_GRAPHMGR_ENUM, &graphmgr->state);
-
- vipx_info("[%s:%d]\n", __func__, __LINE__);
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#ifndef VIPX_GRAPHMGR_H_
-#define VIPX_GRAPHMGR_H_
-
-#include <linux/kthread.h>
-#include <linux/types.h>
-
-#include "vipx-taskmgr.h"
-#include "vipx-graph.h"
-#include "vipx-interface.h"
-
-#define VIPX_MAX_TASKDESC (VIPX_MAX_GRAPH * 2)
-
-enum vipx_taskdesc_state {
- VIPX_TASKDESC_STATE_INVALID,
- VIPX_TASKDESC_STATE_FREE,
- VIPX_TASKDESC_STATE_READY,
- VIPX_TASKDESC_STATE_REQUEST,
- VIPX_TASKDESC_STATE_ALLOC,
- VIPX_TASKDESC_STATE_PROCESS,
- VIPX_TASKDESC_STATE_COMPLETE
-};
-
-struct vipx_taskdesc {
- struct list_head list;
- u32 index;
- u32 priority;
- struct vipx_graph *graph;
- struct vipx_task *task;
- u32 state;
-};
-
-enum vipx_graphmgr_state {
- VIPX_GRAPHMGR_OPEN,
- VIPX_GRAPHMGR_ENUM
-};
-
-enum vipx_graphmgr_client {
- VIPX_GRAPHMGR_CLIENT_GRAPH = 1,
- VIPX_GRAPHMGR_CLIENT_INTERFACE
-};
-
-struct vipx_graphmgr {
- struct vipx_graph *graph[VIPX_MAX_GRAPH];
- atomic_t active_cnt;
- unsigned long state;
- struct mutex mlock;
-
- u32 tick_cnt;
- u32 tick_pos;
- u32 sched_cnt;
- u32 sched_pos;
- struct kthread_worker worker;
- struct task_struct *task_graph;
- struct task_struct *task_timer;
-
- struct vipx_interface *interface;
-
- struct mutex tdlock;
- struct vipx_taskdesc taskdesc[VIPX_MAX_TASKDESC];
- struct list_head tdfre_list;
- struct list_head tdrdy_list;
- struct list_head tdreq_list;
- struct list_head tdalc_list;
- struct list_head tdpro_list;
- struct list_head tdcom_list;
- u32 tdfre_cnt;
- u32 tdrdy_cnt;
- u32 tdreq_cnt;
- u32 tdalc_cnt;
- u32 tdpro_cnt;
- u32 tdcom_cnt;
-};
-
-void vipx_taskdesc_print(struct vipx_graphmgr *graphmgr);
-int vipx_graphmgr_probe(struct vipx_graphmgr *graphmgr);
-int vipx_graphmgr_open(struct vipx_graphmgr *graphmgr);
-int vipx_graphmgr_close(struct vipx_graphmgr *graphmgr);
-int vipx_graphmgr_grp_register(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph);
-int vipx_graphmgr_grp_unregister(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph);
-int vipx_graphmgr_grp_start(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph);
-int vipx_graphmgr_grp_stop(struct vipx_graphmgr *graphmgr, struct vipx_graph *graph);
-int vipx_graphmgr_itf_register(struct vipx_graphmgr *graphmgr, struct vipx_interface *interface);
-int vipx_graphmgr_itf_unregister(struct vipx_graphmgr *graphmgr, struct vipx_interface *interface);
-void vipx_graphmgr_queue(struct vipx_graphmgr *graphmgr, struct vipx_task *task);
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-
-#include "vipx-io.h"
-void *mem2iocpy(void *dst,void *src, u32 size)
-{
- u8 *src8;
- u8 *dst8;
-
- src8 = (u8 *)(src);
- dst8 = (u8 *)(dst);
- /* first copy byte by byte till the source first alignment
- * this step is necessary to ensure we do not even try to access
- * data which is before the source buffer, hence it is not ours.
- */
- /* complete the left overs */
- while (size--)
- {
- IOW8(*dst8, *src8);
- dst8++;
- src8++;
- }
- return dst;
-}
-
-void *io2memcpy(void *dst,void *src, u32 size)
-{
- u8 *src8;
- u8 *dst8;
-
- src8 = (u8 *)(src);
- dst8 = (u8 *)(dst);
-
- while (size--)
- {
- *dst8 = IOR8(*src8);
- dst8++;
- src8++;
- }
-
- return dst;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <video/videonode.h>
-#include <asm/cacheflush.h>
-#include <asm/pgtable.h>
-#include <linux/firmware.h>
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/videodev2.h>
-#include <linux/videodev2_exynos_camera.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/of.h>
-#include <linux/dma-buf.h>
-#include <linux/ion_exynos.h>
-#include <asm/cacheflush.h>
-
-
-#include "vipx-config.h"
-#include "vipx-memory.h"
-
-#include <linux/exynos_iovmm.h>
-
-
-
-extern void *vipx_fw_code_rmem_base;
-
-#if defined(CONFIG_VIDEOBUF2_DMA_SG)
-/* vipx vb2 buffer operations */
-static inline ulong vipx_vb2_ion_plane_kvaddr(
- struct vipx_vb2_buf *vbuf, u32 plane)
-
-{
- return (ulong)vb2_plane_vaddr(&vbuf->vb.vb2_buf, plane);
-}
-
-static inline ulong vipx_vb2_ion_plane_cookie(
- struct vipx_vb2_buf *vbuf, u32 plane)
-{
- return (ulong)vb2_plane_cookie(&vbuf->vb.vb2_buf, plane);
-}
-
-static dma_addr_t vipx_vb2_ion_plane_dvaddr(
- struct vipx_vb2_buf *vbuf, u32 plane)
-
-{
- return (ulong)vb2_dma_sg_plane_dma_addr(&vbuf->vb.vb2_buf, plane);
-}
-#if 0
-static void vipx_vb2_ion_plane_prepare(struct vipx_vb2_buf *vbuf,
- u32 plane, bool exact)
-{
- struct vb2_buffer *vb = &vbuf->vb.vb2_buf;
- enum dma_data_direction dir;
- unsigned long size;
- u32 spare;
-
- /* skip meta plane */
- spare = vb->num_planes - 1;
- if (plane == spare)
- return;
-
- dir = V4L2_TYPE_IS_OUTPUT(vb->type) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- size = exact ?
- vb2_get_plane_payload(vb, plane) : vb2_plane_size(vb, plane);
-
- vb2_ion_sync_for_device((void *)vb2_plane_cookie(vb, plane), 0,
- size, dir);
-}
-
-static void vipx_vb2_ion_plane_finish(struct vipx_vb2_buf *vbuf,
- u32 plane, bool exact)
-{
- struct vb2_buffer *vb = &vbuf->vb.vb2_buf;
- enum dma_data_direction dir;
- unsigned long size;
- u32 spare;
-
- /* skip meta plane */
- spare = vb->num_planes - 1;
- if (plane == spare)
- return;
-
- dir = V4L2_TYPE_IS_OUTPUT(vb->type) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- size = exact ?
- vb2_get_plane_payload(vb, plane) : vb2_plane_size(vb, plane);
-
- vb2_ion_sync_for_cpu((void *)vb2_plane_cookie(vb, plane), 0,
- size, dir);
-}
-
-static void vipx_vb2_ion_buf_prepare(struct vipx_vb2_buf *vbuf, bool exact)
-{
- struct vb2_buffer *vb = &vbuf->vb.vb2_buf;
- enum dma_data_direction dir;
- unsigned long size;
- u32 plane;
- u32 spare;
-
- dir = V4L2_TYPE_IS_OUTPUT(vb->type) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- /* skip meta plane */
- spare = vb->num_planes - 1;
-
- for (plane = 0; plane < spare; plane++) {
- size = exact ?
- vb2_get_plane_payload(vb, plane) : vb2_plane_size(vb, plane);
-
- vb2_ion_sync_for_device((void *)vb2_plane_cookie(vb, plane), 0,
- size, dir);
- }
-}
-
-static void vipx_vb2_ion_buf_finish(struct vipx_vb2_buf *vbuf, bool exact)
-{
- struct vb2_buffer *vb = &vbuf->vb.vb2_buf;
- enum dma_data_direction dir;
- unsigned long size;
- u32 plane;
- u32 spare;
-
- dir = V4L2_TYPE_IS_OUTPUT(vb->type) ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE;
-
- /* skip meta plane */
- spare = vb->num_planes - 1;
-
- for (plane = 0; plane < spare; plane++) {
- size = exact ?
- vb2_get_plane_payload(vb, plane) : vb2_plane_size(vb, plane);
-
- vb2_ion_sync_for_cpu((void *)vb2_plane_cookie(vb, plane), 0,
- size, dir);
- }
-
- clear_bit(VIPX_VBUF_CACHE_INVALIDATE, &vbuf->cache_state);
-}
-#endif
-
-const struct vipx_vb2_buf_ops vipx_vb2_buf_ops_ion = {
- .plane_kvaddr = vipx_vb2_ion_plane_kvaddr,
- .plane_cookie = vipx_vb2_ion_plane_cookie,
- .plane_dvaddr = vipx_vb2_ion_plane_dvaddr,
-// .plane_prepare = vipx_vb2_ion_plane_prepare,
-// .plane_finish = vipx_vb2_ion_plane_finish,
-// .buf_prepare = vipx_vb2_ion_buf_prepare,
-// .buf_finish = vipx_vb2_ion_buf_finish,
-};
-
-/* vipx private buffer operations */
-static void vipx_ion_free(struct vipx_priv_buf *pbuf)
-{
- struct vipx_ion_ctx *alloc_ctx;
-
- alloc_ctx = pbuf->ctx;
- mutex_lock(&alloc_ctx->lock);
- if (pbuf->iova)
- ion_iovmm_unmap(pbuf->attachment, pbuf->iova);
- if (pbuf->kva)
- dma_buf_vunmap(pbuf->dma_buf, pbuf->kva);
- mutex_unlock(&alloc_ctx->lock);
-
- dma_buf_unmap_attachment(pbuf->attachment, pbuf->sgt,
- DMA_BIDIRECTIONAL);
- dma_buf_detach(pbuf->dma_buf, pbuf->attachment);
- dma_buf_put(pbuf->dma_buf);
-
- vfree(pbuf);
-}
-
-static void *vipx_ion_kvaddr(struct vipx_priv_buf *pbuf)
-{
- if (!pbuf)
- return 0;
-
- if (!pbuf->kva)
- pbuf->kva = dma_buf_vmap(pbuf->dma_buf);
-
- return pbuf->kva;
-
-}
-
-static dma_addr_t vipx_ion_dvaddr(struct vipx_priv_buf *pbuf)
-{
- dma_addr_t dva = 0;
-
- if (!pbuf)
- return -EINVAL;
-
- if (pbuf->iova == 0)
- return -EINVAL;
-
- dva = pbuf->iova;
-
- return (ulong)dva;
-}
-
-static phys_addr_t vipx_ion_phaddr(struct vipx_priv_buf *pbuf)
-{
- /* PHCONTIG option is not supported in ION */
- return 0;
-}
-
-static void vipx_ion_sync_for_device(struct vipx_priv_buf *pbuf,
- off_t offset, size_t size, enum dma_data_direction dir)
-{
- struct vipx_ion_ctx *alloc_ctx = pbuf->ctx;
-
- if (pbuf->kva) {
- BUG_ON((offset < 0) || (offset > pbuf->size));
- BUG_ON((offset + size) < size);
- BUG_ON((size > pbuf->size) || ((offset + size) > pbuf->size));
-
- __dma_map_area(pbuf->kva + offset, size, dir);
- }
-}
-
-static void vipx_ion_sync_for_cpu(struct vipx_priv_buf *pbuf,
- off_t offset, size_t size, enum dma_data_direction dir)
-{
- struct vipx_ion_ctx *alloc_ctx = pbuf->ctx;
-
- if (pbuf->kva) {
- BUG_ON((offset < 0) || (offset > pbuf->size));
- BUG_ON((offset + size) < size);
- BUG_ON((size > pbuf->size) || ((offset + size) > pbuf->size));
-
- __dma_unmap_area(pbuf->kva + offset, size, dir);
- }
-}
-
-const struct vipx_priv_buf_ops vipx_priv_buf_ops_ion = {
- .free = vipx_ion_free,
- .kvaddr = vipx_ion_kvaddr,
- .dvaddr = vipx_ion_dvaddr,
- .phaddr = vipx_ion_phaddr,
- .sync_for_device = vipx_ion_sync_for_device,
- .sync_for_cpu = vipx_ion_sync_for_cpu,
-};
-
-/* vipx memory operations */
-static void *vipx_ion_init(struct device *dev)
-{
- struct vipx_ion_ctx *ctx;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return ERR_PTR(-ENOMEM);
-
- ctx->dev = dev;
- ctx->alignment = SZ_4K;
- ctx->flags = ION_FLAG_CACHED;
- mutex_init(&ctx->lock);
-
- return ctx;
-
-}
-
-static void vipx_ion_deinit(void *ctx)
-{
- struct vipx_ion_ctx *alloc_ctx = ctx;
-
- mutex_destroy(&alloc_ctx->lock);
- kfree(alloc_ctx);
-}
-
-static struct vipx_priv_buf *vipx_ion_alloc(void *ctx,
- size_t size, size_t align)
-{
- struct vipx_ion_ctx *alloc_ctx = ctx;
- struct vipx_priv_buf *buf;
- const char *heapname = "ion_system_heap";
- int ret = 0;
-
- buf = vzalloc(sizeof(*buf));
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
- size = PAGE_ALIGN(size);
-
- buf->dma_buf = ion_alloc_dmabuf(heapname, size, alloc_ctx->flags);
- if (IS_ERR(buf->dma_buf)) {
- ret = -ENOMEM;
- goto err_alloc;
- }
-
- buf->attachment = dma_buf_attach(buf->dma_buf, alloc_ctx->dev);
- if (IS_ERR(buf->attachment)) {
- ret = PTR_ERR(buf->attachment);
- goto err_attach;
- }
-
- buf->sgt = dma_buf_map_attachment(
- buf->attachment, DMA_BIDIRECTIONAL);
- if (IS_ERR(buf->sgt)) {
- ret = PTR_ERR(buf->sgt);
- goto err_map_dmabuf;
- }
-
-
- buf->ctx = alloc_ctx;
- buf->size = size;
- buf->direction = DMA_BIDIRECTIONAL;
- buf->ops = &vipx_priv_buf_ops_ion;
-
- mutex_lock(&alloc_ctx->lock);
- buf->iova = ion_iovmm_map(buf->attachment, 0,
- buf->size, buf->direction, 0);
- if (IS_ERR_VALUE(buf->iova)) {
- ret = (int)buf->iova;
- mutex_unlock(&alloc_ctx->lock);
- goto err_ion_map_io;
- }
- mutex_unlock(&alloc_ctx->lock);
-
- return buf;
-
-err_ion_map_io:
- dma_buf_unmap_attachment(buf->attachment, buf->sgt,
- DMA_BIDIRECTIONAL);
-err_map_dmabuf:
- dma_buf_detach(buf->dma_buf, buf->attachment);
-err_attach:
- dma_buf_put(buf->dma_buf);
-err_alloc:
- vfree(buf);
-
-
- pr_err("%s: Error occured while allocating\n", __func__);
- return ERR_PTR(ret);
-}
-
-static int vipx_ion_resume(void *ctx)
-{
- struct vipx_ion_ctx *alloc_ctx = ctx;
- int ret = 0;
-
- pr_info("ASDF %s ASDF", __func__);
-
- if (!alloc_ctx)
- return -ENOENT;
-
- mutex_lock(&alloc_ctx->lock);
- if (alloc_ctx->iommu_active_cnt == 0)
- ret = iovmm_activate(alloc_ctx->dev);
- if (!ret)
- alloc_ctx->iommu_active_cnt++;
- mutex_unlock(&alloc_ctx->lock);
-
- return ret;
-}
-
-static void vipx_ion_suspend(void *ctx)
-{
- struct vipx_ion_ctx *alloc_ctx = ctx;
-
- if (!alloc_ctx)
- return;
-
- mutex_lock(&alloc_ctx->lock);
- BUG_ON(alloc_ctx->iommu_active_cnt == 0);
-
- if (--alloc_ctx->iommu_active_cnt == 0)
- iovmm_deactivate(alloc_ctx->dev);
- mutex_unlock(&alloc_ctx->lock);
-}
-
-const struct vipx_mem_ops vipx_mem_ops_ion = {
- .init = vipx_ion_init,
- .cleanup = vipx_ion_deinit,
- .resume = vipx_ion_resume,
- .suspend = vipx_ion_suspend,
- .alloc = vipx_ion_alloc,
-};
-#endif
-
-/* vipx private buffer operations */
-static void vipx_km_free(struct vipx_priv_buf *pbuf)
-{
- kfree(pbuf->kvaddr);
- kfree(pbuf);
-}
-
-static void *vipx_km_kvaddr(struct vipx_priv_buf *pbuf)
-{
- if (!pbuf)
- return 0;
-
- return pbuf->kvaddr;
-}
-
-static phys_addr_t vipx_km_phaddr(struct vipx_priv_buf *pbuf)
-{
- phys_addr_t pa = 0;
-
- if (!pbuf)
- return 0;
-
- pa = virt_to_phys(pbuf->kvaddr);
-
- return pa;
-}
-const struct vipx_priv_buf_ops vipx_priv_buf_ops_km = {
- .free = vipx_km_free,
- .kvaddr = vipx_km_kvaddr,
- .phaddr = vipx_km_phaddr,
-};
-
-static struct vipx_priv_buf *vipx_kmalloc(size_t size, size_t align)
-{
- struct vipx_priv_buf *buf = NULL;
- int ret = 0;
-
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (!buf)
- return ERR_PTR(-ENOMEM);
-
- buf->kvaddr = kzalloc(size, GFP_KERNEL);
- if (!buf->kvaddr) {
- ret = -ENOMEM;
- goto err_priv_alloc;
- }
-
- buf->size = size;
- buf->align = align;
- buf->ops = &vipx_priv_buf_ops_km;
-
- return buf;
-
-err_priv_alloc:
- kfree(buf);
-
- return ERR_PTR(ret);
-}
-
-int vipx_memory_probe(struct vipx_memory *mem, struct device *dev)
-{
- u32 ret = 0;
-
-#if defined(CONFIG_VIDEOBUF2_DMA_SG)
- mem->vipx_mem_ops = &vipx_mem_ops_ion;
- mem->vb2_mem_ops = &vb2_dma_sg_memops;
- mem->vipx_vb2_buf_ops = &vipx_vb2_buf_ops_ion;
- mem->kmalloc = &vipx_kmalloc;
-#endif
-
- mem->dev = dev;
- mem->iommu_domain = get_domain_from_dev(dev);
-
- mem->default_ctx = CALL_PTR_MEMOP(mem, init, dev);
- if (IS_ERR_OR_NULL(mem->default_ctx)) {
- if (IS_ERR(mem->default_ctx))
- ret = PTR_ERR(mem->default_ctx);
- else
- ret = -EINVAL;
- goto p_err;
- }
-
-p_err:
- probe_info("%s():%d\n", __func__, ret);
- return 0;
-}
-
-dma_addr_t vipx_allocate_heap(struct vipx_memory *mem, u32 size)
-{
- int ret = 0;
- struct vipx_minfo *minfo;
-
- BUG_ON(!mem);
-
- minfo = &mem->info;
-
- if (size != 0) {
- minfo->pb_heap = vipx_ion_alloc(mem->default_ctx, size, SZ_4K);
- if (IS_ERR_OR_NULL(minfo->pb_heap)) {
- vipx_err("failed to allocate buffer for VIPX_CM7_HEAP_SIZE");
- ret = -ENOMEM;
- }
- minfo->kvaddr_heap = vipx_ion_kvaddr(minfo->pb_heap);
- minfo->dvaddr_heap = vipx_ion_dvaddr(minfo->pb_heap);
- vipx_info("heap kva(0x%p), dva(0x%x), size(%ld)\n",
- minfo->kvaddr_heap, (u32)minfo->dvaddr_heap, minfo->pb_heap->size);
- }
- return minfo->dvaddr_heap;
-
-}
-
-void vipx_free_heap(struct vipx_memory *mem, struct vipx_binary *binary, u32 heap_size)
-{
- struct vipx_minfo *minfo;
-#ifdef DUMP_DEBUG_LOG_REGION
- int ret;
-#endif
- BUG_ON(!mem);
-
- minfo = &mem->info;
-#ifdef DUMP_DEBUG_LOG_REGION
-
- vipx_info("heap kva %p\n", minfo->kvaddr_heap);
-
- if (minfo->pb_heap) {
- if (!IS_ERR_OR_NULL(minfo->kvaddr_heap)) {
- ret = vipx_binary_write(binary, VIPX_FW_PATH1, "vipx_heap.bin", minfo->kvaddr_heap, heap_size);
- if (ret)
- vipx_err("vipx_binary_write is fail(%d)\n", ret);
- }
- }
-#endif
-
- vipx_info("Free heap\n");
- if (minfo->pb_heap) {
- vipx_ion_free(minfo->pb_heap);
- minfo->pb_heap = 0;
- minfo->kvaddr_heap = 0;
- minfo->dvaddr_heap = 0;
- }
-}
-
-int vipx_memory_open(struct vipx_memory *mem)
-{
- int ret = 0;
- struct vipx_minfo *minfo;
-
- BUG_ON(!mem);
-
- minfo = &mem->info;
-
- /* TODO */
- if (VIPX_CM7_DRAM_BIN_SIZE != 0) {
-#if 1
- minfo->paddr_fw = VIPX_IOVA_DRAM_FIRMWARE;
- minfo->kvaddr_fw = vipx_fw_code_rmem_base;
- minfo->dvaddr_fw = VIPX_IOVA_DRAM_FIRMWARE;
- iommu_map(mem->iommu_domain, VIPX_IOVA_DRAM_FIRMWARE, minfo->paddr_fw,
- VIPX_CM7_DRAM_BIN_SIZE, 0);
- //memset(minfo->kvaddr_fw, 0x0, VIPX_CM7_DRAM_BIN_SIZE);
-#else
- minfo->kvaddr_fw = dmam_alloc_coherent(mem->dev, VIPX_CM7_DRAM_BIN_SIZE,
- &minfo->paddr_fw, GFP_KERNEL);
- if (IS_ERR_OR_NULL(minfo->kvaddr_fw)) {
- vipx_err("Failed to allocate coherent memory: %ld\n",
- PTR_ERR(minfo->kvaddr_fw));
- ret = PTR_ERR(minfo->kvaddr_fw);
- goto p_err;
- }
- vipx_info("%s(%pa) is mapped on %p with size of %d\n",
- "vipx_firmware", &minfo->paddr_fw, minfo->kvaddr_fw,
- VIPX_CM7_DRAM_BIN_SIZE);
-
- minfo->dvaddr_fw = VIPX_IOVA_DRAM_FIRMWARE;
-
- memset(minfo->kvaddr_fw, 0x0, VIPX_CM7_DRAM_BIN_SIZE);
- iommu_map(mem->iommu_domain, VIPX_IOVA_DRAM_FIRMWARE, minfo->paddr_fw,
- VIPX_CM7_DRAM_BIN_SIZE, 0);
-#endif
- }
-
- if (VIPX_MBOX_SIZE != 0) {
- minfo->kvaddr_mbox = dmam_alloc_coherent(mem->dev, VIPX_MBOX_SIZE,
- &minfo->paddr_mbox, GFP_KERNEL);
- if (IS_ERR_OR_NULL(minfo->kvaddr_mbox)) {
- vipx_err("Failed to allocate coherent memory: %ld\n",
- PTR_ERR(minfo->kvaddr_mbox));
- ret = PTR_ERR(minfo->kvaddr_mbox);
- goto p_err;
- }
- vipx_info("%s(%pa) is mapped on %p with size of %d\n",
- "vipx_mbox", &minfo->paddr_mbox, minfo->kvaddr_mbox,
- VIPX_MBOX_SIZE);
-
- minfo->dvaddr_mbox = VIPX_IOVA_DRAM_MBOX;
-
- //memset(minfo->kvaddr_mbox, 0x0, VIPX_MBOX_SIZE);
- iommu_map(mem->iommu_domain, VIPX_IOVA_DRAM_MBOX, minfo->paddr_mbox,
- VIPX_MBOX_SIZE, 0);
- }
-
- if (VIPX_DEBUG_SIZE != 0) {
- minfo->pb_debug = vipx_ion_alloc(mem->default_ctx, VIPX_DEBUG_SIZE, SZ_4K);
- if (IS_ERR_OR_NULL(minfo->pb_debug)) {
- vipx_err("failed to allocate buffer for VIPX_DEBUG_SIZE");
- ret = -ENOMEM;
- }
- minfo->kvaddr_debug = vipx_ion_kvaddr(minfo->pb_debug);
- minfo->dvaddr_debug = vipx_ion_dvaddr(minfo->pb_debug);
- vipx_info("debug kva(0x%p), dva(0x%x), size(%ld)\n", minfo->kvaddr_debug, (u32)minfo->dvaddr_debug, minfo->pb_debug->size);
- }
-
-p_err:
- return ret;
-}
-
-int vipx_memory_close(struct vipx_memory *mem)
-{
- int ret = 0;
- struct vipx_minfo *minfo;
-
- BUG_ON(!mem);
-
- minfo = &mem->info;
-
- iommu_unmap(mem->iommu_domain, VIPX_IOVA_DRAM_FIRMWARE, VIPX_CM7_DRAM_BIN_SIZE);
-
-#if 0
- if (!IS_ERR_OR_NULL(minfo->kvaddr_fw)) {
- dmam_free_coherent(mem->dev, VIPX_CM7_DRAM_BIN_SIZE, minfo->kvaddr_fw,
- minfo->paddr_fw);
- }
-#endif
-
- iommu_unmap(mem->iommu_domain, VIPX_IOVA_DRAM_MBOX, VIPX_MBOX_SIZE);
-
- if (!IS_ERR_OR_NULL(minfo->kvaddr_mbox)) {
- dmam_free_coherent(mem->dev, VIPX_MBOX_SIZE, minfo->kvaddr_mbox,
- minfo->paddr_mbox);
- }
-
- if (minfo->pb_debug) {
- vipx_ion_free(minfo->pb_debug);
- minfo->pb_debug = 0;
- minfo->kvaddr_debug = 0;
- minfo->dvaddr_debug = 0;
- }
-
- if (minfo->pb_heap) {
- vipx_ion_free(minfo->pb_heap);
- minfo->pb_heap = 0;
- minfo->kvaddr_heap = 0;
- minfo->dvaddr_heap = 0;
- }
-
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "vipx-queue.h"
-#include "vipx-config.h"
-#include "vipx-taskmgr.h"
-#include "vipx-graph.h"
-
-extern const struct vb_ops vb_ops;
-extern const struct vipx_queue_ops vipx_queue_ops;
-
-int vipx_queue_init(struct vipx_queue *queue,
- struct vipx_memory *memory,
- struct mutex *lock)
-{
- int ret = 0;
- struct vb_queue *inq, *otq;
-
- queue->qops = &vipx_queue_ops;
- inq = &queue->inqueue;
- otq = &queue->otqueue;
- inq->private_data = queue;
- otq->private_data = queue;
-
- ret = vb_queue_init(inq, memory->dev, memory->vb2_mem_ops, &vb_ops, lock, VS4L_DIRECTION_IN);
- if (ret) {
- vipx_err("vb_queue_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vb_queue_init(otq, memory->dev, memory->vb2_mem_ops, &vb_ops, lock, VS4L_DIRECTION_OT);
- if (ret) {
- vipx_err("vb_queue_init is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_queue_s_format(struct vipx_queue *queue, struct vs4l_format_list *f)
-{
- int ret = 0;
- struct vb_queue *q, *inq, *otq;
-
- BUG_ON(!queue);
- BUG_ON(!f);
-
- inq = &queue->inqueue;
- otq = &queue->otqueue;
-
- if (f->direction == VS4L_DIRECTION_IN)
- q = inq;
- else
- q = otq;
-
- ret = CALL_QOPS(queue, format, f);
- if (ret) {
- vipx_err("CALL_QOPS(format) is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vb_queue_s_format(q, f);
- if (ret) {
- vipx_err("vb_queue_s_format is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_queue_start(struct vipx_queue *queue)
-{
- int ret = 0;
- struct vb_queue *inq, *otq;
-
- inq = &queue->inqueue;
- otq = &queue->otqueue;
-
- ret = vb_queue_start(inq);
- if (ret) {
- vipx_err("vb_queue_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vb_queue_start(otq);
- if (ret) {
- vipx_err("vb_queue_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = CALL_QOPS(queue, start);
- if (ret) {
- vipx_err("CALL_QOPS(start) is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_queue_stop(struct vipx_queue *queue)
-{
- int ret = 0;
- struct vb_queue *inq, *otq;
-
- inq = &queue->inqueue;
- otq = &queue->otqueue;
-
- ret = CALL_QOPS(queue, stop);
- if (ret) {
- vipx_err("CALL_QOPS(stop) is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vb_queue_stop(inq);
- if (ret) {
- vipx_err("vb_queue_init is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vb_queue_stop(otq);
- if (ret) {
- vipx_err("vb_queue_init is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_queue_poll(struct vipx_queue *queue, struct file *file, poll_table *poll)
-{
- int ret = 0;
- struct vb_queue *inq, *otq;
- unsigned long events;
-
- BUG_ON(!queue);
- BUG_ON(!file);
- BUG_ON(!poll);
-
- events = poll_requested_events(poll);
-
- inq = &queue->inqueue;
- otq = &queue->otqueue;
-
- if (events & POLLIN) {
- if (list_empty(&inq->done_list))
- poll_wait(file, &inq->done_wq, poll);
-
- if (list_empty(&inq->done_list))
- ret |= POLLIN | POLLWRNORM;
- }
-
- if (events & POLLOUT) {
- if (list_empty(&otq->done_list))
- poll_wait(file, &otq->done_wq, poll);
-
- if (list_empty(&otq->done_list))
- ret |= POLLOUT | POLLWRNORM;
- }
-
- return ret;
-}
-
-int vipx_queue_qbuf(struct vipx_queue *queue, struct vs4l_container_list *c)
-{
- int ret = 0;
- struct vb_queue *q, *inq, *otq;
- struct vb_bundle *invb, *otvb;
-
- inq = &queue->inqueue;
- otq = &queue->otqueue;
-
- if (c->direction == VS4L_DIRECTION_IN)
- q = inq;
- else
- q = otq;
-
- ret = vb_queue_qbuf(q, c);
- if (ret) {
- vipx_err("vb_queue_qbuf is fail(%d)\n", ret);
- goto p_err;
- }
-
- if (list_empty(&inq->queued_list))
- goto p_err;
-
- if (list_empty(&otq->queued_list))
- goto p_err;
-
- invb = list_first_entry(&inq->queued_list, struct vb_bundle, queued_entry);
- otvb = list_first_entry(&otq->queued_list, struct vb_bundle, queued_entry);
-
- vb_queue_process(inq, invb);
- vb_queue_process(otq, otvb);
-
- ret = CALL_QOPS(queue, queue, &invb->clist, &otvb->clist);
- if (ret) {
- vipx_err("CALL_QOPS(queue) is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_queue_dqbuf(struct vipx_queue *queue, struct vs4l_container_list *c, bool nonblocking)
-{
- int ret = 0;
- struct vb_queue *q;
- struct vb_bundle *bundle;
-
- BUG_ON(!queue);
-
- if (c->direction == VS4L_DIRECTION_IN)
- q = &queue->inqueue;
- else
- q = &queue->otqueue;
-
- ret = vb_queue_dqbuf(q, c, nonblocking);
- if (ret) {
- vipx_err("vb_queue_dqbuf is fail(%d)\n", ret);
- goto p_err;
- }
-
- if (c->index >= VIPX_MAX_BUFFER) {
- vipx_err("container index(%d) is invalid\n", c->index);
- ret = -EINVAL;
- goto p_err;
- }
-
- bundle = q->bufs[c->index];
- if (!bundle) {
- vipx_err("bundle(%d) is NULL\n", c->index);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (bundle->clist.index != c->index) {
- vipx_err("index is NOT matched(%d != %d)\n", bundle->clist.index, c->index);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = CALL_QOPS(queue, deque, &bundle->clist);
- if (ret) {
- vipx_err("CALL_QOPS(deque) is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-void vipx_queue_done(struct vipx_queue *queue,
- struct vb_container_list *incl,
- struct vb_container_list *otcl,
- unsigned long flags)
-{
- struct vb_queue *inq, *otq;
- struct vb_bundle *invb, *otvb;
-
- BUG_ON(!queue);
- BUG_ON(!incl);
- BUG_ON(!otcl);
-
- inq = &queue->inqueue;
- otq = &queue->otqueue;
-
- if (list_empty(&inq->process_list)) {
- vipx_err("inqueue is empty\n");
- BUG();
- }
-
- if (list_empty(&otq->process_list)) {
- vipx_err("otqueue is empty\n");
- BUG();
- }
-
- invb = container_of(incl, struct vb_bundle, clist);
- otvb = container_of(otcl, struct vb_bundle, clist);
-
- if (invb->state != VB_BUF_STATE_PROCESS) {
- vipx_err("invb state(%d) is invalid\n", invb->state);
- BUG();
- }
-
- if (otvb->state != VB_BUF_STATE_PROCESS) {
- vipx_err("otvb state(%d) is invalid\n", otvb->state);
- BUG();
- }
-
- otvb->flags |= flags;
- vb_queue_done(otq, otvb);
-
- invb->flags |= flags;
- vb_queue_done(inq, invb);
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_QUEUE_H_
-#define VIPX_QUEUE_H_
-
-#include <linux/types.h>
-#include <linux/mutex.h>
-
-#include "vision-buffer.h"
-#include "vipx-taskmgr.h"
-#include "vipx-memory.h"
-
-struct vipx_queue;
-
-struct vipx_queue_ops {
- int (*start)(struct vipx_queue *queue);
- int (*stop)(struct vipx_queue *queue);
- int (*format)(struct vipx_queue *queue, struct vs4l_format_list *f);
- int (*queue)(struct vipx_queue *queue, struct vb_container_list *incl, struct vb_container_list *otcl);
- int (*deque)(struct vipx_queue *queue, struct vb_container_list *clist);
-};
-
-struct vipx_queue {
- struct vb_queue inqueue;
- struct vb_queue otqueue;
- const struct vipx_queue_ops *qops;
-};
-
-int vipx_queue_init(struct vipx_queue *queue, struct vipx_memory *memory, struct mutex *lock);
-int vipx_queue_s_format(struct vipx_queue *queue, struct vs4l_format_list *f);
-int vipx_queue_start(struct vipx_queue *queue);
-int vipx_queue_stop(struct vipx_queue *queue);
-int vipx_queue_poll(struct vipx_queue *queue, struct file *file, poll_table *poll);
-int vipx_queue_qbuf(struct vipx_queue *queue, struct vs4l_container_list *c);
-int vipx_queue_dqbuf(struct vipx_queue *queue, struct vs4l_container_list *c, bool nonblocking);
-void vipx_queue_done(struct vipx_queue *queue, struct vb_container_list *incl, struct vb_container_list *otcl, unsigned long flags);
-
-#define CALL_QOPS(q, op, ...) (((q)->qops->op) ? ((q)->qops->op(q, ##__VA_ARGS__)) : 0)
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/pm_qos.h>
-#include <linux/exynos_iovmm.h>
-#include <asm/cacheflush.h>
-#include <linux/io.h>
-
-#include "vipx-config.h"
-#include "vipx-device.h"
-#include "vipx-system.h"
-
-#define CAM_L0 690000
-#define CAM_L1 680000
-#define CAM_L2 670000
-#define CAM_L3 660000
-#define CAM_L4 650000
-
-#define MIF_L0 2093000
-#define MIF_L1 2002000
-#define MIF_L2 1794000
-#define MIF_L3 1539000
-#define MIF_L4 1352000
-#define MIF_L5 1014000
-#define MIF_L6 845000
-#define MIF_L7 676000
-
-struct pm_qos_request exynos_vipx_qos_cam;
-struct pm_qos_request exynos_vipx_qos_mem;
-
-int vipx_system_probe(struct vipx_system *system, struct platform_device *pdev)
-{
- int ret = 0;
- struct device *dev;
- struct resource *res;
- void __iomem *iomem;
- int irq;
-
- BUG_ON(!system);
- BUG_ON(!pdev);
-
- dev = &pdev->dev;
- system->cam_qos = 0;
- system->mif_qos = 0;
-
- /* VIPX_CPU_SS1 */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- probe_err("platform_get_resource(0) is fail(%p)", res);
- ret = PTR_ERR(res);
- goto p_err;
- }
-
- iomem = devm_ioremap_nocache(dev, res->start, resource_size(res));
- if (IS_ERR_OR_NULL(iomem)) {
- probe_err("devm_ioremap_resource(0) is fail(%p)", iomem);
- ret = PTR_ERR(iomem);
- goto p_err;
- }
-
- system->reg_ss[VIPX_REG_CPU_SS1] = iomem;
- system->reg_ss_size[VIPX_REG_CPU_SS1] = resource_size(res);
- probe_info("resource0 : %p\n", iomem);
-
- /* VIPX_CPU_SS2 */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res) {
- probe_err("platform_get_resource(1) is fail(%p)", res);
- ret = PTR_ERR(res);
- goto p_err;
- }
-
- iomem = devm_ioremap_nocache(dev, res->start, resource_size(res));
- if (IS_ERR_OR_NULL(iomem)) {
- probe_err("devm_ioremap_resource(1) is fail(%p)", iomem);
- ret = PTR_ERR(iomem);
- goto p_err;
- }
-
- system->reg_ss[VIPX_REG_CPU_SS2] = iomem;
- system->reg_ss_size[VIPX_REG_CPU_SS2] = resource_size(res);
- probe_info("resource1 : %p\n", iomem);
-
- /* VIPX ITCM */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
- if (!res) {
- probe_err("platform_get_resource(2) is fail(%p)", res);
- ret = PTR_ERR(res);
- goto p_err;
- }
-
- iomem = devm_ioremap_nocache(dev, res->start, resource_size(res));
- if (IS_ERR_OR_NULL(iomem)) {
- probe_err("devm_ioremap_resource(2) is fail(%p)", iomem);
- ret = PTR_ERR(iomem);
- goto p_err;
- }
-
- system->itcm = iomem;
- system->itcm_size = resource_size(res);
- probe_info("resource2 : %p\n", iomem);
-
- /* VIPX DTCM */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
- if (!res) {
- probe_err("platform_get_resource(3) is fail(%p)", res);
- ret = PTR_ERR(res);
- goto p_err;
- }
-
- iomem = devm_ioremap_nocache(dev, res->start, resource_size(res));
- if (IS_ERR_OR_NULL(iomem)) {
- probe_err("devm_ioremap_resource(3) is fail(%p)", iomem);
- ret = PTR_ERR(iomem);
- goto p_err;
- }
-
- system->dtcm = iomem;
- system->dtcm_size = resource_size(res);
- probe_info("resource3 : %p\n", iomem);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- probe_err("platform_get_irq(0) is fail(%d)", irq);
- ret = -EINVAL;
- goto p_err;
- }
-
- system->irq0 = irq;
-
- irq = platform_get_irq(pdev, 1);
- if (irq < 0) {
- probe_err("platform_get_irq(1) is fail(%d)", irq);
- ret = -EINVAL;
- goto p_err;
- }
-
- system->irq1 = irq;
-
- ret = vipx_exynos_probe(&system->exynos, dev, system->reg_ss, system->itcm, system->dtcm);
- if (ret) {
- probe_err("vipx_exynos_probe is fail(%d)\n", ret);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_memory_probe(&system->memory, dev);
- if (ret) {
- vipx_err("vipx_memory_probe is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_interface_probe(&system->interface, dev,
- system->reg_ss[VIPX_REG_CPU_SS1], system->reg_ss_size[VIPX_REG_CPU_SS1],
- system->irq0, system->irq1);
- if (ret) {
- vipx_err("vipx_interface_probe is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_binary_init(&system->binary, dev);
- if (ret) {
- vipx_err("vipx_binary_init is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- probe_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_system_open(struct vipx_system *system)
-{
- int ret = 0;
-
- ret = vipx_memory_open(&system->memory);
- if (ret) {
- vipx_err("vipx_memory_open is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_interface_open(&system->interface,
- (void *)system->memory.info.kvaddr_mbox, VIPX_MBOX_SIZE);
- if (ret) {
- vipx_err("vipx_interface_open is fail(%d)\n", ret);
- vipx_memory_close(&system->memory);
- goto p_err;
- }
-
-p_err:
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_system_close(struct vipx_system *system)
-{
- int ret = 0;
-
-#ifdef DUMP_DEBUG_LOG_REGION
- struct vipx_binary *binary;
- binary = &system->binary;
-
-// flush_all_cpu_caches();
-
- vipx_info("debug kva %p, heap kva %p\n", system->memory.info.kvaddr_debug, system->memory.info.kvaddr_heap);
- system->memory.info.pb_debug->ops->sync_for_cpu(system->memory.info.pb_debug, 0, system->memory.info.pb_debug->size, 0);
- if (!IS_ERR_OR_NULL(system->memory.info.kvaddr_debug)) {
- ret = vipx_binary_write(binary, VIPX_FW_PATH1, "vipx_log.bin", system->memory.info.kvaddr_debug, VIPX_DEBUG_SIZE);
- if (ret)
- vipx_err("vipx_binary_write is fail(%d)\n", ret);
- }
-
-#endif
-
- ret = vipx_interface_close(&system->interface);
- if (ret)
- vipx_err("vipx_interface_close is fail(%d)\n", ret);
-
- ret = vipx_memory_close(&system->memory);
- if (ret)
- vipx_err("vipx_memory_close is fail(%d)\n", ret);
-
- return ret;
-}
-
-int vipx_system_resume(struct vipx_system *system, u32 mode)
-{
- int ret = 0;
- struct vipx_exynos *exynos;
- struct vipx_memory *memory;
-
- BUG_ON(!system);
-
- exynos = &system->exynos;
- memory = &system->memory;
-
- ret = CLK_OP(exynos, clk_cfg);
- if (ret) {
- vipx_err("CLK_OP(clk_cfg) is fail(%d)\n", ret);
- goto p_err;
- }
-
-#if defined(CONFIG_PM_DEVFREQ)
- pm_qos_add_request(&exynos_vipx_qos_cam, PM_QOS_CAM_THROUGHPUT, CAM_L0);
- pm_qos_add_request(&exynos_vipx_qos_mem, PM_QOS_BUS_THROUGHPUT, MIF_L0);
-#endif
-
- ret = CLK_OP(exynos, clk_on);
- if (ret) {
- vipx_err("CLK_OP(clk_on) is fail(%d)\n", ret);
- goto p_err;
- }
-
-#if defined(CONFIG_VIDEOBUF2_DMA_SG)
- system->memory.vipx_mem_ops->resume(system->memory.default_ctx);
-#endif
-
- if (mode == VIPX_DEVICE_MODE_TEST)
- goto p_err;
-
- ret = vipx_system_fw_bootup(system);
- if (ret) {
- vipx_err("vipx_system_fw_bootup is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-int vipx_system_suspend(struct vipx_system *system)
-{
- int ret = 0;
- struct vipx_exynos *exynos;
- struct vipx_memory *memory;
-
- BUG_ON(!system);
-
- exynos = &system->exynos;
- memory = &system->memory;
-
-#if defined(CONFIG_VIDEOBUF2_DMA_SG)
- system->memory.vipx_mem_ops->suspend(system->memory.default_ctx);
-#endif
-
-#if 0
- ret = CTL_OP(exynos, ctl_reset, 0);
- if (ret)
- vipx_err("CTL_OP(ctl_reset) is fail(%d)\n", ret);
-#endif
- ret = CLK_OP(exynos, clk_off);
- if (ret)
- vipx_err("CLK_OP(clk_off) is fail(%d)\n", ret);
-
-#if defined(CONFIG_PM_DEVFREQ)
- pm_qos_remove_request(&exynos_vipx_qos_cam);
- pm_qos_remove_request(&exynos_vipx_qos_mem);
-#endif
-
- return ret;
-}
-
-int vipx_system_start(struct vipx_system *system)
-{
- int ret = 0;
-
- ret = vipx_interface_start(&system->interface);
- if (ret)
- vipx_err("vipx_interface_start is fail(%d)\n", ret);
-
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_system_stop(struct vipx_system *system)
-{
- int ret = 0;
-
- ret = vipx_interface_stop(&system->interface);
- if (ret)
- vipx_err("vipx_interface_stop is fail(%d)\n", ret);
-
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
-
-int vipx_system_fw_bootup(struct vipx_system *system)
-{
- int ret = 0;
- struct vipx_exynos *exynos;
- struct vipx_memory *memory;
- struct vipx_binary *binary;
-
- struct {
- volatile u32 sign;
- volatile u32 mbox_addr;
- volatile u32 mbox_size;
- volatile u32 debug_addr;
- volatile u32 debug_size;
- } *tail_p;
-
- BUG_ON(!system);
-
-// execl("/system/bin/cp", "/system/bin/cp", "/d/pm_qos/cam_throughput", "/data", (char *)0);
-// execl("/system/bin/cp", "/system/bin/cp", "/d/pm_qos/bus_throughput", "/data", (char *)0);
- exynos = &system->exynos;
- memory = &system->memory;
- binary = &system->binary;
-
- ret = CTL_OP(exynos, ctl_reset, 0);
- if (ret) {
- vipx_err("CTL_OP(ctl_reset) is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_binary_read(binary, VIPX_FW_PATH1, VIPX_FW_DRAM_NAME,
- (void *)system->memory.info.kvaddr_fw, VIPX_CM7_DRAM_BIN_SIZE);
- if (ret) {
- ret = vipx_binary_read(binary, VIPX_FW_PATH2, VIPX_FW_DRAM_NAME,
- (void *)system->memory.info.kvaddr_fw, VIPX_CM7_DRAM_BIN_SIZE);
- if (ret) {
- vipx_err("vipx_dram_binary_load is fail(%d)\n", ret);
- goto p_err;
- }
- }
-
- ret = vipx_binary_read(binary, VIPX_FW_PATH1, VIPX_FW_DTCM_NAME,
- (void *)system->dtcm, system->dtcm_size);
- if (ret) {
- ret = vipx_binary_read(binary, VIPX_FW_PATH2, VIPX_FW_DTCM_NAME,
- (void *)system->dtcm, system->dtcm_size - SZ_1K);
- if (ret) {
- vipx_err("vipx_dtcm_binary_load is fail(%d)\n", ret);
- goto p_err;
- }
- }
-
- tail_p = (void *)(system->dtcm + 0x3FD0);
- tail_p->sign = 0xABCDEFAB;
- tail_p->mbox_addr = system->memory.info.dvaddr_mbox;
- tail_p->mbox_size = VIPX_MBOX_SIZE;
- tail_p->debug_addr = system->memory.info.dvaddr_debug;
- tail_p->debug_size = VIPX_DEBUG_SIZE;
-
- vipx_info("host_shared : %p, mbox_addr : %x, mbox_size : %x, debug_addr : %x, debug_size : %x\n",
- tail_p, tail_p->mbox_addr, tail_p->mbox_size, tail_p->debug_addr, tail_p->debug_size);
-
- ret = vipx_binary_read(binary, VIPX_FW_PATH1, VIPX_FW_ITCM_NAME,
- (void *)system->itcm, system->itcm_size);
- if (ret) {
- ret = vipx_binary_read(binary, VIPX_FW_PATH2, VIPX_FW_ITCM_NAME,
- (void *)system->itcm, system->itcm_size);
- if (ret) {
- vipx_err("vipx_itcm_binary_load is fail(%d)\n", ret);
- goto p_err;
- }
- }
-
-// flush_all_cpu_caches();
-
- ret = CTL_OP(exynos, ctl_start, 0);
- if (ret) {
- vipx_err("CTL_OP(ctl_start) is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_hw_wait_bootup(&system->interface);
- if (ret) {
- vipx_err("vipx_hw_wait_bootup is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_info("%s():%d\n", __func__, ret);
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_SYSTEM_H_
-#define VIPX_SYSTEM_H_
-
-#include <linux/platform_device.h>
-
-#include "vipx-interface.h"
-#include "vipx-memory.h"
-#include "vipx-exynos.h"
-#include "vipx-binary.h"
-
-struct vipx_system {
- struct platform_device *pdev;
- void __iomem *reg_ss[VIPX_REG_MAX_CNT];
- void __iomem *itcm;
- void __iomem *dtcm;
- resource_size_t reg_ss_size[VIPX_REG_MAX_CNT];
- resource_size_t itcm_size;
- resource_size_t dtcm_size;
- int irq0;
- int irq1;
-
- u32 cam_qos;
- u32 mif_qos;
-
- struct vipx_interface interface;
- struct vipx_memory memory;
- struct vipx_exynos exynos;
- struct vipx_binary binary;
-};
-
-int vipx_system_probe(struct vipx_system *system, struct platform_device *pdev);
-int vipx_system_open(struct vipx_system *system);
-int vipx_system_close(struct vipx_system *system);
-int vipx_system_resume(struct vipx_system *system, u32 mode);
-int vipx_system_suspend(struct vipx_system *system);
-int vipx_system_start(struct vipx_system *system);
-int vipx_system_stop(struct vipx_system *system);
-int vipx_system_fw_bootup(struct vipx_system *system);
-
-#endif
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "vipx-debug.h"
-#include "vipx-taskmgr.h"
-#include "vipx-graphmgr.h"
-
-#if 0
-#define taskmgr_debug vipx_info
-#else
-#define taskmgr_debug(fmt, args...)
-#endif
-
-void vipx_task_s_free(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- task->state = VIPX_TASK_STATE_FREE;
-
- list_add_tail(&task->list, &taskmgr->fre_list);
- taskmgr->fre_cnt++;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_g_free(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->fre_cnt &&
- (*task = container_of(taskmgr->fre_list.next, struct vipx_task, list))) {
- list_del(&(*task)->list);
- taskmgr->fre_cnt--;
- (*task)->state = VIPX_TASK_STATE_INVALID;
- } else {
- *task = NULL;
- }
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_free_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->fre_cnt)
- *task = container_of(taskmgr->fre_list.next, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_free_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->fre_cnt)
- *task = container_of(taskmgr->fre_list.prev, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_print_free_list(struct vipx_taskmgr *taskmgr)
-{
- DLOG_INIT();
- struct vipx_task *task, *temp;
-
- DLOG("[FRM] fre(%d, %d) :", taskmgr->id, taskmgr->fre_cnt);
- list_for_each_entry_safe(task, temp, &taskmgr->fre_list, list) {
- DLOG("%d->", task->index);
- }
- DLOG("X");
-
- vipx_info("%s\n", DLOG_OUT());
-}
-
-void vipx_task_s_request(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- task->state = VIPX_TASK_STATE_REQUEST;
-
- list_add_tail(&task->list, &taskmgr->req_list);
- taskmgr->req_cnt++;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_g_request(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->req_cnt &&
- (*task = container_of(taskmgr->req_list.next, struct vipx_task, list))) {
- list_del(&(*task)->list);
- taskmgr->req_cnt--;
- (*task)->state = VIPX_TASK_STATE_INVALID;
- } else {
- *task = NULL;
- }
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_request_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->req_cnt)
- *task = container_of(taskmgr->req_list.next, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_request_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->req_cnt)
- *task = container_of(taskmgr->req_list.prev, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_print_request_list(struct vipx_taskmgr *taskmgr)
-{
- DLOG_INIT();
- struct vipx_task *task, *temp;
-
- DLOG("[FRM] req(%d, %d) :", taskmgr->id, taskmgr->req_cnt);
- list_for_each_entry_safe(task, temp, &taskmgr->req_list, list) {
- DLOG("%d->", task->index);
- }
- DLOG("X");
-
- vipx_info("%s\n", DLOG_OUT());
-}
-
-void vipx_task_s_prepare(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- task->state = VIPX_TASK_STATE_PREPARE;
-
- list_add_tail(&task->list, &taskmgr->pre_list);
- taskmgr->pre_cnt++;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_g_prepare(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->pre_cnt &&
- (*task = container_of(taskmgr->pre_list.next, struct vipx_task, list))) {
- list_del(&(*task)->list);
- taskmgr->pre_cnt--;
- (*task)->state = VIPX_TASK_STATE_INVALID;
- } else {
- *task = NULL;
- }
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_prepare_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->pre_cnt)
- *task = container_of(taskmgr->pre_list.next, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_prepare_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->pre_cnt)
- *task = container_of(taskmgr->pre_list.prev, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_print_prepare_list(struct vipx_taskmgr *taskmgr)
-{
- DLOG_INIT();
- struct vipx_task *task, *temp;
-
- DLOG("[FRM] pre(%d, %d) :", taskmgr->id, taskmgr->pre_cnt);
- list_for_each_entry_safe(task, temp, &taskmgr->pre_list, list) {
- DLOG("%d->", task->index);
- }
- DLOG("X");
-
- vipx_info("%s\n", DLOG_OUT());
-}
-
-void vipx_task_s_process(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- task->state = VIPX_TASK_STATE_PROCESS;
-
- list_add_tail(&task->list, &taskmgr->pro_list);
- taskmgr->pro_cnt++;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_g_process(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->pro_cnt &&
- (*task = container_of(taskmgr->pro_list.next, struct vipx_task, list))) {
- list_del(&(*task)->list);
- taskmgr->pro_cnt--;
- (*task)->state = VIPX_TASK_STATE_INVALID;
- } else {
- *task = NULL;
- }
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_process_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->pro_cnt)
- *task = container_of(taskmgr->pro_list.next, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_process_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->pro_cnt)
- *task = container_of(taskmgr->pro_list.prev, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_print_process_list(struct vipx_taskmgr *taskmgr)
-{
- DLOG_INIT();
- struct vipx_task *task, *temp;
-
- DLOG("[FRM] pro(%d, %d) :", taskmgr->id, taskmgr->pro_cnt);
- list_for_each_entry_safe(task, temp, &taskmgr->pro_list, list) {
- DLOG("%d->", task->index);
- }
- DLOG("X");
-
- vipx_info("%s\n", DLOG_OUT());
-}
-
-void vipx_task_s_complete(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- task->state = VIPX_TASK_STATE_COMPLETE;
-
- list_add_tail(&task->list, &taskmgr->com_list);
- taskmgr->com_cnt++;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_g_complete(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- if (taskmgr->com_cnt &&
- (*task = container_of(taskmgr->com_list.next, struct vipx_task, list))) {
- list_del(&(*task)->list);
- taskmgr->com_cnt--;
- (*task)->state = VIPX_TASK_STATE_INVALID;
- } else {
- *task = NULL;
- }
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_complete_head(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->com_cnt)
- *task = container_of(taskmgr->com_list.next, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_complete_tail(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- if (taskmgr->com_cnt)
- *task = container_of(taskmgr->com_list.prev, struct vipx_task, list);
- else
- *task = NULL;
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_print_complete_list(struct vipx_taskmgr *taskmgr)
-{
- DLOG_INIT();
- struct vipx_task *task, *temp;
-
- DLOG("[FRM] com(%d, %d) :", taskmgr->id, taskmgr->com_cnt);
- list_for_each_entry_safe(task, temp, &taskmgr->com_list, list) {
- DLOG("%d->", task->index);
- }
- DLOG("X");
-
- vipx_info("%s\n", DLOG_OUT());
-}
-
-void vipx_task_trans_fre_to_req(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->fre_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_FREE);
-
- list_del(&task->list);
- taskmgr->fre_cnt--;
- vipx_task_s_request(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_req_to_pre(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->req_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_REQUEST);
-
- list_del(&task->list);
- taskmgr->req_cnt--;
- vipx_task_s_prepare(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_req_to_pro(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->req_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_REQUEST);
-
- list_del(&task->list);
- taskmgr->req_cnt--;
- vipx_task_s_process(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_req_to_com(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->req_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_REQUEST);
-
- list_del(&task->list);
- taskmgr->req_cnt--;
- vipx_task_s_complete(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_req_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->req_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_REQUEST);
-
- list_del(&task->list);
- taskmgr->req_cnt--;
- vipx_task_s_free(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_pre_to_pro(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->pre_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_PREPARE);
-
- list_del(&task->list);
- taskmgr->pre_cnt--;
- vipx_task_s_process(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_pre_to_com(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->pre_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_PREPARE);
-
- list_del(&task->list);
- taskmgr->pre_cnt--;
- vipx_task_s_complete(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_pre_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->pre_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_PREPARE);
-
- list_del(&task->list);
- taskmgr->pre_cnt--;
- vipx_task_s_free(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_pro_to_com(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->pro_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_PROCESS);
-
- list_del(&task->list);
- taskmgr->pro_cnt--;
- vipx_task_s_complete(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_pro_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->pro_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_PROCESS);
-
- list_del(&task->list);
- taskmgr->pro_cnt--;
- vipx_task_s_free(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_com_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
- BUG_ON(!taskmgr->com_cnt);
- BUG_ON(task->state != VIPX_TASK_STATE_COMPLETE);
-
- list_del(&task->list);
- taskmgr->com_cnt--;
- vipx_task_s_free(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_trans_any_to_fre(struct vipx_taskmgr *taskmgr, struct vipx_task *task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- list_del(&task->list);
- switch (task->state) {
- case VIPX_TASK_STATE_REQUEST:
- taskmgr->req_cnt--;
- break;
- case VIPX_TASK_STATE_PREPARE:
- taskmgr->pre_cnt--;
- break;
- case VIPX_TASK_STATE_PROCESS:
- taskmgr->pro_cnt--;
- break;
- case VIPX_TASK_STATE_COMPLETE:
- taskmgr->com_cnt--;
- break;
- default:
- BUG();
- break;
- }
-
- vipx_task_s_free(taskmgr, task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_pick_fre_to_req(struct vipx_taskmgr *taskmgr, struct vipx_task **task)
-{
- BUG_ON(!taskmgr);
- BUG_ON(!task);
-
- vipx_task_free_head(taskmgr, task);
- if (*task)
- vipx_task_trans_fre_to_req(taskmgr, *task);
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
-}
-
-void vipx_task_print_all(struct vipx_taskmgr *taskmgr)
-{
- BUG_ON(!taskmgr);
-
- vipx_task_print_request_list(taskmgr);
- vipx_task_print_prepare_list(taskmgr);
- vipx_task_print_process_list(taskmgr);
- vipx_task_print_complete_list(taskmgr);
-}
-
-int vipx_task_init(struct vipx_taskmgr *taskmgr, void *owner)
-{
- int ret = 0;
- unsigned long flags;
- u32 index;
-
- spin_lock_irqsave(&taskmgr->slock, flags);
-
- INIT_LIST_HEAD(&taskmgr->fre_list);
- INIT_LIST_HEAD(&taskmgr->req_list);
- INIT_LIST_HEAD(&taskmgr->pre_list);
- INIT_LIST_HEAD(&taskmgr->pro_list);
- INIT_LIST_HEAD(&taskmgr->com_list);
-
- taskmgr->tot_cnt = VIPX_MAX_TASK;
- taskmgr->fre_cnt = 0;
- taskmgr->req_cnt = 0;
- taskmgr->pre_cnt = 0;
- taskmgr->pro_cnt = 0;
- taskmgr->com_cnt = 0;
-
- /* task index 0 means invalid because firmware can't accept 0 invocation id */
- for (index = 1; index < taskmgr->tot_cnt; ++index) {
- taskmgr->task[index].index = index;
- taskmgr->task[index].owner = owner;
- taskmgr->task[index].findex = VIPX_MAX_TASK;
- taskmgr->task[index].tdindex = VIPX_MAX_TASKDESC;
- vipx_task_s_free(taskmgr, &taskmgr->task[index]);
- }
-
- spin_unlock_irqrestore(&taskmgr->slock, flags);
-
- return ret;
-}
-
-int vipx_task_deinit(struct vipx_taskmgr *taskmgr)
-{
- int ret = 0;
- unsigned long flags;
- u32 index;
-
- spin_lock_irqsave(&taskmgr->slock, flags);
-
- for (index = 0; index < taskmgr->tot_cnt; ++index)
- vipx_task_s_free(taskmgr, &taskmgr->task[index]);
-
- spin_unlock_irqrestore(&taskmgr->slock, flags);
-
- taskmgr_debug("[TASKMGR] %s[%d]\n", __func__, __LINE__);
- return ret;
-}
-
-void vipx_task_flush(struct vipx_taskmgr *taskmgr)
-{
- unsigned long flag;
- struct vipx_task *task, *temp;
-
- BUG_ON(!taskmgr);
-
- spin_lock_irqsave(&taskmgr->slock, flag);
-
- list_for_each_entry_safe(task, temp, &taskmgr->req_list, list) {
- vipx_task_trans_req_to_fre(taskmgr, task);
- vipx_warn("req task%d is flushed(count : %d)", task->id, taskmgr->req_cnt);
- }
-
- list_for_each_entry_safe(task, temp, &taskmgr->pre_list, list) {
- vipx_task_trans_pre_to_fre(taskmgr, task);
- vipx_warn("pre task%d is flushed(count : %d)", task->id, taskmgr->pre_cnt);
- }
-
- list_for_each_entry_safe(task, temp, &taskmgr->pro_list, list) {
- vipx_task_trans_pro_to_fre(taskmgr, task);
- vipx_warn("pro task%d is flushed(count : %d)", task->id, taskmgr->pro_cnt);
- }
-
- list_for_each_entry_safe(task, temp, &taskmgr->com_list, list) {
- vipx_task_trans_com_to_fre(taskmgr, task);
- vipx_warn("com task%d is flushed(count : %d)", task->id, taskmgr->com_cnt);
- }
-
- spin_unlock_irqrestore(&taskmgr->slock, flag);
-
- BUG_ON(taskmgr->fre_cnt != (taskmgr->tot_cnt - 1));
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "vipx-time.h"
-
-void vipx_get_timestamp(struct vipx_time *time)
-{
- do_gettimeofday(&time->time);
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <video/videonode.h>
-#include <asm/cacheflush.h>
-#include <asm/pgtable.h>
-#include <linux/firmware.h>
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/bug.h>
-
-#include "vipx-config.h"
-#include "vision-ioctl.h"
-#include "vipx-vertex.h"
-#include "vision-dev.h"
-#include "vipx-device.h"
-#include "vipx-graphmgr.h"
-#include "vipx-graph.h"
-#include "vipx-queue.h"
-#include "vipx-control.h"
-
-const struct vision_file_ops vipx_vertex_fops;
-const const struct vertex_ioctl_ops vipx_vertex_ioctl_ops;
-
-static int __vref_open(struct vipx_vertex *vertex)
-{
- struct vipx_device *device = container_of(vertex, struct vipx_device, vertex);
- atomic_set(&vertex->start_cnt.refcount, 0);
- return vipx_device_open(device);
-}
-
-static int __vref_close(struct vipx_vertex *vertex)
-{
- struct vipx_device *device = container_of(vertex, struct vipx_device, vertex);
- return vipx_device_close(device);
-}
-
-static int __vref_start(struct vipx_vertex *vertex)
-{
- struct vipx_device *device = container_of(vertex, struct vipx_device, vertex);
- return vipx_device_start(device);
-}
-
-static int __vref_stop(struct vipx_vertex *vertex)
-{
- struct vipx_device *device = container_of(vertex, struct vipx_device, vertex);
- return vipx_device_stop(device);
-}
-
-static inline void __vref_init(struct vipx_vertex_refcount *vref,
- struct vipx_vertex *vertex, int (*first)(struct vipx_vertex *vertex), int (*final)(struct vipx_vertex *vertex))
-{
- vref->vertex = vertex;
- vref->first = first;
- vref->final = final;
- atomic_set(&vref->refcount, 0);
-}
-
-static inline int __vref_get(struct vipx_vertex_refcount *vref)
-{
- return (atomic_inc_return(&vref->refcount) == 1) ? vref->first(vref->vertex) : 0;
-}
-
-static inline int __vref_put(struct vipx_vertex_refcount *vref)
-{
- return (atomic_dec_return(&vref->refcount) == 0) ? vref->final(vref->vertex) : 0;
-}
-
-int vipx_vertex_probe(struct vipx_vertex *vertex, struct device *parent)
-{
- int ret = 0;
- struct vision_device *vdev;
-
- BUG_ON(!vertex);
- BUG_ON(!parent);
-
- get_device(parent);
- mutex_init(&vertex->lock);
- __vref_init(&vertex->open_cnt, vertex, __vref_open, __vref_close);
- __vref_init(&vertex->start_cnt, vertex, __vref_start, __vref_stop);
-
- vdev = &vertex->vd;
- snprintf(vdev->name, sizeof(vdev->name), "%s", VIPX_VERTEX_NAME);
- vdev->fops = &vipx_vertex_fops;
- vdev->ioctl_ops = &vipx_vertex_ioctl_ops;
- vdev->release = NULL;
- vdev->lock = NULL;
- vdev->parent = parent;
- vdev->type = VISION_DEVICE_TYPE_VERTEX;
- dev_set_drvdata(&vdev->dev, vertex);
-
- ret = vision_register_device(vdev, VIPX_VERTEX_MINOR, vipx_vertex_fops.owner);
- if (ret) {
- probe_err("vision_register_device is fail(%d)\n", ret);
- goto p_err;
- }
-
- probe_info("%s():%d\n", __func__, ret);
-
-p_err:
- return ret;
-}
-
-/*
- * =============================================================================
- * Video File Opertation
- * =============================================================================
- */
-
-static int vipx_vertex_open(struct file *file)
-{
- int ret = 0;
- struct vipx_vertex *vertex = dev_get_drvdata(&vision_devdata(file)->dev);
- struct vipx_device *device = container_of(vertex, struct vipx_device, vertex);
- struct mutex *lock = &vertex->lock;
- struct vipx_vertex_ctx *vctx = NULL;
- struct vipx_graph *graph = NULL;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_err("mutex_lock_interruptible is fail\n");
- return -ERESTARTSYS;
- }
-
- ret = __vref_get(&vertex->open_cnt);
- if (ret) {
- vipx_err("vref_get is fail(%d)", ret);
- goto p_err;
- }
-
- ret = vipx_graph_create(&graph,
- &device->graphmgr,
- &device->system.memory);
- if (ret) {
- vipx_err("vipx_graph_create is fail(%d)", ret);
- goto p_err;
- }
-
- vctx = &graph->vctx;
- vctx->idx = graph->idx;
- vctx->vertex = vertex;
- mutex_init(&vctx->lock);
-
- ret = vipx_queue_init(&vctx->queue, &device->system.memory, &vctx->lock);
- if (ret) {
- vipx_err("vipx_queue_init is fail(%d)", ret);
- goto p_err;
- }
-
- file->private_data = vctx;
- vctx->state = BIT(VIPX_VERTEX_OPEN);
-
-p_err:
- vipx_info("%s():%d\n", __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_close(struct file *file)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_graph *graph = container_of(vctx, struct vipx_graph, vctx);
- struct vipx_vertex *vertex = vctx->vertex;
- struct mutex *lock = &vertex->lock;
-#if !DISABLE_VIPX_LOG
- int idx = vctx->idx;
-#endif
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- ret = vipx_graph_destroy(graph);
- if (ret) {
- vipx_err("vipx_graph_destroy is fail(%d)", ret);
- goto p_err;
- }
-
- ret = __vref_put(&vertex->open_cnt);
- if (ret) {
- vipx_err("vref_put is fail(%d)", ret);
- goto p_err;
- }
-
-p_err:
- vipx_info("[I%d]%s():%d\n", idx, __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static unsigned int vipx_vertex_poll(struct file *file,
- poll_table *poll)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_queue *queue = &vctx->queue;
-
- if (!(vctx->state & BIT(VIPX_VERTEX_START))) {
- vipx_ierr("invalid state(%X)", vctx, vctx->state);
- ret |= POLLERR;
- goto p_err;
- }
-
- ret = vipx_queue_poll(queue, file, poll);
-
-p_err:
- return ret;
-}
-
-const struct vision_file_ops vipx_vertex_fops = {
- .owner = THIS_MODULE,
- .open = vipx_vertex_open,
- .release = vipx_vertex_close,
- .poll = vipx_vertex_poll,
- .ioctl = vertex_ioctl,
- .compat_ioctl = vertex_compat_ioctl32
-};
-
-/*
- * =============================================================================
- * Video Ioctl Opertation
- * =============================================================================
- */
-
-static int vipx_vertex_s_graph(struct file *file, struct vs4l_graph *ginfo)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_graph *graph = container_of(vctx, struct vipx_graph, vctx);
- struct mutex *lock = &vctx->lock;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & BIT(VIPX_VERTEX_OPEN))) {
- vipx_ierr("invalid state(%X)\n", vctx, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_graph_config(graph, ginfo);
- if (ret) {
- vipx_err("vipx_graph_config is fail(%d)\n", ret);
- goto p_err;
- }
-
- vctx->state = BIT(VIPX_VERTEX_GRAPH);
-
-p_err:
- vipx_iinfo("%s():%d\n", vctx, __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_s_format(struct file *file, struct vs4l_format_list *flist)
-{
- int ret = 0;
- int bioctl32 = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_queue *queue = &vctx->queue;
- struct mutex *lock = &vctx->lock;
- struct vs4l_format *tmp_buf = 0;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & (BIT(VIPX_VERTEX_GRAPH) | BIT(VIPX_VERTEX_FORMAT)))) {
- vipx_ierr("invalid state(%X)\n", vctx, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- tmp_buf = kzalloc(flist->count * sizeof(struct vs4l_format), GFP_KERNEL);
- if (!tmp_buf) {
- ret = -ENOMEM;
- goto p_err;
- }
-
- ret = copy_from_user(tmp_buf, (void __user *)flist->formats, flist->count * sizeof(struct vs4l_format));
- if (ret) {
- vipx_err("copy_from_user is fail(%d)\n", ret);
- // kfree(tmp_buf);
- memcpy(tmp_buf, (void __user *)flist->formats, flist->count * sizeof(struct vs4l_format));
- ret = 0;
- // goto p_err;
- bioctl32 = 1;
-
- }
-
- flist->formats = tmp_buf;
-
- ret = vipx_queue_s_format(queue, flist);
- if (ret) {
- vipx_ierr("vipx_queue_s_format is fail(%d)\n", vctx, ret);
- kfree(tmp_buf);
- goto p_err;
- }
-
- if (!bioctl32)
- {
- kfree(tmp_buf);
- }
-
- vctx->state = BIT(VIPX_VERTEX_FORMAT);
-
-p_err:
- vipx_iinfo("%s():%d\n", vctx, __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_s_param(struct file *file, struct vs4l_param_list *plist)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_graph *graph = container_of(vctx, struct vipx_graph, vctx);
- struct mutex *lock = &vctx->lock;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & BIT(VIPX_VERTEX_START))) {
- vipx_ierr("invalid state(%X)\n", vctx, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_graph_param(graph, plist);
- if (ret) {
- vipx_err("vipx_graph_param is fail(%d)\n", ret);
- goto p_err;
- }
-
-p_err:
- vipx_iinfo("%s():%d\n", vctx, __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_s_ctrl(struct file *file, struct vs4l_ctrl *ctrl)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_vertex *vertex = dev_get_drvdata(&vision_devdata(file)->dev);
- struct vipx_device *device = container_of(vertex, struct vipx_device, vertex);
- struct vipx_graph *graph = container_of(vctx, struct vipx_graph, vctx);
- struct mutex *lock = &vctx->lock;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- switch (ctrl->ctrl) {
- case VIPX_CTRL_DUMP:
- vipx_graph_print(graph);
- break;
- case VIPX_CTRL_MODE:
- device->mode = ctrl->value;
- break;
- case VIPX_CTRL_TEST:
- break;
- default:
- vipx_ierr("request control is invalid(%d)\n", vctx, ctrl->ctrl);
- ret = -EINVAL;
- break;
- }
-
- vipx_iinfo("%s(%d):%d\n", vctx, __func__, ctrl->ctrl, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_qbuf(struct file *file, struct vs4l_container_list *clist)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_queue *queue = &vctx->queue;
- struct mutex *lock = &vctx->lock;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & BIT(VIPX_VERTEX_START))) {
- vipx_ierr("(%d) invalid state(%X)\n", vctx, clist->direction, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_queue_qbuf(queue, clist);
- if (ret) {
- vipx_ierr("(%d) vipx_queue_qbuf is fail(%d)\n", vctx, clist->direction, ret);
- goto p_err;
- }
-
-p_err:
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_dqbuf(struct file *file, struct vs4l_container_list *clist)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_queue *queue = &vctx->queue;
- struct mutex *lock = &vctx->lock;
- bool nonblocking = file->f_flags & O_NONBLOCK;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & BIT(VIPX_VERTEX_START))) {
- vipx_ierr("(%d) invalid state(%X)\n", vctx, clist->direction, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_queue_dqbuf(queue, clist, nonblocking);
- if (ret) {
- vipx_ierr("(%d) vipx_queue_dqbuf is fail(%d)\n", vctx, clist->direction, ret);
- goto p_err;
- }
-
-p_err:
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_streamon(struct file *file)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_vertex *vertex = vctx->vertex;
- struct vipx_queue *queue = &vctx->queue;
- struct mutex *lock = &vctx->lock;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & (BIT(VIPX_VERTEX_FORMAT) | BIT(VIPX_VERTEX_STOP)))) {
- vipx_ierr("invalid state(%X)\n", vctx, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = __vref_get(&vertex->start_cnt);
- if (ret) {
- vipx_err("vref_get is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = vipx_queue_start(queue);
- if (ret) {
- vipx_ierr("vipx_queue_start is fail(%d)\n", vctx, ret);
- goto p_err;
- }
-
- vctx->state = BIT(VIPX_VERTEX_START);
-
-p_err:
- vipx_iinfo("%s():%d\n", vctx, __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-static int vipx_vertex_streamoff(struct file *file)
-{
- int ret = 0;
- struct vipx_vertex_ctx *vctx = file->private_data;
- struct vipx_vertex *vertex = vctx->vertex;
- struct vipx_queue *queue = &vctx->queue;
- struct mutex *lock = &vctx->lock;
-
- if (mutex_lock_interruptible(lock)) {
- vipx_ierr("mutex_lock_interruptible is fail\n", vctx);
- return -ERESTARTSYS;
- }
-
- if (!(vctx->state & BIT(VIPX_VERTEX_START))) {
- vipx_ierr("invalid state(%X)\n", vctx, vctx->state);
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = vipx_queue_stop(queue);
- if (ret) {
- vipx_ierr("vipx_queue_stop is fail(%d)\n", vctx, ret);
- goto p_err;
- }
-
- ret = __vref_put(&vertex->start_cnt);
- if (ret) {
- vipx_err("vref_put is fail(%d)\n", ret);
- goto p_err;
- }
-
- vctx->state = BIT(VIPX_VERTEX_STOP);
-
-p_err:
- vipx_iinfo("%s():%d\n", vctx, __func__, ret);
- mutex_unlock(lock);
- return ret;
-}
-
-const struct vertex_ioctl_ops vipx_vertex_ioctl_ops = {
- .vertexioc_s_graph = vipx_vertex_s_graph,
- .vertexioc_s_format = vipx_vertex_s_format,
- .vertexioc_s_param = vipx_vertex_s_param,
- .vertexioc_s_ctrl = vipx_vertex_s_ctrl,
- .vertexioc_qbuf = vipx_vertex_qbuf,
- .vertexioc_dqbuf = vipx_vertex_dqbuf,
- .vertexioc_streamon = vipx_vertex_streamon,
- .vertexioc_streamoff = vipx_vertex_streamoff
-};
+++ /dev/null
-/*
- * Samsung Exynos SoC series VIPx driver
- *
- * Copyright (c) 2017 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef VIPX_VERTEX_H_
-#define VIPX_VERTEX_H_
-
-#define VIPX_VERTEX_NAME "vertex"
-#define VIPX_VERTEX_MINOR 0
-
-#include "vision-dev.h"
-#include "vision-ioctl.h"
-#include "vipx-queue.h"
-
-struct vipx_vertex;
-
-enum vipx_vertex_state {
- VIPX_VERTEX_OPEN,
- VIPX_VERTEX_GRAPH,
- VIPX_VERTEX_FORMAT,
- VIPX_VERTEX_START,
- VIPX_VERTEX_STOP
-};
-
-struct vipx_vertex_refcount {
- atomic_t refcount;
- struct vipx_vertex *vertex;
- int (*first)(struct vipx_vertex *vertex);
- int (*final)(struct vipx_vertex *vertex);
-};
-
-struct vipx_vertex {
- struct mutex lock;
- struct vision_device vd;
- struct vipx_vertex_refcount open_cnt;
- struct vipx_vertex_refcount start_cnt;
-};
-
-struct vipx_vertex_ctx {
- u32 state;
- u32 idx;
- struct mutex lock;
- struct vipx_queue queue;
- struct vipx_vertex *vertex;
-};
-
-int vipx_vertex_probe(struct vipx_vertex *vertex, struct device *parent);
-
-#endif
+++ /dev/null
-config VISION_CORE
- bool "Vision Core"
- help
- This is a vision core
+++ /dev/null
-obj-$(CONFIG_VISION_CORE) += vision-dev.o
-obj-$(CONFIG_VISION_CORE) += vision-compat-ioctl32.o
-obj-$(CONFIG_VISION_CORE) += vision-ioctl.o
-obj-$(CONFIG_VISION_CORE) += vision-buffer.o
-
-EXTRA_CFLAGS += -Idrivers/vision/include
+++ /dev/null
-/*
- * Samsung Exynos SoC series VISION driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/slab.h>
-#include <media/videobuf2-dma-sg.h>
-#include <linux/dma-buf.h>
-#include <linux/ion_exynos.h>
-
-#include "vision-config.h"
-#include "vision-buffer.h"
-
-#include <asm/cacheflush.h>
-
-#define DEBUG_SENTENCE_MAX 300
-
-struct vision_debug_log {
- size_t dsentence_pos;
- char dsentence[DEBUG_SENTENCE_MAX];
-};
-
-#if 1 // should be removed
-void __npu_queue_print(struct vb_queue *q);
-#endif
-
-void vision_dmsg_concate(struct vision_debug_log *log, const char *fmt, ...)
-{
- va_list ap;
- char term[50];
- u32 copy_len;
-
- va_start(ap, fmt);
- vsnprintf(term, sizeof(term), fmt, ap);
- va_end(ap);
-
- if (log->dsentence_pos >= DEBUG_SENTENCE_MAX) {
- vision_err("debug message(%zd) over max\n", log->dsentence_pos);
- return;
- }
-
- copy_len = min((DEBUG_SENTENCE_MAX - log->dsentence_pos - 1), strlen(term));
- strncpy(log->dsentence + log->dsentence_pos, term, copy_len);
- log->dsentence_pos += copy_len;
- log->dsentence[log->dsentence_pos] = 0;
-}
-
-char * vision_dmsg_print(struct vision_debug_log *log)
-{
- log->dsentence_pos = 0;
- return log->dsentence;
-}
-
-#define DLOG_INIT() struct vision_debug_log vision_debug_log = { .dsentence_pos = 0 }
-#define DLOG(fmt, ...) vision_dmsg_concate(&vision_debug_log, fmt, ##__VA_ARGS__)
-#define DLOG_OUT() vision_dmsg_print(&vision_debug_log)
-
-struct vb_fmt vb_fmts[] = {
- {
- .name = "RGB",
- .colorspace = VS4L_DF_IMAGE_RGB,
- .planes = 1,
- .bitsperpixel = { 24 }
- }, {
- .name = "ARGB",
- .colorspace = VS4L_DF_IMAGE_RGBX,
- .planes = 1,
- .bitsperpixel = { 32 }
- }, {
- .name = "YUV 4:2:0 planar, Y/CbCr",
- .colorspace = VS4L_DF_IMAGE_NV12,
- .planes = 2,
- .bitsperpixel = { 8, 8 }
- }, {
- .name = "YUV 4:2:0 planar, Y/CrCb",
- .colorspace = VS4L_DF_IMAGE_NV21,
- .planes = 2,
- .bitsperpixel = { 8, 8 }
- }, {
- .name = "YUV 4:2:0 planar, Y/Cr/Cb",
- .colorspace = VS4L_DF_IMAGE_YV12,
- .planes = 3,
- .bitsperpixel = { 8, 4, 4 }
- }, {
- .name = "YUV 4:2:0 planar, Y/Cb/Cr",
- .colorspace = VS4L_DF_IMAGE_I420,
- .planes = 3,
- .bitsperpixel = { 8, 4, 4 }
- }, {
- .name = "YUV 4:2:2 planar, Y/Cb/Cr",
- .colorspace = VS4L_DF_IMAGE_I422,
- .planes = 3,
- .bitsperpixel = { 8, 4, 4 }
- }, {
- .name = "YUV 4:2:2 packed, YCbYCr",
- .colorspace = VS4L_DF_IMAGE_YUYV,
- .planes = 1,
- .bitsperpixel = { 16 }
- }, {
- .name = "YUV 4:4:4 packed, YCbCr",
- .colorspace = VS4L_DF_IMAGE_YUV4,
- .planes = 1,
- .bitsperpixel = { 24 }
- }, {
- .name = "VX unsigned 8 bit",
- .colorspace = VS4L_DF_IMAGE_U8,
- .planes = 1,
- .bitsperpixel = { 8 }
- }, {
- .name = "VX unsigned 16 bit",
- .colorspace = VS4L_DF_IMAGE_U16,
- .planes = 1,
- .bitsperpixel = { 16 }
- }, {
- .name = "VX unsigned 32 bit",
- .colorspace = VS4L_DF_IMAGE_U32,
- .planes = 1,
- .bitsperpixel = { 32 }
- }, {
- .name = "VX signed 16 bit",
- .colorspace = VS4L_DF_IMAGE_S16,
- .planes = 1,
- .bitsperpixel = { 16 }
- }, {
- .name = "VX signed 32 bit",
- .colorspace = VS4L_DF_IMAGE_S32,
- .planes = 1,
- .bitsperpixel = { 32 }
- }
-};
-
-void __vb_queue_print(struct vb_queue *q)
-{
- DLOG_INIT();
- struct vb_bundle *bundle, *temp;
-
- DLOG("[VB] queued(%d) :", atomic_read(&q->queued_count));
- list_for_each_entry_safe(bundle, temp, &q->queued_list, queued_entry) {
- DLOG("%d->", bundle->clist.index);
- }
- DLOG("X");
-
- vision_info("%s\n", DLOG_OUT());
-
- DLOG("[VB] process(%d) :", atomic_read(&q->process_count));
- list_for_each_entry_safe(bundle, temp, &q->process_list, process_entry) {
- DLOG("%d->", bundle->clist.index);
- }
- DLOG("X");
-
- vision_info("%s\n", DLOG_OUT());
-
- DLOG("[VB] done(%d) :", atomic_read(&q->done_count));
- list_for_each_entry_safe(bundle, temp, &q->done_list, done_entry) {
- DLOG("%d->", bundle->clist.index);
- }
- DLOG("X");
-
- vision_info("%s\n", DLOG_OUT());
-}
-
-void __vb_buffer_print(struct vs4l_container_list *c)
-{
- vision_info("[VB] c->direction : %d", c->direction);
- vision_info("[VB] c->id : %d", c->id);
- vision_info("[VB] c->index : %d", c->count);
-}
-
-static struct vb_fmt * __vb_find_format(u32 colorspace)
-{
- int ret = 0;
- u32 i;
- struct vb_fmt *fmt = NULL;
-
- for (i = 0; i < ARRAY_SIZE(vb_fmts); ++i) {
- if (vb_fmts[i].colorspace == colorspace) {
- fmt = &vb_fmts[i];
- break;
- }
- }
- if (i == ARRAY_SIZE(vb_fmts)) {
- vision_err("Format %d not found!!!\n", colorspace);
- ret = -EINVAL;
- goto p_err;
- }
-
-p_err:
- return fmt;
-}
-
-static int __vb_plane_size(struct vb_format *format)
-{
- int ret = 0;
- u32 plane;
- struct vb_fmt *fmt;
-
- BUG_ON(!format);
-
- fmt = format->fmt;
-
- if (fmt->planes > VB_MAX_PLANES) {
- vision_err("planes(%d) is invalid\n", fmt->planes);
- ret = -EINVAL;
- goto p_err;
- }
-
- for (plane = 0; plane < fmt->planes; ++plane)
- format->size[plane] = format->width * fmt->bitsperpixel[plane] / BITS_PER_BYTE* format->height * fmt->bitsperpixel[plane] / BITS_PER_BYTE;
-
-p_err:
- return ret;
-}
-
-static int __vb_unmap_dmabuf(struct vb_queue *q, struct vb_buffer *buffer)
-{
- int ret = 0;
-
- if (buffer->vaddr)
- dma_buf_vunmap(buffer->dma_buf, buffer->vaddr);
- if (buffer->daddr)
- ion_iovmm_unmap(buffer->attachment, buffer->daddr);
- if (buffer->sgt)
- dma_buf_unmap_attachment(buffer->attachment, buffer->sgt, DMA_BIDIRECTIONAL);
- if (buffer->attachment)
- dma_buf_detach(buffer->dma_buf, buffer->attachment);
- if (buffer->dma_buf)
- dma_buf_put(buffer->dma_buf);
-
- buffer->attachment = NULL;
- buffer->sgt = NULL;
- buffer->daddr = 0;
- buffer->vaddr = NULL;
-
- return ret;
-}
-
-static int __vb_unmap_virtptr(struct vb_queue *q, struct vb_buffer *buffer)
-{
- int ret = 0;
-
- if (buffer->reserved)
- kfree((void *)buffer->m.userptr);
-
- buffer->mem_priv = NULL;
- buffer->cookie = NULL;
- buffer->kvaddr = NULL;
- buffer->dbuf = NULL;
- buffer->dvaddr = 0;
- buffer->reserved = 0;
-
- return ret;
-}
-
-static int __vb_map_dmabuf(struct vb_queue *q, struct vb_buffer *buffer, u32 size)
-{
- int ret = 0;
- bool complete_suc = false;
-
- struct dma_buf_attachment *attachment;
- struct sg_table *sgt;
- dma_addr_t daddr;
- void *vaddr;
-
- buffer->attachment = NULL;
- buffer->sgt = NULL;
- buffer->daddr = 0;
- buffer->vaddr = NULL;
-
- buffer->dma_buf = dma_buf_get(buffer->m.fd);
- vision_err("ASDFASDFASDFASDF : %d, %p\n",buffer->m.fd, buffer->dma_buf);
-
- attachment = dma_buf_attach(buffer->dma_buf, q->alloc_dev);
- if (IS_ERR(attachment)) {
- ret = PTR_ERR(attachment);
- goto p_err;
- }
- buffer->attachment = attachment;
-
- sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
- if (IS_ERR(sgt)) {
- ret = PTR_ERR(sgt);
- goto p_err;
- }
- buffer->sgt = sgt;
-
- daddr = ion_iovmm_map(attachment, 0, size, DMA_BIDIRECTIONAL, 0);
- if (IS_ERR_VALUE(daddr)) {
- vision_err("Failed to allocate iova (err 0x%p)\n", &daddr);
- goto p_err;
- }
- buffer->daddr = daddr;
- buffer->dvaddr = daddr;
- vision_err("ASDFASDFASDF buffer->daddr : %x",(unsigned int)buffer->daddr);
-
- vaddr = dma_buf_vmap(buffer->dma_buf);
- if (IS_ERR(vaddr)) {
- vision_err("Failed to get vaddr (err 0x%p)\n", &vaddr);
- goto p_err;
- }
- buffer->vaddr = vaddr;
- buffer->kvaddr = vaddr;
- vision_err("ASDFASDFASDF buffer->vaddr : %x",(unsigned int)buffer->vaddr);
-
- complete_suc = true;
-p_err:
- if (complete_suc != true) {
- __vb_unmap_dmabuf(q, buffer);
- }
- return ret;
-}
-
-static int __vb_map_virtptr(struct vb_queue *q, struct vb_buffer *buffer, u32 size)
-{
- int ret = 0;
- unsigned long tmp_buffer;
- void *mbuf = NULL;
-
- mbuf = kmalloc(size, GFP_KERNEL);
- if (!mbuf) {
- ret = -ENOMEM;
- goto p_err;
- }
-
- tmp_buffer = (unsigned long)mbuf;
-
- ret = copy_from_user((void *)tmp_buffer, (void *)buffer->m.userptr, size);
- if (ret) {
- vision_err("copy_from_user() is fail(%d)\n", ret);
- memcpy((void *)tmp_buffer, (void *)buffer->m.userptr, size);
- ret = 0;
- //goto p_err;
-
- }
-
- /* back up - userptr */
- buffer->reserved = buffer->m.userptr;
- buffer->m.userptr = (unsigned long)tmp_buffer;
-
-p_err:
- return ret;
-}
-
-static int __vb_queue_alloc(struct vb_queue *q,
- struct vs4l_container_list *c)
-{
- DLOG_INIT();
- int ret = 0;
- u32 i, j;
- size_t alloc_size;
- u8 *mapped_ptr;
- struct vb_format_list *flist;
- struct vb_bundle *bundle;
- struct vb_container_list *clist;
- struct vb_container *container;
- struct vb_buffer *buffer;
- struct vs4l_container *tmp_containers = NULL;
- struct vs4l_buffer tmp_buffer;
-
- BUG_ON(!q);
- BUG_ON(!c);
- BUG_ON(c->index >= VB_MAX_BUFFER);
-
- flist = &q->format;
-
-
- /* allocation */
- alloc_size = sizeof(struct vb_bundle);
- alloc_size += sizeof(struct vb_container) * c->count;
-
- tmp_containers = kzalloc(sizeof(struct vs4l_container) * c->count, GFP_KERNEL);
-
- for (i = 0; i < c->count; ++i) {
- ret = copy_from_user((void *)&tmp_containers[i], (void *)&c->containers[i], sizeof(struct vs4l_container));
- if (ret) {
- vision_err("copy_from_user() is fail(%d)\n", ret);
- memcpy((void *)&tmp_containers[i], (void *)&c->containers[i], sizeof(struct vs4l_container));
- ret = 0;
- // goto p_err;
- }
-
- alloc_size += sizeof(struct vb_buffer) * tmp_containers[i].count;
- }
-
- bundle = kzalloc(alloc_size, GFP_KERNEL);
- if (!bundle) {
- ret = -ENOMEM;
- goto p_err;
- }
-
- /* mapping */
- mapped_ptr = (u8 *)bundle + sizeof(struct vb_bundle);
- bundle->clist.containers = (struct vb_container *)mapped_ptr;
- mapped_ptr += sizeof(struct vb_container) * c->count;
- for (i = 0; i < c->count; ++i) {
- bundle->clist.containers[i].buffers = (struct vb_buffer *)mapped_ptr;
- mapped_ptr += sizeof(struct vb_buffer) * tmp_containers[i].count;
- }
-
- /* fill */
- bundle->state = VB_BUF_STATE_DEQUEUED;
- clear_bit(VS4L_CL_FLAG_PREPARE, &bundle->flags);
- clear_bit(VS4L_CL_FLAG_INVALID, &bundle->flags);
- clear_bit(VS4L_CL_FLAG_DONE, &bundle->flags);
-
- clist = &bundle->clist;
- clist->index = c->index;
- clist->id = c->id;
- clist->direction = c->direction;
- clist->count = c->count;
- clist->flags = c->flags;
-
- for (i = 0; i < _MAX_NUM_OF_USER_PARAMS; ++i)
- clist->user_params[i] = c->user_params[i];
-
- for (i = 0; i < clist->count; ++i) {
- container = &clist->containers[i];
- container->count = tmp_containers[i].count;
- container->memory = tmp_containers[i].memory;
- container->reserved[0] = tmp_containers[i].reserved[0];
- container->reserved[1] = tmp_containers[i].reserved[1];
- container->reserved[2] = tmp_containers[i].reserved[2];
- container->reserved[3] = tmp_containers[i].reserved[3];
- container->target = tmp_containers[i].target;
- container->type = tmp_containers[i].type;
-
- for (j = 0; j < flist->count; ++j) {
- DLOG("c%d t%d == f%d t%d\n", i, container->target, j, flist->formats[j].target);
- if (container->target == flist->formats[j].target) {
- container->format = &flist->formats[j];
- break;
- }
- }
-
- if (!container->format) {
- vision_err("format is not found\n");
- vision_err("%s", DLOG_OUT());
- kfree(bundle);
- ret = -EINVAL;
- goto p_err;
- }
-
- for (j = 0; j < container->count; ++j) {
- buffer = &container->buffers[j];
-
- ret = copy_from_user((void *)&tmp_buffer, (void *)&tmp_containers[i].buffers[j], sizeof(struct vs4l_buffer));
- if (ret) {
- vision_err("copy_from_user() is fail(%d)\n", ret);
- memcpy((void *)&tmp_buffer,
- (void *)&tmp_containers[i].buffers[j], sizeof(struct vs4l_buffer));
- ret = 0;
- //goto p_err;
- }
- buffer->roi = tmp_buffer.roi;
- buffer->m.userptr = tmp_buffer.m.userptr;
- buffer->dbuf = NULL;
- buffer->mem_priv = NULL;
- buffer->cookie = NULL;
- buffer->kvaddr = NULL;
- buffer->dvaddr = 0;
- }
- }
-
- q->bufs[c->index] = bundle;
- q->num_buffers++;
-
-p_err:
- if (tmp_containers)
- kfree(tmp_containers);
-
- return ret;
-}
-
-static int __vb_queue_free(struct vb_queue *q,
- struct vb_bundle *bundle)
-{
- int ret = 0;
-
- BUG_ON(!bundle);
- BUG_ON(bundle->clist.index >= VB_MAX_BUFFER);
-
- q->bufs[bundle->clist.index] = NULL;
- kfree(bundle);
- q->num_buffers--;
-
- return ret;
-}
-
-static int __vb_queue_check(struct vb_bundle *bundle,
- struct vs4l_container_list *c)
-{
- int ret = 0;
- u32 i, j;
- struct vb_container_list *clist;
- struct vb_container *container;
- struct vb_buffer *buffer;
- struct vs4l_container tmp_container;
- struct vs4l_buffer tmp_buffer;
-
- BUG_ON(!bundle);
- BUG_ON(!c);
-
- clist = &bundle->clist;
-
- if (clist->index != c->index) {
- vision_err("index is conflict(%d != %d)\n", clist->index, c->index);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (clist->direction != c->direction) {
- vision_err("direction is conflict(%d != %d)\n", clist->direction, c->direction);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (clist->count != c->count) {
- vision_err("count is conflict(%d != %d)\n", clist->count, c->count);
- ret = -EINVAL;
- goto p_err;
- }
-
- clist->flags = c->flags;
- clist->id = c->id;
-
- for (i = 0; i < clist->count; ++i) {
- container = &clist->containers[i];
-
- ret = copy_from_user((void *)&tmp_container, (void *)&c->containers[i], sizeof(struct vs4l_container));
- if (ret) {
- vision_err("copy_from_user() is fail(%d)\n", ret);
- memcpy((void *)&tmp_container, (void *)&c->containers[i], sizeof(struct vs4l_container));
- ret = 0;
- //goto p_err;
- }
-
- if (container->target != tmp_container.target) {
- vision_err("target is conflict(%d != %d)\n", container->target, tmp_container.target);
- ret = -EINVAL;
- goto p_err;
- }
-
- if (container->count != tmp_container.count) {
- vision_err("count is conflict(%d != %d)\n", container->count, tmp_container.count);
- ret = -EINVAL;
- goto p_err;
- }
-
- for (j = 0; j < container->count; ++j) {
- buffer = &container->buffers[j];
- ret = copy_from_user((void *)&tmp_buffer, (void *)&tmp_container.buffers[j], sizeof(struct vs4l_buffer));
- if (ret) {
- vision_err("copy_from_user() is fail(%d)\n", ret);
- memcpy((void *)&tmp_buffer,
- (void *)&tmp_container.buffers[j], sizeof(struct vs4l_buffer));
- ret = 0;
- //goto p_err;
- }
- buffer->roi = tmp_buffer.roi;
-
- if (buffer->m.fd != tmp_buffer.m.fd) {
- vision_err("index(%d) buffer is conflict(%d != %d)\n", c->index, buffer->m.fd, tmp_buffer.m.fd);
- ret = -EINVAL;
- goto p_err;
- }
- }
- }
-
-p_err:
- return ret;
-}
-
-static int __vb_buf_prepare(struct vb_queue *q, struct vb_bundle *bundle)
-{
- int ret = 0;
- u32 i, j, k;
- struct vb_format *format;
- struct vb_container *container;
- struct vb_buffer *buffer;
-
- BUG_ON(!q);
- BUG_ON(!bundle);
-
- if (test_bit(VS4L_CL_FLAG_PREPARE, &bundle->flags))
- goto p_err;
-
- for (i = 0; i < bundle->clist.count; ++i) {
- container = &bundle->clist.containers[i];
- format = container->format;
-
- switch (container->type) {
- case VS4L_BUFFER_LIST:
- k = container->count;
- break;
- case VS4L_BUFFER_ROI:
- k = container->count;
- break;
- case VS4L_BUFFER_PYRAMID:
- k = container->count;
- break;
- default:
- vision_err("unsupported container type\n");
- goto p_err;
- }
-
- switch (container->memory) {
- case VS4L_MEMORY_DMABUF:
- for (j = 0; j < k; ++j) {
- buffer = &container->buffers[j];
- ret = __vb_map_dmabuf(q, buffer, format->size[j]);
- vision_err("1234 kvaddr %p, dvaddr %x\n",buffer->kvaddr, buffer->dvaddr);
- if (ret) {
- vision_err("__vb_qbuf_dmabuf[%d/%d] is fail(%d)\n", j, k, ret);
- goto p_err;
- }
- }
- break;
- case VS4L_MEMORY_VIRTPTR:
- for (j = 0; j < k; ++j) {
- buffer = &container->buffers[j];
- ret = __vb_map_virtptr(q, buffer, format->size[j]);
- if (ret) {
- vision_err("__vb_map_virtptr is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- default:
- vision_err("unsupported container memory type\n");
- goto p_err;
- }
- }
-
- ret = call_op(q, buf_prepare, q, &bundle->clist);
- if (ret) {
- vision_err("call_op(buf_prepare) is fail(%d)\n", ret);
- goto p_err;
- }
-
- set_bit(VS4L_CL_FLAG_PREPARE, &bundle->flags);
-
-p_err:
- return ret;
-}
-
-static int __vb_buf_unprepare(struct vb_queue *q, struct vb_bundle *bundle)
-{
- int ret = 0;
- u32 i, j, k;
- struct vb_format *format;
- struct vb_container *container;
- struct vb_buffer *buffer;
-
- BUG_ON(!q);
- BUG_ON(!bundle);
-
-
- if (!test_bit(VS4L_CL_FLAG_PREPARE, &bundle->flags))
- goto p_err;
-
- for (i = 0; i < bundle->clist.count; ++i) {
- container = &bundle->clist.containers[i];
- format = container->format;
-
- switch (container->type) {
- case VS4L_BUFFER_LIST:
- k = container->count;
- break;
- case VS4L_BUFFER_ROI:
- k = container->count;
- break;
- case VS4L_BUFFER_PYRAMID:
- k = container->count;
- break;
- default:
- vision_err("unsupported container type\n");
- goto p_err;
- }
-
- switch (container->memory) {
- case VS4L_MEMORY_DMABUF:
- for (j = 0; j < k; ++j) {
- buffer = &container->buffers[j];
- ret = __vb_unmap_dmabuf(q, buffer);
- if (ret) {
- vision_err("__vb_qbuf_dmabuf is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_MEMORY_VIRTPTR:
- for (j = 0; j < k; ++j) {
- buffer = &container->buffers[j];
- ret = __vb_unmap_virtptr(q, buffer);
- if (ret) {
- vision_err("__vb_unmap_virtptr is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- default:
- vision_err("unsupported container memory type\n");
- goto p_err;
- }
- }
-
- ret = call_op(q, buf_unprepare, q, &bundle->clist);
- if (ret) {
- vision_err("call_op(buf_unprepare) is fail(%d)\n", ret);
- goto p_err;
- }
-
- clear_bit(VS4L_CL_FLAG_PREPARE, &bundle->flags);
-
-p_err:
- return ret;
-}
-
-static int __vb_wait_for_done_vb(struct vb_queue *q, int nonblocking)
-{
- int ret = 0;
-
- if (!q->streaming) {
- vision_err("Streaming off, will not wait for buffers\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- if (!list_empty(&q->done_list))
- goto p_err;
-
- if (nonblocking) {
- vision_err("Nonblocking and no buffers to dequeue, will not wait\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- mutex_unlock(q->lock);
-
- ret = wait_event_interruptible(q->done_wq, !list_empty(&q->done_list) || !q->streaming);
-
- mutex_lock(q->lock);
-
-p_err:
- return ret;
-}
-
-static int __vb_get_done_vb(struct vb_queue *q,
- struct vb_bundle **bundle,
- struct vs4l_container_list *c,
- int nonblocking)
-{
- unsigned long flags;
- int ret;
-
- /*
- * Wait for at least one buffer to become available on the done_list.
- */
- ret = __vb_wait_for_done_vb(q, nonblocking);
- if (ret)
- return ret;
-
- /*
- * Driver's lock has been held since we last verified that done_list
- * is not empty, so no need for another list_empty(done_list) check.
- */
-
- spin_lock_irqsave(&q->done_lock, flags);
-
- *bundle = list_first_entry(&q->done_list, struct vb_bundle, done_entry);
-
- list_del(&(*bundle)->done_entry);
- atomic_dec(&q->done_count);
-
- spin_unlock_irqrestore(&q->done_lock, flags);
-
- return ret;
-}
-
-static void __fill_vs4l_buffer(struct vb_bundle *bundle,
- struct vs4l_container_list *c)
-{
- struct vb_container_list *clist;
-
- clist = &bundle->clist;
- c->flags &= ~(1 << VS4L_CL_FLAG_TIMESTAMP);
- c->flags &= ~(1 << VS4L_CL_FLAG_PREPARE);
- c->flags &= ~(1 << VS4L_CL_FLAG_INVALID);
- c->flags &= ~(1 << VS4L_CL_FLAG_DONE);
-
- if (test_bit(VS4L_CL_FLAG_TIMESTAMP, &clist->flags)) {
- c->flags |= (1 << VS4L_CL_FLAG_TIMESTAMP);
- memcpy(c->timestamp, clist->timestamp, sizeof(clist->timestamp));
- }
-
- if (test_bit(VS4L_CL_FLAG_PREPARE, &bundle->flags))
- c->flags |= (1 << VS4L_CL_FLAG_PREPARE);
-
- if (test_bit(VS4L_CL_FLAG_INVALID, &bundle->flags))
- c->flags |= (1 << VS4L_CL_FLAG_INVALID);
-
- if (test_bit(VS4L_CL_FLAG_DONE, &bundle->flags))
- c->flags |= (1 << VS4L_CL_FLAG_DONE);
-
- c->index = clist->index;
- c->id = clist->id;
-}
-
-static void __vb_dqbuf(struct vb_bundle *bundle)
-{
- if (bundle->state == VB_BUF_STATE_DEQUEUED)
- return;
-
- bundle->state = VB_BUF_STATE_DEQUEUED;
-}
-
-int vb_queue_init(struct vb_queue *q,
- void *alloc_dev,
- const struct vb2_mem_ops *mem_ops,
- const struct vb_ops *ops,
- struct mutex *lock,
- u32 direction)
-{
- int ret = 0;
-
- INIT_LIST_HEAD(&q->queued_list);
- atomic_set(&q->queued_count, 0);
-
- INIT_LIST_HEAD(&q->process_list);
- atomic_set(&q->process_count, 0);
-
- INIT_LIST_HEAD(&q->done_list);
- atomic_set(&q->done_count, 0);
-
- spin_lock_init(&q->done_lock);
- init_waitqueue_head(&q->done_wq);
-
- q->num_buffers = 0;
- q->direction = direction;
- q->lock = lock;
- q->streaming = 0;
- q->alloc_dev = alloc_dev;
- q->mem_ops = mem_ops;
- q->ops = ops;
-
- clear_bit(VB_QUEUE_STATE_FORMAT, &q->state);
- q->format.count = 0;
- q->format.formats = NULL;
-
- return ret;
-}
-
-int vb_queue_s_format(struct vb_queue *q, struct vs4l_format_list *flist)
-{
- int ret = 0;
- u32 i;
- struct vs4l_format *f;
- struct vb_fmt *fmt;
-
- q->format.count = flist->count;
- q->format.formats = kcalloc(flist->count, sizeof(struct vb_format), GFP_KERNEL);
-
- for (i = 0; i < flist->count; ++i) {
- f = &flist->formats[i];
-
- fmt = __vb_find_format(f->format);
- if (!fmt) {
- vision_err("__vb_find_format is fail\n");
- kfree(q->format.formats);
- ret = -EINVAL;
- goto p_err;
- }
-
- q->format.formats[i].fmt = fmt;
- q->format.formats[i].colorspace = f->format;
- q->format.formats[i].target = f->target;
- q->format.formats[i].plane = f->plane;
- q->format.formats[i].width = f->width;
- q->format.formats[i].height = f->height;
-
- ret = __vb_plane_size(&q->format.formats[i]);
- if (ret) {
- vision_err("__vb_plane_size is fail(%d)\n", ret);
- kfree(q->format.formats);
- goto p_err;
- }
- }
-
- set_bit(VB_QUEUE_STATE_FORMAT, &q->state);
-
-p_err:
- return ret;
-}
-
-int vb_queue_start(struct vb_queue *q)
-{
- int ret = 0;
-
- if (!test_bit(VB_QUEUE_STATE_FORMAT, &q->state)) {
- vision_err("format is not configured\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- q->streaming = 1;
- set_bit(VB_QUEUE_STATE_START, &q->state);
-
-p_err:
- return ret;
-}
-
-int vb_queue_stop(struct vb_queue *q)
-{
- int ret = 0;
- u32 i;
- struct vb_bundle *bundle;
-
- q->streaming = 0;
-
- wake_up_all(&q->done_wq);
-
- if (atomic_read(&q->queued_count) > 0) {
- vision_err("queued list is not empty\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- if (atomic_read(&q->process_count) > 0) {
- vision_err("process list is not empty\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- if (atomic_read(&q->done_count) > 0) {
- vision_err("done list is not empty\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- INIT_LIST_HEAD(&q->queued_list);
- INIT_LIST_HEAD(&q->process_list);
- INIT_LIST_HEAD(&q->done_list);
-
-// for (i = 0; i < VB_MAX_BUFFER; ++i) {
- for (i = 0; i < q->num_buffers; ++i) {
-
- bundle = q->bufs[i];
- if (!bundle)
- continue;
-
- ret = __vb_buf_unprepare(q, bundle);
- if (ret) {
- vision_err("__vb_buf_unprepare is fail(%d)\n", ret);
- goto p_err;
- }
-
- ret = __vb_queue_free(q, bundle);
- if (ret) {
- vision_err("__vb_queue_free is fail(%d)\n", ret);
- goto p_err;
- }
- }
-
- if (q->num_buffers != 0) {
- vision_err("memroy leakage is issued(%d)\n", q->num_buffers);
- BUG();
- }
-
- clear_bit(VB_QUEUE_STATE_START, &q->state);
-
-p_err:
- return ret;
-}
-
-int vb_queue_qbuf(struct vb_queue *q, struct vs4l_container_list *c)
-{
- int ret = 0;
- struct vb_bundle *bundle;
- struct vb_container *container;
- u32 direction;
- u32 i;
- u32 j, k, size;
-
- if (q->direction != c->direction) {
- vision_err("qbuf: invalid buffer direction\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- if (c->index >= VB_MAX_BUFFER) {
- vision_err("qbuf: buffer index out of range\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- bundle = q->bufs[c->index];
- if (bundle) {
- ret = __vb_queue_check(bundle, c);
- if (ret) {
- vision_err("__vb_queue_check is fail(%d)\n", ret);
- goto p_err;
- }
- } else {
- ret = __vb_queue_alloc(q, c);
- if (ret) {
- vision_err("__vb_queue_alloc is fail(%d)\n", ret);
- goto p_err;
- }
-
- bundle = q->bufs[c->index];
- }
-
- if (bundle->state != VB_BUF_STATE_DEQUEUED) {
- vision_err("qbuf: buffer already in use\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = __vb_buf_prepare(q, bundle);
- if (ret) {
- vision_err("__vb_buf_prepare is fail(%d)\n", ret);
- goto p_err;
- }
-
- if (q->direction == VS4L_DIRECTION_OT) {
- direction = DMA_FROM_DEVICE;
- } else {
- direction = DMA_TO_DEVICE;
- }
-
- /* sync buffers */
- for (i = 0; i < bundle->clist.count; ++i) {
- container = &bundle->clist.containers[i];
- BUG_ON(!container->format);
-#ifdef CONFIG_ION_EXYNOS
- if (container->memory != VS4L_MEMORY_VIRTPTR) {
- k = container->count;
- size = container->format->size[container->format->plane];
- for (j = 0; j < k; ++j) {
- vision_err("QWER kvaddr %p, dvaddr %x",container->buffers[j].kvaddr, container->buffers[j].dvaddr);
- __dma_map_area(container->buffers[j].vaddr, size, direction);
- vision_err("1QWER kvaddr %p, dvaddr %x",container->buffers[j].kvaddr, container->buffers[j].dvaddr);
- }
- }
-#endif
- }
-
- /*
- * Add to the queued buffers list, a buffer will stay on it until
- * dequeued in dqbuf.
- */
- list_add_tail(&bundle->queued_entry, &q->queued_list);
- bundle->state = VB_BUF_STATE_QUEUED;
- atomic_inc(&q->queued_count);
-
- /* vb_buffer_print(&vb->buffer); */
-
-p_err:
- return ret;
-}
-
-int vb_queue_dqbuf(struct vb_queue *q,
- struct vs4l_container_list *c,
- bool nonblocking)
-{
- int ret = 0;
- struct vb_bundle *bundle;
-
- if (q->direction != c->direction) {
- vision_err("qbuf: invalid buffer direction\n");
- ret = -EINVAL;
- goto p_err;
- }
-
- ret = __vb_get_done_vb(q, &bundle, c, nonblocking);
- if (ret < 0) {
- vision_err("__vb2_get_done_vb is fail(%d)\n", ret);
- return ret;
- }
-
- if (bundle->state != VB_BUF_STATE_DONE) {
- vision_err("dqbuf: Invalid buffer state(%X)\n", bundle->state);
- return -EINVAL;
- }
-
- /* Fill buffer information for the userspace */
- __fill_vs4l_buffer(bundle, c);
- /* Remove from videobuf queue */
- /* go back to dequeued state */
- __vb_dqbuf(bundle);
-
- list_del(&bundle->queued_entry);
- atomic_dec(&q->queued_count);
-
-p_err:
- return ret;
-}
-
-void vb_queue_process(struct vb_queue *q, struct vb_bundle *bundle)
-{
- BUG_ON(!q);
- BUG_ON(!bundle);
- BUG_ON(q->direction != bundle->clist.direction);
-
- bundle->state = VB_BUF_STATE_PROCESS;
- list_add_tail(&bundle->process_entry, &q->process_list);
- atomic_inc(&q->process_count);
-}
-
-void vb_queue_done(struct vb_queue *q, struct vb_bundle *bundle)
-{
- struct vb_container *container;
- unsigned long flag;
- u32 direction, size;
- u32 i, j, k;
-
- BUG_ON(!q);
- BUG_ON(!bundle);
- BUG_ON(q->direction != bundle->clist.direction);
-
- if (q->direction == VS4L_DIRECTION_OT)
- direction = DMA_FROM_DEVICE;
- else
- direction = DMA_TO_DEVICE;
-
- /* sync buffers */
- for (i = 0; i < bundle->clist.count; ++i) {
- container = &bundle->clist.containers[i];
- BUG_ON(!container->format);
-#ifdef CONFIG_ION_EXYNOS
- if (container->memory != VS4L_MEMORY_VIRTPTR) {
- k = container->count;
- size = container->format->size[container->format->plane];
- for (j = 0; j < k; ++j)
- __dma_map_area(container->buffers[j].vaddr, size, direction);
- }
-#endif
- }
-
- spin_lock_irqsave(&q->done_lock, flag);
-
- list_del(&bundle->process_entry);
- atomic_dec(&q->process_count);
-
- bundle->state = VB_BUF_STATE_DONE;
- list_add_tail(&bundle->done_entry, &q->done_list);
- atomic_inc(&q->done_count);
-
- spin_unlock_irqrestore(&q->done_lock, flag);
- wake_up(&q->done_wq);
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VISION driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/device.h>
-#include <asm/uaccess.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-
-#include "vision-config.h"
-#include "vision-dev.h"
-#include "vision-ioctl.h"
-
-struct vs4l_graph32 {
- __u32 id;
- __u32 priority;
- __u32 time;
- __u32 flags;
- __u32 size;
- compat_caddr_t addr;
-};
-
-struct vs4l_format32 {
- __u32 target;
- __u32 format;
- __u32 plane;
- __u32 width;
- __u32 height;
-};
-
-struct vs4l_format_list32 {
- __u32 direction;
- __u32 count;
- compat_caddr_t formats;
-};
-
-struct vs4l_param32 {
- __u32 target;
- compat_caddr_t addr;
- __u32 offset;
- __u32 size;
-};
-
-struct vs4l_param_list32 {
- __u32 count;
- compat_caddr_t params;
-};
-
-struct vs4l_ctrl32 {
- __u32 ctrl;
- __u32 value;
-};
-
-struct vs4l_roi32 {
- __u32 x;
- __u32 y;
- __u32 w;
- __u32 h;
-};
-
-struct vs4l_buffer32 {
- struct vs4l_roi roi;
- union {
- compat_caddr_t userptr;
- __s32 fd;
- } m;
- compat_caddr_t reserved;
-};
-
-struct vs4l_container32 {
- __u32 type;
- __u32 target;
- __u32 memory;
- __u32 reserved[4];
- __u32 count;
- compat_caddr_t buffers;
-};
-
-struct vs4l_container_list32 {
- __u32 direction;
- __u32 id;
- __u32 index;
- __u32 flags;
- struct compat_timeval timestamp[6];
- __u32 count;
- __u32 user_params[_MAX_NUM_OF_USER_PARAMS];
- compat_caddr_t containers;
-};
-
-#define VS4L_VERTEXIOC_S_GRAPH32 _IOW('V', 0, struct vs4l_graph32)
-#define VS4L_VERTEXIOC_S_FORMAT32 _IOW('V', 1, struct vs4l_format_list32)
-#define VS4L_VERTEXIOC_S_PARAM32 _IOW('V', 2, struct vs4l_param_list32)
-#define VS4L_VERTEXIOC_S_CTRL32 _IOW('V', 3, struct vs4l_ctrl32)
-#define VS4L_VERTEXIOC_QBUF32 _IOW('V', 6, struct vs4l_container_list32)
-#define VS4L_VERTEXIOC_DQBUF32 _IOW('V', 7, struct vs4l_container_list32)
-
-static int get_vs4l_graph32(struct vs4l_graph *kp, struct vs4l_graph32 __user *up)
-{
- int ret = 0;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct vs4l_graph32)) ||
- get_user(kp->id, &up->id) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->time, &up->time) ||
- get_user(kp->size, &up->size) ||
- get_user(kp->addr, &up->addr) ||
- get_user(kp->priority, &up->priority)) {
- vision_err("get_user is fail1\n");
- ret = -EFAULT;
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-static void put_vs4l_graph32(struct vs4l_graph *kp, struct vs4l_graph32 __user *up)
-{
-}
-
-static int get_vs4l_format32(struct vs4l_format_list *kp, struct vs4l_format_list32 __user *up)
-{
- int ret = 0;
- u32 index, size;
- compat_caddr_t p;
- struct vs4l_format32 __user *uformats32;
- struct vs4l_format *kformats;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct vs4l_format_list32)) ||
- get_user(kp->direction, &up->direction) ||
- get_user(kp->count, &up->count)) {
- vision_err("get_user is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- if (get_user(p, &up->formats)) {
- vision_err("get_user(formats) is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- size = kp->count * sizeof(struct vs4l_format32);
- uformats32 = compat_ptr(p);
- if (!access_ok(VERIFY_READ, uformats32, size)) {
- vision_err("acesss is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- size = kp->count * sizeof(struct vs4l_format);
- kformats = kmalloc(size, GFP_KERNEL);
- if (!kformats) {
- vision_err("kmalloc is fail\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- for (index = 0; index < kp->count; ++index) {
- if (get_user(kformats[index].target, &uformats32[index].target)) {
- vision_err("get_user(target) is fail\n");
- ret = -EFAULT;
- goto p_err_format_alloc;
- }
-
- if (get_user(kformats[index].format, &uformats32[index].format)) {
- vision_err("get_user(format) is fail\n");
- ret = -EFAULT;
- goto p_err_format_alloc;
- }
-
- if (get_user(kformats[index].plane, &uformats32[index].plane)) {
- vision_err("get_user(plane) is fail\n");
- ret = -EFAULT;
- goto p_err_format_alloc;
- }
-
- if (get_user(kformats[index].width, &uformats32[index].width)) {
- vision_err("get_user(width) is fail\n");
- ret = -EFAULT;
- goto p_err_format_alloc;
- }
-
- if (get_user(kformats[index].height, &uformats32[index].height)) {
- vision_err("get_user(height) is fail\n");
- ret = -EFAULT;
- goto p_err_format_alloc;
- }
- }
-
- kp->formats = kformats;
- return ret;
-
-p_err_format_alloc:
- kfree(kformats);
- kp->formats = NULL;
-
-p_err:
- vision_err("Return with failure (%d)\n", ret);
- return ret;
-}
-
-static void put_vs4l_format32(struct vs4l_format_list *kp, struct vs4l_format_list32 __user *up)
-{
- kfree(kp->formats);
-}
-
-static int get_vs4l_param32(struct vs4l_param_list *kp, struct vs4l_param_list32 __user *up)
-{
- int ret = 0;
- u32 index, size;
- compat_caddr_t p;
- struct vs4l_param32 __user *uparams32;
- struct vs4l_param *kparams;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct vs4l_param_list32)) ||
- get_user(kp->count, &up->count)) {
- vision_err("get_user is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- if (get_user(p, &up->params)) {
- vision_err("get_user(params) is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- size = kp->count * sizeof(struct vs4l_param32);
- uparams32 = compat_ptr(p);
- if (!access_ok(VERIFY_READ, uparams32, size)) {
- vision_err("access is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- size = kp->count * sizeof(struct vs4l_param);
- kparams = kmalloc(size, GFP_KERNEL);
- if (!kparams) {
- vision_err("kmalloc is fail\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- for (index = 0; index < kp->count; ++index) {
- if (get_user(kparams[index].target, &uparams32[index].target)) {
- vision_err("get_user(target) is fail\n");
- ret = -EFAULT;
- goto p_err_alloc;
- }
-
- if (get_user(kparams[index].addr, &uparams32[index].addr)) {
- vision_err("get_user(addr) is fail\n");
- ret = -EFAULT;
- goto p_err_alloc;
- }
-
- if (get_user(kparams[index].offset, &uparams32[index].offset)) {
- vision_err("get_user(offset) is fail\n");
- ret = -EFAULT;
- goto p_err_alloc;
- }
-
- if (get_user(kparams[index].size, &uparams32[index].size)) {
- vision_err("get_user(size) is fail\n");
- ret = -EFAULT;
- goto p_err_alloc;
- }
- }
-
- kp->params = kparams;
- return ret;
-
-p_err_alloc:
- kfree(kparams);
- kp->params = NULL;
-
-p_err:
- vision_err("Return with failure (%d)\n", ret);
- return ret;
-}
-
-static void put_vs4l_param32(struct vs4l_param_list *kp, struct vs4l_param_list32 __user *up)
-{
- kfree(kp->params);
-}
-
-static int get_vs4l_ctrl32(struct vs4l_ctrl *kp, struct vs4l_ctrl32 __user *up)
-{
- int ret = 0;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct vs4l_ctrl32)) ||
- get_user(kp->ctrl, &up->ctrl) ||
- get_user(kp->value, &up->value)) {
- vision_err("get_user is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-static void put_vs4l_ctrl32(struct vs4l_ctrl *kp, struct vs4l_ctrl32 __user *up)
-{
-}
-
-static int get_vs4l_container32(struct vs4l_container_list *kp, struct vs4l_container_list32 __user *up)
-{
- int ret = 0;
- u32 i, j, size;
- compat_caddr_t p;
- struct vs4l_container32 *ucontainer32;
- struct vs4l_container *kcontainer;
- struct vs4l_buffer32 *ubuffer32;
- struct vs4l_buffer *kbuffer;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct vs4l_container_list32)) ||
- get_user(kp->direction, &up->direction) ||
- get_user(kp->id, &up->id) ||
- get_user(kp->index, &up->index) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->count, &up->count) ||
- copy_from_user((void *)kp->user_params, (void *)&up->user_params, sizeof(__u32)*_MAX_NUM_OF_USER_PARAMS)) {
- vision_err("get_user is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- if (get_user(p, &up->containers)) {
- vision_err("get_user(containers) is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- size = sizeof(struct vs4l_container32) * kp->count;
- ucontainer32 = compat_ptr(p);
- if (!access_ok(VERIFY_READ, ucontainer32, size)) {
- vision_err("access is fail\n");
- ret = -EFAULT;
- goto p_err;
- }
-
- size = sizeof(struct vs4l_container) * kp->count;
- kcontainer = kzalloc(size, GFP_KERNEL);
- if (!kcontainer) {
- vision_err("kmalloc is fail(%zu, %u)\n", size, kp->count);
- ret = -ENOMEM;
- goto p_err;
- }
-
- kp->containers = kcontainer;
-
- for (i = 0; i < kp->count; ++i) {
- if (get_user(kcontainer[i].type, &ucontainer32[i].type)) {
- vision_err("get_user(type) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].target, &ucontainer32[i].target)) {
- vision_err("get_user(target) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].memory, &ucontainer32[i].memory)) {
- vision_err("get_user(memory) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].reserved[0], &ucontainer32[i].reserved[0])) {
- vision_err("get_user(reserved[0]) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].reserved[1], &ucontainer32[i].reserved[1])) {
- vision_err("get_user(reserved[1]) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].reserved[2], &ucontainer32[i].reserved[2])) {
- vision_err("get_user(reserved[2]) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].reserved[3], &ucontainer32[i].reserved[3])) {
- vision_err("get_user(reserved[3]) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kcontainer[i].count, &ucontainer32[i].count)) {
- vision_err("get_user(count) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(p, &ucontainer32[i].buffers)) {
- vision_err("get_user(buffers) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
-
- size = sizeof(struct vs4l_buffer32) * kcontainer[i].count;
- ubuffer32 = compat_ptr(p);
- if (!access_ok(VERIFY_READ, ubuffer32, size)) {
- vision_err("access is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- size = sizeof(struct vs4l_buffer) * kcontainer[i].count;
- kbuffer = kmalloc(size, GFP_KERNEL);
- if (!kbuffer) {
- vision_err("kmalloc is fail(size : %zu)\n", size);
- ret = -ENOMEM;
- goto p_err_container_alloc;
- }
-
- kcontainer[i].buffers = kbuffer;
-
- for (j = 0; j < kcontainer[i].count; ++j) {
- if (get_user(kbuffer[j].roi.x, &ubuffer32[j].roi.x)) {
- vision_err("get_user(roi.x) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kbuffer[j].roi.y, &ubuffer32[j].roi.y)) {
- vision_err("get_user(roi.y) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kbuffer[j].roi.w, &ubuffer32[j].roi.w)) {
- vision_err("get_user(roi.w) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (get_user(kbuffer[j].roi.h, &ubuffer32[j].roi.h)) {
- vision_err("get_user(roi.h) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
-
- if (kcontainer[i].memory == VS4L_MEMORY_DMABUF) {
- if (get_user(kbuffer[j].m.fd, &ubuffer32[j].m.fd)) {
- vision_err("get_user(fd) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
- } else {
- if (get_user(kbuffer[j].m.userptr, &ubuffer32[j].m.userptr)) {
- vision_err("get_user(userptr) is fail\n");
- ret = -EFAULT;
- goto p_err_container_alloc;
- }
- }
- }
- }
- return ret;
-
-p_err_container_alloc:
- for (i = 0; i < kp->count; ++i) {
- if (kcontainer[i].buffers) {
- kfree(kcontainer[i].buffers);
- kcontainer[i].buffers = NULL;
- }
- }
-
- if (kp->containers) {
- kfree(kp->containers);
- kp->containers = NULL;
- }
-
-p_err:
- return ret;
-}
-
-static void put_vs4l_container32(struct vs4l_container_list *kp, struct vs4l_container_list32 __user *up)
-{
- u32 i;
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct vs4l_container_list32)) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->index, &up->index) ||
- put_user(kp->id, &up->id) ||
- put_user(kp->timestamp[0].tv_sec, &up->timestamp[0].tv_sec) ||
- put_user(kp->timestamp[0].tv_usec, &up->timestamp[0].tv_usec) ||
- put_user(kp->timestamp[1].tv_sec, &up->timestamp[1].tv_sec) ||
- put_user(kp->timestamp[1].tv_usec, &up->timestamp[1].tv_usec) ||
- put_user(kp->timestamp[2].tv_sec, &up->timestamp[2].tv_sec) ||
- put_user(kp->timestamp[2].tv_usec, &up->timestamp[2].tv_usec) ||
- put_user(kp->timestamp[3].tv_sec, &up->timestamp[3].tv_sec) ||
- put_user(kp->timestamp[3].tv_usec, &up->timestamp[3].tv_usec) ||
- put_user(kp->timestamp[4].tv_sec, &up->timestamp[4].tv_sec) ||
- put_user(kp->timestamp[4].tv_usec, &up->timestamp[4].tv_usec) ||
- put_user(kp->timestamp[5].tv_sec, &up->timestamp[5].tv_sec) ||
- put_user(kp->timestamp[5].tv_usec, &up->timestamp[5].tv_usec) ||
- copy_to_user(up->user_params, kp->user_params, sizeof(__u32)*_MAX_NUM_OF_USER_PARAMS)) {
- vision_err("write access error\n");
- BUG();
- }
-
- for (i = 0; i < kp->count; ++i)
- kfree(kp->containers[i].buffers);
-
- kfree(kp->containers);
-}
-
-long vertex_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
-{
- long ret = 0;
- union {
- struct vs4l_graph vsgp;
- struct vs4l_format_list vsfl;
- struct vs4l_param_list vspl;
- struct vs4l_ctrl vsct;
- struct vs4l_container_list vscl;
- } karg;
- void __user *up = compat_ptr(arg);
- struct vision_device *vdev = vision_devdata(file);
- const struct vertex_ioctl_ops *ops = vdev->ioctl_ops;
-
- switch (cmd) {
- case VS4L_VERTEXIOC_S_GRAPH32:
- ret = get_vs4l_graph32(&karg.vsgp, up);
- if (ret) {
- vision_err("get_vs4l_graph32 is fail(%ld)\n", ret);
- goto p_err;
- }
-
- ret = ops->vertexioc_s_graph(file, &karg.vsgp);
- put_vs4l_graph32(&karg.vsgp, up);
- break;
- case VS4L_VERTEXIOC_S_FORMAT32:
- ret = get_vs4l_format32(&karg.vsfl, up);
- if (ret) {
- vision_err("get_vs4l_format32 is fail(%ld)\n", ret);
- goto p_err;
- }
-
- ret = ops->vertexioc_s_format(file, &karg.vsfl);
- put_vs4l_format32(&karg.vsfl, up);
- break;
- case VS4L_VERTEXIOC_S_PARAM32:
- ret = get_vs4l_param32(&karg.vspl, up);
- if (ret) {
- vision_err("get_vs4l_param32 is fail(%ld)\n", ret);
- goto p_err;
- }
-
- ret = ops->vertexioc_s_param(file, &karg.vspl);
- put_vs4l_param32(&karg.vspl, up);
- break;
- case VS4L_VERTEXIOC_S_CTRL32:
- ret = get_vs4l_ctrl32(&karg.vsct, up);
- if (ret) {
- vision_err("get_vs4l_ctrl32 is fail(%ld)\n", ret);
- goto p_err;
- }
-
- ret = ops->vertexioc_s_ctrl(file, &karg.vsct);
- put_vs4l_ctrl32(&karg.vsct, up);
- break;
- case VS4L_VERTEXIOC_STREAM_ON:
- ret = ops->vertexioc_streamon(file);
- break;
- case VS4L_VERTEXIOC_STREAM_OFF:
- ret = ops->vertexioc_streamoff(file);
- break;
- case VS4L_VERTEXIOC_QBUF32:
- ret = get_vs4l_container32(&karg.vscl, up);
- if (ret) {
- vision_err("qbuf, get_vs4l_container32 is fail(%ld)\n", ret);
- goto p_err;
- }
-
- ret = ops->vertexioc_qbuf(file, &karg.vscl);
- put_vs4l_container32(&karg.vscl, up);
- break;
- case VS4L_VERTEXIOC_DQBUF32:
- ret = get_vs4l_container32(&karg.vscl, up);
- if (ret) {
- vision_err("dqbuf, get_vs4l_container32 is fail(%ld)\n", ret);
- goto p_err;
- }
-
- ret = ops->vertexioc_dqbuf(file, &karg.vscl);
- put_vs4l_container32(&karg.vscl, up);
- break;
- default:
- vision_err("%x iocontrol is not supported(%lx, %zd)\n", cmd, VS4L_VERTEXIOC_S_FORMAT, sizeof(struct vs4l_format_list));
- break;
- }
-
-p_err:
- return ret;
-}
+++ /dev/null
-/*
- * Samsung Exynos SoC series VPU driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/device.h>
-#include <linux/poll.h>
-#include <asm/uaccess.h>
-
-#include "vision-config.h"
-#include "vision-dev.h"
-
-static struct vision_device *vision_device[VISION_NUM_DEVICES];
-static DEFINE_MUTEX(visiondev_lock);
-
-struct vision_device *vision_devdata(struct file *file)
-{
- return vision_device[iminor(file_inode(file))];
-}
-
-static int vision_open(struct inode *inode, struct file *file)
-{
- int ret = 0;
- struct vision_device *vdev;
-
- mutex_lock(&visiondev_lock);
-
- vdev = vision_devdata(file);
- if (!vdev) {
- mutex_unlock(&visiondev_lock);
- vision_err("vision device is NULL\n");
- ret = -ENODEV;
- goto p_err;
- }
-
- if (!(vdev->flags & (1 << VISION_DEVICE_TYPE_VERTEX))) {
- mutex_unlock(&visiondev_lock);
- vision_err("[V] vision device is not registered\n");
- ret = -ENODEV;
- goto p_err;
- }
-
- get_device(&vdev->dev);
- mutex_unlock(&visiondev_lock);
-
- ret = (vdev->fops->open ? vdev->fops->open(file) : -EINVAL);
- if (ret) {
- put_device(&vdev->dev);
- goto p_err;
- }
-
-p_err:
- return ret;
-}
-
-static int vision_release(struct inode *inode, struct file *file)
-{
- int ret = 0;
- struct vision_device *vdev = vision_devdata(file);
-
- ret = (vdev->fops->release ? vdev->fops->release(file) : -EINVAL);
- put_device(&vdev->dev);
-
- return 0;
-}
-
-static long vision_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int ret = 0;
- struct vision_device *vdev = vision_devdata(file);
- struct mutex *lock = vdev->lock;
-
- if (!vdev->fops->ioctl) {
- vision_err("ioctl is not registered\n");
- ret = -ENOTTY;
- goto p_err;
- }
-
- if (lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
-
- ret = vdev->fops->ioctl(file, cmd, arg);
-
- if (lock)
- mutex_unlock(lock);
-
-p_err:
- return ret;
-}
-
-static long vision_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int ret = 0;
- struct vision_device *vdev = vision_devdata(file);
- struct mutex *lock = vdev->lock;
-
- if (!vdev->fops->compat_ioctl) {
- vision_err("compat_ioctl is not registered\n");
- ret = -ENOTTY;
- goto p_err;
- }
-
- if (lock && mutex_lock_interruptible(lock))
- return -ERESTARTSYS;
-
- ret = vdev->fops->compat_ioctl(file, cmd, arg);
-
- if (lock)
- mutex_unlock(lock);
-
-p_err:
- return ret;
-}
-
-static unsigned int vision_poll(struct file *file, struct poll_table_struct *poll)
-{
- struct vision_device *vdev = vision_devdata(file);
-
- if (!vdev->fops->poll)
- return DEFAULT_POLLMASK;
-
- return vdev->fops->poll(file, poll);
-}
-
-static const struct file_operations vision_fops = {
- .owner = THIS_MODULE,
- .open = vision_open,
- .release = vision_release,
- .unlocked_ioctl = vision_ioctl,
- .compat_ioctl = vision_compat_ioctl32,
- .poll = vision_poll,
- .llseek = no_llseek,
-};
-
-static ssize_t index_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct vision_device *vdev = container_of(dev, struct vision_device, dev);
-
- return sprintf(buf, "%i\n", vdev->index);
-}
-static DEVICE_ATTR_RO(index);
-
-static ssize_t debug_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct vision_device *vdev = container_of(dev, struct vision_device, dev);
-
- return sprintf(buf, "%i\n", vdev->debug);
-}
-
-static ssize_t debug_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
-{
- struct vision_device *vdev = container_of(dev, struct vision_device, dev);
- int res = 0;
- u16 value;
-
- res = kstrtou16(buf, 0, &value);
- if (res)
- return res;
-
- vdev->debug = value;
- return len;
-}
-static DEVICE_ATTR_RW(debug);
-
-static ssize_t name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct vision_device *vdev = container_of(dev, struct vision_device, dev);
-
- return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name);
-}
-static DEVICE_ATTR_RO(name);
-
-static struct attribute *vision_device_attrs[] = {
- &dev_attr_name.attr,
- &dev_attr_debug.attr,
- &dev_attr_index.attr,
- NULL,
-};
-ATTRIBUTE_GROUPS(vision_device);
-
-static struct class vision_class = {
- .name = VISION_NAME,
- .dev_groups = vision_device_groups,
-};
-
-static void vision_device_release(struct device *dev)
-{
- struct vision_device *vdev = container_of(dev, struct vision_device, dev);
-
- mutex_lock(&visiondev_lock);
- if (WARN_ON(vision_device[vdev->minor] != vdev)) {
- /* should not happen */
- mutex_unlock(&visiondev_lock);
- return;
- }
-
- /* Free up this device for reuse */
- vision_device[vdev->minor] = NULL;
-
- /* Delete the cdev on this minor as well */
- cdev_del(vdev->cdev);
- /* Just in case some driver tries to access this from
- the release() callback. */
- vdev->cdev = NULL;
-
- mutex_unlock(&visiondev_lock);
-
- /* Release video_device and perform other
- cleanups as needed. */
- vdev->release(vdev);
-}
-
-int vision_register_device(struct vision_device *vdev, int minor, struct module *owner)
-{
- int ret = 0;
- const char *name_base;
-
- BUG_ON(!vdev->parent);
- WARN_ON(vision_device[minor] != NULL);
-
- vdev->cdev = NULL;
-
- switch (vdev->type) {
- case VISION_DEVICE_TYPE_VERTEX:
- name_base = "vertex";
- break;
- default:
- printk(KERN_ERR "%s called with unknown type: %d\n", __func__, vdev->type);
- return -EINVAL;
- }
-
- /* Part 3: Initialize the character device */
- vdev->cdev = cdev_alloc();
- if (vdev->cdev == NULL) {
- ret = -ENOMEM;
- goto cleanup;
- }
- vdev->cdev->ops = &vision_fops;
- vdev->cdev->owner = owner;
- ret = cdev_add(vdev->cdev, MKDEV(VISION_MAJOR, minor), 1);
- if (ret < 0) {
- printk(KERN_ERR "%s: cdev_add failed\n", __func__);
- kfree(vdev->cdev);
- vdev->cdev = NULL;
- goto cleanup;
- }
-
- /* Part 4: register the device with sysfs */
- vdev->dev.class = &vision_class;
- vdev->dev.parent = vdev->parent;
- vdev->dev.devt = MKDEV(VISION_MAJOR, minor);
- dev_set_name(&vdev->dev, "%s%d", name_base, minor);
- ret = device_register(&vdev->dev);
- if (ret < 0) {
- printk(KERN_ERR "%s: device_register failed\n", __func__);
- goto cleanup;
- }
- /* Register the release callback that will be called when the last
- reference to the device goes away. */
- vdev->dev.release = vision_device_release;
-
- /* Part 6: Activate this minor. The char device can now be used. */
- set_bit(VISION_FL_REGISTERED, &vdev->flags);
-
- mutex_lock(&visiondev_lock);
- vdev->minor = minor;
- vision_device[minor] = vdev;
- mutex_unlock(&visiondev_lock);
-
- return 0;
-
-cleanup:
- mutex_lock(&visiondev_lock);
- if (vdev->cdev)
- cdev_del(vdev->cdev);
- mutex_unlock(&visiondev_lock);
- /* Mark this video device as never having been registered. */
- vdev->minor = -1;
- return ret;
-}
-EXPORT_SYMBOL(vision_register_device);
-
-static int __init visiondev_init(void)
-{
- int ret;
- dev_t dev = MKDEV(VISION_MAJOR, 0);
-
- printk(KERN_INFO "Linux vision interface: v1.00\n");
- ret = register_chrdev_region(dev, VISION_NUM_DEVICES, VISION_NAME);
- if (ret < 0) {
- printk(KERN_WARNING "videodev: unable to get major %d\n", VISION_MAJOR);
- return ret;
- }
-
- ret = class_register(&vision_class);
- if (ret < 0) {
- unregister_chrdev_region(dev, VISION_NUM_DEVICES);
- printk(KERN_WARNING "video_dev: class_register failed\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static void __exit visiondev_exit(void)
-{
- dev_t dev = MKDEV(VISION_MAJOR, 0);
-
- class_unregister(&vision_class);
- unregister_chrdev_region(dev, VISION_NUM_DEVICES);
-}
-
-subsys_initcall(visiondev_init);
-module_exit(visiondev_exit)
-
-MODULE_AUTHOR("Gilyeon Lim <kilyeon.im@samsung.com>");
-MODULE_DESCRIPTION("Device registrar for Vision4Linux drivers v1");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_CHARDEV_MAJOR(VISION_MAJOR);
+++ /dev/null
-/*
- * Samsung Exynos SoC series VISION driver
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/device.h>
-#include <asm/uaccess.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-
-#include "vision-config.h"
-#include "vision-dev.h"
-#include "vision-ioctl.h"
-
-long vertex_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int ret = 0;
- struct vision_device *vdev = vision_devdata(file);
- const struct vertex_ioctl_ops *ops = vdev->ioctl_ops;
- char sbuf[128];
- void *mbuf = NULL;
- void *parg = (void *)arg;
- unsigned int cmdsize = _IOC_SIZE(cmd);
-
- if (cmdsize <= sizeof(sbuf)) {
- parg = sbuf;
- } else {
- /* too big to allocate from stack */
- mbuf = kmalloc(cmdsize, GFP_KERNEL);
- if (NULL == mbuf) {
- vision_err("kmalloc is fail\n");
- ret = -ENOMEM;
- goto p_err;
- }
-
- parg = mbuf;
- }
-
- ret = copy_from_user(parg, (void __user *)arg, cmdsize);
- if (ret) {
- vision_err("copy_from_user is fail(%d)\n", ret);
- memcpy(parg, (void __user *)arg, cmdsize);
- ret = 0;
- //goto p_err;
- }
-
- switch (cmd) {
- case VS4L_VERTEXIOC_S_GRAPH:
- {
- ret = ops->vertexioc_s_graph(file, parg);
- if (ret) {
- vision_err("vertexioc_s_graph is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_S_FORMAT:
- {
- ret = ops->vertexioc_s_format(file, parg);
- if (ret) {
- vision_err("vertexioc_s_format is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_S_PARAM:
- {
- ret = ops->vertexioc_s_param(file, parg);
- if (ret) {
- vision_err("vertexioc_s_param is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_S_CTRL:
- {
- ret = ops->vertexioc_s_ctrl(file, parg);
- if (ret) {
- vision_err("vertexioc_s_ctrl is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_STREAM_ON:
- {
- ret = ops->vertexioc_streamon(file);
- if (ret) {
- vision_err("vertexioc_streamon is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_STREAM_OFF:
- {
- ret = ops->vertexioc_streamoff(file);
- if (ret) {
- vision_err("vertexioc_streamoff is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_QBUF:
- {
- ret = ops->vertexioc_qbuf(file, parg);
- if (ret) {
- vision_err("vertexioc_qbuf is fail(%d)\n", ret);
- goto p_err;
- }
- }
- break;
- case VS4L_VERTEXIOC_DQBUF:
- {
- ret = ops->vertexioc_dqbuf(file, parg);
- if (ret) {
- vision_err("vertexioc_dqbuf is fail(%d)\n", ret);
- goto p_err;
- }
- ret = copy_to_user((void __user *)arg, parg, cmdsize);
- if (ret) {
- vision_err("copy_to_user is fail(%d)\n", ret);
- memcpy((void __user *)arg, parg, cmdsize);
- ret = 0;
- goto p_err;
- }
- }
- break;
- default:
- vision_err("%x iocontrol is not supported(%lx, %zd)\n", cmd, VS4L_VERTEXIOC_S_FORMAT, sizeof(struct vs4l_format_list));
- break;
- }
-
-p_err:
- kfree(mbuf);
- return ret;
-}