• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Samsung TV Mixer driver
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5  *
6  * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundiation. either version 2 of the License,
11  * or (at your option) any later version
12  */
13 
14 #ifndef SAMSUNG_MIXER_H
15 #define SAMSUNG_MIXER_H
16 
17 #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
18 	#define DEBUG
19 #endif
20 
21 #include <linux/fb.h>
22 #include <linux/kernel.h>
23 #include <linux/spinlock.h>
24 #include <linux/wait.h>
25 #include <media/v4l2-device.h>
26 #include <media/videobuf2-core.h>
27 
28 #include "regs-mixer.h"
29 
30 /** maximum number of output interfaces */
31 #define MXR_MAX_OUTPUTS 2
32 /** maximum number of input interfaces (layers) */
33 #define MXR_MAX_LAYERS 3
34 #define MXR_DRIVER_NAME "s5p-mixer"
35 /** maximal number of planes for every layer */
36 #define MXR_MAX_PLANES	2
37 
38 #define MXR_ENABLE 1
39 #define MXR_DISABLE 0
40 
41 /** description of a macroblock for packed formats */
42 struct mxr_block {
43 	/** vertical number of pixels in macroblock */
44 	unsigned int width;
45 	/** horizontal number of pixels in macroblock */
46 	unsigned int height;
47 	/** size of block in bytes */
48 	unsigned int size;
49 };
50 
51 /** description of supported format */
52 struct mxr_format {
53 	/** format name/mnemonic */
54 	const char *name;
55 	/** fourcc identifier */
56 	u32 fourcc;
57 	/** colorspace identifier */
58 	enum v4l2_colorspace colorspace;
59 	/** number of planes in image data */
60 	int num_planes;
61 	/** description of block for each plane */
62 	struct mxr_block plane[MXR_MAX_PLANES];
63 	/** number of subframes in image data */
64 	int num_subframes;
65 	/** specifies to which subframe belong given plane */
66 	int plane2subframe[MXR_MAX_PLANES];
67 	/** internal code, driver dependant */
68 	unsigned long cookie;
69 };
70 
71 /** description of crop configuration for image */
72 struct mxr_crop {
73 	/** width of layer in pixels */
74 	unsigned int full_width;
75 	/** height of layer in pixels */
76 	unsigned int full_height;
77 	/** horizontal offset of first pixel to be displayed */
78 	unsigned int x_offset;
79 	/** vertical offset of first pixel to be displayed */
80 	unsigned int y_offset;
81 	/** width of displayed data in pixels */
82 	unsigned int width;
83 	/** height of displayed data in pixels */
84 	unsigned int height;
85 	/** indicate which fields are present in buffer */
86 	unsigned int field;
87 };
88 
89 /** stages of geometry operations */
90 enum mxr_geometry_stage {
91 	MXR_GEOMETRY_SINK,
92 	MXR_GEOMETRY_COMPOSE,
93 	MXR_GEOMETRY_CROP,
94 	MXR_GEOMETRY_SOURCE,
95 };
96 
97 /* flag indicating that offset should be 0 */
98 #define MXR_NO_OFFSET	0x80000000
99 
100 /** description of transformation from source to destination image */
101 struct mxr_geometry {
102 	/** cropping for source image */
103 	struct mxr_crop src;
104 	/** cropping for destination image */
105 	struct mxr_crop dst;
106 	/** layer-dependant description of horizontal scaling */
107 	unsigned int x_ratio;
108 	/** layer-dependant description of vertical scaling */
109 	unsigned int y_ratio;
110 };
111 
112 /** instance of a buffer */
113 struct mxr_buffer {
114 	/** common v4l buffer stuff -- must be first */
115 	struct vb2_buffer	vb;
116 	/** node for layer's lists */
117 	struct list_head	list;
118 };
119 
120 
121 /** internal states of layer */
122 enum mxr_layer_state {
123 	/** layers is not shown */
124 	MXR_LAYER_IDLE = 0,
125 	/** layer is shown */
126 	MXR_LAYER_STREAMING,
127 	/** state before STREAMOFF is finished */
128 	MXR_LAYER_STREAMING_FINISH,
129 };
130 
131 /** forward declarations */
132 struct mxr_device;
133 struct mxr_layer;
134 
135 /** callback for layers operation */
136 struct mxr_layer_ops {
137 	/* TODO: try to port it to subdev API */
138 	/** handler for resource release function */
139 	void (*release)(struct mxr_layer *);
140 	/** setting buffer to HW */
141 	void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *);
142 	/** setting format and geometry in HW */
143 	void (*format_set)(struct mxr_layer *);
144 	/** streaming stop/start */
145 	void (*stream_set)(struct mxr_layer *, int);
146 	/** adjusting geometry */
147 	void (*fix_geometry)(struct mxr_layer *,
148 		enum mxr_geometry_stage, unsigned long);
149 };
150 
151 /** layer instance, a single window and content displayed on output */
152 struct mxr_layer {
153 	/** parent mixer device */
154 	struct mxr_device *mdev;
155 	/** layer index (unique identifier) */
156 	int idx;
157 	/** callbacks for layer methods */
158 	struct mxr_layer_ops ops;
159 	/** format array */
160 	const struct mxr_format **fmt_array;
161 	/** size of format array */
162 	unsigned long fmt_array_size;
163 
164 	/** lock for protection of list and state fields */
165 	spinlock_t enq_slock;
166 	/** list for enqueued buffers */
167 	struct list_head enq_list;
168 	/** buffer currently owned by hardware in temporary registers */
169 	struct mxr_buffer *update_buf;
170 	/** buffer currently owned by hardware in shadow registers */
171 	struct mxr_buffer *shadow_buf;
172 	/** state of layer IDLE/STREAMING */
173 	enum mxr_layer_state state;
174 
175 	/** mutex for protection of fields below */
176 	struct mutex mutex;
177 	/** handler for video node */
178 	struct video_device vfd;
179 	/** queue for output buffers */
180 	struct vb2_queue vb_queue;
181 	/** current image format */
182 	const struct mxr_format *fmt;
183 	/** current geometry of image */
184 	struct mxr_geometry geo;
185 };
186 
187 /** description of mixers output interface */
188 struct mxr_output {
189 	/** name of output */
190 	char name[32];
191 	/** output subdev */
192 	struct v4l2_subdev *sd;
193 	/** cookie used for configuration of registers */
194 	int cookie;
195 };
196 
197 /** specify source of output subdevs */
198 struct mxr_output_conf {
199 	/** name of output (connector) */
200 	char *output_name;
201 	/** name of module that generates output subdev */
202 	char *module_name;
203 	/** cookie need for mixer HW */
204 	int cookie;
205 };
206 
207 struct clk;
208 struct regulator;
209 
210 /** auxiliary resources used my mixer */
211 struct mxr_resources {
212 	/** interrupt index */
213 	int irq;
214 	/** pointer to Mixer registers */
215 	void __iomem *mxr_regs;
216 	/** pointer to Video Processor registers */
217 	void __iomem *vp_regs;
218 	/** other resources, should used under mxr_device.mutex */
219 	struct clk *mixer;
220 	struct clk *vp;
221 	struct clk *sclk_mixer;
222 	struct clk *sclk_hdmi;
223 	struct clk *sclk_dac;
224 };
225 
226 /* event flags used  */
227 enum mxr_devide_flags {
228 	MXR_EVENT_VSYNC = 0,
229 };
230 
231 /** drivers instance */
232 struct mxr_device {
233 	/** master device */
234 	struct device *dev;
235 	/** state of each layer */
236 	struct mxr_layer *layer[MXR_MAX_LAYERS];
237 	/** state of each output */
238 	struct mxr_output *output[MXR_MAX_OUTPUTS];
239 	/** number of registered outputs */
240 	int output_cnt;
241 
242 	/* video resources */
243 
244 	/** V4L2 device */
245 	struct v4l2_device v4l2_dev;
246 	/** context of allocator */
247 	void *alloc_ctx;
248 	/** event wait queue */
249 	wait_queue_head_t event_queue;
250 	/** state flags */
251 	unsigned long event_flags;
252 
253 	/** spinlock for protection of registers */
254 	spinlock_t reg_slock;
255 
256 	/** mutex for protection of fields below */
257 	struct mutex mutex;
258 	/** number of entities depndant on output configuration */
259 	int n_output;
260 	/** number of users that do streaming */
261 	int n_streamer;
262 	/** index of current output */
263 	int current_output;
264 	/** auxiliary resources used my mixer */
265 	struct mxr_resources res;
266 };
267 
268 /** transform device structure into mixer device */
to_mdev(struct device * dev)269 static inline struct mxr_device *to_mdev(struct device *dev)
270 {
271 	struct v4l2_device *vdev = dev_get_drvdata(dev);
272 	return container_of(vdev, struct mxr_device, v4l2_dev);
273 }
274 
275 /** get current output data, should be called under mdev's mutex */
to_output(struct mxr_device * mdev)276 static inline struct mxr_output *to_output(struct mxr_device *mdev)
277 {
278 	return mdev->output[mdev->current_output];
279 }
280 
281 /** get current output subdev, should be called under mdev's mutex */
to_outsd(struct mxr_device * mdev)282 static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev)
283 {
284 	struct mxr_output *out = to_output(mdev);
285 	return out ? out->sd : NULL;
286 }
287 
288 /** forward declaration for mixer platform data */
289 struct mxr_platform_data;
290 
291 /** acquiring common video resources */
292 int __devinit mxr_acquire_video(struct mxr_device *mdev,
293 	struct mxr_output_conf *output_cont, int output_count);
294 
295 /** releasing common video resources */
296 void __devexit mxr_release_video(struct mxr_device *mdev);
297 
298 struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx);
299 struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx);
300 struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
301 	int idx, char *name, struct mxr_layer_ops *ops);
302 
303 void mxr_base_layer_release(struct mxr_layer *layer);
304 void mxr_layer_release(struct mxr_layer *layer);
305 
306 int mxr_base_layer_register(struct mxr_layer *layer);
307 void mxr_base_layer_unregister(struct mxr_layer *layer);
308 
309 unsigned long mxr_get_plane_size(const struct mxr_block *blk,
310 	unsigned int width, unsigned int height);
311 
312 /** adds new consumer for mixer's power */
313 int __must_check mxr_power_get(struct mxr_device *mdev);
314 /** removes consumer for mixer's power */
315 void mxr_power_put(struct mxr_device *mdev);
316 /** add new client for output configuration */
317 void mxr_output_get(struct mxr_device *mdev);
318 /** removes new client for output configuration */
319 void mxr_output_put(struct mxr_device *mdev);
320 /** add new client for streaming */
321 void mxr_streamer_get(struct mxr_device *mdev);
322 /** removes new client for streaming */
323 void mxr_streamer_put(struct mxr_device *mdev);
324 /** returns format of data delivared to current output */
325 void mxr_get_mbus_fmt(struct mxr_device *mdev,
326 	struct v4l2_mbus_framefmt *mbus_fmt);
327 
328 /* Debug */
329 
330 #define mxr_err(mdev, fmt, ...)  dev_err(mdev->dev, fmt, ##__VA_ARGS__)
331 #define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__)
332 #define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__)
333 
334 #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
335 	#define mxr_dbg(mdev, fmt, ...)  dev_dbg(mdev->dev, fmt, ##__VA_ARGS__)
336 #else
337 	#define mxr_dbg(mdev, fmt, ...)  do { (void) mdev; } while (0)
338 #endif
339 
340 /* accessing Mixer's and Video Processor's registers */
341 
342 void mxr_vsync_set_update(struct mxr_device *mdev, int en);
343 void mxr_reg_reset(struct mxr_device *mdev);
344 irqreturn_t mxr_irq_handler(int irq, void *dev_data);
345 void mxr_reg_s_output(struct mxr_device *mdev, int cookie);
346 void mxr_reg_streamon(struct mxr_device *mdev);
347 void mxr_reg_streamoff(struct mxr_device *mdev);
348 int mxr_reg_wait4vsync(struct mxr_device *mdev);
349 void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
350 	struct v4l2_mbus_framefmt *fmt);
351 void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en);
352 void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr);
353 void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
354 	const struct mxr_format *fmt, const struct mxr_geometry *geo);
355 
356 void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en);
357 void mxr_reg_vp_buffer(struct mxr_device *mdev,
358 	dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]);
359 void mxr_reg_vp_format(struct mxr_device *mdev,
360 	const struct mxr_format *fmt, const struct mxr_geometry *geo);
361 void mxr_reg_dump(struct mxr_device *mdev);
362 
363 #endif /* SAMSUNG_MIXER_H */
364 
365