123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /* 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_
- 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
|