Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[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 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