#ifndef _EXYNOS_DRM_IPP_H_
#define _EXYNOS_DRM_IPP_H_
struct exynos_drm_ipp;
struct exynos_drm_ipp_task;
struct exynos_drm_ipp_funcs {
int (*commit)(struct exynos_drm_ipp *ipp,
struct exynos_drm_ipp_task *task);
void (*abort)(struct exynos_drm_ipp *ipp,
struct exynos_drm_ipp_task *task);
};
struct exynos_drm_ipp {
struct drm_device *drm_dev;
struct device *dev;
struct list_head head;
unsigned int id;
const char *name;
const struct exynos_drm_ipp_funcs *funcs;
unsigned int capabilities;
const struct exynos_drm_ipp_formats *formats;
unsigned int num_formats;
atomic_t sequence;
spinlock_t lock;
struct exynos_drm_ipp_task *task;
struct list_head todo_list;
wait_queue_head_t done_wq;
};
struct exynos_drm_ipp_buffer {
struct drm_exynos_ipp_task_buffer buf;
struct drm_exynos_ipp_task_rect rect;
struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
const struct drm_format_info *format;
dma_addr_t dma_addr[MAX_FB_BUFFER];
};
struct exynos_drm_ipp_task {
struct device *dev;
struct exynos_drm_ipp *ipp;
struct list_head head;
struct exynos_drm_ipp_buffer src;
struct exynos_drm_ipp_buffer dst;
struct drm_exynos_ipp_task_transform transform;
struct drm_exynos_ipp_task_alpha alpha;
struct work_struct cleanup_work;
unsigned int flags;
int ret;
struct drm_pending_exynos_ipp_event *event;
};
#define DRM_EXYNOS_IPP_TASK_DONE (1 << 0)
#define DRM_EXYNOS_IPP_TASK_ASYNC (1 << 1)
struct exynos_drm_ipp_formats {
uint32_t fourcc;
uint32_t type;
uint64_t modifier;
const struct drm_exynos_ipp_limit *limits;
unsigned int num_limits;
};
#define IPP_SRCDST_MFORMAT(f, m, l) \
.fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
.num_limits = ARRAY_SIZE(l), \
.type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
DRM_EXYNOS_IPP_FORMAT_DESTINATION)
#define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
#define IPP_SIZE_LIMIT(l, val...) \
.type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
#define IPP_SCALE_LIMIT(val...) \
.type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp,
const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
const struct exynos_drm_ipp_formats *formats,
unsigned int num_formats, const char *name);
void exynos_drm_ipp_unregister(struct device *dev,
struct exynos_drm_ipp *ipp);
void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
#ifdef CONFIG_DRM_EXYNOS_IPP
int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
#else
static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_exynos_ioctl_ipp_get_res *resp = data;
resp->count_ipps = 0;
return 0;
}
static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
return -ENODEV;
}
static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
return -ENODEV;
}
static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
return -ENODEV;
}
#endif
#endif