Merge tag 'keys-acl-20190703' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / exynos / exynos_drm_ipp.h
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