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