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