blob: ffad91e93b6efdd0e260dc3d8b2cc4d4760b1458 [file] [log] [blame]
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001/*
2 * ispvideo.c
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/clk.h>
28#include <linux/mm.h>
Dmitry Artamonow025521f2011-11-20 12:54:26 -030029#include <linux/module.h>
Laurent Pinchartad614ac2011-02-12 18:05:06 -030030#include <linux/pagemap.h>
31#include <linux/scatterlist.h>
32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35#include <media/v4l2-dev.h>
36#include <media/v4l2-ioctl.h>
37#include <plat/iommu.h>
38#include <plat/iovmm.h>
39#include <plat/omap-pm.h>
40
41#include "ispvideo.h"
42#include "isp.h"
43
44
45/* -----------------------------------------------------------------------------
46 * Helper functions
47 */
48
Sakari Ailus8f4f2982011-12-28 06:28:41 -030049/*
50 * NOTE: When adding new media bus codes, always remember to add
51 * corresponding in-memory formats to the table below!!!
52 */
Laurent Pinchartad614ac2011-02-12 18:05:06 -030053static struct isp_format_info formats[] = {
54 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
Michael Jonesc09af042011-03-29 05:19:09 -030055 V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
56 V4L2_PIX_FMT_GREY, 8, },
Michael Jones5782f972011-03-29 05:19:08 -030057 { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -030058 V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
59 V4L2_PIX_FMT_Y10, 10, },
Michael Jones5782f972011-03-29 05:19:08 -030060 { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -030061 V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
62 V4L2_PIX_FMT_Y12, 12, },
Michael Jones5782f972011-03-29 05:19:08 -030063 { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
Michael Jonesc09af042011-03-29 05:19:09 -030064 V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
65 V4L2_PIX_FMT_SBGGR8, 8, },
Michael Jones5782f972011-03-29 05:19:08 -030066 { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
Michael Jonesc09af042011-03-29 05:19:09 -030067 V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
68 V4L2_PIX_FMT_SGBRG8, 8, },
Michael Jones5782f972011-03-29 05:19:08 -030069 { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
Michael Jonesc09af042011-03-29 05:19:09 -030070 V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
71 V4L2_PIX_FMT_SGRBG8, 8, },
Michael Jones5782f972011-03-29 05:19:08 -030072 { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
Michael Jonesc09af042011-03-29 05:19:09 -030073 V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
74 V4L2_PIX_FMT_SRGGB8, 8, },
Sakari Ailus8f4f2982011-12-28 06:28:41 -030075 { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
76 V4L2_MBUS_FMT_SBGGR10_1X10, 0,
77 V4L2_PIX_FMT_SBGGR10DPCM8, 8, },
78 { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
79 V4L2_MBUS_FMT_SGBRG10_1X10, 0,
80 V4L2_PIX_FMT_SGBRG10DPCM8, 8, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -030081 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
Michael Jonesc09af042011-03-29 05:19:09 -030082 V4L2_MBUS_FMT_SGRBG10_1X10, 0,
83 V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
Sakari Ailus8f4f2982011-12-28 06:28:41 -030084 { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
85 V4L2_MBUS_FMT_SRGGB10_1X10, 0,
86 V4L2_PIX_FMT_SRGGB10DPCM8, 8, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -030087 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -030088 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
89 V4L2_PIX_FMT_SBGGR10, 10, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -030090 { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -030091 V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
92 V4L2_PIX_FMT_SGBRG10, 10, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -030093 { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -030094 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
95 V4L2_PIX_FMT_SGRBG10, 10, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -030096 { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -030097 V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
98 V4L2_PIX_FMT_SRGGB10, 10, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -030099 { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -0300100 V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
101 V4L2_PIX_FMT_SBGGR12, 12, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300102 { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -0300103 V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
104 V4L2_PIX_FMT_SGBRG12, 12, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300105 { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -0300106 V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
107 V4L2_PIX_FMT_SGRBG12, 12, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300108 { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
Michael Jonesc09af042011-03-29 05:19:09 -0300109 V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
110 V4L2_PIX_FMT_SRGGB12, 12, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300111 { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
Michael Jonesc09af042011-03-29 05:19:09 -0300112 V4L2_MBUS_FMT_UYVY8_1X16, 0,
113 V4L2_PIX_FMT_UYVY, 16, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300114 { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
Michael Jonesc09af042011-03-29 05:19:09 -0300115 V4L2_MBUS_FMT_YUYV8_1X16, 0,
116 V4L2_PIX_FMT_YUYV, 16, },
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300117};
118
119const struct isp_format_info *
120omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
121{
122 unsigned int i;
123
124 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
125 if (formats[i].code == code)
126 return &formats[i];
127 }
128
129 return NULL;
130}
131
132/*
Michael Jonesc09af042011-03-29 05:19:09 -0300133 * Decide whether desired output pixel code can be obtained with
134 * the lane shifter by shifting the input pixel code.
135 * @in: input pixelcode to shifter
136 * @out: output pixelcode from shifter
137 * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
138 *
139 * return true if the combination is possible
140 * return false otherwise
141 */
142static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in,
143 enum v4l2_mbus_pixelcode out,
144 unsigned int additional_shift)
145{
146 const struct isp_format_info *in_info, *out_info;
147
148 if (in == out)
149 return true;
150
151 in_info = omap3isp_video_format_info(in);
152 out_info = omap3isp_video_format_info(out);
153
154 if ((in_info->flavor == 0) || (out_info->flavor == 0))
155 return false;
156
157 if (in_info->flavor != out_info->flavor)
158 return false;
159
160 return in_info->bpp - out_info->bpp + additional_shift <= 6;
161}
162
163/*
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300164 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
165 * @video: ISP video instance
166 * @mbus: v4l2_mbus_framefmt format (input)
167 * @pix: v4l2_pix_format format (output)
168 *
169 * Fill the output pix structure with information from the input mbus format.
170 * The bytesperline and sizeimage fields are computed from the requested bytes
171 * per line value in the pix format and information from the video instance.
172 *
173 * Return the number of padding bytes at end of line.
174 */
175static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
176 const struct v4l2_mbus_framefmt *mbus,
177 struct v4l2_pix_format *pix)
178{
179 unsigned int bpl = pix->bytesperline;
180 unsigned int min_bpl;
181 unsigned int i;
182
183 memset(pix, 0, sizeof(*pix));
184 pix->width = mbus->width;
185 pix->height = mbus->height;
186
187 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
188 if (formats[i].code == mbus->code)
189 break;
190 }
191
192 if (WARN_ON(i == ARRAY_SIZE(formats)))
193 return 0;
194
195 min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8;
196
197 /* Clamp the requested bytes per line value. If the maximum bytes per
198 * line value is zero, the module doesn't support user configurable line
199 * sizes. Override the requested value with the minimum in that case.
200 */
201 if (video->bpl_max)
202 bpl = clamp(bpl, min_bpl, video->bpl_max);
203 else
204 bpl = min_bpl;
205
206 if (!video->bpl_zero_padding || bpl != min_bpl)
207 bpl = ALIGN(bpl, video->bpl_alignment);
208
209 pix->pixelformat = formats[i].pixelformat;
210 pix->bytesperline = bpl;
211 pix->sizeimage = pix->bytesperline * pix->height;
212 pix->colorspace = mbus->colorspace;
213 pix->field = mbus->field;
214
215 return bpl - min_bpl;
216}
217
218static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
219 struct v4l2_mbus_framefmt *mbus)
220{
221 unsigned int i;
222
223 memset(mbus, 0, sizeof(*mbus));
224 mbus->width = pix->width;
225 mbus->height = pix->height;
226
Laurent Pinchartc3cd2572011-11-28 08:25:30 -0300227 /* Skip the last format in the loop so that it will be selected if no
228 * match is found.
229 */
230 for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300231 if (formats[i].pixelformat == pix->pixelformat)
232 break;
233 }
234
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300235 mbus->code = formats[i].code;
236 mbus->colorspace = pix->colorspace;
237 mbus->field = pix->field;
238}
239
240static struct v4l2_subdev *
241isp_video_remote_subdev(struct isp_video *video, u32 *pad)
242{
243 struct media_pad *remote;
244
245 remote = media_entity_remote_source(&video->pad);
246
247 if (remote == NULL ||
248 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
249 return NULL;
250
251 if (pad)
252 *pad = remote->index;
253
254 return media_entity_to_v4l2_subdev(remote->entity);
255}
256
257/* Return a pointer to the ISP video instance at the far end of the pipeline. */
Sakari Ailusae5df812012-03-05 20:22:41 -0300258static int isp_video_get_graph_data(struct isp_video *video,
259 struct isp_pipeline *pipe)
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300260{
261 struct media_entity_graph graph;
262 struct media_entity *entity = &video->video.entity;
263 struct media_device *mdev = entity->parent;
264 struct isp_video *far_end = NULL;
265
266 mutex_lock(&mdev->graph_mutex);
267 media_entity_graph_walk_start(&graph, entity);
268
269 while ((entity = media_entity_graph_walk_next(&graph))) {
Sakari Ailusae5df812012-03-05 20:22:41 -0300270 struct isp_video *__video;
271
272 pipe->entities |= 1 << entity->id;
273
274 if (far_end != NULL)
275 continue;
276
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300277 if (entity == &video->video.entity)
278 continue;
279
280 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
281 continue;
282
Sakari Ailusae5df812012-03-05 20:22:41 -0300283 __video = to_isp_video(media_entity_to_video_device(entity));
284 if (__video->type != video->type)
285 far_end = __video;
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300286 }
287
288 mutex_unlock(&mdev->graph_mutex);
Sakari Ailusae5df812012-03-05 20:22:41 -0300289
290 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
291 pipe->input = far_end;
292 pipe->output = video;
293 } else {
294 if (far_end == NULL)
295 return -EPIPE;
296
297 pipe->input = video;
298 pipe->output = far_end;
299 }
300
301 return 0;
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300302}
303
304/*
305 * Validate a pipeline by checking both ends of all links for format
306 * discrepancies.
307 *
308 * Compute the minimum time per frame value as the maximum of time per frame
309 * limits reported by every block in the pipeline.
310 *
311 * Return 0 if all formats match, or -EPIPE if at least one link is found with
Laurent Pinchart00542ed2011-07-31 17:12:02 +0200312 * different formats on its two ends or if the pipeline doesn't start with a
313 * video source (either a subdev with no input pad, or a non-subdev entity).
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300314 */
315static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
316{
317 struct isp_device *isp = pipe->output->isp;
318 struct v4l2_subdev_format fmt_source;
319 struct v4l2_subdev_format fmt_sink;
320 struct media_pad *pad;
321 struct v4l2_subdev *subdev;
322 int ret;
323
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300324 subdev = isp_video_remote_subdev(pipe->output, NULL);
325 if (subdev == NULL)
326 return -EPIPE;
327
328 while (1) {
Michael Jonesc09af042011-03-29 05:19:09 -0300329 unsigned int shifter_link;
Laurent Pinchart1567bb72011-11-18 11:28:24 -0300330
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300331 /* Retrieve the sink format */
332 pad = &subdev->entity.pads[0];
333 if (!(pad->flags & MEDIA_PAD_FL_SINK))
334 break;
335
336 fmt_sink.pad = pad->index;
337 fmt_sink.which = V4L2_SUBDEV_FORMAT_ACTIVE;
338 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_sink);
339 if (ret < 0 && ret != -ENOIOCTLCMD)
340 return -EPIPE;
341
342 /* Update the maximum frame rate */
343 if (subdev == &isp->isp_res.subdev)
344 omap3isp_resizer_max_rate(&isp->isp_res,
345 &pipe->max_rate);
346
347 /* Check ccdc maximum data rate when data comes from sensor
348 * TODO: Include ccdc rate in pipe->max_rate and compare the
349 * total pipe rate with the input data rate from sensor.
350 */
351 if (subdev == &isp->isp_ccdc.subdev && pipe->input == NULL) {
352 unsigned int rate = UINT_MAX;
353
354 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
355 if (isp->isp_ccdc.vpcfg.pixelclk > rate)
356 return -ENOSPC;
357 }
358
Michael Jonesc09af042011-03-29 05:19:09 -0300359 /* If sink pad is on CCDC, the link has the lane shifter
360 * in the middle of it. */
361 shifter_link = subdev == &isp->isp_ccdc.subdev;
362
Laurent Pinchart00542ed2011-07-31 17:12:02 +0200363 /* Retrieve the source format. Return an error if no source
364 * entity can be found, and stop checking the pipeline if the
365 * source entity isn't a subdev.
366 */
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300367 pad = media_entity_remote_source(pad);
Laurent Pinchart00542ed2011-07-31 17:12:02 +0200368 if (pad == NULL)
369 return -EPIPE;
370
371 if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300372 break;
373
374 subdev = media_entity_to_v4l2_subdev(pad->entity);
375
376 fmt_source.pad = pad->index;
377 fmt_source.which = V4L2_SUBDEV_FORMAT_ACTIVE;
378 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_source);
379 if (ret < 0 && ret != -ENOIOCTLCMD)
380 return -EPIPE;
381
382 /* Check if the two ends match */
Michael Jonesc09af042011-03-29 05:19:09 -0300383 if (fmt_source.format.width != fmt_sink.format.width ||
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300384 fmt_source.format.height != fmt_sink.format.height)
385 return -EPIPE;
Michael Jonesc09af042011-03-29 05:19:09 -0300386
387 if (shifter_link) {
388 unsigned int parallel_shift = 0;
389 if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) {
390 struct isp_parallel_platform_data *pdata =
391 &((struct isp_v4l2_subdevs_group *)
392 subdev->host_priv)->bus.parallel;
393 parallel_shift = pdata->data_lane_shift * 2;
394 }
395 if (!isp_video_is_shiftable(fmt_source.format.code,
396 fmt_sink.format.code,
397 parallel_shift))
398 return -EPIPE;
399 } else if (fmt_source.format.code != fmt_sink.format.code)
400 return -EPIPE;
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300401 }
402
403 return 0;
404}
405
406static int
407__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
408{
409 struct v4l2_subdev_format fmt;
410 struct v4l2_subdev *subdev;
411 u32 pad;
412 int ret;
413
414 subdev = isp_video_remote_subdev(video, &pad);
415 if (subdev == NULL)
416 return -EINVAL;
417
418 mutex_lock(&video->mutex);
419
420 fmt.pad = pad;
421 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
422 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
423 if (ret == -ENOIOCTLCMD)
424 ret = -EINVAL;
425
426 mutex_unlock(&video->mutex);
427
428 if (ret)
429 return ret;
430
431 format->type = video->type;
432 return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
433}
434
435static int
436isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
437{
438 struct v4l2_format format;
439 int ret;
440
441 memcpy(&format, &vfh->format, sizeof(format));
442 ret = __isp_video_get_format(video, &format);
443 if (ret < 0)
444 return ret;
445
446 if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
447 vfh->format.fmt.pix.height != format.fmt.pix.height ||
448 vfh->format.fmt.pix.width != format.fmt.pix.width ||
449 vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
450 vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage)
451 return -EINVAL;
452
453 return ret;
454}
455
456/* -----------------------------------------------------------------------------
457 * IOMMU management
458 */
459
460#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
461
462/*
463 * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
464 * @dev: Device pointer specific to the OMAP3 ISP.
465 * @sglist: Pointer to source Scatter gather list to allocate.
466 * @sglen: Number of elements of the scatter-gatter list.
467 *
468 * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
469 * we ran out of memory.
470 */
471static dma_addr_t
472ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
473{
474 struct sg_table *sgt;
475 u32 da;
476
477 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
478 if (sgt == NULL)
479 return -ENOMEM;
480
481 sgt->sgl = (struct scatterlist *)sglist;
482 sgt->nents = sglen;
483 sgt->orig_nents = sglen;
484
Ohad Ben-Cohenfabdbca2011-10-11 00:18:33 +0200485 da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300486 if (IS_ERR_VALUE(da))
487 kfree(sgt);
488
489 return da;
490}
491
492/*
493 * ispmmu_vunmap - Unmap a device address from the ISP MMU
494 * @dev: Device pointer specific to the OMAP3 ISP.
495 * @da: Device address generated from a ispmmu_vmap call.
496 */
497static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
498{
499 struct sg_table *sgt;
500
Ohad Ben-Cohenfabdbca2011-10-11 00:18:33 +0200501 sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300502 kfree(sgt);
503}
504
505/* -----------------------------------------------------------------------------
506 * Video queue operations
507 */
508
509static void isp_video_queue_prepare(struct isp_video_queue *queue,
510 unsigned int *nbuffers, unsigned int *size)
511{
512 struct isp_video_fh *vfh =
513 container_of(queue, struct isp_video_fh, queue);
514 struct isp_video *video = vfh->video;
515
516 *size = vfh->format.fmt.pix.sizeimage;
517 if (*size == 0)
518 return;
519
520 *nbuffers = min(*nbuffers, video->capture_mem / PAGE_ALIGN(*size));
521}
522
523static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
524{
525 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
526 struct isp_buffer *buffer = to_isp_buffer(buf);
527 struct isp_video *video = vfh->video;
528
529 if (buffer->isp_addr) {
530 ispmmu_vunmap(video->isp, buffer->isp_addr);
531 buffer->isp_addr = 0;
532 }
533}
534
535static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
536{
537 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
538 struct isp_buffer *buffer = to_isp_buffer(buf);
539 struct isp_video *video = vfh->video;
540 unsigned long addr;
541
542 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
543 if (IS_ERR_VALUE(addr))
544 return -EIO;
545
546 if (!IS_ALIGNED(addr, 32)) {
547 dev_dbg(video->isp->dev, "Buffer address must be "
548 "aligned to 32 bytes boundary.\n");
549 ispmmu_vunmap(video->isp, buffer->isp_addr);
550 return -EINVAL;
551 }
552
553 buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
554 buffer->isp_addr = addr;
555 return 0;
556}
557
558/*
559 * isp_video_buffer_queue - Add buffer to streaming queue
560 * @buf: Video buffer
561 *
562 * In memory-to-memory mode, start streaming on the pipeline if buffers are
563 * queued on both the input and the output, if the pipeline isn't already busy.
564 * If the pipeline is busy, it will be restarted in the output module interrupt
565 * handler.
566 */
567static void isp_video_buffer_queue(struct isp_video_buffer *buf)
568{
569 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
570 struct isp_buffer *buffer = to_isp_buffer(buf);
571 struct isp_video *video = vfh->video;
572 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
573 enum isp_pipeline_state state;
574 unsigned long flags;
575 unsigned int empty;
576 unsigned int start;
577
578 empty = list_empty(&video->dmaqueue);
579 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
580
581 if (empty) {
582 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
583 state = ISP_PIPELINE_QUEUE_OUTPUT;
584 else
585 state = ISP_PIPELINE_QUEUE_INPUT;
586
587 spin_lock_irqsave(&pipe->lock, flags);
588 pipe->state |= state;
589 video->ops->queue(video, buffer);
590 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
591
592 start = isp_pipeline_ready(pipe);
593 if (start)
594 pipe->state |= ISP_PIPELINE_STREAM;
595 spin_unlock_irqrestore(&pipe->lock, flags);
596
597 if (start)
598 omap3isp_pipeline_set_stream(pipe,
599 ISP_PIPELINE_STREAM_SINGLESHOT);
600 }
601}
602
603static const struct isp_video_queue_operations isp_video_queue_ops = {
604 .queue_prepare = &isp_video_queue_prepare,
605 .buffer_prepare = &isp_video_buffer_prepare,
606 .buffer_queue = &isp_video_buffer_queue,
607 .buffer_cleanup = &isp_video_buffer_cleanup,
608};
609
610/*
611 * omap3isp_video_buffer_next - Complete the current buffer and return the next
612 * @video: ISP video object
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300613 *
614 * Remove the current video buffer from the DMA queue and fill its timestamp,
615 * field count and state fields before waking up its completion handler.
616 *
Laurent Pinchart875e2e32011-12-07 08:34:50 -0300617 * For capture video nodes the buffer state is set to ISP_BUF_STATE_DONE if no
618 * error has been flagged in the pipeline, or to ISP_BUF_STATE_ERROR otherwise.
619 * For video output nodes the buffer state is always set to ISP_BUF_STATE_DONE.
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300620 *
621 * The DMA queue is expected to contain at least one buffer.
622 *
623 * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
624 * empty.
625 */
Laurent Pinchart875e2e32011-12-07 08:34:50 -0300626struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300627{
628 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
629 struct isp_video_queue *queue = video->queue;
630 enum isp_pipeline_state state;
631 struct isp_video_buffer *buf;
632 unsigned long flags;
633 struct timespec ts;
634
635 spin_lock_irqsave(&queue->irqlock, flags);
636 if (WARN_ON(list_empty(&video->dmaqueue))) {
637 spin_unlock_irqrestore(&queue->irqlock, flags);
638 return NULL;
639 }
640
641 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
642 irqlist);
643 list_del(&buf->irqlist);
644 spin_unlock_irqrestore(&queue->irqlock, flags);
645
646 ktime_get_ts(&ts);
647 buf->vbuf.timestamp.tv_sec = ts.tv_sec;
648 buf->vbuf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
649
650 /* Do frame number propagation only if this is the output video node.
651 * Frame number either comes from the CSI receivers or it gets
652 * incremented here if H3A is not active.
653 * Note: There is no guarantee that the output buffer will finish
654 * first, so the input number might lag behind by 1 in some cases.
655 */
656 if (video == pipe->output && !pipe->do_propagation)
657 buf->vbuf.sequence = atomic_inc_return(&pipe->frame_number);
658 else
659 buf->vbuf.sequence = atomic_read(&pipe->frame_number);
660
Laurent Pinchart875e2e32011-12-07 08:34:50 -0300661 /* Report pipeline errors to userspace on the capture device side. */
662 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
663 buf->state = ISP_BUF_STATE_ERROR;
664 pipe->error = false;
665 } else {
666 buf->state = ISP_BUF_STATE_DONE;
667 }
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300668
669 wake_up(&buf->wait);
670
671 if (list_empty(&video->dmaqueue)) {
672 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
673 state = ISP_PIPELINE_QUEUE_OUTPUT
674 | ISP_PIPELINE_STREAM;
675 else
676 state = ISP_PIPELINE_QUEUE_INPUT
677 | ISP_PIPELINE_STREAM;
678
679 spin_lock_irqsave(&pipe->lock, flags);
680 pipe->state &= ~state;
681 if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
682 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
683 spin_unlock_irqrestore(&pipe->lock, flags);
684 return NULL;
685 }
686
687 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
688 spin_lock_irqsave(&pipe->lock, flags);
689 pipe->state &= ~ISP_PIPELINE_STREAM;
690 spin_unlock_irqrestore(&pipe->lock, flags);
691 }
692
693 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
694 irqlist);
695 buf->state = ISP_BUF_STATE_ACTIVE;
696 return to_isp_buffer(buf);
697}
698
699/*
700 * omap3isp_video_resume - Perform resume operation on the buffers
701 * @video: ISP video object
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300702 * @continuous: Pipeline is in single shot mode if 0 or continuous mode otherwise
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300703 *
704 * This function is intended to be used on suspend/resume scenario. It
705 * requests video queue layer to discard buffers marked as DONE if it's in
706 * continuous mode and requests ISP modules to queue again the ACTIVE buffer
707 * if there's any.
708 */
709void omap3isp_video_resume(struct isp_video *video, int continuous)
710{
711 struct isp_buffer *buf = NULL;
712
713 if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
714 omap3isp_video_queue_discard_done(video->queue);
715
716 if (!list_empty(&video->dmaqueue)) {
717 buf = list_first_entry(&video->dmaqueue,
718 struct isp_buffer, buffer.irqlist);
719 video->ops->queue(video, buf);
720 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
721 } else {
722 if (continuous)
723 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
724 }
725}
726
727/* -----------------------------------------------------------------------------
728 * V4L2 ioctls
729 */
730
731static int
732isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
733{
734 struct isp_video *video = video_drvdata(file);
735
736 strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
737 strlcpy(cap->card, video->video.name, sizeof(cap->card));
738 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
Laurent Pinchartad614ac2011-02-12 18:05:06 -0300739
740 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
741 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
742 else
743 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
744
745 return 0;
746}
747
748static int
749isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
750{
751 struct isp_video_fh *vfh = to_isp_video_fh(fh);
752 struct isp_video *video = video_drvdata(file);
753
754 if (format->type != video->type)
755 return -EINVAL;
756
757 mutex_lock(&video->mutex);
758 *format = vfh->format;
759 mutex_unlock(&video->mutex);
760
761 return 0;
762}
763
764static int
765isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
766{
767 struct isp_video_fh *vfh = to_isp_video_fh(fh);
768 struct isp_video *video = video_drvdata(file);
769 struct v4l2_mbus_framefmt fmt;
770
771 if (format->type != video->type)
772 return -EINVAL;
773
774 mutex_lock(&video->mutex);
775
776 /* Fill the bytesperline and sizeimage fields by converting to media bus
777 * format and back to pixel format.
778 */
779 isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
780 isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
781
782 vfh->format = *format;
783
784 mutex_unlock(&video->mutex);
785 return 0;
786}
787
788static int
789isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
790{
791 struct isp_video *video = video_drvdata(file);
792 struct v4l2_subdev_format fmt;
793 struct v4l2_subdev *subdev;
794 u32 pad;
795 int ret;
796
797 if (format->type != video->type)
798 return -EINVAL;
799
800 subdev = isp_video_remote_subdev(video, &pad);
801 if (subdev == NULL)
802 return -EINVAL;
803
804 isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
805
806 fmt.pad = pad;
807 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
808 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
809 if (ret)
810 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
811
812 isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
813 return 0;
814}
815
816static int
817isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
818{
819 struct isp_video *video = video_drvdata(file);
820 struct v4l2_subdev *subdev;
821 int ret;
822
823 subdev = isp_video_remote_subdev(video, NULL);
824 if (subdev == NULL)
825 return -EINVAL;
826
827 mutex_lock(&video->mutex);
828 ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
829 mutex_unlock(&video->mutex);
830
831 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
832}
833
834static int
835isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
836{
837 struct isp_video *video = video_drvdata(file);
838 struct v4l2_subdev_format format;
839 struct v4l2_subdev *subdev;
840 u32 pad;
841 int ret;
842
843 subdev = isp_video_remote_subdev(video, &pad);
844 if (subdev == NULL)
845 return -EINVAL;
846
847 /* Try the get crop operation first and fallback to get format if not
848 * implemented.
849 */
850 ret = v4l2_subdev_call(subdev, video, g_crop, crop);
851 if (ret != -ENOIOCTLCMD)
852 return ret;
853
854 format.pad = pad;
855 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
856 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
857 if (ret < 0)
858 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
859
860 crop->c.left = 0;
861 crop->c.top = 0;
862 crop->c.width = format.format.width;
863 crop->c.height = format.format.height;
864
865 return 0;
866}
867
868static int
869isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
870{
871 struct isp_video *video = video_drvdata(file);
872 struct v4l2_subdev *subdev;
873 int ret;
874
875 subdev = isp_video_remote_subdev(video, NULL);
876 if (subdev == NULL)
877 return -EINVAL;
878
879 mutex_lock(&video->mutex);
880 ret = v4l2_subdev_call(subdev, video, s_crop, crop);
881 mutex_unlock(&video->mutex);
882
883 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
884}
885
886static int
887isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
888{
889 struct isp_video_fh *vfh = to_isp_video_fh(fh);
890 struct isp_video *video = video_drvdata(file);
891
892 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
893 video->type != a->type)
894 return -EINVAL;
895
896 memset(a, 0, sizeof(*a));
897 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
898 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
899 a->parm.output.timeperframe = vfh->timeperframe;
900
901 return 0;
902}
903
904static int
905isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
906{
907 struct isp_video_fh *vfh = to_isp_video_fh(fh);
908 struct isp_video *video = video_drvdata(file);
909
910 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
911 video->type != a->type)
912 return -EINVAL;
913
914 if (a->parm.output.timeperframe.denominator == 0)
915 a->parm.output.timeperframe.denominator = 1;
916
917 vfh->timeperframe = a->parm.output.timeperframe;
918
919 return 0;
920}
921
922static int
923isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
924{
925 struct isp_video_fh *vfh = to_isp_video_fh(fh);
926
927 return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
928}
929
930static int
931isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
932{
933 struct isp_video_fh *vfh = to_isp_video_fh(fh);
934
935 return omap3isp_video_queue_querybuf(&vfh->queue, b);
936}
937
938static int
939isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
940{
941 struct isp_video_fh *vfh = to_isp_video_fh(fh);
942
943 return omap3isp_video_queue_qbuf(&vfh->queue, b);
944}
945
946static int
947isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
948{
949 struct isp_video_fh *vfh = to_isp_video_fh(fh);
950
951 return omap3isp_video_queue_dqbuf(&vfh->queue, b,
952 file->f_flags & O_NONBLOCK);
953}
954
Sakari Ailusccddd912012-01-17 12:29:38 -0300955static int isp_video_check_external_subdevs(struct isp_video *video,
956 struct isp_pipeline *pipe)
957{
958 struct isp_device *isp = video->isp;
959 struct media_entity *ents[] = {
960 &isp->isp_csi2a.subdev.entity,
961 &isp->isp_csi2c.subdev.entity,
962 &isp->isp_ccp2.subdev.entity,
963 &isp->isp_ccdc.subdev.entity
964 };
965 struct media_pad *source_pad;
966 struct media_entity *source = NULL;
967 struct media_entity *sink;
968 struct v4l2_subdev_format fmt;
969 struct v4l2_ext_controls ctrls;
970 struct v4l2_ext_control ctrl;
971 unsigned int i;
972 int ret = 0;
973
974 for (i = 0; i < ARRAY_SIZE(ents); i++) {
975 /* Is the entity part of the pipeline? */
976 if (!(pipe->entities & (1 << ents[i]->id)))
977 continue;
978
979 /* ISP entities have always sink pad == 0. Find source. */
980 source_pad = media_entity_remote_source(&ents[i]->pads[0]);
981 if (source_pad == NULL)
982 continue;
983
984 source = source_pad->entity;
985 sink = ents[i];
986 break;
987 }
988
989 if (!source) {
990 dev_warn(isp->dev, "can't find source, failing now\n");
991 return ret;
992 }
993
994 if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
995 return 0;
996
997 pipe->external = media_entity_to_v4l2_subdev(source);
998
999 fmt.pad = source_pad->index;
1000 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1001 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
1002 pad, get_fmt, NULL, &fmt);
1003 if (unlikely(ret < 0)) {
1004 dev_warn(isp->dev, "get_fmt returned null!\n");
1005 return ret;
1006 }
1007
1008 pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
1009
1010 memset(&ctrls, 0, sizeof(ctrls));
1011 memset(&ctrl, 0, sizeof(ctrl));
1012
1013 ctrl.id = V4L2_CID_PIXEL_RATE;
1014
1015 ctrls.count = 1;
1016 ctrls.controls = &ctrl;
1017
1018 ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
1019 if (ret < 0) {
1020 dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
1021 pipe->external->name);
1022 return ret;
1023 }
1024
1025 pipe->external_rate = ctrl.value64;
1026
1027 return 0;
1028}
1029
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001030/*
1031 * Stream management
1032 *
1033 * Every ISP pipeline has a single input and a single output. The input can be
1034 * either a sensor or a video node. The output is always a video node.
1035 *
1036 * As every pipeline has an output video node, the ISP video objects at the
1037 * pipeline output stores the pipeline state. It tracks the streaming state of
1038 * both the input and output, as well as the availability of buffers.
1039 *
1040 * In sensor-to-memory mode, frames are always available at the pipeline input.
1041 * Starting the sensor usually requires I2C transfers and must be done in
1042 * interruptible context. The pipeline is started and stopped synchronously
1043 * to the stream on/off commands. All modules in the pipeline will get their
1044 * subdev set stream handler called. The module at the end of the pipeline must
1045 * delay starting the hardware until buffers are available at its output.
1046 *
1047 * In memory-to-memory mode, starting/stopping the stream requires
1048 * synchronization between the input and output. ISP modules can't be stopped
1049 * in the middle of a frame, and at least some of the modules seem to become
1050 * busy as soon as they're started, even if they don't receive a frame start
1051 * event. For that reason frames need to be processed in single-shot mode. The
1052 * driver needs to wait until a frame is completely processed and written to
1053 * memory before restarting the pipeline for the next frame. Pipelined
1054 * processing might be possible but requires more testing.
1055 *
1056 * Stream start must be delayed until buffers are available at both the input
1057 * and output. The pipeline must be started in the videobuf queue callback with
1058 * the buffers queue spinlock held. The modules subdev set stream operation must
1059 * not sleep.
1060 */
1061static int
1062isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1063{
1064 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1065 struct isp_video *video = video_drvdata(file);
1066 enum isp_pipeline_state state;
1067 struct isp_pipeline *pipe;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001068 unsigned long flags;
1069 int ret;
1070
1071 if (type != video->type)
1072 return -EINVAL;
1073
1074 mutex_lock(&video->stream_lock);
1075
1076 if (video->streaming) {
1077 mutex_unlock(&video->stream_lock);
1078 return -EBUSY;
1079 }
1080
1081 /* Start streaming on the pipeline. No link touching an entity in the
1082 * pipeline can be activated or deactivated once streaming is started.
1083 */
1084 pipe = video->video.entity.pipe
1085 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
Sakari Ailusb0cd79e2012-01-16 18:59:02 -03001086
Sakari Ailusae5df812012-03-05 20:22:41 -03001087 pipe->entities = 0;
1088
Sakari Ailusb0cd79e2012-01-16 18:59:02 -03001089 if (video->isp->pdata->set_constraints)
1090 video->isp->pdata->set_constraints(video->isp, true);
1091 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
1092 pipe->max_rate = pipe->l3_ick;
1093
Sakari Ailusda392572011-10-10 17:05:24 -03001094 ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
1095 if (ret < 0)
1096 goto err_pipeline_start;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001097
1098 /* Verify that the currently configured format matches the output of
1099 * the connected subdev.
1100 */
1101 ret = isp_video_check_format(video, vfh);
1102 if (ret < 0)
Sakari Ailusda392572011-10-10 17:05:24 -03001103 goto err_check_format;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001104
1105 video->bpl_padding = ret;
1106 video->bpl_value = vfh->format.fmt.pix.bytesperline;
1107
Sakari Ailusae5df812012-03-05 20:22:41 -03001108 ret = isp_video_get_graph_data(video, pipe);
1109 if (ret < 0)
1110 goto err_check_format;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001111
Sakari Ailusae5df812012-03-05 20:22:41 -03001112 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001113 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
Sakari Ailusae5df812012-03-05 20:22:41 -03001114 else
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001115 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001116
Sakari Ailusccddd912012-01-17 12:29:38 -03001117 ret = isp_video_check_external_subdevs(video, pipe);
1118 if (ret < 0)
1119 goto err_check_format;
1120
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001121 /* Validate the pipeline and update its state. */
1122 ret = isp_video_validate_pipeline(pipe);
1123 if (ret < 0)
Sakari Ailusda392572011-10-10 17:05:24 -03001124 goto err_check_format;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001125
Laurent Pinchart875e2e32011-12-07 08:34:50 -03001126 pipe->error = false;
1127
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001128 spin_lock_irqsave(&pipe->lock, flags);
1129 pipe->state &= ~ISP_PIPELINE_STREAM;
1130 pipe->state |= state;
1131 spin_unlock_irqrestore(&pipe->lock, flags);
1132
1133 /* Set the maximum time per frame as the value requested by userspace.
1134 * This is a soft limit that can be overridden if the hardware doesn't
1135 * support the request limit.
1136 */
1137 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1138 pipe->max_timeperframe = vfh->timeperframe;
1139
1140 video->queue = &vfh->queue;
1141 INIT_LIST_HEAD(&video->dmaqueue);
1142 atomic_set(&pipe->frame_number, -1);
1143
1144 ret = omap3isp_video_queue_streamon(&vfh->queue);
1145 if (ret < 0)
Sakari Ailusda392572011-10-10 17:05:24 -03001146 goto err_check_format;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001147
1148 /* In sensor-to-memory mode, the stream can be started synchronously
1149 * to the stream on command. In memory-to-memory mode, it will be
1150 * started when buffers are queued on both the input and output.
1151 */
1152 if (pipe->input == NULL) {
1153 ret = omap3isp_pipeline_set_stream(pipe,
1154 ISP_PIPELINE_STREAM_CONTINUOUS);
1155 if (ret < 0)
Sakari Ailusda392572011-10-10 17:05:24 -03001156 goto err_set_stream;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001157 spin_lock_irqsave(&video->queue->irqlock, flags);
1158 if (list_empty(&video->dmaqueue))
1159 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
1160 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1161 }
1162
Sakari Ailusda392572011-10-10 17:05:24 -03001163 video->streaming = 1;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001164
Sakari Ailusda392572011-10-10 17:05:24 -03001165 mutex_unlock(&video->stream_lock);
1166 return 0;
1167
1168err_set_stream:
1169 omap3isp_video_queue_streamoff(&vfh->queue);
1170err_check_format:
1171 media_entity_pipeline_stop(&video->video.entity);
1172err_pipeline_start:
1173 if (video->isp->pdata->set_constraints)
1174 video->isp->pdata->set_constraints(video->isp, false);
1175 /* The DMA queue must be emptied here, otherwise CCDC interrupts that
1176 * will get triggered the next time the CCDC is powered up will try to
1177 * access buffers that might have been freed but still present in the
1178 * DMA queue. This can easily get triggered if the above
1179 * omap3isp_pipeline_set_stream() call fails on a system with a
1180 * free-running sensor.
1181 */
1182 INIT_LIST_HEAD(&video->dmaqueue);
1183 video->queue = NULL;
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001184
1185 mutex_unlock(&video->stream_lock);
1186 return ret;
1187}
1188
1189static int
1190isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1191{
1192 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1193 struct isp_video *video = video_drvdata(file);
1194 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
1195 enum isp_pipeline_state state;
1196 unsigned int streaming;
1197 unsigned long flags;
1198
1199 if (type != video->type)
1200 return -EINVAL;
1201
1202 mutex_lock(&video->stream_lock);
1203
1204 /* Make sure we're not streaming yet. */
1205 mutex_lock(&vfh->queue.lock);
1206 streaming = vfh->queue.streaming;
1207 mutex_unlock(&vfh->queue.lock);
1208
1209 if (!streaming)
1210 goto done;
1211
1212 /* Update the pipeline state. */
1213 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1214 state = ISP_PIPELINE_STREAM_OUTPUT
1215 | ISP_PIPELINE_QUEUE_OUTPUT;
1216 else
1217 state = ISP_PIPELINE_STREAM_INPUT
1218 | ISP_PIPELINE_QUEUE_INPUT;
1219
1220 spin_lock_irqsave(&pipe->lock, flags);
1221 pipe->state &= ~state;
1222 spin_unlock_irqrestore(&pipe->lock, flags);
1223
1224 /* Stop the stream. */
1225 omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
1226 omap3isp_video_queue_streamoff(&vfh->queue);
1227 video->queue = NULL;
1228 video->streaming = 0;
1229
Laurent Pinchart4b0ec192011-03-03 10:05:22 -03001230 if (video->isp->pdata->set_constraints)
1231 video->isp->pdata->set_constraints(video->isp, false);
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001232 media_entity_pipeline_stop(&video->video.entity);
1233
1234done:
1235 mutex_unlock(&video->stream_lock);
1236 return 0;
1237}
1238
1239static int
1240isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
1241{
1242 if (input->index > 0)
1243 return -EINVAL;
1244
1245 strlcpy(input->name, "camera", sizeof(input->name));
1246 input->type = V4L2_INPUT_TYPE_CAMERA;
1247
1248 return 0;
1249}
1250
1251static int
1252isp_video_g_input(struct file *file, void *fh, unsigned int *input)
1253{
1254 *input = 0;
1255
1256 return 0;
1257}
1258
1259static int
1260isp_video_s_input(struct file *file, void *fh, unsigned int input)
1261{
1262 return input == 0 ? 0 : -EINVAL;
1263}
1264
1265static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
1266 .vidioc_querycap = isp_video_querycap,
1267 .vidioc_g_fmt_vid_cap = isp_video_get_format,
1268 .vidioc_s_fmt_vid_cap = isp_video_set_format,
1269 .vidioc_try_fmt_vid_cap = isp_video_try_format,
1270 .vidioc_g_fmt_vid_out = isp_video_get_format,
1271 .vidioc_s_fmt_vid_out = isp_video_set_format,
1272 .vidioc_try_fmt_vid_out = isp_video_try_format,
1273 .vidioc_cropcap = isp_video_cropcap,
1274 .vidioc_g_crop = isp_video_get_crop,
1275 .vidioc_s_crop = isp_video_set_crop,
1276 .vidioc_g_parm = isp_video_get_param,
1277 .vidioc_s_parm = isp_video_set_param,
1278 .vidioc_reqbufs = isp_video_reqbufs,
1279 .vidioc_querybuf = isp_video_querybuf,
1280 .vidioc_qbuf = isp_video_qbuf,
1281 .vidioc_dqbuf = isp_video_dqbuf,
1282 .vidioc_streamon = isp_video_streamon,
1283 .vidioc_streamoff = isp_video_streamoff,
1284 .vidioc_enum_input = isp_video_enum_input,
1285 .vidioc_g_input = isp_video_g_input,
1286 .vidioc_s_input = isp_video_s_input,
1287};
1288
1289/* -----------------------------------------------------------------------------
1290 * V4L2 file operations
1291 */
1292
1293static int isp_video_open(struct file *file)
1294{
1295 struct isp_video *video = video_drvdata(file);
1296 struct isp_video_fh *handle;
1297 int ret = 0;
1298
1299 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1300 if (handle == NULL)
1301 return -ENOMEM;
1302
1303 v4l2_fh_init(&handle->vfh, &video->video);
1304 v4l2_fh_add(&handle->vfh);
1305
1306 /* If this is the first user, initialise the pipeline. */
1307 if (omap3isp_get(video->isp) == NULL) {
1308 ret = -EBUSY;
1309 goto done;
1310 }
1311
1312 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1);
1313 if (ret < 0) {
1314 omap3isp_put(video->isp);
1315 goto done;
1316 }
1317
1318 omap3isp_video_queue_init(&handle->queue, video->type,
1319 &isp_video_queue_ops, video->isp->dev,
1320 sizeof(struct isp_buffer));
1321
1322 memset(&handle->format, 0, sizeof(handle->format));
1323 handle->format.type = video->type;
1324 handle->timeperframe.denominator = 1;
1325
1326 handle->video = video;
1327 file->private_data = &handle->vfh;
1328
1329done:
1330 if (ret < 0) {
1331 v4l2_fh_del(&handle->vfh);
1332 kfree(handle);
1333 }
1334
1335 return ret;
1336}
1337
1338static int isp_video_release(struct file *file)
1339{
1340 struct isp_video *video = video_drvdata(file);
1341 struct v4l2_fh *vfh = file->private_data;
1342 struct isp_video_fh *handle = to_isp_video_fh(vfh);
1343
1344 /* Disable streaming and free the buffers queue resources. */
1345 isp_video_streamoff(file, vfh, video->type);
1346
1347 mutex_lock(&handle->queue.lock);
1348 omap3isp_video_queue_cleanup(&handle->queue);
1349 mutex_unlock(&handle->queue.lock);
1350
1351 omap3isp_pipeline_pm_use(&video->video.entity, 0);
1352
1353 /* Release the file handle. */
1354 v4l2_fh_del(vfh);
1355 kfree(handle);
1356 file->private_data = NULL;
1357
1358 omap3isp_put(video->isp);
1359
1360 return 0;
1361}
1362
1363static unsigned int isp_video_poll(struct file *file, poll_table *wait)
1364{
1365 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1366 struct isp_video_queue *queue = &vfh->queue;
1367
1368 return omap3isp_video_queue_poll(queue, file, wait);
1369}
1370
1371static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1372{
1373 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1374
1375 return omap3isp_video_queue_mmap(&vfh->queue, vma);
1376}
1377
1378static struct v4l2_file_operations isp_video_fops = {
1379 .owner = THIS_MODULE,
1380 .unlocked_ioctl = video_ioctl2,
1381 .open = isp_video_open,
1382 .release = isp_video_release,
1383 .poll = isp_video_poll,
1384 .mmap = isp_video_mmap,
1385};
1386
1387/* -----------------------------------------------------------------------------
1388 * ISP video core
1389 */
1390
1391static const struct isp_video_operations isp_video_dummy_ops = {
1392};
1393
1394int omap3isp_video_init(struct isp_video *video, const char *name)
1395{
1396 const char *direction;
1397 int ret;
1398
1399 switch (video->type) {
1400 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1401 direction = "output";
1402 video->pad.flags = MEDIA_PAD_FL_SINK;
1403 break;
1404 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1405 direction = "input";
1406 video->pad.flags = MEDIA_PAD_FL_SOURCE;
1407 break;
1408
1409 default:
1410 return -EINVAL;
1411 }
1412
1413 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
1414 if (ret < 0)
1415 return ret;
1416
1417 mutex_init(&video->mutex);
1418 atomic_set(&video->active, 0);
1419
1420 spin_lock_init(&video->pipe.lock);
1421 mutex_init(&video->stream_lock);
1422
1423 /* Initialize the video device. */
1424 if (video->ops == NULL)
1425 video->ops = &isp_video_dummy_ops;
1426
1427 video->video.fops = &isp_video_fops;
1428 snprintf(video->video.name, sizeof(video->video.name),
1429 "OMAP3 ISP %s %s", name, direction);
1430 video->video.vfl_type = VFL_TYPE_GRABBER;
1431 video->video.release = video_device_release_empty;
1432 video->video.ioctl_ops = &isp_video_ioctl_ops;
1433 video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
1434
1435 video_set_drvdata(&video->video, video);
1436
1437 return 0;
1438}
1439
Laurent Pinchart63b4ca22011-09-22 16:54:34 -03001440void omap3isp_video_cleanup(struct isp_video *video)
1441{
1442 media_entity_cleanup(&video->video.entity);
Laurent Pincharted33ac82011-09-22 17:09:26 -03001443 mutex_destroy(&video->stream_lock);
1444 mutex_destroy(&video->mutex);
Laurent Pinchart63b4ca22011-09-22 16:54:34 -03001445}
1446
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001447int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1448{
1449 int ret;
1450
1451 video->video.v4l2_dev = vdev;
1452
1453 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1454 if (ret < 0)
1455 printk(KERN_ERR "%s: could not register video device (%d)\n",
1456 __func__, ret);
1457
1458 return ret;
1459}
1460
1461void omap3isp_video_unregister(struct isp_video *video)
1462{
Laurent Pinchart63b4ca22011-09-22 16:54:34 -03001463 if (video_is_registered(&video->video))
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001464 video_unregister_device(&video->video);
Laurent Pinchartad614ac2011-02-12 18:05:06 -03001465}