[go: nahoru, domu]

1/*
2 * ispccp2.c
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 *	     Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/mm.h>
20#include <linux/module.h>
21#include <linux/mutex.h>
22#include <linux/uaccess.h>
23#include <linux/regulator/consumer.h>
24
25#include "isp.h"
26#include "ispreg.h"
27#include "ispccp2.h"
28
29/* Number of LCX channels */
30#define CCP2_LCx_CHANS_NUM			3
31/* Max/Min size for CCP2 video port */
32#define ISPCCP2_DAT_START_MIN			0
33#define ISPCCP2_DAT_START_MAX			4095
34#define ISPCCP2_DAT_SIZE_MIN			0
35#define ISPCCP2_DAT_SIZE_MAX			4095
36#define ISPCCP2_VPCLK_FRACDIV			65536
37#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP	0x12
38#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP	0x16
39/* Max/Min size for CCP2 memory channel */
40#define ISPCCP2_LCM_HSIZE_COUNT_MIN		16
41#define ISPCCP2_LCM_HSIZE_COUNT_MAX		8191
42#define ISPCCP2_LCM_HSIZE_SKIP_MIN		0
43#define ISPCCP2_LCM_HSIZE_SKIP_MAX		8191
44#define ISPCCP2_LCM_VSIZE_MIN			1
45#define ISPCCP2_LCM_VSIZE_MAX			8191
46#define ISPCCP2_LCM_HWORDS_MIN			1
47#define ISPCCP2_LCM_HWORDS_MAX			4095
48#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X		5
49#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL	0
50#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10	2
51#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8	2
52#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10	3
53#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10	3
54#define ISPCCP2_LCM_CTRL_DST_PORT_VP		0
55#define ISPCCP2_LCM_CTRL_DST_PORT_MEM		1
56
57/* Set only the required bits */
58#define BIT_SET(var, shift, mask, val)			\
59	do {						\
60		var = ((var) & ~((mask) << (shift)))	\
61			| ((val) << (shift));		\
62	} while (0)
63
64/*
65 * ccp2_print_status - Print current CCP2 module register values.
66 */
67#define CCP2_PRINT_REGISTER(isp, name)\
68	dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \
69		isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name))
70
71static void ccp2_print_status(struct isp_ccp2_device *ccp2)
72{
73	struct isp_device *isp = to_isp_device(ccp2);
74
75	dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n");
76
77	CCP2_PRINT_REGISTER(isp, SYSCONFIG);
78	CCP2_PRINT_REGISTER(isp, SYSSTATUS);
79	CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE);
80	CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS);
81	CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE);
82	CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS);
83	CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE);
84	CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS);
85	CCP2_PRINT_REGISTER(isp, CTRL);
86	CCP2_PRINT_REGISTER(isp, LCx_CTRL(0));
87	CCP2_PRINT_REGISTER(isp, LCx_CODE(0));
88	CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0));
89	CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0));
90	CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0));
91	CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0));
92	CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0));
93	CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0));
94	CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0));
95	CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0));
96	CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0));
97	CCP2_PRINT_REGISTER(isp, LCM_CTRL);
98	CCP2_PRINT_REGISTER(isp, LCM_VSIZE);
99	CCP2_PRINT_REGISTER(isp, LCM_HSIZE);
100	CCP2_PRINT_REGISTER(isp, LCM_PREFETCH);
101	CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR);
102	CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST);
103	CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR);
104	CCP2_PRINT_REGISTER(isp, LCM_DST_OFST);
105
106	dev_dbg(isp->dev, "--------------------------------------------\n");
107}
108
109/*
110 * ccp2_reset - Reset the CCP2
111 * @ccp2: pointer to ISP CCP2 device
112 */
113static void ccp2_reset(struct isp_ccp2_device *ccp2)
114{
115	struct isp_device *isp = to_isp_device(ccp2);
116	int i = 0;
117
118	/* Reset the CSI1/CCP2B and wait for reset to complete */
119	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
120		    ISPCCP2_SYSCONFIG_SOFT_RESET);
121	while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
122		 ISPCCP2_SYSSTATUS_RESET_DONE)) {
123		udelay(10);
124		if (i++ > 10) {  /* try read 10 times */
125			dev_warn(isp->dev,
126				"omap3_isp: timeout waiting for ccp2 reset\n");
127			break;
128		}
129	}
130}
131
132/*
133 * ccp2_pwr_cfg - Configure the power mode settings
134 * @ccp2: pointer to ISP CCP2 device
135 */
136static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)
137{
138	struct isp_device *isp = to_isp_device(ccp2);
139
140	isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART |
141			((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ?
142			  ISPCCP2_SYSCONFIG_AUTO_IDLE : 0),
143		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG);
144}
145
146/*
147 * ccp2_if_enable - Enable CCP2 interface.
148 * @ccp2: pointer to ISP CCP2 device
149 * @enable: enable/disable flag
150 */
151static int ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
152{
153	struct isp_device *isp = to_isp_device(ccp2);
154	int ret;
155	int i;
156
157	if (enable && ccp2->vdds_csib) {
158		ret = regulator_enable(ccp2->vdds_csib);
159		if (ret < 0)
160			return ret;
161	}
162
163	/* Enable/Disable all the LCx channels */
164	for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
165		isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
166				ISPCCP2_LCx_CTRL_CHAN_EN,
167				enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);
168
169	/* Enable/Disable ccp2 interface in ccp2 mode */
170	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
171			ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
172			enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);
173
174	if (!enable && ccp2->vdds_csib)
175		regulator_disable(ccp2->vdds_csib);
176
177	return 0;
178}
179
180/*
181 * ccp2_mem_enable - Enable CCP2 memory interface.
182 * @ccp2: pointer to ISP CCP2 device
183 * @enable: enable/disable flag
184 */
185static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
186{
187	struct isp_device *isp = to_isp_device(ccp2);
188
189	if (enable)
190		ccp2_if_enable(ccp2, 0);
191
192	/* Enable/Disable ccp2 interface in ccp2 mode */
193	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
194			ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0);
195
196	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL,
197			ISPCCP2_LCM_CTRL_CHAN_EN,
198			enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0);
199}
200
201/*
202 * ccp2_phyif_config - Initialize CCP2 phy interface config
203 * @ccp2: Pointer to ISP CCP2 device
204 * @pdata: CCP2 platform data
205 *
206 * Configure the CCP2 physical interface module from platform data.
207 *
208 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
209 */
210static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
211			     const struct isp_ccp2_platform_data *pdata)
212{
213	struct isp_device *isp = to_isp_device(ccp2);
214	u32 val;
215
216	/* CCP2B mode */
217	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) |
218			    ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
219	/* Data/strobe physical layer */
220	BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
221		pdata->phy_layer);
222	BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
223		pdata->strobe_clk_pol);
224	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
225
226	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
227	if (!(val & ISPCCP2_CTRL_MODE)) {
228		if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2)
229			dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
230		if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
231			/* Strobe mode requires CCP2 */
232			return -EIO;
233	}
234
235	return 0;
236}
237
238/*
239 * ccp2_vp_config - Initialize CCP2 video port interface.
240 * @ccp2: Pointer to ISP CCP2 device
241 * @vpclk_div: Video port divisor
242 *
243 * Configure the CCP2 video port with the given clock divisor. The valid divisor
244 * values depend on the ISP revision:
245 *
246 * - revision 1.0 and 2.0	1 to 4
247 * - revision 15.0		1 to 65536
248 *
249 * The exact divisor value used might differ from the requested value, as ISP
250 * revision 15.0 represent the divisor by 65536 divided by an integer.
251 */
252static void ccp2_vp_config(struct isp_ccp2_device *ccp2,
253			   unsigned int vpclk_div)
254{
255	struct isp_device *isp = to_isp_device(ccp2);
256	u32 val;
257
258	/* ISPCCP2_CTRL Video port */
259	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
260	val |= ISPCCP2_CTRL_VP_ONLY_EN;	/* Disable the memory write port */
261
262	if (isp->revision == ISP_REVISION_15_0) {
263		vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536);
264		vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U);
265		BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT,
266			ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div);
267	} else {
268		vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 4);
269		BIT_SET(val, ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT,
270			ISPCCP2_CTRL_VP_OUT_CTRL_MASK, vpclk_div - 1);
271	}
272
273	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
274}
275
276/*
277 * ccp2_lcx_config - Initialize CCP2 logical channel interface.
278 * @ccp2: Pointer to ISP CCP2 device
279 * @config: Pointer to ISP LCx config structure.
280 *
281 * This will analyze the parameters passed by the interface config
282 * and configure CSI1/CCP2 logical channel
283 *
284 */
285static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
286			    struct isp_interface_lcx_config *config)
287{
288	struct isp_device *isp = to_isp_device(ccp2);
289	u32 val, format;
290
291	switch (config->format) {
292	case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
293		format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP;
294		break;
295	case V4L2_MBUS_FMT_SGRBG10_1X10:
296	default:
297		format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP;	/* RAW10+VP */
298		break;
299	}
300	/* ISPCCP2_LCx_CTRL logical channel #0 */
301	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0))
302			    | (ISPCCP2_LCx_CTRL_REGION_EN); /* Region */
303
304	if (isp->revision == ISP_REVISION_15_0) {
305		/* CRC */
306		BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0,
307			ISPCCP2_LCx_CTRL_CRC_MASK,
308			config->crc);
309		/* Format = RAW10+VP or RAW8+DPCM10+VP*/
310		BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0,
311			ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0, format);
312	} else {
313		BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT,
314			ISPCCP2_LCx_CTRL_CRC_MASK,
315			config->crc);
316
317		BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT,
318			ISPCCP2_LCx_CTRL_FORMAT_MASK, format);
319	}
320	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0));
321
322	/* ISPCCP2_DAT_START for logical channel #0 */
323	isp_reg_writel(isp, config->data_start << ISPCCP2_LCx_DAT_SHIFT,
324		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_START(0));
325
326	/* ISPCCP2_DAT_SIZE for logical channel #0 */
327	isp_reg_writel(isp, config->data_size << ISPCCP2_LCx_DAT_SHIFT,
328		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_SIZE(0));
329
330	/* Enable error IRQs for logical channel #0 */
331	val = ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
332	      ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
333	      ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
334	      ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
335	      ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
336	      ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
337
338	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQSTATUS);
339	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQENABLE, val);
340}
341
342/*
343 * ccp2_if_configure - Configure ccp2 with data from sensor
344 * @ccp2: Pointer to ISP CCP2 device
345 *
346 * Return 0 on success or a negative error code
347 */
348static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
349{
350	const struct isp_v4l2_subdevs_group *pdata;
351	struct v4l2_mbus_framefmt *format;
352	struct media_pad *pad;
353	struct v4l2_subdev *sensor;
354	u32 lines = 0;
355	int ret;
356
357	ccp2_pwr_cfg(ccp2);
358
359	pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
360	sensor = media_entity_to_v4l2_subdev(pad->entity);
361	pdata = sensor->host_priv;
362
363	ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
364	if (ret < 0)
365		return ret;
366
367	ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
368
369	v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
370
371	format = &ccp2->formats[CCP2_PAD_SINK];
372
373	ccp2->if_cfg.data_start = lines;
374	ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
375	ccp2->if_cfg.format = format->code;
376	ccp2->if_cfg.data_size = format->height;
377
378	ccp2_lcx_config(ccp2, &ccp2->if_cfg);
379
380	return 0;
381}
382
383static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2)
384{
385	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
386	struct isp_device *isp = to_isp_device(ccp2);
387	const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE];
388	unsigned long l3_ick = pipe->l3_ick;
389	struct v4l2_fract *timeperframe;
390	unsigned int vpclk_div = 2;
391	unsigned int value;
392	u64 bound;
393	u64 area;
394
395	/* Compute the minimum clock divisor, based on the pipeline maximum
396	 * data rate. This is an absolute lower bound if we don't want SBL
397	 * overflows, so round the value up.
398	 */
399	vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate),
400			  vpclk_div);
401
402	/* Compute the maximum clock divisor, based on the requested frame rate.
403	 * This is a soft lower bound to achieve a frame rate equal or higher
404	 * than the requested value, so round the value down.
405	 */
406	timeperframe = &pipe->max_timeperframe;
407
408	if (timeperframe->numerator) {
409		area = ofmt->width * ofmt->height;
410		bound = div_u64(area * timeperframe->denominator,
411				timeperframe->numerator);
412		value = min_t(u64, bound, l3_ick);
413		vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div);
414	}
415
416	dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__,
417		vpclk_div);
418
419	return vpclk_div;
420}
421
422/*
423 * ccp2_mem_configure - Initialize CCP2 memory input/output interface
424 * @ccp2: Pointer to ISP CCP2 device
425 * @config: Pointer to ISP mem interface config structure
426 *
427 * This will analyze the parameters passed by the interface config
428 * structure, and configure the respective registers for proper
429 * CSI1/CCP2 memory input.
430 */
431static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,
432			       struct isp_interface_mem_config *config)
433{
434	struct isp_device *isp = to_isp_device(ccp2);
435	u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code;
436	u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code;
437	unsigned int dpcm_decompress = 0;
438	u32 val, hwords;
439
440	if (sink_pixcode != source_pixcode &&
441	    sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
442		dpcm_decompress = 1;
443
444	ccp2_pwr_cfg(ccp2);
445
446	/* Hsize, Skip */
447	isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN |
448		       (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT),
449		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE);
450
451	/* Vsize, no. of lines */
452	isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT,
453		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE);
454
455	if (ccp2->video_in.bpl_padding == 0)
456		config->src_ofst = 0;
457	else
458		config->src_ofst = ccp2->video_in.bpl_value;
459
460	isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2,
461		       ISPCCP2_LCM_SRC_OFST);
462
463	/* Source and Destination formats */
464	val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 <<
465	      ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT;
466
467	if (dpcm_decompress) {
468		/* source format is RAW8 */
469		val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 <<
470		       ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
471
472		/* RAW8 + DPCM10 - simple predictor */
473		val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED;
474
475		/* enable source DPCM decompression */
476		val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 <<
477		       ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT;
478	} else {
479		/* source format is RAW10 */
480		val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 <<
481		       ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
482	}
483
484	/* Burst size to 32x64 */
485	val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X <<
486	       ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT;
487
488	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL);
489
490	/* Prefetch setup */
491	if (dpcm_decompress)
492		hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
493			  config->hsize_count) >> 3;
494	else
495		hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
496			  config->hsize_count) >> 2;
497
498	isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT,
499		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH);
500
501	/* Video port */
502	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
503		    ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE);
504	ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2));
505
506	/* Clear LCM interrupts */
507	isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ |
508		       ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,
509		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);
510
511	/* Enable LCM interrupts */
512	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,
513		    ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |
514		    ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);
515}
516
517/*
518 * ccp2_set_inaddr - Sets memory address of input frame.
519 * @ccp2: Pointer to ISP CCP2 device
520 * @addr: 32bit memory address aligned on 32byte boundary.
521 *
522 * Configures the memory address from which the input frame is to be read.
523 */
524static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr)
525{
526	struct isp_device *isp = to_isp_device(ccp2);
527
528	isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR);
529}
530
531/* -----------------------------------------------------------------------------
532 * Interrupt handling
533 */
534
535static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2)
536{
537	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
538	struct isp_buffer *buffer;
539
540	buffer = omap3isp_video_buffer_next(&ccp2->video_in);
541	if (buffer != NULL)
542		ccp2_set_inaddr(ccp2, buffer->dma);
543
544	pipe->state |= ISP_PIPELINE_IDLE_INPUT;
545
546	if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
547		if (isp_pipeline_ready(pipe))
548			omap3isp_pipeline_set_stream(pipe,
549						ISP_PIPELINE_STREAM_SINGLESHOT);
550	}
551}
552
553/*
554 * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts
555 * @ccp2: Pointer to ISP CCP2 device
556 *
557 * This will handle the CCP2 interrupts
558 */
559void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
560{
561	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
562	struct isp_device *isp = to_isp_device(ccp2);
563	static const u32 ISPCCP2_LC01_ERROR =
564		ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
565		ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
566		ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
567		ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
568		ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
569		ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
570	u32 lcx_irqstatus, lcm_irqstatus;
571
572	/* First clear the interrupts */
573	lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
574				      ISPCCP2_LC01_IRQSTATUS);
575	isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2,
576		       ISPCCP2_LC01_IRQSTATUS);
577
578	lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
579				      ISPCCP2_LCM_IRQSTATUS);
580	isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2,
581		       ISPCCP2_LCM_IRQSTATUS);
582	/* Errors */
583	if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {
584		pipe->error = true;
585		dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);
586		return;
587	}
588
589	if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {
590		pipe->error = true;
591		dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);
592	}
593
594	if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
595		return;
596
597	/* Handle queued buffers on frame end interrupts */
598	if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
599		ccp2_isr_buffer(ccp2);
600}
601
602/* -----------------------------------------------------------------------------
603 * V4L2 subdev operations
604 */
605
606static const unsigned int ccp2_fmts[] = {
607	V4L2_MBUS_FMT_SGRBG10_1X10,
608	V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
609};
610
611/*
612 * __ccp2_get_format - helper function for getting ccp2 format
613 * @ccp2  : Pointer to ISP CCP2 device
614 * @fh    : V4L2 subdev file handle
615 * @pad   : pad number
616 * @which : wanted subdev format
617 * return format structure or NULL on error
618 */
619static struct v4l2_mbus_framefmt *
620__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh,
621		     unsigned int pad, enum v4l2_subdev_format_whence which)
622{
623	if (which == V4L2_SUBDEV_FORMAT_TRY)
624		return v4l2_subdev_get_try_format(fh, pad);
625	else
626		return &ccp2->formats[pad];
627}
628
629/*
630 * ccp2_try_format - Handle try format by pad subdev method
631 * @ccp2  : Pointer to ISP CCP2 device
632 * @fh    : V4L2 subdev file handle
633 * @pad   : pad num
634 * @fmt   : pointer to v4l2 mbus format structure
635 * @which : wanted subdev format
636 */
637static void ccp2_try_format(struct isp_ccp2_device *ccp2,
638			       struct v4l2_subdev_fh *fh, unsigned int pad,
639			       struct v4l2_mbus_framefmt *fmt,
640			       enum v4l2_subdev_format_whence which)
641{
642	struct v4l2_mbus_framefmt *format;
643
644	switch (pad) {
645	case CCP2_PAD_SINK:
646		if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
647			fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
648
649		if (ccp2->input == CCP2_INPUT_SENSOR) {
650			fmt->width = clamp_t(u32, fmt->width,
651					     ISPCCP2_DAT_START_MIN,
652					     ISPCCP2_DAT_START_MAX);
653			fmt->height = clamp_t(u32, fmt->height,
654					      ISPCCP2_DAT_SIZE_MIN,
655					      ISPCCP2_DAT_SIZE_MAX);
656		} else if (ccp2->input == CCP2_INPUT_MEMORY) {
657			fmt->width = clamp_t(u32, fmt->width,
658					     ISPCCP2_LCM_HSIZE_COUNT_MIN,
659					     ISPCCP2_LCM_HSIZE_COUNT_MAX);
660			fmt->height = clamp_t(u32, fmt->height,
661					      ISPCCP2_LCM_VSIZE_MIN,
662					      ISPCCP2_LCM_VSIZE_MAX);
663		}
664		break;
665
666	case CCP2_PAD_SOURCE:
667		/* Source format - copy sink format and change pixel code
668		 * to SGRBG10_1X10 as we don't support CCP2 write to memory.
669		 * When CCP2 write to memory feature will be added this
670		 * should be changed properly.
671		 */
672		format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which);
673		memcpy(fmt, format, sizeof(*fmt));
674		fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
675		break;
676	}
677
678	fmt->field = V4L2_FIELD_NONE;
679	fmt->colorspace = V4L2_COLORSPACE_SRGB;
680}
681
682/*
683 * ccp2_enum_mbus_code - Handle pixel format enumeration
684 * @sd     : pointer to v4l2 subdev structure
685 * @fh     : V4L2 subdev file handle
686 * @code   : pointer to v4l2_subdev_mbus_code_enum structure
687 * return -EINVAL or zero on success
688 */
689static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
690				  struct v4l2_subdev_fh *fh,
691				  struct v4l2_subdev_mbus_code_enum *code)
692{
693	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
694	struct v4l2_mbus_framefmt *format;
695
696	if (code->pad == CCP2_PAD_SINK) {
697		if (code->index >= ARRAY_SIZE(ccp2_fmts))
698			return -EINVAL;
699
700		code->code = ccp2_fmts[code->index];
701	} else {
702		if (code->index != 0)
703			return -EINVAL;
704
705		format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK,
706					      V4L2_SUBDEV_FORMAT_TRY);
707		code->code = format->code;
708	}
709
710	return 0;
711}
712
713static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
714				   struct v4l2_subdev_fh *fh,
715				   struct v4l2_subdev_frame_size_enum *fse)
716{
717	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
718	struct v4l2_mbus_framefmt format;
719
720	if (fse->index != 0)
721		return -EINVAL;
722
723	format.code = fse->code;
724	format.width = 1;
725	format.height = 1;
726	ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
727	fse->min_width = format.width;
728	fse->min_height = format.height;
729
730	if (format.code != fse->code)
731		return -EINVAL;
732
733	format.code = fse->code;
734	format.width = -1;
735	format.height = -1;
736	ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
737	fse->max_width = format.width;
738	fse->max_height = format.height;
739
740	return 0;
741}
742
743/*
744 * ccp2_get_format - Handle get format by pads subdev method
745 * @sd    : pointer to v4l2 subdev structure
746 * @fh    : V4L2 subdev file handle
747 * @fmt   : pointer to v4l2 subdev format structure
748 * return -EINVAL or zero on success
749 */
750static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
751			      struct v4l2_subdev_format *fmt)
752{
753	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
754	struct v4l2_mbus_framefmt *format;
755
756	format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
757	if (format == NULL)
758		return -EINVAL;
759
760	fmt->format = *format;
761	return 0;
762}
763
764/*
765 * ccp2_set_format - Handle set format by pads subdev method
766 * @sd    : pointer to v4l2 subdev structure
767 * @fh    : V4L2 subdev file handle
768 * @fmt   : pointer to v4l2 subdev format structure
769 * returns zero
770 */
771static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
772			      struct v4l2_subdev_format *fmt)
773{
774	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
775	struct v4l2_mbus_framefmt *format;
776
777	format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
778	if (format == NULL)
779		return -EINVAL;
780
781	ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which);
782	*format = fmt->format;
783
784	/* Propagate the format from sink to source */
785	if (fmt->pad == CCP2_PAD_SINK) {
786		format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE,
787					   fmt->which);
788		*format = fmt->format;
789		ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which);
790	}
791
792	return 0;
793}
794
795/*
796 * ccp2_init_formats - Initialize formats on all pads
797 * @sd: ISP CCP2 V4L2 subdevice
798 * @fh: V4L2 subdev file handle
799 *
800 * Initialize all pad formats with default values. If fh is not NULL, try
801 * formats are initialized on the file handle. Otherwise active formats are
802 * initialized on the device.
803 */
804static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
805{
806	struct v4l2_subdev_format format;
807
808	memset(&format, 0, sizeof(format));
809	format.pad = CCP2_PAD_SINK;
810	format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
811	format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
812	format.format.width = 4096;
813	format.format.height = 4096;
814	ccp2_set_format(sd, fh, &format);
815
816	return 0;
817}
818
819/*
820 * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev
821 * @sd    : pointer to v4l2 subdev structure
822 * @enable: 1 == Enable, 0 == Disable
823 * return zero
824 */
825static int ccp2_s_stream(struct v4l2_subdev *sd, int enable)
826{
827	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
828	struct isp_device *isp = to_isp_device(ccp2);
829	struct device *dev = to_device(ccp2);
830	int ret;
831
832	if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) {
833		if (enable == ISP_PIPELINE_STREAM_STOPPED)
834			return 0;
835		atomic_set(&ccp2->stopping, 0);
836	}
837
838	switch (enable) {
839	case ISP_PIPELINE_STREAM_CONTINUOUS:
840		if (ccp2->phy) {
841			ret = omap3isp_csiphy_acquire(ccp2->phy);
842			if (ret < 0)
843				return ret;
844		}
845
846		ccp2_if_configure(ccp2);
847		ccp2_print_status(ccp2);
848
849		/* Enable CSI1/CCP2 interface */
850		ret = ccp2_if_enable(ccp2, 1);
851		if (ret < 0) {
852			if (ccp2->phy)
853				omap3isp_csiphy_release(ccp2->phy);
854			return ret;
855		}
856		break;
857
858	case ISP_PIPELINE_STREAM_SINGLESHOT:
859		if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) {
860			struct v4l2_mbus_framefmt *format;
861
862			format = &ccp2->formats[CCP2_PAD_SINK];
863
864			ccp2->mem_cfg.hsize_count = format->width;
865			ccp2->mem_cfg.vsize_count = format->height;
866			ccp2->mem_cfg.src_ofst = 0;
867
868			ccp2_mem_configure(ccp2, &ccp2->mem_cfg);
869			omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ);
870			ccp2_print_status(ccp2);
871		}
872		ccp2_mem_enable(ccp2, 1);
873		break;
874
875	case ISP_PIPELINE_STREAM_STOPPED:
876		if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait,
877					      &ccp2->stopping))
878			dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
879		if (ccp2->input == CCP2_INPUT_MEMORY) {
880			ccp2_mem_enable(ccp2, 0);
881			omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ);
882		} else if (ccp2->input == CCP2_INPUT_SENSOR) {
883			/* Disable CSI1/CCP2 interface */
884			ccp2_if_enable(ccp2, 0);
885			if (ccp2->phy)
886				omap3isp_csiphy_release(ccp2->phy);
887		}
888		break;
889	}
890
891	ccp2->state = enable;
892	return 0;
893}
894
895/* subdev video operations */
896static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = {
897	.s_stream = ccp2_s_stream,
898};
899
900/* subdev pad operations */
901static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = {
902	.enum_mbus_code = ccp2_enum_mbus_code,
903	.enum_frame_size = ccp2_enum_frame_size,
904	.get_fmt = ccp2_get_format,
905	.set_fmt = ccp2_set_format,
906};
907
908/* subdev operations */
909static const struct v4l2_subdev_ops ccp2_sd_ops = {
910	.video = &ccp2_sd_video_ops,
911	.pad = &ccp2_sd_pad_ops,
912};
913
914/* subdev internal operations */
915static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = {
916	.open = ccp2_init_formats,
917};
918
919/* --------------------------------------------------------------------------
920 * ISP ccp2 video device node
921 */
922
923/*
924 * ccp2_video_queue - Queue video buffer.
925 * @video : Pointer to isp video structure
926 * @buffer: Pointer to isp_buffer structure
927 * return -EIO or zero on success
928 */
929static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer)
930{
931	struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2;
932
933	ccp2_set_inaddr(ccp2, buffer->dma);
934	return 0;
935}
936
937static const struct isp_video_operations ccp2_video_ops = {
938	.queue = ccp2_video_queue,
939};
940
941/* -----------------------------------------------------------------------------
942 * Media entity operations
943 */
944
945/*
946 * ccp2_link_setup - Setup ccp2 connections.
947 * @entity : Pointer to media entity structure
948 * @local  : Pointer to local pad array
949 * @remote : Pointer to remote pad array
950 * @flags  : Link flags
951 * return -EINVAL on error or zero on success
952 */
953static int ccp2_link_setup(struct media_entity *entity,
954			   const struct media_pad *local,
955			   const struct media_pad *remote, u32 flags)
956{
957	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
958	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
959
960	switch (local->index | media_entity_type(remote->entity)) {
961	case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE:
962		/* read from memory */
963		if (flags & MEDIA_LNK_FL_ENABLED) {
964			if (ccp2->input == CCP2_INPUT_SENSOR)
965				return -EBUSY;
966			ccp2->input = CCP2_INPUT_MEMORY;
967		} else {
968			if (ccp2->input == CCP2_INPUT_MEMORY)
969				ccp2->input = CCP2_INPUT_NONE;
970		}
971		break;
972
973	case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
974		/* read from sensor/phy */
975		if (flags & MEDIA_LNK_FL_ENABLED) {
976			if (ccp2->input == CCP2_INPUT_MEMORY)
977				return -EBUSY;
978			ccp2->input = CCP2_INPUT_SENSOR;
979		} else {
980			if (ccp2->input == CCP2_INPUT_SENSOR)
981				ccp2->input = CCP2_INPUT_NONE;
982		} break;
983
984	case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
985		/* write to video port/ccdc */
986		if (flags & MEDIA_LNK_FL_ENABLED)
987			ccp2->output = CCP2_OUTPUT_CCDC;
988		else
989			ccp2->output = CCP2_OUTPUT_NONE;
990		break;
991
992	default:
993		return -EINVAL;
994	}
995
996	return 0;
997}
998
999/* media operations */
1000static const struct media_entity_operations ccp2_media_ops = {
1001	.link_setup = ccp2_link_setup,
1002	.link_validate = v4l2_subdev_link_validate,
1003};
1004
1005/*
1006 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
1007 * @ccp2: Pointer to ISP CCP2 device
1008 */
1009void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1010{
1011	v4l2_device_unregister_subdev(&ccp2->subdev);
1012	omap3isp_video_unregister(&ccp2->video_in);
1013}
1014
1015/*
1016 * omap3isp_ccp2_register_entities - Register the subdev media entity
1017 * @ccp2: Pointer to ISP CCP2 device
1018 * @vdev: Pointer to v4l device
1019 * return negative error code or zero on success
1020 */
1021
1022int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1023				    struct v4l2_device *vdev)
1024{
1025	int ret;
1026
1027	/* Register the subdev and video nodes. */
1028	ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1029	if (ret < 0)
1030		goto error;
1031
1032	ret = omap3isp_video_register(&ccp2->video_in, vdev);
1033	if (ret < 0)
1034		goto error;
1035
1036	return 0;
1037
1038error:
1039	omap3isp_ccp2_unregister_entities(ccp2);
1040	return ret;
1041}
1042
1043/* -----------------------------------------------------------------------------
1044 * ISP ccp2 initialisation and cleanup
1045 */
1046
1047/*
1048 * ccp2_init_entities - Initialize ccp2 subdev and media entity.
1049 * @ccp2: Pointer to ISP CCP2 device
1050 * return negative error code or zero on success
1051 */
1052static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1053{
1054	struct v4l2_subdev *sd = &ccp2->subdev;
1055	struct media_pad *pads = ccp2->pads;
1056	struct media_entity *me = &sd->entity;
1057	int ret;
1058
1059	ccp2->input = CCP2_INPUT_NONE;
1060	ccp2->output = CCP2_OUTPUT_NONE;
1061
1062	v4l2_subdev_init(sd, &ccp2_sd_ops);
1063	sd->internal_ops = &ccp2_sd_internal_ops;
1064	strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
1065	sd->grp_id = 1 << 16;   /* group ID for isp subdevs */
1066	v4l2_set_subdevdata(sd, ccp2);
1067	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1068
1069	pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
1070				    | MEDIA_PAD_FL_MUST_CONNECT;
1071	pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1072
1073	me->ops = &ccp2_media_ops;
1074	ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
1075	if (ret < 0)
1076		return ret;
1077
1078	ccp2_init_formats(sd, NULL);
1079
1080	/*
1081	 * The CCP2 has weird line alignment requirements, possibly caused by
1082	 * DPCM8 decompression. Line length for data read from memory must be a
1083	 * multiple of 128 bits (16 bytes) in continuous mode (when no padding
1084	 * is present at end of lines). Additionally, if padding is used, the
1085	 * padded line length must be a multiple of 32 bytes. To simplify the
1086	 * implementation we use a fixed 32 bytes alignment regardless of the
1087	 * input format and width. If strict 128 bits alignment support is
1088	 * required ispvideo will need to be made aware of this special dual
1089	 * alignment requirements.
1090	 */
1091	ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1092	ccp2->video_in.bpl_alignment = 32;
1093	ccp2->video_in.bpl_max = 0xffffffe0;
1094	ccp2->video_in.isp = to_isp_device(ccp2);
1095	ccp2->video_in.ops = &ccp2_video_ops;
1096	ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1097
1098	ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1099	if (ret < 0)
1100		goto error_video;
1101
1102	/* Connect the video node to the ccp2 subdev. */
1103	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1104				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1105	if (ret < 0)
1106		goto error_link;
1107
1108	return 0;
1109
1110error_link:
1111	omap3isp_video_cleanup(&ccp2->video_in);
1112error_video:
1113	media_entity_cleanup(&ccp2->subdev.entity);
1114	return ret;
1115}
1116
1117/*
1118 * omap3isp_ccp2_init - CCP2 initialization.
1119 * @isp : Pointer to ISP device
1120 * return negative error code or zero on success
1121 */
1122int omap3isp_ccp2_init(struct isp_device *isp)
1123{
1124	struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1125	int ret;
1126
1127	init_waitqueue_head(&ccp2->wait);
1128
1129	/*
1130	 * On the OMAP34xx the CSI1 receiver is operated in the CSIb IO
1131	 * complex, which is powered by vdds_csib power rail. Hence the
1132	 * request for the regulator.
1133	 *
1134	 * On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with
1135	 * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly
1136	 * configured.
1137	 *
1138	 * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c).
1139	 */
1140	if (isp->revision == ISP_REVISION_2_0) {
1141		ccp2->vdds_csib = devm_regulator_get(isp->dev, "vdds_csib");
1142		if (IS_ERR(ccp2->vdds_csib)) {
1143			dev_dbg(isp->dev,
1144				"Could not get regulator vdds_csib\n");
1145			ccp2->vdds_csib = NULL;
1146		}
1147	} else if (isp->revision == ISP_REVISION_15_0) {
1148		ccp2->phy = &isp->isp_csiphy1;
1149	}
1150
1151	ret = ccp2_init_entities(ccp2);
1152	if (ret < 0)
1153		return ret;
1154
1155	ccp2_reset(ccp2);
1156	return 0;
1157}
1158
1159/*
1160 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1161 * @isp : Pointer to ISP device
1162 */
1163void omap3isp_ccp2_cleanup(struct isp_device *isp)
1164{
1165	struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1166
1167	omap3isp_video_cleanup(&ccp2->video_in);
1168	media_entity_cleanup(&ccp2->subdev.entity);
1169}
1170