1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (c) 2017 Samsung Electronics Co., Ltd. 4 */ 5 6 #ifndef _EXYNOS_DRM_IPP_H_ 7 #define _EXYNOS_DRM_IPP_H_ 8 9 struct exynos_drm_ipp; 10 struct exynos_drm_ipp_task; 11 12 /** 13 * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions 14 */ 15 struct exynos_drm_ipp_funcs { 16 /** 17 * @commit: 18 * 19 * This is the main entry point to start framebuffer processing 20 * in the hardware. The exynos_drm_ipp_task has been already validated. 21 * This function must not wait until the device finishes processing. 22 * When the driver finishes processing, it has to call 23 * exynos_exynos_drm_ipp_task_done() function. 24 * 25 * RETURNS: 26 * 27 * 0 on success or negative error codes in case of failure. 28 */ 29 int (*commit)(struct exynos_drm_ipp *ipp, 30 struct exynos_drm_ipp_task *task); 31 32 /** 33 * @abort: 34 * 35 * Informs the driver that it has to abort the currently running 36 * task as soon as possible (i.e. as soon as it can stop the device 37 * safely), even if the task would not have been finished by then. 38 * After the driver performs the necessary steps, it has to call 39 * exynos_drm_ipp_task_done() (as if the task ended normally). 40 * This function does not have to (and will usually not) wait 41 * until the device enters a state when it can be stopped. 42 */ 43 void (*abort)(struct exynos_drm_ipp *ipp, 44 struct exynos_drm_ipp_task *task); 45 }; 46 47 /** 48 * struct exynos_drm_ipp - central picture processor module structure 49 */ 50 struct exynos_drm_ipp { 51 struct drm_device *drm_dev; 52 struct device *dev; 53 struct list_head head; 54 unsigned int id; 55 56 const char *name; 57 const struct exynos_drm_ipp_funcs *funcs; 58 unsigned int capabilities; 59 const struct exynos_drm_ipp_formats *formats; 60 unsigned int num_formats; 61 atomic_t sequence; 62 63 spinlock_t lock; 64 struct exynos_drm_ipp_task *task; 65 struct list_head todo_list; 66 wait_queue_head_t done_wq; 67 }; 68 69 struct exynos_drm_ipp_buffer { 70 struct drm_exynos_ipp_task_buffer buf; 71 struct drm_exynos_ipp_task_rect rect; 72 73 struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER]; 74 const struct drm_format_info *format; 75 dma_addr_t dma_addr[MAX_FB_BUFFER]; 76 }; 77 78 /** 79 * struct exynos_drm_ipp_task - a structure describing transformation that 80 * has to be performed by the picture processor hardware module 81 */ 82 struct exynos_drm_ipp_task { 83 struct device *dev; 84 struct exynos_drm_ipp *ipp; 85 struct list_head head; 86 87 struct exynos_drm_ipp_buffer src; 88 struct exynos_drm_ipp_buffer dst; 89 90 struct drm_exynos_ipp_task_transform transform; 91 struct drm_exynos_ipp_task_alpha alpha; 92 93 struct work_struct cleanup_work; 94 unsigned int flags; 95 int ret; 96 97 struct drm_pending_exynos_ipp_event *event; 98 }; 99 100 #define DRM_EXYNOS_IPP_TASK_DONE (1 << 0) 101 #define DRM_EXYNOS_IPP_TASK_ASYNC (1 << 1) 102 103 struct exynos_drm_ipp_formats { 104 uint32_t fourcc; 105 uint32_t type; 106 uint64_t modifier; 107 const struct drm_exynos_ipp_limit *limits; 108 unsigned int num_limits; 109 }; 110 111 /* helper macros to set exynos_drm_ipp_formats structure and limits*/ 112 #define IPP_SRCDST_MFORMAT(f, m, l) \ 113 .fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \ 114 .num_limits = ARRAY_SIZE(l), \ 115 .type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \ 116 DRM_EXYNOS_IPP_FORMAT_DESTINATION) 117 118 #define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l) 119 120 #define IPP_SIZE_LIMIT(l, val...) \ 121 .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \ 122 DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val 123 124 #define IPP_SCALE_LIMIT(val...) \ 125 .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val 126 127 int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp, 128 const struct exynos_drm_ipp_funcs *funcs, unsigned int caps, 129 const struct exynos_drm_ipp_formats *formats, 130 unsigned int num_formats, const char *name); 131 void exynos_drm_ipp_unregister(struct device *dev, 132 struct exynos_drm_ipp *ipp); 133 134 void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret); 135 136 #ifdef CONFIG_DRM_EXYNOS_IPP 137 int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data, 138 struct drm_file *file_priv); 139 int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data, 140 struct drm_file *file_priv); 141 int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data, 142 struct drm_file *file_priv); 143 int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, 144 void *data, struct drm_file *file_priv); 145 #else 146 static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, 147 void *data, struct drm_file *file_priv) 148 { 149 struct drm_exynos_ioctl_ipp_get_res *resp = data; 150 151 resp->count_ipps = 0; 152 return 0; 153 } 154 static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, 155 void *data, struct drm_file *file_priv) 156 { 157 return -ENODEV; 158 } 159 static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, 160 void *data, struct drm_file *file_priv) 161 { 162 return -ENODEV; 163 } 164 static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, 165 void *data, struct drm_file *file_priv) 166 { 167 return -ENODEV; 168 } 169 #endif 170 #endif 171