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