1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3  *
4  * Authors:
5  *	Eunchul Kim <chulspro.kim@samsung.com>
6  *	Jinyoung Jeon <jy0.jeon@samsung.com>
7  *	Sangmin Lee <lsmin.lee@samsung.com>
8  *
9  * This program is free software; you can redistribute  it and/or modify it
10  * under  the terms of  the GNU General  Public License as published by the
11  * Free Software Foundation;  either version 2 of the  License, or (at your
12  * option) any later version.
13  */
14 
15 #ifndef _EXYNOS_DRM_IPP_H_
16 #define _EXYNOS_DRM_IPP_H_
17 
18 #define for_each_ipp_ops(pos)	\
19 	for (pos = 0; pos < EXYNOS_DRM_OPS_MAX; pos++)
20 #define for_each_ipp_planar(pos)	\
21 	for (pos = 0; pos < EXYNOS_DRM_PLANAR_MAX; pos++)
22 
23 #define IPP_GET_LCD_WIDTH	_IOR('F', 302, int)
24 #define IPP_GET_LCD_HEIGHT	_IOR('F', 303, int)
25 #define IPP_SET_WRITEBACK	_IOW('F', 304, u32)
26 
27 /* definition of state */
28 enum drm_exynos_ipp_state {
29 	IPP_STATE_IDLE,
30 	IPP_STATE_START,
31 	IPP_STATE_STOP,
32 };
33 
34 /*
35  * A structure of command work information.
36  * @work: work structure.
37  * @ippdrv: current work ippdrv.
38  * @c_node: command node information.
39  * @ctrl: command control.
40  */
41 struct drm_exynos_ipp_cmd_work {
42 	struct work_struct	work;
43 	struct exynos_drm_ippdrv	*ippdrv;
44 	struct drm_exynos_ipp_cmd_node *c_node;
45 	enum drm_exynos_ipp_ctrl	ctrl;
46 };
47 
48 /*
49  * A structure of command node.
50  *
51  * @list: list head to command queue information.
52  * @event_list: list head of event.
53  * @mem_list: list head to source,destination memory queue information.
54  * @lock: lock for synchronization of access to ioctl.
55  * @mem_lock: lock for synchronization of access to memory nodes.
56  * @event_lock: lock for synchronization of access to scheduled event.
57  * @start_complete: completion of start of command.
58  * @stop_complete: completion of stop of command.
59  * @property: property information.
60  * @start_work: start command work structure.
61  * @stop_work: stop command work structure.
62  * @event_work: event work structure.
63  * @state: state of command node.
64  * @filp: associated file pointer.
65  */
66 struct drm_exynos_ipp_cmd_node {
67 	struct list_head	list;
68 	struct list_head	event_list;
69 	struct list_head	mem_list[EXYNOS_DRM_OPS_MAX];
70 	struct mutex	lock;
71 	struct mutex	mem_lock;
72 	struct mutex	event_lock;
73 	struct completion	start_complete;
74 	struct completion	stop_complete;
75 	struct drm_exynos_ipp_property	property;
76 	struct drm_exynos_ipp_cmd_work *start_work;
77 	struct drm_exynos_ipp_cmd_work *stop_work;
78 	struct drm_exynos_ipp_event_work *event_work;
79 	enum drm_exynos_ipp_state	state;
80 	struct drm_file	*filp;
81 };
82 
83 /*
84  * A structure of buffer information.
85  *
86  * @handles: Y, Cb, Cr each gem object handle.
87  * @base: Y, Cb, Cr each planar address.
88  */
89 struct drm_exynos_ipp_buf_info {
90 	unsigned long	handles[EXYNOS_DRM_PLANAR_MAX];
91 	dma_addr_t	base[EXYNOS_DRM_PLANAR_MAX];
92 };
93 
94 /*
95  * A structure of wb setting information.
96  *
97  * @enable: enable flag for wb.
98  * @refresh: HZ of the refresh rate.
99  */
100 struct drm_exynos_ipp_set_wb {
101 	__u32	enable;
102 	__u32	refresh;
103 };
104 
105 /*
106  * A structure of event work information.
107  *
108  * @work: work structure.
109  * @ippdrv: current work ippdrv.
110  * @buf_id: id of src, dst buffer.
111  */
112 struct drm_exynos_ipp_event_work {
113 	struct work_struct	work;
114 	struct exynos_drm_ippdrv *ippdrv;
115 	u32	buf_id[EXYNOS_DRM_OPS_MAX];
116 };
117 
118 /*
119  * A structure of source,destination operations.
120  *
121  * @set_fmt: set format of image.
122  * @set_transf: set transform(rotations, flip).
123  * @set_size: set size of region.
124  * @set_addr: set address for dma.
125  */
126 struct exynos_drm_ipp_ops {
127 	int (*set_fmt)(struct device *dev, u32 fmt);
128 	int (*set_transf)(struct device *dev,
129 		enum drm_exynos_degree degree,
130 		enum drm_exynos_flip flip, bool *swap);
131 	int (*set_size)(struct device *dev, int swap,
132 		struct drm_exynos_pos *pos, struct drm_exynos_sz *sz);
133 	int (*set_addr)(struct device *dev,
134 		 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id,
135 		enum drm_exynos_ipp_buf_type buf_type);
136 };
137 
138 /*
139  * A structure of ipp driver.
140  *
141  * @drv_list: list head for registed sub driver information.
142  * @parent_dev: parent device information.
143  * @dev: platform device.
144  * @drm_dev: drm device.
145  * @dedicated: dedicated ipp device.
146  * @ops: source, destination operations.
147  * @event_workq: event work queue.
148  * @c_node: current command information.
149  * @cmd_list: list head for command information.
150  * @cmd_lock: lock for synchronization of access to cmd_list.
151  * @prop_list: property informations of current ipp driver.
152  * @check_property: check property about format, size, buffer.
153  * @reset: reset ipp block.
154  * @start: ipp each device start.
155  * @stop: ipp each device stop.
156  * @sched_event: work schedule handler.
157  */
158 struct exynos_drm_ippdrv {
159 	struct list_head	drv_list;
160 	struct device	*parent_dev;
161 	struct device	*dev;
162 	struct drm_device	*drm_dev;
163 	bool	dedicated;
164 	struct exynos_drm_ipp_ops	*ops[EXYNOS_DRM_OPS_MAX];
165 	struct workqueue_struct	*event_workq;
166 	struct drm_exynos_ipp_cmd_node *c_node;
167 	struct list_head	cmd_list;
168 	struct mutex	cmd_lock;
169 	struct drm_exynos_ipp_prop_list prop_list;
170 
171 	int (*check_property)(struct device *dev,
172 		struct drm_exynos_ipp_property *property);
173 	int (*reset)(struct device *dev);
174 	int (*start)(struct device *dev, enum drm_exynos_ipp_cmd cmd);
175 	void (*stop)(struct device *dev, enum drm_exynos_ipp_cmd cmd);
176 	void (*sched_event)(struct work_struct *work);
177 };
178 
179 #ifdef CONFIG_DRM_EXYNOS_IPP
180 extern int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv);
181 extern int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv);
182 extern int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
183 					 struct drm_file *file);
184 extern int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
185 					 struct drm_file *file);
186 extern int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
187 					 struct drm_file *file);
188 extern int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
189 					 struct drm_file *file);
190 extern int exynos_drm_ippnb_register(struct notifier_block *nb);
191 extern int exynos_drm_ippnb_unregister(struct notifier_block *nb);
192 extern int exynos_drm_ippnb_send_event(unsigned long val, void *v);
193 extern void ipp_sched_cmd(struct work_struct *work);
194 extern void ipp_sched_event(struct work_struct *work);
195 
196 #else
197 static inline int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
198 {
199 	return -ENODEV;
200 }
201 
202 static inline int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
203 {
204 	return -ENODEV;
205 }
206 
207 static inline int exynos_drm_ipp_get_property(struct drm_device *drm_dev,
208 						void *data,
209 						struct drm_file *file_priv)
210 {
211 	return -ENOTTY;
212 }
213 
214 static inline int exynos_drm_ipp_set_property(struct drm_device *drm_dev,
215 						void *data,
216 						struct drm_file *file_priv)
217 {
218 	return -ENOTTY;
219 }
220 
221 static inline int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev,
222 						void *data,
223 						struct drm_file *file)
224 {
225 	return -ENOTTY;
226 }
227 
228 static inline int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev,
229 						void *data,
230 						struct drm_file *file)
231 {
232 	return -ENOTTY;
233 }
234 
235 static inline int exynos_drm_ippnb_register(struct notifier_block *nb)
236 {
237 	return -ENODEV;
238 }
239 
240 static inline int exynos_drm_ippnb_unregister(struct notifier_block *nb)
241 {
242 	return -ENODEV;
243 }
244 
245 static inline int exynos_drm_ippnb_send_event(unsigned long val, void *v)
246 {
247 	return -ENOTTY;
248 }
249 #endif
250 
251 #endif /* _EXYNOS_DRM_IPP_H_ */
252 
253