1*2874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
29913f74fSMarek Szyprowski /*
39913f74fSMarek Szyprowski * Copyright (c) 2017 Samsung Electronics Co., Ltd.
49913f74fSMarek Szyprowski */
59913f74fSMarek Szyprowski
69913f74fSMarek Szyprowski #ifndef _EXYNOS_DRM_IPP_H_
79913f74fSMarek Szyprowski #define _EXYNOS_DRM_IPP_H_
89913f74fSMarek Szyprowski
99913f74fSMarek Szyprowski struct exynos_drm_ipp;
109913f74fSMarek Szyprowski struct exynos_drm_ipp_task;
119913f74fSMarek Szyprowski
129913f74fSMarek Szyprowski /**
139913f74fSMarek Szyprowski * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions
149913f74fSMarek Szyprowski */
159913f74fSMarek Szyprowski struct exynos_drm_ipp_funcs {
169913f74fSMarek Szyprowski /**
179913f74fSMarek Szyprowski * @commit:
189913f74fSMarek Szyprowski *
199913f74fSMarek Szyprowski * This is the main entry point to start framebuffer processing
209913f74fSMarek Szyprowski * in the hardware. The exynos_drm_ipp_task has been already validated.
219913f74fSMarek Szyprowski * This function must not wait until the device finishes processing.
229913f74fSMarek Szyprowski * When the driver finishes processing, it has to call
239913f74fSMarek Szyprowski * exynos_exynos_drm_ipp_task_done() function.
249913f74fSMarek Szyprowski *
259913f74fSMarek Szyprowski * RETURNS:
269913f74fSMarek Szyprowski *
279913f74fSMarek Szyprowski * 0 on success or negative error codes in case of failure.
289913f74fSMarek Szyprowski */
299913f74fSMarek Szyprowski int (*commit)(struct exynos_drm_ipp *ipp,
309913f74fSMarek Szyprowski struct exynos_drm_ipp_task *task);
319913f74fSMarek Szyprowski
329913f74fSMarek Szyprowski /**
339913f74fSMarek Szyprowski * @abort:
349913f74fSMarek Szyprowski *
359913f74fSMarek Szyprowski * Informs the driver that it has to abort the currently running
369913f74fSMarek Szyprowski * task as soon as possible (i.e. as soon as it can stop the device
379913f74fSMarek Szyprowski * safely), even if the task would not have been finished by then.
389913f74fSMarek Szyprowski * After the driver performs the necessary steps, it has to call
399913f74fSMarek Szyprowski * exynos_drm_ipp_task_done() (as if the task ended normally).
409913f74fSMarek Szyprowski * This function does not have to (and will usually not) wait
419913f74fSMarek Szyprowski * until the device enters a state when it can be stopped.
429913f74fSMarek Szyprowski */
439913f74fSMarek Szyprowski void (*abort)(struct exynos_drm_ipp *ipp,
449913f74fSMarek Szyprowski struct exynos_drm_ipp_task *task);
459913f74fSMarek Szyprowski };
469913f74fSMarek Szyprowski
479913f74fSMarek Szyprowski /**
489913f74fSMarek Szyprowski * struct exynos_drm_ipp - central picture processor module structure
499913f74fSMarek Szyprowski */
509913f74fSMarek Szyprowski struct exynos_drm_ipp {
518b955034SInki Dae struct drm_device *drm_dev;
528b955034SInki Dae struct device *dev;
539913f74fSMarek Szyprowski struct list_head head;
549913f74fSMarek Szyprowski unsigned int id;
559913f74fSMarek Szyprowski
569913f74fSMarek Szyprowski const char *name;
579913f74fSMarek Szyprowski const struct exynos_drm_ipp_funcs *funcs;
589913f74fSMarek Szyprowski unsigned int capabilities;
599913f74fSMarek Szyprowski const struct exynos_drm_ipp_formats *formats;
609913f74fSMarek Szyprowski unsigned int num_formats;
619913f74fSMarek Szyprowski atomic_t sequence;
629913f74fSMarek Szyprowski
639913f74fSMarek Szyprowski spinlock_t lock;
649913f74fSMarek Szyprowski struct exynos_drm_ipp_task *task;
659913f74fSMarek Szyprowski struct list_head todo_list;
669913f74fSMarek Szyprowski wait_queue_head_t done_wq;
679913f74fSMarek Szyprowski };
689913f74fSMarek Szyprowski
699913f74fSMarek Szyprowski struct exynos_drm_ipp_buffer {
709913f74fSMarek Szyprowski struct drm_exynos_ipp_task_buffer buf;
719913f74fSMarek Szyprowski struct drm_exynos_ipp_task_rect rect;
729913f74fSMarek Szyprowski
739913f74fSMarek Szyprowski struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
749913f74fSMarek Szyprowski const struct drm_format_info *format;
759913f74fSMarek Szyprowski dma_addr_t dma_addr[MAX_FB_BUFFER];
769913f74fSMarek Szyprowski };
779913f74fSMarek Szyprowski
789913f74fSMarek Szyprowski /**
799913f74fSMarek Szyprowski * struct exynos_drm_ipp_task - a structure describing transformation that
809913f74fSMarek Szyprowski * has to be performed by the picture processor hardware module
819913f74fSMarek Szyprowski */
829913f74fSMarek Szyprowski struct exynos_drm_ipp_task {
838b955034SInki Dae struct device *dev;
849913f74fSMarek Szyprowski struct exynos_drm_ipp *ipp;
859913f74fSMarek Szyprowski struct list_head head;
869913f74fSMarek Szyprowski
879913f74fSMarek Szyprowski struct exynos_drm_ipp_buffer src;
889913f74fSMarek Szyprowski struct exynos_drm_ipp_buffer dst;
899913f74fSMarek Szyprowski
909913f74fSMarek Szyprowski struct drm_exynos_ipp_task_transform transform;
919913f74fSMarek Szyprowski struct drm_exynos_ipp_task_alpha alpha;
929913f74fSMarek Szyprowski
939913f74fSMarek Szyprowski struct work_struct cleanup_work;
949913f74fSMarek Szyprowski unsigned int flags;
959913f74fSMarek Szyprowski int ret;
969913f74fSMarek Szyprowski
979913f74fSMarek Szyprowski struct drm_pending_exynos_ipp_event *event;
989913f74fSMarek Szyprowski };
999913f74fSMarek Szyprowski
1009913f74fSMarek Szyprowski #define DRM_EXYNOS_IPP_TASK_DONE (1 << 0)
1019913f74fSMarek Szyprowski #define DRM_EXYNOS_IPP_TASK_ASYNC (1 << 1)
1029913f74fSMarek Szyprowski
1039913f74fSMarek Szyprowski struct exynos_drm_ipp_formats {
1049913f74fSMarek Szyprowski uint32_t fourcc;
1059913f74fSMarek Szyprowski uint32_t type;
1069913f74fSMarek Szyprowski uint64_t modifier;
1079913f74fSMarek Szyprowski const struct drm_exynos_ipp_limit *limits;
1089913f74fSMarek Szyprowski unsigned int num_limits;
1099913f74fSMarek Szyprowski };
1109913f74fSMarek Szyprowski
1119913f74fSMarek Szyprowski /* helper macros to set exynos_drm_ipp_formats structure and limits*/
1129913f74fSMarek Szyprowski #define IPP_SRCDST_MFORMAT(f, m, l) \
1139913f74fSMarek Szyprowski .fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
1149913f74fSMarek Szyprowski .num_limits = ARRAY_SIZE(l), \
1159913f74fSMarek Szyprowski .type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
1169913f74fSMarek Szyprowski DRM_EXYNOS_IPP_FORMAT_DESTINATION)
1179913f74fSMarek Szyprowski
1189913f74fSMarek Szyprowski #define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
1199913f74fSMarek Szyprowski
1209913f74fSMarek Szyprowski #define IPP_SIZE_LIMIT(l, val...) \
1219913f74fSMarek Szyprowski .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
1229913f74fSMarek Szyprowski DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
1239913f74fSMarek Szyprowski
1249913f74fSMarek Szyprowski #define IPP_SCALE_LIMIT(val...) \
1259913f74fSMarek Szyprowski .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
1269913f74fSMarek Szyprowski
1278b955034SInki Dae int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp,
1289913f74fSMarek Szyprowski const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
1299913f74fSMarek Szyprowski const struct exynos_drm_ipp_formats *formats,
1309913f74fSMarek Szyprowski unsigned int num_formats, const char *name);
1318b955034SInki Dae void exynos_drm_ipp_unregister(struct device *dev,
1329913f74fSMarek Szyprowski struct exynos_drm_ipp *ipp);
1339913f74fSMarek Szyprowski
1349913f74fSMarek Szyprowski void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
1359913f74fSMarek Szyprowski
1369913f74fSMarek Szyprowski #ifdef CONFIG_DRM_EXYNOS_IPP
1379913f74fSMarek Szyprowski int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
1389913f74fSMarek Szyprowski struct drm_file *file_priv);
1399913f74fSMarek Szyprowski int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
1409913f74fSMarek Szyprowski struct drm_file *file_priv);
1419913f74fSMarek Szyprowski int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
1429913f74fSMarek Szyprowski struct drm_file *file_priv);
1439913f74fSMarek Szyprowski int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
1449913f74fSMarek Szyprowski void *data, struct drm_file *file_priv);
1459913f74fSMarek Szyprowski #else
exynos_drm_ipp_get_res_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1469913f74fSMarek Szyprowski static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
1479913f74fSMarek Szyprowski void *data, struct drm_file *file_priv)
1489913f74fSMarek Szyprowski {
1499913f74fSMarek Szyprowski struct drm_exynos_ioctl_ipp_get_res *resp = data;
1509913f74fSMarek Szyprowski
1519913f74fSMarek Szyprowski resp->count_ipps = 0;
1529913f74fSMarek Szyprowski return 0;
1539913f74fSMarek Szyprowski }
exynos_drm_ipp_get_caps_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1549913f74fSMarek Szyprowski static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev,
1559913f74fSMarek Szyprowski void *data, struct drm_file *file_priv)
1569913f74fSMarek Szyprowski {
1579913f74fSMarek Szyprowski return -ENODEV;
1589913f74fSMarek Szyprowski }
exynos_drm_ipp_get_limits_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1599913f74fSMarek Szyprowski static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev,
1609913f74fSMarek Szyprowski void *data, struct drm_file *file_priv)
1619913f74fSMarek Szyprowski {
1629913f74fSMarek Szyprowski return -ENODEV;
1639913f74fSMarek Szyprowski }
exynos_drm_ipp_commit_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1649913f74fSMarek Szyprowski static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
1659913f74fSMarek Szyprowski void *data, struct drm_file *file_priv)
1669913f74fSMarek Szyprowski {
1679913f74fSMarek Szyprowski return -ENODEV;
1689913f74fSMarek Szyprowski }
1699913f74fSMarek Szyprowski #endif
1709913f74fSMarek Szyprowski #endif
171