1 /*
2 * TI OMAP4 ISS V4L2 Driver
3 *
4 * Copyright (C) 2012, Texas Instruments
5 *
6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.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 by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/device.h>
17 #include <linux/dma-mapping.h>
18 #include <linux/i2c.h>
19 #include <linux/interrupt.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/slab.h>
23 #include <linux/sched.h>
24 #include <linux/vmalloc.h>
25
26 #include <media/v4l2-common.h>
27 #include <media/v4l2-device.h>
28 #include <media/v4l2-ctrls.h>
29
30 #include "iss.h"
31 #include "iss_regs.h"
32
33 #define ISS_PRINT_REGISTER(iss, name)\
34 dev_dbg(iss->dev, "###ISS " #name "=0x%08x\n", \
35 iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_##name))
36
iss_print_status(struct iss_device * iss)37 static void iss_print_status(struct iss_device *iss)
38 {
39 dev_dbg(iss->dev, "-------------ISS HL Register dump-------------\n");
40
41 ISS_PRINT_REGISTER(iss, HL_REVISION);
42 ISS_PRINT_REGISTER(iss, HL_SYSCONFIG);
43 ISS_PRINT_REGISTER(iss, HL_IRQSTATUS(5));
44 ISS_PRINT_REGISTER(iss, HL_IRQENABLE_SET(5));
45 ISS_PRINT_REGISTER(iss, HL_IRQENABLE_CLR(5));
46 ISS_PRINT_REGISTER(iss, CTRL);
47 ISS_PRINT_REGISTER(iss, CLKCTRL);
48 ISS_PRINT_REGISTER(iss, CLKSTAT);
49
50 dev_dbg(iss->dev, "-----------------------------------------------\n");
51 }
52
53 /*
54 * omap4iss_flush - Post pending L3 bus writes by doing a register readback
55 * @iss: OMAP4 ISS device
56 *
57 * In order to force posting of pending writes, we need to write and
58 * readback the same register, in this case the revision register.
59 *
60 * See this link for reference:
61 * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
62 */
omap4iss_flush(struct iss_device * iss)63 void omap4iss_flush(struct iss_device *iss)
64 {
65 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION, 0);
66 iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
67 }
68
69 /*
70 * iss_isp_enable_interrupts - Enable ISS ISP interrupts.
71 * @iss: OMAP4 ISS device
72 */
omap4iss_isp_enable_interrupts(struct iss_device * iss)73 static void omap4iss_isp_enable_interrupts(struct iss_device *iss)
74 {
75 static const u32 isp_irq = ISP5_IRQ_OCP_ERR |
76 ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
77 ISP5_IRQ_RSZ_FIFO_OVF |
78 ISP5_IRQ_RSZ_INT_DMA |
79 ISP5_IRQ_ISIF_INT(0);
80
81 /* Enable ISP interrupts */
82 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0), isp_irq);
83 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_SET(0),
84 isp_irq);
85 }
86
87 /*
88 * iss_isp_disable_interrupts - Disable ISS interrupts.
89 * @iss: OMAP4 ISS device
90 */
omap4iss_isp_disable_interrupts(struct iss_device * iss)91 static void omap4iss_isp_disable_interrupts(struct iss_device *iss)
92 {
93 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_CLR(0), ~0);
94 }
95
96 /*
97 * iss_enable_interrupts - Enable ISS interrupts.
98 * @iss: OMAP4 ISS device
99 */
iss_enable_interrupts(struct iss_device * iss)100 static void iss_enable_interrupts(struct iss_device *iss)
101 {
102 static const u32 hl_irq = ISS_HL_IRQ_CSIA | ISS_HL_IRQ_CSIB
103 | ISS_HL_IRQ_ISP(0);
104
105 /* Enable HL interrupts */
106 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), hl_irq);
107 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_SET(5), hl_irq);
108
109 if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
110 omap4iss_isp_enable_interrupts(iss);
111 }
112
113 /*
114 * iss_disable_interrupts - Disable ISS interrupts.
115 * @iss: OMAP4 ISS device
116 */
iss_disable_interrupts(struct iss_device * iss)117 static void iss_disable_interrupts(struct iss_device *iss)
118 {
119 if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
120 omap4iss_isp_disable_interrupts(iss);
121
122 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_CLR(5), ~0);
123 }
124
omap4iss_get_external_info(struct iss_pipeline * pipe,struct media_link * link)125 int omap4iss_get_external_info(struct iss_pipeline *pipe,
126 struct media_link *link)
127 {
128 struct iss_device *iss =
129 container_of(pipe, struct iss_video, pipe)->iss;
130 struct v4l2_subdev_format fmt;
131 struct v4l2_ctrl *ctrl;
132 int ret;
133
134 if (!pipe->external)
135 return 0;
136
137 if (pipe->external_rate)
138 return 0;
139
140 memset(&fmt, 0, sizeof(fmt));
141
142 fmt.pad = link->source->index;
143 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
144 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
145 pad, get_fmt, NULL, &fmt);
146 if (ret < 0)
147 return -EPIPE;
148
149 pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp;
150
151 ctrl = v4l2_ctrl_find(pipe->external->ctrl_handler,
152 V4L2_CID_PIXEL_RATE);
153 if (ctrl == NULL) {
154 dev_warn(iss->dev, "no pixel rate control in subdev %s\n",
155 pipe->external->name);
156 return -EPIPE;
157 }
158
159 pipe->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
160
161 return 0;
162 }
163
164 /*
165 * Configure the bridge. Valid inputs are
166 *
167 * IPIPEIF_INPUT_CSI2A: CSI2a receiver
168 * IPIPEIF_INPUT_CSI2B: CSI2b receiver
169 *
170 * The bridge and lane shifter are configured according to the selected input
171 * and the ISP platform data.
172 */
omap4iss_configure_bridge(struct iss_device * iss,enum ipipeif_input_entity input)173 void omap4iss_configure_bridge(struct iss_device *iss,
174 enum ipipeif_input_entity input)
175 {
176 u32 issctrl_val;
177 u32 isp5ctrl_val;
178
179 issctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL);
180 issctrl_val &= ~ISS_CTRL_INPUT_SEL_MASK;
181 issctrl_val &= ~ISS_CTRL_CLK_DIV_MASK;
182
183 isp5ctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL);
184
185 switch (input) {
186 case IPIPEIF_INPUT_CSI2A:
187 issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2A;
188 break;
189
190 case IPIPEIF_INPUT_CSI2B:
191 issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2B;
192 break;
193
194 default:
195 return;
196 }
197
198 issctrl_val |= ISS_CTRL_SYNC_DETECT_VS_RAISING;
199
200 isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT | ISP5_CTRL_PSYNC_CLK_SEL |
201 ISP5_CTRL_SYNC_ENABLE;
202
203 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL, issctrl_val);
204 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val);
205 }
206
207 #ifdef ISS_ISR_DEBUG
iss_isr_dbg(struct iss_device * iss,u32 irqstatus)208 static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus)
209 {
210 static const char * const name[] = {
211 "ISP_0",
212 "ISP_1",
213 "ISP_2",
214 "ISP_3",
215 "CSIA",
216 "CSIB",
217 "CCP2_0",
218 "CCP2_1",
219 "CCP2_2",
220 "CCP2_3",
221 "CBUFF",
222 "BTE",
223 "SIMCOP_0",
224 "SIMCOP_1",
225 "SIMCOP_2",
226 "SIMCOP_3",
227 "CCP2_8",
228 "HS_VS",
229 "18",
230 "19",
231 "20",
232 "21",
233 "22",
234 "23",
235 "24",
236 "25",
237 "26",
238 "27",
239 "28",
240 "29",
241 "30",
242 "31",
243 };
244 unsigned int i;
245
246 dev_dbg(iss->dev, "ISS IRQ: ");
247
248 for (i = 0; i < ARRAY_SIZE(name); i++) {
249 if ((1 << i) & irqstatus)
250 pr_cont("%s ", name[i]);
251 }
252 pr_cont("\n");
253 }
254
iss_isp_isr_dbg(struct iss_device * iss,u32 irqstatus)255 static void iss_isp_isr_dbg(struct iss_device *iss, u32 irqstatus)
256 {
257 static const char * const name[] = {
258 "ISIF_0",
259 "ISIF_1",
260 "ISIF_2",
261 "ISIF_3",
262 "IPIPEREQ",
263 "IPIPELAST_PIX",
264 "IPIPEDMA",
265 "IPIPEBSC",
266 "IPIPEHST",
267 "IPIPEIF",
268 "AEW",
269 "AF",
270 "H3A",
271 "RSZ_REG",
272 "RSZ_LAST_PIX",
273 "RSZ_DMA",
274 "RSZ_CYC_RZA",
275 "RSZ_CYC_RZB",
276 "RSZ_FIFO_OVF",
277 "RSZ_FIFO_IN_BLK_ERR",
278 "20",
279 "21",
280 "RSZ_EOF0",
281 "RSZ_EOF1",
282 "H3A_EOF",
283 "IPIPE_EOF",
284 "26",
285 "IPIPE_DPC_INI",
286 "IPIPE_DPC_RNEW0",
287 "IPIPE_DPC_RNEW1",
288 "30",
289 "OCP_ERR",
290 };
291 unsigned int i;
292
293 dev_dbg(iss->dev, "ISP IRQ: ");
294
295 for (i = 0; i < ARRAY_SIZE(name); i++) {
296 if ((1 << i) & irqstatus)
297 pr_cont("%s ", name[i]);
298 }
299 pr_cont("\n");
300 }
301 #endif
302
303 /*
304 * iss_isr - Interrupt Service Routine for ISS module.
305 * @irq: Not used currently.
306 * @_iss: Pointer to the OMAP4 ISS device
307 *
308 * Handles the corresponding callback if plugged in.
309 *
310 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
311 * IRQ wasn't handled.
312 */
iss_isr(int irq,void * _iss)313 static irqreturn_t iss_isr(int irq, void *_iss)
314 {
315 static const u32 ipipeif_events = ISP5_IRQ_IPIPEIF_IRQ |
316 ISP5_IRQ_ISIF_INT(0);
317 static const u32 resizer_events = ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
318 ISP5_IRQ_RSZ_FIFO_OVF |
319 ISP5_IRQ_RSZ_INT_DMA;
320 struct iss_device *iss = _iss;
321 u32 irqstatus;
322
323 irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5));
324 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), irqstatus);
325
326 if (irqstatus & ISS_HL_IRQ_CSIA)
327 omap4iss_csi2_isr(&iss->csi2a);
328
329 if (irqstatus & ISS_HL_IRQ_CSIB)
330 omap4iss_csi2_isr(&iss->csi2b);
331
332 if (irqstatus & ISS_HL_IRQ_ISP(0)) {
333 u32 isp_irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1,
334 ISP5_IRQSTATUS(0));
335 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0),
336 isp_irqstatus);
337
338 if (isp_irqstatus & ISP5_IRQ_OCP_ERR)
339 dev_dbg(iss->dev, "ISP5 OCP Error!\n");
340
341 if (isp_irqstatus & ipipeif_events) {
342 omap4iss_ipipeif_isr(&iss->ipipeif,
343 isp_irqstatus & ipipeif_events);
344 }
345
346 if (isp_irqstatus & resizer_events)
347 omap4iss_resizer_isr(&iss->resizer,
348 isp_irqstatus & resizer_events);
349
350 #ifdef ISS_ISR_DEBUG
351 iss_isp_isr_dbg(iss, isp_irqstatus);
352 #endif
353 }
354
355 omap4iss_flush(iss);
356
357 #ifdef ISS_ISR_DEBUG
358 iss_isr_dbg(iss, irqstatus);
359 #endif
360
361 return IRQ_HANDLED;
362 }
363
364 /* -----------------------------------------------------------------------------
365 * Pipeline power management
366 *
367 * Entities must be powered up when part of a pipeline that contains at least
368 * one open video device node.
369 *
370 * To achieve this use the entity use_count field to track the number of users.
371 * For entities corresponding to video device nodes the use_count field stores
372 * the users count of the node. For entities corresponding to subdevs the
373 * use_count field stores the total number of users of all video device nodes
374 * in the pipeline.
375 *
376 * The omap4iss_pipeline_pm_use() function must be called in the open() and
377 * close() handlers of video device nodes. It increments or decrements the use
378 * count of all subdev entities in the pipeline.
379 *
380 * To react to link management on powered pipelines, the link setup notification
381 * callback updates the use count of all entities in the source and sink sides
382 * of the link.
383 */
384
385 /*
386 * iss_pipeline_pm_use_count - Count the number of users of a pipeline
387 * @entity: The entity
388 *
389 * Return the total number of users of all video device nodes in the pipeline.
390 */
iss_pipeline_pm_use_count(struct media_entity * entity)391 static int iss_pipeline_pm_use_count(struct media_entity *entity)
392 {
393 struct media_entity_graph graph;
394 int use = 0;
395
396 media_entity_graph_walk_start(&graph, entity);
397
398 while ((entity = media_entity_graph_walk_next(&graph))) {
399 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
400 use += entity->use_count;
401 }
402
403 return use;
404 }
405
406 /*
407 * iss_pipeline_pm_power_one - Apply power change to an entity
408 * @entity: The entity
409 * @change: Use count change
410 *
411 * Change the entity use count by @change. If the entity is a subdev update its
412 * power state by calling the core::s_power operation when the use count goes
413 * from 0 to != 0 or from != 0 to 0.
414 *
415 * Return 0 on success or a negative error code on failure.
416 */
iss_pipeline_pm_power_one(struct media_entity * entity,int change)417 static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
418 {
419 struct v4l2_subdev *subdev;
420
421 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
422 ? media_entity_to_v4l2_subdev(entity) : NULL;
423
424 if (entity->use_count == 0 && change > 0 && subdev != NULL) {
425 int ret;
426
427 ret = v4l2_subdev_call(subdev, core, s_power, 1);
428 if (ret < 0 && ret != -ENOIOCTLCMD)
429 return ret;
430 }
431
432 entity->use_count += change;
433 WARN_ON(entity->use_count < 0);
434
435 if (entity->use_count == 0 && change < 0 && subdev != NULL)
436 v4l2_subdev_call(subdev, core, s_power, 0);
437
438 return 0;
439 }
440
441 /*
442 * iss_pipeline_pm_power - Apply power change to all entities in a pipeline
443 * @entity: The entity
444 * @change: Use count change
445 *
446 * Walk the pipeline to update the use count and the power state of all non-node
447 * entities.
448 *
449 * Return 0 on success or a negative error code on failure.
450 */
iss_pipeline_pm_power(struct media_entity * entity,int change)451 static int iss_pipeline_pm_power(struct media_entity *entity, int change)
452 {
453 struct media_entity_graph graph;
454 struct media_entity *first = entity;
455 int ret = 0;
456
457 if (!change)
458 return 0;
459
460 media_entity_graph_walk_start(&graph, entity);
461
462 while (!ret && (entity = media_entity_graph_walk_next(&graph)))
463 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
464 ret = iss_pipeline_pm_power_one(entity, change);
465
466 if (!ret)
467 return 0;
468
469 media_entity_graph_walk_start(&graph, first);
470
471 while ((first = media_entity_graph_walk_next(&graph))
472 && first != entity)
473 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
474 iss_pipeline_pm_power_one(first, -change);
475
476 return ret;
477 }
478
479 /*
480 * omap4iss_pipeline_pm_use - Update the use count of an entity
481 * @entity: The entity
482 * @use: Use (1) or stop using (0) the entity
483 *
484 * Update the use count of all entities in the pipeline and power entities on or
485 * off accordingly.
486 *
487 * Return 0 on success or a negative error code on failure. Powering entities
488 * off is assumed to never fail. No failure can occur when the use parameter is
489 * set to 0.
490 */
omap4iss_pipeline_pm_use(struct media_entity * entity,int use)491 int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
492 {
493 int change = use ? 1 : -1;
494 int ret;
495
496 mutex_lock(&entity->parent->graph_mutex);
497
498 /* Apply use count to node. */
499 entity->use_count += change;
500 WARN_ON(entity->use_count < 0);
501
502 /* Apply power change to connected non-nodes. */
503 ret = iss_pipeline_pm_power(entity, change);
504 if (ret < 0)
505 entity->use_count -= change;
506
507 mutex_unlock(&entity->parent->graph_mutex);
508
509 return ret;
510 }
511
512 /*
513 * iss_pipeline_link_notify - Link management notification callback
514 * @link: The link
515 * @flags: New link flags that will be applied
516 *
517 * React to link management on powered pipelines by updating the use count of
518 * all entities in the source and sink sides of the link. Entities are powered
519 * on or off accordingly.
520 *
521 * Return 0 on success or a negative error code on failure. Powering entities
522 * off is assumed to never fail. This function will not fail for disconnection
523 * events.
524 */
iss_pipeline_link_notify(struct media_link * link,u32 flags,unsigned int notification)525 static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
526 unsigned int notification)
527 {
528 struct media_entity *source = link->source->entity;
529 struct media_entity *sink = link->sink->entity;
530 int source_use = iss_pipeline_pm_use_count(source);
531 int sink_use = iss_pipeline_pm_use_count(sink);
532 int ret;
533
534 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
535 !(link->flags & MEDIA_LNK_FL_ENABLED)) {
536 /* Powering off entities is assumed to never fail. */
537 iss_pipeline_pm_power(source, -sink_use);
538 iss_pipeline_pm_power(sink, -source_use);
539 return 0;
540 }
541
542 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
543 (flags & MEDIA_LNK_FL_ENABLED)) {
544 ret = iss_pipeline_pm_power(source, sink_use);
545 if (ret < 0)
546 return ret;
547
548 ret = iss_pipeline_pm_power(sink, source_use);
549 if (ret < 0)
550 iss_pipeline_pm_power(source, -sink_use);
551
552 return ret;
553 }
554
555 return 0;
556 }
557
558 /* -----------------------------------------------------------------------------
559 * Pipeline stream management
560 */
561
562 /*
563 * iss_pipeline_enable - Enable streaming on a pipeline
564 * @pipe: ISS pipeline
565 * @mode: Stream mode (single shot or continuous)
566 *
567 * Walk the entities chain starting at the pipeline output video node and start
568 * all modules in the chain in the given mode.
569 *
570 * Return 0 if successful, or the return value of the failed video::s_stream
571 * operation otherwise.
572 */
iss_pipeline_enable(struct iss_pipeline * pipe,enum iss_pipeline_stream_state mode)573 static int iss_pipeline_enable(struct iss_pipeline *pipe,
574 enum iss_pipeline_stream_state mode)
575 {
576 struct iss_device *iss = pipe->output->iss;
577 struct media_entity *entity;
578 struct media_pad *pad;
579 struct v4l2_subdev *subdev;
580 unsigned long flags;
581 int ret;
582
583 /* If one of the entities in the pipeline has crashed it will not work
584 * properly. Refuse to start streaming in that case. This check must be
585 * performed before the loop below to avoid starting entities if the
586 * pipeline won't start anyway (those entities would then likely fail to
587 * stop, making the problem worse).
588 */
589 if (pipe->entities & iss->crashed)
590 return -EIO;
591
592 spin_lock_irqsave(&pipe->lock, flags);
593 pipe->state &= ~(ISS_PIPELINE_IDLE_INPUT | ISS_PIPELINE_IDLE_OUTPUT);
594 spin_unlock_irqrestore(&pipe->lock, flags);
595
596 pipe->do_propagation = false;
597
598 entity = &pipe->output->video.entity;
599 while (1) {
600 pad = &entity->pads[0];
601 if (!(pad->flags & MEDIA_PAD_FL_SINK))
602 break;
603
604 pad = media_entity_remote_pad(pad);
605 if (pad == NULL ||
606 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
607 break;
608
609 entity = pad->entity;
610 subdev = media_entity_to_v4l2_subdev(entity);
611
612 ret = v4l2_subdev_call(subdev, video, s_stream, mode);
613 if (ret < 0 && ret != -ENOIOCTLCMD)
614 return ret;
615 }
616 iss_print_status(pipe->output->iss);
617 return 0;
618 }
619
620 /*
621 * iss_pipeline_disable - Disable streaming on a pipeline
622 * @pipe: ISS pipeline
623 *
624 * Walk the entities chain starting at the pipeline output video node and stop
625 * all modules in the chain. Wait synchronously for the modules to be stopped if
626 * necessary.
627 */
iss_pipeline_disable(struct iss_pipeline * pipe)628 static int iss_pipeline_disable(struct iss_pipeline *pipe)
629 {
630 struct iss_device *iss = pipe->output->iss;
631 struct media_entity *entity;
632 struct media_pad *pad;
633 struct v4l2_subdev *subdev;
634 int failure = 0;
635 int ret;
636
637 entity = &pipe->output->video.entity;
638 while (1) {
639 pad = &entity->pads[0];
640 if (!(pad->flags & MEDIA_PAD_FL_SINK))
641 break;
642
643 pad = media_entity_remote_pad(pad);
644 if (pad == NULL ||
645 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
646 break;
647
648 entity = pad->entity;
649 subdev = media_entity_to_v4l2_subdev(entity);
650
651 ret = v4l2_subdev_call(subdev, video, s_stream, 0);
652 if (ret < 0) {
653 dev_dbg(iss->dev, "%s: module stop timeout.\n",
654 subdev->name);
655 /* If the entity failed to stopped, assume it has
656 * crashed. Mark it as such, the ISS will be reset when
657 * applications will release it.
658 */
659 iss->crashed |= 1U << subdev->entity.id;
660 failure = -ETIMEDOUT;
661 }
662 }
663
664 return failure;
665 }
666
667 /*
668 * omap4iss_pipeline_set_stream - Enable/disable streaming on a pipeline
669 * @pipe: ISS pipeline
670 * @state: Stream state (stopped, single shot or continuous)
671 *
672 * Set the pipeline to the given stream state. Pipelines can be started in
673 * single-shot or continuous mode.
674 *
675 * Return 0 if successful, or the return value of the failed video::s_stream
676 * operation otherwise. The pipeline state is not updated when the operation
677 * fails, except when stopping the pipeline.
678 */
omap4iss_pipeline_set_stream(struct iss_pipeline * pipe,enum iss_pipeline_stream_state state)679 int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
680 enum iss_pipeline_stream_state state)
681 {
682 int ret;
683
684 if (state == ISS_PIPELINE_STREAM_STOPPED)
685 ret = iss_pipeline_disable(pipe);
686 else
687 ret = iss_pipeline_enable(pipe, state);
688
689 if (ret == 0 || state == ISS_PIPELINE_STREAM_STOPPED)
690 pipe->stream_state = state;
691
692 return ret;
693 }
694
695 /*
696 * omap4iss_pipeline_cancel_stream - Cancel stream on a pipeline
697 * @pipe: ISS pipeline
698 *
699 * Cancelling a stream mark all buffers on all video nodes in the pipeline as
700 * erroneous and makes sure no new buffer can be queued. This function is called
701 * when a fatal error that prevents any further operation on the pipeline
702 * occurs.
703 */
omap4iss_pipeline_cancel_stream(struct iss_pipeline * pipe)704 void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe)
705 {
706 if (pipe->input)
707 omap4iss_video_cancel_stream(pipe->input);
708 if (pipe->output)
709 omap4iss_video_cancel_stream(pipe->output);
710 }
711
712 /*
713 * iss_pipeline_is_last - Verify if entity has an enabled link to the output
714 * video node
715 * @me: ISS module's media entity
716 *
717 * Returns 1 if the entity has an enabled link to the output video node or 0
718 * otherwise. It's true only while pipeline can have no more than one output
719 * node.
720 */
iss_pipeline_is_last(struct media_entity * me)721 static int iss_pipeline_is_last(struct media_entity *me)
722 {
723 struct iss_pipeline *pipe;
724 struct media_pad *pad;
725
726 if (!me->pipe)
727 return 0;
728 pipe = to_iss_pipeline(me);
729 if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED)
730 return 0;
731 pad = media_entity_remote_pad(&pipe->output->pad);
732 return pad->entity == me;
733 }
734
iss_reset(struct iss_device * iss)735 static int iss_reset(struct iss_device *iss)
736 {
737 unsigned int timeout;
738
739 iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG,
740 ISS_HL_SYSCONFIG_SOFTRESET);
741
742 timeout = iss_poll_condition_timeout(
743 !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
744 ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 100);
745 if (timeout) {
746 dev_err(iss->dev, "ISS reset timeout\n");
747 return -ETIMEDOUT;
748 }
749
750 iss->crashed = 0;
751 return 0;
752 }
753
iss_isp_reset(struct iss_device * iss)754 static int iss_isp_reset(struct iss_device *iss)
755 {
756 unsigned int timeout;
757
758 /* Fist, ensure that the ISP is IDLE (no transactions happening) */
759 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
760 ISP5_SYSCONFIG_STANDBYMODE_MASK,
761 ISP5_SYSCONFIG_STANDBYMODE_SMART);
762
763 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY);
764
765 timeout = iss_poll_condition_timeout(
766 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
767 ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500);
768 if (timeout) {
769 dev_err(iss->dev, "ISP5 standby timeout\n");
770 return -ETIMEDOUT;
771 }
772
773 /* Now finally, do the reset */
774 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
775 ISP5_SYSCONFIG_SOFTRESET);
776
777 timeout = iss_poll_condition_timeout(
778 !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
779 ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500);
780 if (timeout) {
781 dev_err(iss->dev, "ISP5 reset timeout\n");
782 return -ETIMEDOUT;
783 }
784
785 return 0;
786 }
787
788 /*
789 * iss_module_sync_idle - Helper to sync module with its idle state
790 * @me: ISS submodule's media entity
791 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
792 * @stopping: flag which tells module wants to stop
793 *
794 * This function checks if ISS submodule needs to wait for next interrupt. If
795 * yes, makes the caller to sleep while waiting for such event.
796 */
omap4iss_module_sync_idle(struct media_entity * me,wait_queue_head_t * wait,atomic_t * stopping)797 int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
798 atomic_t *stopping)
799 {
800 struct iss_pipeline *pipe = to_iss_pipeline(me);
801 struct iss_video *video = pipe->output;
802 unsigned long flags;
803
804 if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED ||
805 (pipe->stream_state == ISS_PIPELINE_STREAM_SINGLESHOT &&
806 !iss_pipeline_ready(pipe)))
807 return 0;
808
809 /*
810 * atomic_set() doesn't include memory barrier on ARM platform for SMP
811 * scenario. We'll call it here to avoid race conditions.
812 */
813 atomic_set(stopping, 1);
814 smp_wmb();
815
816 /*
817 * If module is the last one, it's writing to memory. In this case,
818 * it's necessary to check if the module is already paused due to
819 * DMA queue underrun or if it has to wait for next interrupt to be
820 * idle.
821 * If it isn't the last one, the function won't sleep but *stopping
822 * will still be set to warn next submodule caller's interrupt the
823 * module wants to be idle.
824 */
825 if (!iss_pipeline_is_last(me))
826 return 0;
827
828 spin_lock_irqsave(&video->qlock, flags);
829 if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
830 spin_unlock_irqrestore(&video->qlock, flags);
831 atomic_set(stopping, 0);
832 smp_wmb();
833 return 0;
834 }
835 spin_unlock_irqrestore(&video->qlock, flags);
836 if (!wait_event_timeout(*wait, !atomic_read(stopping),
837 msecs_to_jiffies(1000))) {
838 atomic_set(stopping, 0);
839 smp_wmb();
840 return -ETIMEDOUT;
841 }
842
843 return 0;
844 }
845
846 /*
847 * omap4iss_module_sync_is_stopped - Helper to verify if module was stopping
848 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
849 * @stopping: flag which tells module wants to stop
850 *
851 * This function checks if ISS submodule was stopping. In case of yes, it
852 * notices the caller by setting stopping to 0 and waking up the wait queue.
853 * Returns 1 if it was stopping or 0 otherwise.
854 */
omap4iss_module_sync_is_stopping(wait_queue_head_t * wait,atomic_t * stopping)855 int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
856 atomic_t *stopping)
857 {
858 if (atomic_cmpxchg(stopping, 1, 0)) {
859 wake_up(wait);
860 return 1;
861 }
862
863 return 0;
864 }
865
866 /* --------------------------------------------------------------------------
867 * Clock management
868 */
869
870 #define ISS_CLKCTRL_MASK (ISS_CLKCTRL_CSI2_A |\
871 ISS_CLKCTRL_CSI2_B |\
872 ISS_CLKCTRL_ISP)
873
__iss_subclk_update(struct iss_device * iss)874 static int __iss_subclk_update(struct iss_device *iss)
875 {
876 u32 clk = 0;
877 int ret = 0, timeout = 1000;
878
879 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_A)
880 clk |= ISS_CLKCTRL_CSI2_A;
881
882 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_B)
883 clk |= ISS_CLKCTRL_CSI2_B;
884
885 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_ISP)
886 clk |= ISS_CLKCTRL_ISP;
887
888 iss_reg_update(iss, OMAP4_ISS_MEM_TOP, ISS_CLKCTRL,
889 ISS_CLKCTRL_MASK, clk);
890
891 /* Wait for HW assertion */
892 while (--timeout > 0) {
893 udelay(1);
894 if ((iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CLKSTAT) &
895 ISS_CLKCTRL_MASK) == clk)
896 break;
897 }
898
899 if (!timeout)
900 ret = -EBUSY;
901
902 return ret;
903 }
904
omap4iss_subclk_enable(struct iss_device * iss,enum iss_subclk_resource res)905 int omap4iss_subclk_enable(struct iss_device *iss,
906 enum iss_subclk_resource res)
907 {
908 iss->subclk_resources |= res;
909
910 return __iss_subclk_update(iss);
911 }
912
omap4iss_subclk_disable(struct iss_device * iss,enum iss_subclk_resource res)913 int omap4iss_subclk_disable(struct iss_device *iss,
914 enum iss_subclk_resource res)
915 {
916 iss->subclk_resources &= ~res;
917
918 return __iss_subclk_update(iss);
919 }
920
921 #define ISS_ISP5_CLKCTRL_MASK (ISP5_CTRL_BL_CLK_ENABLE |\
922 ISP5_CTRL_ISIF_CLK_ENABLE |\
923 ISP5_CTRL_H3A_CLK_ENABLE |\
924 ISP5_CTRL_RSZ_CLK_ENABLE |\
925 ISP5_CTRL_IPIPE_CLK_ENABLE |\
926 ISP5_CTRL_IPIPEIF_CLK_ENABLE)
927
__iss_isp_subclk_update(struct iss_device * iss)928 static void __iss_isp_subclk_update(struct iss_device *iss)
929 {
930 u32 clk = 0;
931
932 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_ISIF)
933 clk |= ISP5_CTRL_ISIF_CLK_ENABLE;
934
935 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_H3A)
936 clk |= ISP5_CTRL_H3A_CLK_ENABLE;
937
938 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_RSZ)
939 clk |= ISP5_CTRL_RSZ_CLK_ENABLE;
940
941 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPE)
942 clk |= ISP5_CTRL_IPIPE_CLK_ENABLE;
943
944 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPEIF)
945 clk |= ISP5_CTRL_IPIPEIF_CLK_ENABLE;
946
947 if (clk)
948 clk |= ISP5_CTRL_BL_CLK_ENABLE;
949
950 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL,
951 ISS_ISP5_CLKCTRL_MASK, clk);
952 }
953
omap4iss_isp_subclk_enable(struct iss_device * iss,enum iss_isp_subclk_resource res)954 void omap4iss_isp_subclk_enable(struct iss_device *iss,
955 enum iss_isp_subclk_resource res)
956 {
957 iss->isp_subclk_resources |= res;
958
959 __iss_isp_subclk_update(iss);
960 }
961
omap4iss_isp_subclk_disable(struct iss_device * iss,enum iss_isp_subclk_resource res)962 void omap4iss_isp_subclk_disable(struct iss_device *iss,
963 enum iss_isp_subclk_resource res)
964 {
965 iss->isp_subclk_resources &= ~res;
966
967 __iss_isp_subclk_update(iss);
968 }
969
970 /*
971 * iss_enable_clocks - Enable ISS clocks
972 * @iss: OMAP4 ISS device
973 *
974 * Return 0 if successful, or clk_enable return value if any of tthem fails.
975 */
iss_enable_clocks(struct iss_device * iss)976 static int iss_enable_clocks(struct iss_device *iss)
977 {
978 int ret;
979
980 ret = clk_enable(iss->iss_fck);
981 if (ret) {
982 dev_err(iss->dev, "clk_enable iss_fck failed\n");
983 return ret;
984 }
985
986 ret = clk_enable(iss->iss_ctrlclk);
987 if (ret) {
988 dev_err(iss->dev, "clk_enable iss_ctrlclk failed\n");
989 clk_disable(iss->iss_fck);
990 return ret;
991 }
992
993 return 0;
994 }
995
996 /*
997 * iss_disable_clocks - Disable ISS clocks
998 * @iss: OMAP4 ISS device
999 */
iss_disable_clocks(struct iss_device * iss)1000 static void iss_disable_clocks(struct iss_device *iss)
1001 {
1002 clk_disable(iss->iss_ctrlclk);
1003 clk_disable(iss->iss_fck);
1004 }
1005
iss_get_clocks(struct iss_device * iss)1006 static int iss_get_clocks(struct iss_device *iss)
1007 {
1008 iss->iss_fck = devm_clk_get(iss->dev, "iss_fck");
1009 if (IS_ERR(iss->iss_fck)) {
1010 dev_err(iss->dev, "Unable to get iss_fck clock info\n");
1011 return PTR_ERR(iss->iss_fck);
1012 }
1013
1014 iss->iss_ctrlclk = devm_clk_get(iss->dev, "iss_ctrlclk");
1015 if (IS_ERR(iss->iss_ctrlclk)) {
1016 dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n");
1017 return PTR_ERR(iss->iss_ctrlclk);
1018 }
1019
1020 return 0;
1021 }
1022
1023 /*
1024 * omap4iss_get - Acquire the ISS resource.
1025 *
1026 * Initializes the clocks for the first acquire.
1027 *
1028 * Increment the reference count on the ISS. If the first reference is taken,
1029 * enable clocks and power-up all submodules.
1030 *
1031 * Return a pointer to the ISS device structure, or NULL if an error occurred.
1032 */
omap4iss_get(struct iss_device * iss)1033 struct iss_device *omap4iss_get(struct iss_device *iss)
1034 {
1035 struct iss_device *__iss = iss;
1036
1037 if (iss == NULL)
1038 return NULL;
1039
1040 mutex_lock(&iss->iss_mutex);
1041 if (iss->ref_count > 0)
1042 goto out;
1043
1044 if (iss_enable_clocks(iss) < 0) {
1045 __iss = NULL;
1046 goto out;
1047 }
1048
1049 iss_enable_interrupts(iss);
1050
1051 out:
1052 if (__iss != NULL)
1053 iss->ref_count++;
1054 mutex_unlock(&iss->iss_mutex);
1055
1056 return __iss;
1057 }
1058
1059 /*
1060 * omap4iss_put - Release the ISS
1061 *
1062 * Decrement the reference count on the ISS. If the last reference is released,
1063 * power-down all submodules, disable clocks and free temporary buffers.
1064 */
omap4iss_put(struct iss_device * iss)1065 void omap4iss_put(struct iss_device *iss)
1066 {
1067 if (iss == NULL)
1068 return;
1069
1070 mutex_lock(&iss->iss_mutex);
1071 BUG_ON(iss->ref_count == 0);
1072 if (--iss->ref_count == 0) {
1073 iss_disable_interrupts(iss);
1074 /* Reset the ISS if an entity has failed to stop. This is the
1075 * only way to recover from such conditions, although it would
1076 * be worth investigating whether resetting the ISP only can't
1077 * fix the problem in some cases.
1078 */
1079 if (iss->crashed)
1080 iss_reset(iss);
1081 iss_disable_clocks(iss);
1082 }
1083 mutex_unlock(&iss->iss_mutex);
1084 }
1085
iss_map_mem_resource(struct platform_device * pdev,struct iss_device * iss,enum iss_mem_resources res)1086 static int iss_map_mem_resource(struct platform_device *pdev,
1087 struct iss_device *iss,
1088 enum iss_mem_resources res)
1089 {
1090 struct resource *mem;
1091
1092 mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
1093
1094 iss->regs[res] = devm_ioremap_resource(iss->dev, mem);
1095
1096 return PTR_ERR_OR_ZERO(iss->regs[res]);
1097 }
1098
iss_unregister_entities(struct iss_device * iss)1099 static void iss_unregister_entities(struct iss_device *iss)
1100 {
1101 omap4iss_resizer_unregister_entities(&iss->resizer);
1102 omap4iss_ipipe_unregister_entities(&iss->ipipe);
1103 omap4iss_ipipeif_unregister_entities(&iss->ipipeif);
1104 omap4iss_csi2_unregister_entities(&iss->csi2a);
1105 omap4iss_csi2_unregister_entities(&iss->csi2b);
1106
1107 v4l2_device_unregister(&iss->v4l2_dev);
1108 media_device_unregister(&iss->media_dev);
1109 }
1110
1111 /*
1112 * iss_register_subdev_group - Register a group of subdevices
1113 * @iss: OMAP4 ISS device
1114 * @board_info: I2C subdevs board information array
1115 *
1116 * Register all I2C subdevices in the board_info array. The array must be
1117 * terminated by a NULL entry, and the first entry must be the sensor.
1118 *
1119 * Return a pointer to the sensor media entity if it has been successfully
1120 * registered, or NULL otherwise.
1121 */
1122 static struct v4l2_subdev *
iss_register_subdev_group(struct iss_device * iss,struct iss_subdev_i2c_board_info * board_info)1123 iss_register_subdev_group(struct iss_device *iss,
1124 struct iss_subdev_i2c_board_info *board_info)
1125 {
1126 struct v4l2_subdev *sensor = NULL;
1127 unsigned int first;
1128
1129 if (board_info->board_info == NULL)
1130 return NULL;
1131
1132 for (first = 1; board_info->board_info; ++board_info, first = 0) {
1133 struct v4l2_subdev *subdev;
1134 struct i2c_adapter *adapter;
1135
1136 adapter = i2c_get_adapter(board_info->i2c_adapter_id);
1137 if (adapter == NULL) {
1138 dev_err(iss->dev,
1139 "%s: Unable to get I2C adapter %d for device %s\n",
1140 __func__, board_info->i2c_adapter_id,
1141 board_info->board_info->type);
1142 continue;
1143 }
1144
1145 subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter,
1146 board_info->board_info, NULL);
1147 if (subdev == NULL) {
1148 dev_err(iss->dev, "%s: Unable to register subdev %s\n",
1149 __func__, board_info->board_info->type);
1150 continue;
1151 }
1152
1153 if (first)
1154 sensor = subdev;
1155 }
1156
1157 return sensor;
1158 }
1159
iss_register_entities(struct iss_device * iss)1160 static int iss_register_entities(struct iss_device *iss)
1161 {
1162 struct iss_platform_data *pdata = iss->pdata;
1163 struct iss_v4l2_subdevs_group *subdevs;
1164 int ret;
1165
1166 iss->media_dev.dev = iss->dev;
1167 strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
1168 sizeof(iss->media_dev.model));
1169 iss->media_dev.hw_revision = iss->revision;
1170 iss->media_dev.link_notify = iss_pipeline_link_notify;
1171 ret = media_device_register(&iss->media_dev);
1172 if (ret < 0) {
1173 dev_err(iss->dev, "%s: Media device registration failed (%d)\n",
1174 __func__, ret);
1175 return ret;
1176 }
1177
1178 iss->v4l2_dev.mdev = &iss->media_dev;
1179 ret = v4l2_device_register(iss->dev, &iss->v4l2_dev);
1180 if (ret < 0) {
1181 dev_err(iss->dev, "%s: V4L2 device registration failed (%d)\n",
1182 __func__, ret);
1183 goto done;
1184 }
1185
1186 /* Register internal entities */
1187 ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev);
1188 if (ret < 0)
1189 goto done;
1190
1191 ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev);
1192 if (ret < 0)
1193 goto done;
1194
1195 ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev);
1196 if (ret < 0)
1197 goto done;
1198
1199 ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev);
1200 if (ret < 0)
1201 goto done;
1202
1203 ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev);
1204 if (ret < 0)
1205 goto done;
1206
1207 /* Register external entities */
1208 for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
1209 struct v4l2_subdev *sensor;
1210 struct media_entity *input;
1211 unsigned int flags;
1212 unsigned int pad;
1213
1214 sensor = iss_register_subdev_group(iss, subdevs->subdevs);
1215 if (sensor == NULL)
1216 continue;
1217
1218 sensor->host_priv = subdevs;
1219
1220 /* Connect the sensor to the correct interface module.
1221 * CSI2a receiver through CSIPHY1, or
1222 * CSI2b receiver through CSIPHY2
1223 */
1224 switch (subdevs->interface) {
1225 case ISS_INTERFACE_CSI2A_PHY1:
1226 input = &iss->csi2a.subdev.entity;
1227 pad = CSI2_PAD_SINK;
1228 flags = MEDIA_LNK_FL_IMMUTABLE
1229 | MEDIA_LNK_FL_ENABLED;
1230 break;
1231
1232 case ISS_INTERFACE_CSI2B_PHY2:
1233 input = &iss->csi2b.subdev.entity;
1234 pad = CSI2_PAD_SINK;
1235 flags = MEDIA_LNK_FL_IMMUTABLE
1236 | MEDIA_LNK_FL_ENABLED;
1237 break;
1238
1239 default:
1240 dev_err(iss->dev, "%s: invalid interface type %u\n",
1241 __func__, subdevs->interface);
1242 ret = -EINVAL;
1243 goto done;
1244 }
1245
1246 ret = media_entity_create_link(&sensor->entity, 0, input, pad,
1247 flags);
1248 if (ret < 0)
1249 goto done;
1250 }
1251
1252 ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev);
1253
1254 done:
1255 if (ret < 0)
1256 iss_unregister_entities(iss);
1257
1258 return ret;
1259 }
1260
iss_cleanup_modules(struct iss_device * iss)1261 static void iss_cleanup_modules(struct iss_device *iss)
1262 {
1263 omap4iss_csi2_cleanup(iss);
1264 omap4iss_ipipeif_cleanup(iss);
1265 omap4iss_ipipe_cleanup(iss);
1266 omap4iss_resizer_cleanup(iss);
1267 }
1268
iss_initialize_modules(struct iss_device * iss)1269 static int iss_initialize_modules(struct iss_device *iss)
1270 {
1271 int ret;
1272
1273 ret = omap4iss_csiphy_init(iss);
1274 if (ret < 0) {
1275 dev_err(iss->dev, "CSI PHY initialization failed\n");
1276 goto error_csiphy;
1277 }
1278
1279 ret = omap4iss_csi2_init(iss);
1280 if (ret < 0) {
1281 dev_err(iss->dev, "CSI2 initialization failed\n");
1282 goto error_csi2;
1283 }
1284
1285 ret = omap4iss_ipipeif_init(iss);
1286 if (ret < 0) {
1287 dev_err(iss->dev, "ISP IPIPEIF initialization failed\n");
1288 goto error_ipipeif;
1289 }
1290
1291 ret = omap4iss_ipipe_init(iss);
1292 if (ret < 0) {
1293 dev_err(iss->dev, "ISP IPIPE initialization failed\n");
1294 goto error_ipipe;
1295 }
1296
1297 ret = omap4iss_resizer_init(iss);
1298 if (ret < 0) {
1299 dev_err(iss->dev, "ISP RESIZER initialization failed\n");
1300 goto error_resizer;
1301 }
1302
1303 /* Connect the submodules. */
1304 ret = media_entity_create_link(
1305 &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
1306 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1307 if (ret < 0)
1308 goto error_link;
1309
1310 ret = media_entity_create_link(
1311 &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
1312 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1313 if (ret < 0)
1314 goto error_link;
1315
1316 ret = media_entity_create_link(
1317 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1318 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1319 if (ret < 0)
1320 goto error_link;
1321
1322 ret = media_entity_create_link(
1323 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1324 &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
1325 if (ret < 0)
1326 goto error_link;
1327
1328 ret = media_entity_create_link(
1329 &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
1330 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1331 if (ret < 0)
1332 goto error_link;
1333
1334 return 0;
1335
1336 error_link:
1337 omap4iss_resizer_cleanup(iss);
1338 error_resizer:
1339 omap4iss_ipipe_cleanup(iss);
1340 error_ipipe:
1341 omap4iss_ipipeif_cleanup(iss);
1342 error_ipipeif:
1343 omap4iss_csi2_cleanup(iss);
1344 error_csi2:
1345 error_csiphy:
1346 return ret;
1347 }
1348
iss_probe(struct platform_device * pdev)1349 static int iss_probe(struct platform_device *pdev)
1350 {
1351 struct iss_platform_data *pdata = pdev->dev.platform_data;
1352 struct iss_device *iss;
1353 unsigned int i;
1354 int ret;
1355
1356 if (pdata == NULL)
1357 return -EINVAL;
1358
1359 iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
1360 if (!iss) {
1361 dev_err(&pdev->dev, "Could not allocate memory\n");
1362 return -ENOMEM;
1363 }
1364
1365 mutex_init(&iss->iss_mutex);
1366
1367 iss->dev = &pdev->dev;
1368 iss->pdata = pdata;
1369
1370 iss->raw_dmamask = DMA_BIT_MASK(32);
1371 iss->dev->dma_mask = &iss->raw_dmamask;
1372 iss->dev->coherent_dma_mask = DMA_BIT_MASK(32);
1373
1374 platform_set_drvdata(pdev, iss);
1375
1376 /* Clocks */
1377 ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP);
1378 if (ret < 0)
1379 goto error;
1380
1381 ret = iss_get_clocks(iss);
1382 if (ret < 0)
1383 goto error;
1384
1385 if (omap4iss_get(iss) == NULL)
1386 goto error;
1387
1388 ret = iss_reset(iss);
1389 if (ret < 0)
1390 goto error_iss;
1391
1392 iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
1393 dev_info(iss->dev, "Revision %08x found\n", iss->revision);
1394
1395 for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) {
1396 ret = iss_map_mem_resource(pdev, iss, i);
1397 if (ret)
1398 goto error_iss;
1399 }
1400
1401 /* Configure BTE BW_LIMITER field to max recommended value (1 GB) */
1402 iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL,
1403 BTE_CTRL_BW_LIMITER_MASK,
1404 18 << BTE_CTRL_BW_LIMITER_SHIFT);
1405
1406 /* Perform ISP reset */
1407 ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP);
1408 if (ret < 0)
1409 goto error_iss;
1410
1411 ret = iss_isp_reset(iss);
1412 if (ret < 0)
1413 goto error_iss;
1414
1415 dev_info(iss->dev, "ISP Revision %08x found\n",
1416 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION));
1417
1418 /* Interrupt */
1419 iss->irq_num = platform_get_irq(pdev, 0);
1420 if (iss->irq_num <= 0) {
1421 dev_err(iss->dev, "No IRQ resource\n");
1422 ret = -ENODEV;
1423 goto error_iss;
1424 }
1425
1426 if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
1427 "OMAP4 ISS", iss)) {
1428 dev_err(iss->dev, "Unable to request IRQ\n");
1429 ret = -EINVAL;
1430 goto error_iss;
1431 }
1432
1433 /* Entities */
1434 ret = iss_initialize_modules(iss);
1435 if (ret < 0)
1436 goto error_iss;
1437
1438 ret = iss_register_entities(iss);
1439 if (ret < 0)
1440 goto error_modules;
1441
1442 omap4iss_put(iss);
1443
1444 return 0;
1445
1446 error_modules:
1447 iss_cleanup_modules(iss);
1448 error_iss:
1449 omap4iss_put(iss);
1450 error:
1451 platform_set_drvdata(pdev, NULL);
1452
1453 mutex_destroy(&iss->iss_mutex);
1454
1455 return ret;
1456 }
1457
iss_remove(struct platform_device * pdev)1458 static int iss_remove(struct platform_device *pdev)
1459 {
1460 struct iss_device *iss = platform_get_drvdata(pdev);
1461
1462 iss_unregister_entities(iss);
1463 iss_cleanup_modules(iss);
1464
1465 return 0;
1466 }
1467
1468 static struct platform_device_id omap4iss_id_table[] = {
1469 { "omap4iss", 0 },
1470 { },
1471 };
1472 MODULE_DEVICE_TABLE(platform, omap4iss_id_table);
1473
1474 static struct platform_driver iss_driver = {
1475 .probe = iss_probe,
1476 .remove = iss_remove,
1477 .id_table = omap4iss_id_table,
1478 .driver = {
1479 .owner = THIS_MODULE,
1480 .name = "omap4iss",
1481 },
1482 };
1483
1484 module_platform_driver(iss_driver);
1485
1486 MODULE_DESCRIPTION("TI OMAP4 ISS driver");
1487 MODULE_AUTHOR("Sergio Aguirre <sergio.a.aguirre@gmail.com>");
1488 MODULE_LICENSE("GPL");
1489 MODULE_VERSION(ISS_VIDEO_DRIVER_VERSION);
1490