brintos

brintos / linux-shallow public Read only

0
0
Text · 33.6 KiB · 1204ee2 Raw
1183 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * ispccp2.c4 *5 * TI OMAP3 ISP - CCP2 module6 *7 * Copyright (C) 2010 Nokia Corporation8 * Copyright (C) 2010 Texas Instruments, Inc.9 *10 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>11 *	     Sakari Ailus <sakari.ailus@iki.fi>12 */13 14#include <linux/delay.h>15#include <linux/device.h>16#include <linux/mm.h>17#include <linux/module.h>18#include <linux/mutex.h>19#include <linux/uaccess.h>20#include <linux/regulator/consumer.h>21 22#include "isp.h"23#include "ispreg.h"24#include "ispccp2.h"25 26/* Number of LCX channels */27#define CCP2_LCx_CHANS_NUM			328/* Max/Min size for CCP2 video port */29#define ISPCCP2_DAT_START_MIN			030#define ISPCCP2_DAT_START_MAX			409531#define ISPCCP2_DAT_SIZE_MIN			032#define ISPCCP2_DAT_SIZE_MAX			409533#define ISPCCP2_VPCLK_FRACDIV			6553634#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP	0x1235#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP	0x1636/* Max/Min size for CCP2 memory channel */37#define ISPCCP2_LCM_HSIZE_COUNT_MIN		1638#define ISPCCP2_LCM_HSIZE_COUNT_MAX		819139#define ISPCCP2_LCM_HSIZE_SKIP_MIN		040#define ISPCCP2_LCM_HSIZE_SKIP_MAX		819141#define ISPCCP2_LCM_VSIZE_MIN			142#define ISPCCP2_LCM_VSIZE_MAX			819143#define ISPCCP2_LCM_HWORDS_MIN			144#define ISPCCP2_LCM_HWORDS_MAX			409545#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X		546#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL	047#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10	248#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8	249#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10	350#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10	351#define ISPCCP2_LCM_CTRL_DST_PORT_VP		052#define ISPCCP2_LCM_CTRL_DST_PORT_MEM		153 54/* Set only the required bits */55#define BIT_SET(var, shift, mask, val)			\56	do {						\57		var = ((var) & ~((mask) << (shift)))	\58			| ((val) << (shift));		\59	} while (0)60 61/*62 * ccp2_print_status - Print current CCP2 module register values.63 */64#define CCP2_PRINT_REGISTER(isp, name)\65	dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \66		isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name))67 68static void ccp2_print_status(struct isp_ccp2_device *ccp2)69{70	struct isp_device *isp = to_isp_device(ccp2);71 72	dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n");73 74	CCP2_PRINT_REGISTER(isp, SYSCONFIG);75	CCP2_PRINT_REGISTER(isp, SYSSTATUS);76	CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE);77	CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS);78	CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE);79	CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS);80	CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE);81	CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS);82	CCP2_PRINT_REGISTER(isp, CTRL);83	CCP2_PRINT_REGISTER(isp, LCx_CTRL(0));84	CCP2_PRINT_REGISTER(isp, LCx_CODE(0));85	CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0));86	CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0));87	CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0));88	CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0));89	CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0));90	CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0));91	CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0));92	CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0));93	CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0));94	CCP2_PRINT_REGISTER(isp, LCM_CTRL);95	CCP2_PRINT_REGISTER(isp, LCM_VSIZE);96	CCP2_PRINT_REGISTER(isp, LCM_HSIZE);97	CCP2_PRINT_REGISTER(isp, LCM_PREFETCH);98	CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR);99	CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST);100	CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR);101	CCP2_PRINT_REGISTER(isp, LCM_DST_OFST);102 103	dev_dbg(isp->dev, "--------------------------------------------\n");104}105 106/*107 * ccp2_reset - Reset the CCP2108 * @ccp2: pointer to ISP CCP2 device109 */110static void ccp2_reset(struct isp_ccp2_device *ccp2)111{112	struct isp_device *isp = to_isp_device(ccp2);113	int i = 0;114 115	/* Reset the CSI1/CCP2B and wait for reset to complete */116	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,117		    ISPCCP2_SYSCONFIG_SOFT_RESET);118	while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &119		 ISPCCP2_SYSSTATUS_RESET_DONE)) {120		udelay(10);121		if (i++ > 10) {  /* try read 10 times */122			dev_warn(isp->dev,123				"omap3_isp: timeout waiting for ccp2 reset\n");124			break;125		}126	}127}128 129/*130 * ccp2_pwr_cfg - Configure the power mode settings131 * @ccp2: pointer to ISP CCP2 device132 */133static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)134{135	struct isp_device *isp = to_isp_device(ccp2);136 137	isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART |138			((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ?139			  ISPCCP2_SYSCONFIG_AUTO_IDLE : 0),140		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG);141}142 143/*144 * ccp2_if_enable - Enable CCP2 interface.145 * @ccp2: pointer to ISP CCP2 device146 * @enable: enable/disable flag147 */148static int ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)149{150	struct isp_device *isp = to_isp_device(ccp2);151	int ret;152	int i;153 154	if (enable && ccp2->vdds_csib) {155		ret = regulator_enable(ccp2->vdds_csib);156		if (ret < 0)157			return ret;158	}159 160	/* Enable/Disable all the LCx channels */161	for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)162		isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),163				ISPCCP2_LCx_CTRL_CHAN_EN,164				enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);165 166	/* Enable/Disable ccp2 interface in ccp2 mode */167	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,168			ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,169			enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);170 171	if (!enable && ccp2->vdds_csib)172		regulator_disable(ccp2->vdds_csib);173 174	return 0;175}176 177/*178 * ccp2_mem_enable - Enable CCP2 memory interface.179 * @ccp2: pointer to ISP CCP2 device180 * @enable: enable/disable flag181 */182static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)183{184	struct isp_device *isp = to_isp_device(ccp2);185 186	if (enable)187		ccp2_if_enable(ccp2, 0);188 189	/* Enable/Disable ccp2 interface in ccp2 mode */190	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,191			ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0);192 193	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL,194			ISPCCP2_LCM_CTRL_CHAN_EN,195			enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0);196}197 198/*199 * ccp2_phyif_config - Initialize CCP2 phy interface config200 * @ccp2: Pointer to ISP CCP2 device201 * @buscfg: CCP2 platform data202 *203 * Configure the CCP2 physical interface module from platform data.204 *205 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.206 */207static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,208			     const struct isp_ccp2_cfg *buscfg)209{210	struct isp_device *isp = to_isp_device(ccp2);211	u32 val;212 213	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) |214			    ISPCCP2_CTRL_MODE;215	/* Data/strobe physical layer */216	BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,217		buscfg->phy_layer);218	BIT_SET(val, ISPCCP2_CTRL_IO_OUT_SEL_SHIFT,219		ISPCCP2_CTRL_IO_OUT_SEL_MASK, buscfg->ccp2_mode);220	BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,221		buscfg->strobe_clk_pol);222	BIT_SET(val, ISPCCP2_CTRL_VP_CLK_POL_SHIFT,223		ISPCCP2_CTRL_VP_CLK_POL_MASK, buscfg->vp_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 (buscfg->ccp2_mode == ISP_CCP2_MODE_CCP2)229			dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");230		if (buscfg->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 device241 * @vpclk_div: Video port divisor242 *243 * Configure the CCP2 video port with the given clock divisor. The valid divisor244 * values depend on the ISP revision:245 *246 * - revision 1.0 and 2.0	1 to 4247 * - revision 15.0		1 to 65536248 *249 * The exact divisor value used might differ from the requested value, as ISP250 * 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 device279 * @config: Pointer to ISP LCx config structure.280 *281 * This will analyze the parameters passed by the interface config282 * and configure CSI1/CCP2 logical channel283 *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 MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:293		format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP;294		break;295	case MEDIA_BUS_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 sensor344 * @ccp2: Pointer to ISP CCP2 device345 *346 * Return 0 on success or a negative error code347 */348static int ccp2_if_configure(struct isp_ccp2_device *ccp2)349{350	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);351	const struct isp_bus_cfg *buscfg;352	struct v4l2_mbus_framefmt *format;353	struct media_pad *pad;354	struct v4l2_subdev *sensor;355	u32 lines = 0;356	int ret;357 358	ccp2_pwr_cfg(ccp2);359 360	pad = media_pad_remote_pad_first(&ccp2->pads[CCP2_PAD_SINK]);361	sensor = media_entity_to_v4l2_subdev(pad->entity);362	buscfg = v4l2_subdev_to_bus_cfg(pipe->external);363	if (WARN_ON(!buscfg))364		return -EPIPE;365 366	ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2);367	if (ret < 0)368		return ret;369 370	ccp2_vp_config(ccp2, buscfg->bus.ccp2.vpclk_div + 1);371 372	v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);373 374	format = &ccp2->formats[CCP2_PAD_SINK];375 376	ccp2->if_cfg.data_start = lines;377	ccp2->if_cfg.crc = buscfg->bus.ccp2.crc;378	ccp2->if_cfg.format = format->code;379	ccp2->if_cfg.data_size = format->height;380 381	ccp2_lcx_config(ccp2, &ccp2->if_cfg);382 383	return 0;384}385 386static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2)387{388	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);389	struct isp_device *isp = to_isp_device(ccp2);390	const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE];391	unsigned long l3_ick = pipe->l3_ick;392	struct v4l2_fract *timeperframe;393	unsigned int vpclk_div = 2;394	unsigned int value;395	u64 bound;396	u64 area;397 398	/* Compute the minimum clock divisor, based on the pipeline maximum399	 * data rate. This is an absolute lower bound if we don't want SBL400	 * overflows, so round the value up.401	 */402	vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate),403			  vpclk_div);404 405	/* Compute the maximum clock divisor, based on the requested frame rate.406	 * This is a soft lower bound to achieve a frame rate equal or higher407	 * than the requested value, so round the value down.408	 */409	timeperframe = &pipe->max_timeperframe;410 411	if (timeperframe->numerator) {412		area = ofmt->width * ofmt->height;413		bound = div_u64(area * timeperframe->denominator,414				timeperframe->numerator);415		value = min_t(u64, bound, l3_ick);416		vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div);417	}418 419	dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__,420		vpclk_div);421 422	return vpclk_div;423}424 425/*426 * ccp2_mem_configure - Initialize CCP2 memory input/output interface427 * @ccp2: Pointer to ISP CCP2 device428 * @config: Pointer to ISP mem interface config structure429 *430 * This will analyze the parameters passed by the interface config431 * structure, and configure the respective registers for proper432 * CSI1/CCP2 memory input.433 */434static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,435			       struct isp_interface_mem_config *config)436{437	struct isp_device *isp = to_isp_device(ccp2);438	u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code;439	u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code;440	unsigned int dpcm_decompress = 0;441	u32 val, hwords;442 443	if (sink_pixcode != source_pixcode &&444	    sink_pixcode == MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8)445		dpcm_decompress = 1;446 447	ccp2_pwr_cfg(ccp2);448 449	/* Hsize, Skip */450	isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN |451		       (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT),452		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE);453 454	/* Vsize, no. of lines */455	isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT,456		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE);457 458	if (ccp2->video_in.bpl_padding == 0)459		config->src_ofst = 0;460	else461		config->src_ofst = ccp2->video_in.bpl_value;462 463	isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2,464		       ISPCCP2_LCM_SRC_OFST);465 466	/* Source and Destination formats */467	val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 <<468	      ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT;469 470	if (dpcm_decompress) {471		/* source format is RAW8 */472		val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 <<473		       ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;474 475		/* RAW8 + DPCM10 - simple predictor */476		val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED;477 478		/* enable source DPCM decompression */479		val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 <<480		       ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT;481	} else {482		/* source format is RAW10 */483		val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 <<484		       ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;485	}486 487	/* Burst size to 32x64 */488	val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X <<489	       ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT;490 491	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL);492 493	/* Prefetch setup */494	if (dpcm_decompress)495		hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +496			  config->hsize_count) >> 3;497	else498		hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +499			  config->hsize_count) >> 2;500 501	isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT,502		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH);503 504	/* Video port */505	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,506		    ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE);507	ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2));508 509	/* Clear LCM interrupts */510	isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ |511		       ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,512		       OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);513 514	/* Enable LCM interrupts */515	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,516		    ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |517		    ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);518}519 520/*521 * ccp2_set_inaddr - Sets memory address of input frame.522 * @ccp2: Pointer to ISP CCP2 device523 * @addr: 32bit memory address aligned on 32byte boundary.524 *525 * Configures the memory address from which the input frame is to be read.526 */527static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr)528{529	struct isp_device *isp = to_isp_device(ccp2);530 531	isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR);532}533 534/* -----------------------------------------------------------------------------535 * Interrupt handling536 */537 538static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2)539{540	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);541	struct isp_buffer *buffer;542 543	buffer = omap3isp_video_buffer_next(&ccp2->video_in);544	if (buffer != NULL)545		ccp2_set_inaddr(ccp2, buffer->dma);546 547	pipe->state |= ISP_PIPELINE_IDLE_INPUT;548 549	if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) {550		if (isp_pipeline_ready(pipe))551			omap3isp_pipeline_set_stream(pipe,552						ISP_PIPELINE_STREAM_SINGLESHOT);553	}554}555 556/*557 * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts558 * @ccp2: Pointer to ISP CCP2 device559 *560 * This will handle the CCP2 interrupts561 */562void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)563{564	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);565	struct isp_device *isp = to_isp_device(ccp2);566	static const u32 ISPCCP2_LC01_ERROR =567		ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |568		ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |569		ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |570		ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |571		ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |572		ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;573	u32 lcx_irqstatus, lcm_irqstatus;574 575	/* First clear the interrupts */576	lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,577				      ISPCCP2_LC01_IRQSTATUS);578	isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2,579		       ISPCCP2_LC01_IRQSTATUS);580 581	lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,582				      ISPCCP2_LCM_IRQSTATUS);583	isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2,584		       ISPCCP2_LCM_IRQSTATUS);585	/* Errors */586	if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {587		pipe->error = true;588		dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);589		return;590	}591 592	if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {593		pipe->error = true;594		dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);595	}596 597	if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))598		return;599 600	/* Handle queued buffers on frame end interrupts */601	if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)602		ccp2_isr_buffer(ccp2);603}604 605/* -----------------------------------------------------------------------------606 * V4L2 subdev operations607 */608 609static const unsigned int ccp2_fmts[] = {610	MEDIA_BUS_FMT_SGRBG10_1X10,611	MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,612};613 614/*615 * __ccp2_get_format - helper function for getting ccp2 format616 * @ccp2  : Pointer to ISP CCP2 device617 * @sd_state: V4L2 subdev state618 * @pad   : pad number619 * @which : wanted subdev format620 * return format structure or NULL on error621 */622static struct v4l2_mbus_framefmt *623__ccp2_get_format(struct isp_ccp2_device *ccp2,624		  struct v4l2_subdev_state *sd_state,625		  unsigned int pad, enum v4l2_subdev_format_whence which)626{627	if (which == V4L2_SUBDEV_FORMAT_TRY)628		return v4l2_subdev_state_get_format(sd_state, pad);629	else630		return &ccp2->formats[pad];631}632 633/*634 * ccp2_try_format - Handle try format by pad subdev method635 * @ccp2  : Pointer to ISP CCP2 device636 * @sd_state: V4L2 subdev state637 * @pad   : pad num638 * @fmt   : pointer to v4l2 mbus format structure639 * @which : wanted subdev format640 */641static void ccp2_try_format(struct isp_ccp2_device *ccp2,642			       struct v4l2_subdev_state *sd_state,643			       unsigned int pad,644			       struct v4l2_mbus_framefmt *fmt,645			       enum v4l2_subdev_format_whence which)646{647	struct v4l2_mbus_framefmt *format;648 649	switch (pad) {650	case CCP2_PAD_SINK:651		if (fmt->code != MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8)652			fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;653 654		if (ccp2->input == CCP2_INPUT_SENSOR) {655			fmt->width = clamp_t(u32, fmt->width,656					     ISPCCP2_DAT_START_MIN,657					     ISPCCP2_DAT_START_MAX);658			fmt->height = clamp_t(u32, fmt->height,659					      ISPCCP2_DAT_SIZE_MIN,660					      ISPCCP2_DAT_SIZE_MAX);661		} else if (ccp2->input == CCP2_INPUT_MEMORY) {662			fmt->width = clamp_t(u32, fmt->width,663					     ISPCCP2_LCM_HSIZE_COUNT_MIN,664					     ISPCCP2_LCM_HSIZE_COUNT_MAX);665			fmt->height = clamp_t(u32, fmt->height,666					      ISPCCP2_LCM_VSIZE_MIN,667					      ISPCCP2_LCM_VSIZE_MAX);668		}669		break;670 671	case CCP2_PAD_SOURCE:672		/* Source format - copy sink format and change pixel code673		 * to SGRBG10_1X10 as we don't support CCP2 write to memory.674		 * When CCP2 write to memory feature will be added this675		 * should be changed properly.676		 */677		format = __ccp2_get_format(ccp2, sd_state, CCP2_PAD_SINK,678					   which);679		memcpy(fmt, format, sizeof(*fmt));680		fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;681		break;682	}683 684	fmt->field = V4L2_FIELD_NONE;685	fmt->colorspace = V4L2_COLORSPACE_SRGB;686}687 688/*689 * ccp2_enum_mbus_code - Handle pixel format enumeration690 * @sd     : pointer to v4l2 subdev structure691 * @sd_state: V4L2 subdev state692 * @code   : pointer to v4l2_subdev_mbus_code_enum structure693 * return -EINVAL or zero on success694 */695static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,696				  struct v4l2_subdev_state *sd_state,697				  struct v4l2_subdev_mbus_code_enum *code)698{699	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);700	struct v4l2_mbus_framefmt *format;701 702	if (code->pad == CCP2_PAD_SINK) {703		if (code->index >= ARRAY_SIZE(ccp2_fmts))704			return -EINVAL;705 706		code->code = ccp2_fmts[code->index];707	} else {708		if (code->index != 0)709			return -EINVAL;710 711		format = __ccp2_get_format(ccp2, sd_state, CCP2_PAD_SINK,712					   code->which);713		code->code = format->code;714	}715 716	return 0;717}718 719static int ccp2_enum_frame_size(struct v4l2_subdev *sd,720				   struct v4l2_subdev_state *sd_state,721				   struct v4l2_subdev_frame_size_enum *fse)722{723	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);724	struct v4l2_mbus_framefmt format;725 726	if (fse->index != 0)727		return -EINVAL;728 729	format.code = fse->code;730	format.width = 1;731	format.height = 1;732	ccp2_try_format(ccp2, sd_state, fse->pad, &format, fse->which);733	fse->min_width = format.width;734	fse->min_height = format.height;735 736	if (format.code != fse->code)737		return -EINVAL;738 739	format.code = fse->code;740	format.width = -1;741	format.height = -1;742	ccp2_try_format(ccp2, sd_state, fse->pad, &format, fse->which);743	fse->max_width = format.width;744	fse->max_height = format.height;745 746	return 0;747}748 749/*750 * ccp2_get_format - Handle get format by pads subdev method751 * @sd    : pointer to v4l2 subdev structure752 * @sd_state: V4L2 subdev state753 * @fmt   : pointer to v4l2 subdev format structure754 * return -EINVAL or zero on success755 */756static int ccp2_get_format(struct v4l2_subdev *sd,757			   struct v4l2_subdev_state *sd_state,758			   struct v4l2_subdev_format *fmt)759{760	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);761	struct v4l2_mbus_framefmt *format;762 763	format = __ccp2_get_format(ccp2, sd_state, fmt->pad, fmt->which);764	if (format == NULL)765		return -EINVAL;766 767	fmt->format = *format;768	return 0;769}770 771/*772 * ccp2_set_format - Handle set format by pads subdev method773 * @sd    : pointer to v4l2 subdev structure774 * @sd_state: V4L2 subdev state775 * @fmt   : pointer to v4l2 subdev format structure776 * returns zero777 */778static int ccp2_set_format(struct v4l2_subdev *sd,779			   struct v4l2_subdev_state *sd_state,780			   struct v4l2_subdev_format *fmt)781{782	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);783	struct v4l2_mbus_framefmt *format;784 785	format = __ccp2_get_format(ccp2, sd_state, fmt->pad, fmt->which);786	if (format == NULL)787		return -EINVAL;788 789	ccp2_try_format(ccp2, sd_state, fmt->pad, &fmt->format, fmt->which);790	*format = fmt->format;791 792	/* Propagate the format from sink to source */793	if (fmt->pad == CCP2_PAD_SINK) {794		format = __ccp2_get_format(ccp2, sd_state, CCP2_PAD_SOURCE,795					   fmt->which);796		*format = fmt->format;797		ccp2_try_format(ccp2, sd_state, CCP2_PAD_SOURCE, format,798				fmt->which);799	}800 801	return 0;802}803 804/*805 * ccp2_init_formats - Initialize formats on all pads806 * @sd: ISP CCP2 V4L2 subdevice807 * @fh: V4L2 subdev file handle808 *809 * Initialize all pad formats with default values. If fh is not NULL, try810 * formats are initialized on the file handle. Otherwise active formats are811 * initialized on the device.812 */813static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)814{815	struct v4l2_subdev_format format;816 817	memset(&format, 0, sizeof(format));818	format.pad = CCP2_PAD_SINK;819	format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;820	format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10;821	format.format.width = 4096;822	format.format.height = 4096;823	ccp2_set_format(sd, fh ? fh->state : NULL, &format);824 825	return 0;826}827 828/*829 * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev830 * @sd    : pointer to v4l2 subdev structure831 * @enable: 1 == Enable, 0 == Disable832 * return zero833 */834static int ccp2_s_stream(struct v4l2_subdev *sd, int enable)835{836	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);837	struct isp_device *isp = to_isp_device(ccp2);838	struct device *dev = to_device(ccp2);839	int ret;840 841	if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) {842		if (enable == ISP_PIPELINE_STREAM_STOPPED)843			return 0;844		atomic_set(&ccp2->stopping, 0);845	}846 847	switch (enable) {848	case ISP_PIPELINE_STREAM_CONTINUOUS:849		if (ccp2->phy) {850			ret = omap3isp_csiphy_acquire(ccp2->phy, &sd->entity);851			if (ret < 0)852				return ret;853		}854 855		ccp2_if_configure(ccp2);856		ccp2_print_status(ccp2);857 858		/* Enable CSI1/CCP2 interface */859		ret = ccp2_if_enable(ccp2, 1);860		if (ret < 0) {861			if (ccp2->phy)862				omap3isp_csiphy_release(ccp2->phy);863			return ret;864		}865		break;866 867	case ISP_PIPELINE_STREAM_SINGLESHOT:868		if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) {869			struct v4l2_mbus_framefmt *format;870 871			format = &ccp2->formats[CCP2_PAD_SINK];872 873			ccp2->mem_cfg.hsize_count = format->width;874			ccp2->mem_cfg.vsize_count = format->height;875			ccp2->mem_cfg.src_ofst = 0;876 877			ccp2_mem_configure(ccp2, &ccp2->mem_cfg);878			omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ);879			ccp2_print_status(ccp2);880		}881		ccp2_mem_enable(ccp2, 1);882		break;883 884	case ISP_PIPELINE_STREAM_STOPPED:885		if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait,886					      &ccp2->stopping))887			dev_dbg(dev, "%s: module stop timeout.\n", sd->name);888		if (ccp2->input == CCP2_INPUT_MEMORY) {889			ccp2_mem_enable(ccp2, 0);890			omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ);891		} else if (ccp2->input == CCP2_INPUT_SENSOR) {892			/* Disable CSI1/CCP2 interface */893			ccp2_if_enable(ccp2, 0);894			if (ccp2->phy)895				omap3isp_csiphy_release(ccp2->phy);896		}897		break;898	}899 900	ccp2->state = enable;901	return 0;902}903 904/* subdev video operations */905static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = {906	.s_stream = ccp2_s_stream,907};908 909/* subdev pad operations */910static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = {911	.enum_mbus_code = ccp2_enum_mbus_code,912	.enum_frame_size = ccp2_enum_frame_size,913	.get_fmt = ccp2_get_format,914	.set_fmt = ccp2_set_format,915};916 917/* subdev operations */918static const struct v4l2_subdev_ops ccp2_sd_ops = {919	.video = &ccp2_sd_video_ops,920	.pad = &ccp2_sd_pad_ops,921};922 923/* subdev internal operations */924static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = {925	.open = ccp2_init_formats,926};927 928/* --------------------------------------------------------------------------929 * ISP ccp2 video device node930 */931 932/*933 * ccp2_video_queue - Queue video buffer.934 * @video : Pointer to isp video structure935 * @buffer: Pointer to isp_buffer structure936 * return -EIO or zero on success937 */938static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer)939{940	struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2;941 942	ccp2_set_inaddr(ccp2, buffer->dma);943	return 0;944}945 946static const struct isp_video_operations ccp2_video_ops = {947	.queue = ccp2_video_queue,948};949 950/* -----------------------------------------------------------------------------951 * Media entity operations952 */953 954/*955 * ccp2_link_setup - Setup ccp2 connections.956 * @entity : Pointer to media entity structure957 * @local  : Pointer to local pad array958 * @remote : Pointer to remote pad array959 * @flags  : Link flags960 * return -EINVAL on error or zero on success961 */962static int ccp2_link_setup(struct media_entity *entity,963			   const struct media_pad *local,964			   const struct media_pad *remote, u32 flags)965{966	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);967	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);968	unsigned int index = local->index;969 970	/* FIXME: this is actually a hack! */971	if (is_media_entity_v4l2_subdev(remote->entity))972		index |= 2 << 16;973 974	switch (index) {975	case CCP2_PAD_SINK:976		/* read from memory */977		if (flags & MEDIA_LNK_FL_ENABLED) {978			if (ccp2->input == CCP2_INPUT_SENSOR)979				return -EBUSY;980			ccp2->input = CCP2_INPUT_MEMORY;981		} else {982			if (ccp2->input == CCP2_INPUT_MEMORY)983				ccp2->input = CCP2_INPUT_NONE;984		}985		break;986 987	case CCP2_PAD_SINK | 2 << 16:988		/* read from sensor/phy */989		if (flags & MEDIA_LNK_FL_ENABLED) {990			if (ccp2->input == CCP2_INPUT_MEMORY)991				return -EBUSY;992			ccp2->input = CCP2_INPUT_SENSOR;993		} else {994			if (ccp2->input == CCP2_INPUT_SENSOR)995				ccp2->input = CCP2_INPUT_NONE;996		} break;997 998	case CCP2_PAD_SOURCE | 2 << 16:999		/* write to video port/ccdc */1000		if (flags & MEDIA_LNK_FL_ENABLED)1001			ccp2->output = CCP2_OUTPUT_CCDC;1002		else1003			ccp2->output = CCP2_OUTPUT_NONE;1004		break;1005 1006	default:1007		return -EINVAL;1008	}1009 1010	return 0;1011}1012 1013/* media operations */1014static const struct media_entity_operations ccp2_media_ops = {1015	.link_setup = ccp2_link_setup,1016	.link_validate = v4l2_subdev_link_validate,1017};1018 1019/*1020 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev1021 * @ccp2: Pointer to ISP CCP2 device1022 */1023void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)1024{1025	v4l2_device_unregister_subdev(&ccp2->subdev);1026	omap3isp_video_unregister(&ccp2->video_in);1027}1028 1029/*1030 * omap3isp_ccp2_register_entities - Register the subdev media entity1031 * @ccp2: Pointer to ISP CCP2 device1032 * @vdev: Pointer to v4l device1033 * return negative error code or zero on success1034 */1035 1036int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,1037				    struct v4l2_device *vdev)1038{1039	int ret;1040 1041	/* Register the subdev and video nodes. */1042	ccp2->subdev.dev = vdev->mdev->dev;1043	ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);1044	if (ret < 0)1045		goto error;1046 1047	ret = omap3isp_video_register(&ccp2->video_in, vdev);1048	if (ret < 0)1049		goto error;1050 1051	return 0;1052 1053error:1054	omap3isp_ccp2_unregister_entities(ccp2);1055	return ret;1056}1057 1058/* -----------------------------------------------------------------------------1059 * ISP ccp2 initialisation and cleanup1060 */1061 1062/*1063 * ccp2_init_entities - Initialize ccp2 subdev and media entity.1064 * @ccp2: Pointer to ISP CCP2 device1065 * return negative error code or zero on success1066 */1067static int ccp2_init_entities(struct isp_ccp2_device *ccp2)1068{1069	struct v4l2_subdev *sd = &ccp2->subdev;1070	struct media_pad *pads = ccp2->pads;1071	struct media_entity *me = &sd->entity;1072	int ret;1073 1074	ccp2->input = CCP2_INPUT_NONE;1075	ccp2->output = CCP2_OUTPUT_NONE;1076 1077	v4l2_subdev_init(sd, &ccp2_sd_ops);1078	sd->internal_ops = &ccp2_sd_internal_ops;1079	strscpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));1080	sd->grp_id = 1 << 16;   /* group ID for isp subdevs */1081	v4l2_set_subdevdata(sd, ccp2);1082	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;1083 1084	pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK1085				    | MEDIA_PAD_FL_MUST_CONNECT;1086	pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;1087 1088	me->ops = &ccp2_media_ops;1089	ret = media_entity_pads_init(me, CCP2_PADS_NUM, pads);1090	if (ret < 0)1091		return ret;1092 1093	ccp2_init_formats(sd, NULL);1094 1095	/*1096	 * The CCP2 has weird line alignment requirements, possibly caused by1097	 * DPCM8 decompression. Line length for data read from memory must be a1098	 * multiple of 128 bits (16 bytes) in continuous mode (when no padding1099	 * is present at end of lines). Additionally, if padding is used, the1100	 * padded line length must be a multiple of 32 bytes. To simplify the1101	 * implementation we use a fixed 32 bytes alignment regardless of the1102	 * input format and width. If strict 128 bits alignment support is1103	 * required ispvideo will need to be made aware of this special dual1104	 * alignment requirements.1105	 */1106	ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;1107	ccp2->video_in.bpl_alignment = 32;1108	ccp2->video_in.bpl_max = 0xffffffe0;1109	ccp2->video_in.isp = to_isp_device(ccp2);1110	ccp2->video_in.ops = &ccp2_video_ops;1111	ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;1112 1113	ret = omap3isp_video_init(&ccp2->video_in, "CCP2");1114	if (ret < 0)1115		goto error;1116 1117	return 0;1118 1119error:1120	media_entity_cleanup(&ccp2->subdev.entity);1121	return ret;1122}1123 1124/*1125 * omap3isp_ccp2_init - CCP2 initialization.1126 * @isp : Pointer to ISP device1127 * return negative error code or zero on success1128 */1129int omap3isp_ccp2_init(struct isp_device *isp)1130{1131	struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;1132	int ret;1133 1134	init_waitqueue_head(&ccp2->wait);1135 1136	/*1137	 * On the OMAP34xx the CSI1 receiver is operated in the CSIb IO1138	 * complex, which is powered by vdds_csib power rail. Hence the1139	 * request for the regulator.1140	 *1141	 * On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with1142	 * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly1143	 * configured.1144	 *1145	 * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c).1146	 */1147	if (isp->revision == ISP_REVISION_2_0) {1148		ccp2->vdds_csib = devm_regulator_get(isp->dev, "vdds_csib");1149		if (IS_ERR(ccp2->vdds_csib)) {1150			if (PTR_ERR(ccp2->vdds_csib) == -EPROBE_DEFER) {1151				dev_dbg(isp->dev,1152					"Can't get regulator vdds_csib, deferring probing\n");1153				return -EPROBE_DEFER;1154			}1155			dev_dbg(isp->dev,1156				"Could not get regulator vdds_csib\n");1157			ccp2->vdds_csib = NULL;1158		}1159		ccp2->phy = &isp->isp_csiphy2;1160	} else if (isp->revision == ISP_REVISION_15_0) {1161		ccp2->phy = &isp->isp_csiphy1;1162	}1163 1164	ret = ccp2_init_entities(ccp2);1165	if (ret < 0)1166		return ret;1167 1168	ccp2_reset(ccp2);1169	return 0;1170}1171 1172/*1173 * omap3isp_ccp2_cleanup - CCP2 un-initialization1174 * @isp : Pointer to ISP device1175 */1176void omap3isp_ccp2_cleanup(struct isp_device *isp)1177{1178	struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;1179 1180	omap3isp_video_cleanup(&ccp2->video_in);1181	media_entity_cleanup(&ccp2->subdev.entity);1182}1183