blob: e2242243f63dbf33742cb2fcfc3082c3b54d19fb [file] [log] [blame]
Tomasz Stanislawskifef1c8d2011-02-02 05:40:08 -03001/*
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 */
42struct 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 */
52struct 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 */
72struct 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/** description of transformation from source to destination image */
90struct mxr_geometry {
91 /** cropping for source image */
92 struct mxr_crop src;
93 /** cropping for destination image */
94 struct mxr_crop dst;
95 /** layer-dependant description of horizontal scaling */
96 unsigned int x_ratio;
97 /** layer-dependant description of vertical scaling */
98 unsigned int y_ratio;
99};
100
101/** instance of a buffer */
102struct mxr_buffer {
103 /** common v4l buffer stuff -- must be first */
104 struct vb2_buffer vb;
105 /** node for layer's lists */
106 struct list_head list;
107};
108
109
110/** internal states of layer */
111enum mxr_layer_state {
112 /** layers is not shown */
113 MXR_LAYER_IDLE = 0,
114 /** state between STREAMON and hardware start */
115 MXR_LAYER_STREAMING_START,
116 /** layer is shown */
117 MXR_LAYER_STREAMING,
118 /** state before STREAMOFF is finished */
119 MXR_LAYER_STREAMING_FINISH,
120};
121
122/** forward declarations */
123struct mxr_device;
124struct mxr_layer;
125
126/** callback for layers operation */
127struct mxr_layer_ops {
128 /* TODO: try to port it to subdev API */
129 /** handler for resource release function */
130 void (*release)(struct mxr_layer *);
131 /** setting buffer to HW */
132 void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *);
133 /** setting format and geometry in HW */
134 void (*format_set)(struct mxr_layer *);
135 /** streaming stop/start */
136 void (*stream_set)(struct mxr_layer *, int);
137 /** adjusting geometry */
138 void (*fix_geometry)(struct mxr_layer *);
139};
140
141/** layer instance, a single window and content displayed on output */
142struct mxr_layer {
143 /** parent mixer device */
144 struct mxr_device *mdev;
145 /** layer index (unique identifier) */
146 int idx;
147 /** callbacks for layer methods */
148 struct mxr_layer_ops ops;
149 /** format array */
150 const struct mxr_format **fmt_array;
151 /** size of format array */
152 unsigned long fmt_array_size;
153
154 /** lock for protection of list and state fields */
155 spinlock_t enq_slock;
156 /** list for enqueued buffers */
157 struct list_head enq_list;
158 /** buffer currently owned by hardware in temporary registers */
159 struct mxr_buffer *update_buf;
160 /** buffer currently owned by hardware in shadow registers */
161 struct mxr_buffer *shadow_buf;
162 /** state of layer IDLE/STREAMING */
163 enum mxr_layer_state state;
164
165 /** mutex for protection of fields below */
166 struct mutex mutex;
167 /** handler for video node */
168 struct video_device vfd;
169 /** queue for output buffers */
170 struct vb2_queue vb_queue;
171 /** current image format */
172 const struct mxr_format *fmt;
173 /** current geometry of image */
174 struct mxr_geometry geo;
175};
176
177/** description of mixers output interface */
178struct mxr_output {
179 /** name of output */
180 char name[32];
181 /** output subdev */
182 struct v4l2_subdev *sd;
183 /** cookie used for configuration of registers */
184 int cookie;
185};
186
187/** specify source of output subdevs */
188struct mxr_output_conf {
189 /** name of output (connector) */
190 char *output_name;
191 /** name of module that generates output subdev */
192 char *module_name;
193 /** cookie need for mixer HW */
194 int cookie;
195};
196
197struct clk;
198struct regulator;
199
200/** auxiliary resources used my mixer */
201struct mxr_resources {
202 /** interrupt index */
203 int irq;
204 /** pointer to Mixer registers */
205 void __iomem *mxr_regs;
206 /** pointer to Video Processor registers */
207 void __iomem *vp_regs;
208 /** other resources, should used under mxr_device.mutex */
209 struct clk *mixer;
210 struct clk *vp;
211 struct clk *sclk_mixer;
212 struct clk *sclk_hdmi;
213 struct clk *sclk_dac;
214};
215
216/* event flags used */
217enum mxr_devide_flags {
218 MXR_EVENT_VSYNC = 0,
219};
220
221/** drivers instance */
222struct mxr_device {
223 /** master device */
224 struct device *dev;
225 /** state of each layer */
226 struct mxr_layer *layer[MXR_MAX_LAYERS];
227 /** state of each output */
228 struct mxr_output *output[MXR_MAX_OUTPUTS];
229 /** number of registered outputs */
230 int output_cnt;
231
232 /* video resources */
233
234 /** V4L2 device */
235 struct v4l2_device v4l2_dev;
236 /** context of allocator */
237 void *alloc_ctx;
238 /** event wait queue */
239 wait_queue_head_t event_queue;
240 /** state flags */
241 unsigned long event_flags;
242
243 /** spinlock for protection of registers */
244 spinlock_t reg_slock;
245
246 /** mutex for protection of fields below */
247 struct mutex mutex;
248 /** number of entities depndant on output configuration */
249 int n_output;
250 /** number of users that do streaming */
251 int n_streamer;
252 /** index of current output */
253 int current_output;
254 /** auxiliary resources used my mixer */
255 struct mxr_resources res;
256};
257
258/** transform device structure into mixer device */
259static inline struct mxr_device *to_mdev(struct device *dev)
260{
261 struct v4l2_device *vdev = dev_get_drvdata(dev);
262 return container_of(vdev, struct mxr_device, v4l2_dev);
263}
264
265/** get current output data, should be called under mdev's mutex */
266static inline struct mxr_output *to_output(struct mxr_device *mdev)
267{
268 return mdev->output[mdev->current_output];
269}
270
271/** get current output subdev, should be called under mdev's mutex */
272static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev)
273{
274 struct mxr_output *out = to_output(mdev);
275 return out ? out->sd : NULL;
276}
277
278/** forward declaration for mixer platform data */
279struct mxr_platform_data;
280
281/** acquiring common video resources */
282int __devinit mxr_acquire_video(struct mxr_device *mdev,
283 struct mxr_output_conf *output_cont, int output_count);
284
285/** releasing common video resources */
286void __devexit mxr_release_video(struct mxr_device *mdev);
287
288struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx);
289struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx);
290struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
291 int idx, char *name, struct mxr_layer_ops *ops);
292
293void mxr_base_layer_release(struct mxr_layer *layer);
294void mxr_layer_release(struct mxr_layer *layer);
295
296int mxr_base_layer_register(struct mxr_layer *layer);
297void mxr_base_layer_unregister(struct mxr_layer *layer);
298
299unsigned long mxr_get_plane_size(const struct mxr_block *blk,
300 unsigned int width, unsigned int height);
301
302/** adds new consumer for mixer's power */
303int __must_check mxr_power_get(struct mxr_device *mdev);
304/** removes consumer for mixer's power */
305void mxr_power_put(struct mxr_device *mdev);
306/** add new client for output configuration */
307void mxr_output_get(struct mxr_device *mdev);
308/** removes new client for output configuration */
309void mxr_output_put(struct mxr_device *mdev);
310/** add new client for streaming */
311void mxr_streamer_get(struct mxr_device *mdev);
312/** removes new client for streaming */
313void mxr_streamer_put(struct mxr_device *mdev);
314/** returns format of data delivared to current output */
315void mxr_get_mbus_fmt(struct mxr_device *mdev,
316 struct v4l2_mbus_framefmt *mbus_fmt);
317
318/* Debug */
319
320#define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__)
321#define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__)
322#define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__)
323
324#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
325 #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__)
326#else
327 #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0)
328#endif
329
330/* accessing Mixer's and Video Processor's registers */
331
332void mxr_vsync_set_update(struct mxr_device *mdev, int en);
333void mxr_reg_reset(struct mxr_device *mdev);
334irqreturn_t mxr_irq_handler(int irq, void *dev_data);
335void mxr_reg_s_output(struct mxr_device *mdev, int cookie);
336void mxr_reg_streamon(struct mxr_device *mdev);
337void mxr_reg_streamoff(struct mxr_device *mdev);
338int mxr_reg_wait4vsync(struct mxr_device *mdev);
339void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
340 struct v4l2_mbus_framefmt *fmt);
341void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en);
342void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr);
343void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
344 const struct mxr_format *fmt, const struct mxr_geometry *geo);
345
346void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en);
347void mxr_reg_vp_buffer(struct mxr_device *mdev,
348 dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]);
349void mxr_reg_vp_format(struct mxr_device *mdev,
350 const struct mxr_format *fmt, const struct mxr_geometry *geo);
351void mxr_reg_dump(struct mxr_device *mdev);
352
353#endif /* SAMSUNG_MIXER_H */
354