xref: /openbmc/linux/drivers/gpu/drm/exynos/exynos_drm_ipp.h (revision 4984dd069f2995f239f075199ee8c0d9f020bcd9)
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
177