173 lines
4.8 KiB
C
173 lines
4.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
|
|
*/
|
|
|
|
#ifndef _EXYNOS_DRM_IPP_H_
|
|
#define _EXYNOS_DRM_IPP_H_
|
|
|
|
#include <drm/drmP.h>
|
|
|
|
struct exynos_drm_ipp;
|
|
struct exynos_drm_ipp_task;
|
|
|
|
/**
|
|
* struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions
|
|
*/
|
|
struct exynos_drm_ipp_funcs {
|
|
/**
|
|
* @commit:
|
|
*
|
|
* This is the main entry point to start framebuffer processing
|
|
* in the hardware. The exynos_drm_ipp_task has been already validated.
|
|
* This function must not wait until the device finishes processing.
|
|
* When the driver finishes processing, it has to call
|
|
* exynos_exynos_drm_ipp_task_done() function.
|
|
*
|
|
* RETURNS:
|
|
*
|
|
* 0 on success or negative error codes in case of failure.
|
|
*/
|
|
int (*commit)(struct exynos_drm_ipp *ipp,
|
|
struct exynos_drm_ipp_task *task);
|
|
|
|
/**
|
|
* @abort:
|
|
*
|
|
* Informs the driver that it has to abort the currently running
|
|
* task as soon as possible (i.e. as soon as it can stop the device
|
|
* safely), even if the task would not have been finished by then.
|
|
* After the driver performs the necessary steps, it has to call
|
|
* exynos_drm_ipp_task_done() (as if the task ended normally).
|
|
* This function does not have to (and will usually not) wait
|
|
* until the device enters a state when it can be stopped.
|
|
*/
|
|
void (*abort)(struct exynos_drm_ipp *ipp,
|
|
struct exynos_drm_ipp_task *task);
|
|
};
|
|
|
|
/**
|
|
* struct exynos_drm_ipp - central picture processor module structure
|
|
*/
|
|
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 - a structure describing transformation that
|
|
* has to be performed by the picture processor hardware module
|
|
*/
|
|
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;
|
|
};
|
|
|
|
/* helper macros to set exynos_drm_ipp_formats structure and 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
|