drm/exynos: ipp: Add IPP v2 framework
[platform/kernel/linux-rpi.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 *dev;
58         struct list_head head;
59         unsigned int id;
60
61         const char *name;
62         const struct exynos_drm_ipp_funcs *funcs;
63         unsigned int capabilities;
64         const struct exynos_drm_ipp_formats *formats;
65         unsigned int num_formats;
66         atomic_t sequence;
67
68         spinlock_t lock;
69         struct exynos_drm_ipp_task *task;
70         struct list_head todo_list;
71         wait_queue_head_t done_wq;
72 };
73
74 struct exynos_drm_ipp_buffer {
75         struct drm_exynos_ipp_task_buffer buf;
76         struct drm_exynos_ipp_task_rect rect;
77
78         struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
79         const struct drm_format_info *format;
80         dma_addr_t dma_addr[MAX_FB_BUFFER];
81 };
82
83 /**
84  * struct exynos_drm_ipp_task - a structure describing transformation that
85  * has to be performed by the picture processor hardware module
86  */
87 struct exynos_drm_ipp_task {
88         struct drm_device *dev;
89         struct exynos_drm_ipp *ipp;
90         struct list_head head;
91
92         struct exynos_drm_ipp_buffer src;
93         struct exynos_drm_ipp_buffer dst;
94
95         struct drm_exynos_ipp_task_transform transform;
96         struct drm_exynos_ipp_task_alpha alpha;
97
98         struct work_struct cleanup_work;
99         unsigned int flags;
100         int ret;
101
102         struct drm_pending_exynos_ipp_event *event;
103 };
104
105 #define DRM_EXYNOS_IPP_TASK_DONE        (1 << 0)
106 #define DRM_EXYNOS_IPP_TASK_ASYNC       (1 << 1)
107
108 struct exynos_drm_ipp_formats {
109         uint32_t fourcc;
110         uint32_t type;
111         uint64_t modifier;
112         const struct drm_exynos_ipp_limit *limits;
113         unsigned int num_limits;
114 };
115
116 /* helper macros to set exynos_drm_ipp_formats structure and limits*/
117 #define IPP_SRCDST_MFORMAT(f, m, l) \
118         .fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
119         .num_limits = ARRAY_SIZE(l), \
120         .type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
121                  DRM_EXYNOS_IPP_FORMAT_DESTINATION)
122
123 #define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
124
125 #define IPP_SIZE_LIMIT(l, val...)       \
126         .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
127                  DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
128
129 #define IPP_SCALE_LIMIT(val...)         \
130         .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
131
132 int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp,
133                 const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
134                 const struct exynos_drm_ipp_formats *formats,
135                 unsigned int num_formats, const char *name);
136 void exynos_drm_ipp_unregister(struct drm_device *dev,
137                                struct exynos_drm_ipp *ipp);
138
139 void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
140
141 #ifdef CONFIG_DRM_EXYNOS_IPP
142 int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
143                                  struct drm_file *file_priv);
144 int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
145                                   struct drm_file *file_priv);
146 int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
147                                     struct drm_file *file_priv);
148 int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
149                                 void *data, struct drm_file *file_priv);
150 #else
151 static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
152          void *data, struct drm_file *file_priv)
153 {
154         struct drm_exynos_ioctl_ipp_get_res *resp = data;
155
156         resp->count_ipps = 0;
157         return 0;
158 }
159 static inline int exynos_drm_ipp_get_caps_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_get_limits_ioctl(struct drm_device *dev,
165          void *data, struct drm_file *file_priv)
166 {
167         return -ENODEV;
168 }
169 static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
170          void *data, struct drm_file *file_priv)
171 {
172         return -ENODEV;
173 }
174 #endif
175 #endif