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