brintos

brintos / linux-shallow public Read only

0
0
Text · 63.9 KiB · 91101ba Raw
2490 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * isp.c4 *5 * TI OMAP3 ISP - Core6 *7 * Copyright (C) 2006-2010 Nokia Corporation8 * Copyright (C) 2007-2009 Texas Instruments, Inc.9 *10 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>11 *	     Sakari Ailus <sakari.ailus@iki.fi>12 *13 * Contributors:14 *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>15 *	Sakari Ailus <sakari.ailus@iki.fi>16 *	David Cohen <dacohen@gmail.com>17 *	Stanimir Varbanov <svarbanov@mm-sol.com>18 *	Vimarsh Zutshi <vimarsh.zutshi@gmail.com>19 *	Tuukka Toivonen <tuukkat76@gmail.com>20 *	Sergio Aguirre <saaguirre@ti.com>21 *	Antti Koskipaa <akoskipa@gmail.com>22 *	Ivan T. Ivanov <iivanov@mm-sol.com>23 *	RaniSuneela <r-m@ti.com>24 *	Atanas Filipov <afilipov@mm-sol.com>25 *	Gjorgji Rosikopulos <grosikopulos@mm-sol.com>26 *	Hiroshi DOYU <hiroshi.doyu@nokia.com>27 *	Nayden Kanchev <nkanchev@mm-sol.com>28 *	Phil Carmody <ext-phil.2.carmody@nokia.com>29 *	Artem Bityutskiy <artem.bityutskiy@nokia.com>30 *	Dominic Curran <dcurran@ti.com>31 *	Ilkka Myllyperkio <ilkka.myllyperkio@sofica.fi>32 *	Pallavi Kulkarni <p-kulkarni@ti.com>33 *	Vaibhav Hiremath <hvaibhav@ti.com>34 *	Mohit Jalori <mjalori@ti.com>35 *	Sameer Venkatraman <sameerv@ti.com>36 *	Senthilvadivu Guruswamy <svadivu@ti.com>37 *	Thara Gopinath <thara@ti.com>38 *	Toni Leinonen <toni.leinonen@nokia.com>39 *	Troy Laramy <t-laramy@ti.com>40 */41 42#include <linux/clk.h>43#include <linux/clkdev.h>44#include <linux/delay.h>45#include <linux/device.h>46#include <linux/dma-mapping.h>47#include <linux/i2c.h>48#include <linux/interrupt.h>49#include <linux/mfd/syscon.h>50#include <linux/module.h>51#include <linux/omap-iommu.h>52#include <linux/platform_device.h>53#include <linux/property.h>54#include <linux/regulator/consumer.h>55#include <linux/slab.h>56#include <linux/sched.h>57#include <linux/vmalloc.h>58 59#ifdef CONFIG_ARM_DMA_USE_IOMMU60#include <asm/dma-iommu.h>61#endif62 63#include <media/v4l2-common.h>64#include <media/v4l2-fwnode.h>65#include <media/v4l2-device.h>66#include <media/v4l2-mc.h>67 68#include "isp.h"69#include "ispreg.h"70#include "ispccdc.h"71#include "isppreview.h"72#include "ispresizer.h"73#include "ispcsi2.h"74#include "ispccp2.h"75#include "isph3a.h"76#include "isphist.h"77 78static unsigned int autoidle;79module_param(autoidle, int, 0444);80MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support");81 82static void isp_save_ctx(struct isp_device *isp);83 84static void isp_restore_ctx(struct isp_device *isp);85 86static const struct isp_res_mapping isp_res_maps[] = {87	{88		.isp_rev = ISP_REVISION_2_0,89		.offset = {90			/* first MMIO area */91			0x0000, /* base, len 0x0070 */92			0x0400, /* ccp2, len 0x01f0 */93			0x0600, /* ccdc, len 0x00a8 */94			0x0a00, /* hist, len 0x0048 */95			0x0c00, /* h3a, len 0x0060 */96			0x0e00, /* preview, len 0x00a0 */97			0x1000, /* resizer, len 0x00ac */98			0x1200, /* sbl, len 0x00fc */99			/* second MMIO area */100			0x0000, /* csi2a, len 0x0170 */101			0x0170, /* csiphy2, len 0x000c */102		},103		.phy_type = ISP_PHY_TYPE_3430,104	},105	{106		.isp_rev = ISP_REVISION_15_0,107		.offset = {108			/* first MMIO area */109			0x0000, /* base, len 0x0070 */110			0x0400, /* ccp2, len 0x01f0 */111			0x0600, /* ccdc, len 0x00a8 */112			0x0a00, /* hist, len 0x0048 */113			0x0c00, /* h3a, len 0x0060 */114			0x0e00, /* preview, len 0x00a0 */115			0x1000, /* resizer, len 0x00ac */116			0x1200, /* sbl, len 0x00fc */117			/* second MMIO area */118			0x0000, /* csi2a, len 0x0170 (1st area) */119			0x0170, /* csiphy2, len 0x000c */120			0x01c0, /* csi2a, len 0x0040 (2nd area) */121			0x0400, /* csi2c, len 0x0170 (1st area) */122			0x0570, /* csiphy1, len 0x000c */123			0x05c0, /* csi2c, len 0x0040 (2nd area) */124		},125		.phy_type = ISP_PHY_TYPE_3630,126	},127};128 129/* Structure for saving/restoring ISP module registers */130static struct isp_reg isp_reg_list[] = {131	{OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0},132	{OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0},133	{OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0},134	{0, ISP_TOK_TERM, 0}135};136 137/*138 * omap3isp_flush - Post pending L3 bus writes by doing a register readback139 * @isp: OMAP3 ISP device140 *141 * In order to force posting of pending writes, we need to write and142 * readback the same register, in this case the revision register.143 *144 * See this link for reference:145 *   https://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html146 */147void omap3isp_flush(struct isp_device *isp)148{149	isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);150	isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);151}152 153/* -----------------------------------------------------------------------------154 * XCLK155 */156 157#define to_isp_xclk(_hw)	container_of(_hw, struct isp_xclk, hw)158 159static void isp_xclk_update(struct isp_xclk *xclk, u32 divider)160{161	switch (xclk->id) {162	case ISP_XCLK_A:163		isp_reg_clr_set(xclk->isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,164				ISPTCTRL_CTRL_DIVA_MASK,165				divider << ISPTCTRL_CTRL_DIVA_SHIFT);166		break;167	case ISP_XCLK_B:168		isp_reg_clr_set(xclk->isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,169				ISPTCTRL_CTRL_DIVB_MASK,170				divider << ISPTCTRL_CTRL_DIVB_SHIFT);171		break;172	}173}174 175static int isp_xclk_prepare(struct clk_hw *hw)176{177	struct isp_xclk *xclk = to_isp_xclk(hw);178 179	omap3isp_get(xclk->isp);180 181	return 0;182}183 184static void isp_xclk_unprepare(struct clk_hw *hw)185{186	struct isp_xclk *xclk = to_isp_xclk(hw);187 188	omap3isp_put(xclk->isp);189}190 191static int isp_xclk_enable(struct clk_hw *hw)192{193	struct isp_xclk *xclk = to_isp_xclk(hw);194	unsigned long flags;195 196	spin_lock_irqsave(&xclk->lock, flags);197	isp_xclk_update(xclk, xclk->divider);198	xclk->enabled = true;199	spin_unlock_irqrestore(&xclk->lock, flags);200 201	return 0;202}203 204static void isp_xclk_disable(struct clk_hw *hw)205{206	struct isp_xclk *xclk = to_isp_xclk(hw);207	unsigned long flags;208 209	spin_lock_irqsave(&xclk->lock, flags);210	isp_xclk_update(xclk, 0);211	xclk->enabled = false;212	spin_unlock_irqrestore(&xclk->lock, flags);213}214 215static unsigned long isp_xclk_recalc_rate(struct clk_hw *hw,216					  unsigned long parent_rate)217{218	struct isp_xclk *xclk = to_isp_xclk(hw);219 220	return parent_rate / xclk->divider;221}222 223static u32 isp_xclk_calc_divider(unsigned long *rate, unsigned long parent_rate)224{225	u32 divider;226 227	if (*rate >= parent_rate) {228		*rate = parent_rate;229		return ISPTCTRL_CTRL_DIV_BYPASS;230	}231 232	if (*rate == 0)233		*rate = 1;234 235	divider = DIV_ROUND_CLOSEST(parent_rate, *rate);236	if (divider >= ISPTCTRL_CTRL_DIV_BYPASS)237		divider = ISPTCTRL_CTRL_DIV_BYPASS - 1;238 239	*rate = parent_rate / divider;240	return divider;241}242 243static long isp_xclk_round_rate(struct clk_hw *hw, unsigned long rate,244				unsigned long *parent_rate)245{246	isp_xclk_calc_divider(&rate, *parent_rate);247	return rate;248}249 250static int isp_xclk_set_rate(struct clk_hw *hw, unsigned long rate,251			     unsigned long parent_rate)252{253	struct isp_xclk *xclk = to_isp_xclk(hw);254	unsigned long flags;255	u32 divider;256 257	divider = isp_xclk_calc_divider(&rate, parent_rate);258 259	spin_lock_irqsave(&xclk->lock, flags);260 261	xclk->divider = divider;262	if (xclk->enabled)263		isp_xclk_update(xclk, divider);264 265	spin_unlock_irqrestore(&xclk->lock, flags);266 267	dev_dbg(xclk->isp->dev, "%s: cam_xclk%c set to %lu Hz (div %u)\n",268		__func__, xclk->id == ISP_XCLK_A ? 'a' : 'b', rate, divider);269	return 0;270}271 272static const struct clk_ops isp_xclk_ops = {273	.prepare = isp_xclk_prepare,274	.unprepare = isp_xclk_unprepare,275	.enable = isp_xclk_enable,276	.disable = isp_xclk_disable,277	.recalc_rate = isp_xclk_recalc_rate,278	.round_rate = isp_xclk_round_rate,279	.set_rate = isp_xclk_set_rate,280};281 282static const char *isp_xclk_parent_name = "cam_mclk";283 284static struct clk *isp_xclk_src_get(struct of_phandle_args *clkspec, void *data)285{286	unsigned int idx = clkspec->args[0];287	struct isp_device *isp = data;288 289	if (idx >= ARRAY_SIZE(isp->xclks))290		return ERR_PTR(-ENOENT);291 292	return isp->xclks[idx].clk;293}294 295static int isp_xclk_init(struct isp_device *isp)296{297	struct device_node *np = isp->dev->of_node;298	struct clk_init_data init = {};299	unsigned int i;300 301	for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i)302		isp->xclks[i].clk = ERR_PTR(-EINVAL);303 304	for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {305		struct isp_xclk *xclk = &isp->xclks[i];306 307		xclk->isp = isp;308		xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B;309		xclk->divider = 1;310		spin_lock_init(&xclk->lock);311 312		init.name = i == 0 ? "cam_xclka" : "cam_xclkb";313		init.ops = &isp_xclk_ops;314		init.parent_names = &isp_xclk_parent_name;315		init.num_parents = 1;316 317		xclk->hw.init = &init;318		/*319		 * The first argument is NULL in order to avoid circular320		 * reference, as this driver takes reference on the321		 * sensor subdevice modules and the sensors would take322		 * reference on this module through clk_get().323		 */324		xclk->clk = clk_register(NULL, &xclk->hw);325		if (IS_ERR(xclk->clk))326			return PTR_ERR(xclk->clk);327	}328 329	if (np)330		of_clk_add_provider(np, isp_xclk_src_get, isp);331 332	return 0;333}334 335static void isp_xclk_cleanup(struct isp_device *isp)336{337	struct device_node *np = isp->dev->of_node;338	unsigned int i;339 340	if (np)341		of_clk_del_provider(np);342 343	for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {344		struct isp_xclk *xclk = &isp->xclks[i];345 346		if (!IS_ERR(xclk->clk))347			clk_unregister(xclk->clk);348	}349}350 351/* -----------------------------------------------------------------------------352 * Interrupts353 */354 355/*356 * isp_enable_interrupts - Enable ISP interrupts.357 * @isp: OMAP3 ISP device358 */359static void isp_enable_interrupts(struct isp_device *isp)360{361	static const u32 irq = IRQ0ENABLE_CSIA_IRQ362			     | IRQ0ENABLE_CSIB_IRQ363			     | IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ364			     | IRQ0ENABLE_CCDC_LSC_DONE_IRQ365			     | IRQ0ENABLE_CCDC_VD0_IRQ366			     | IRQ0ENABLE_CCDC_VD1_IRQ367			     | IRQ0ENABLE_HS_VS_IRQ368			     | IRQ0ENABLE_HIST_DONE_IRQ369			     | IRQ0ENABLE_H3A_AWB_DONE_IRQ370			     | IRQ0ENABLE_H3A_AF_DONE_IRQ371			     | IRQ0ENABLE_PRV_DONE_IRQ372			     | IRQ0ENABLE_RSZ_DONE_IRQ;373 374	isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);375	isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);376}377 378/*379 * isp_disable_interrupts - Disable ISP interrupts.380 * @isp: OMAP3 ISP device381 */382static void isp_disable_interrupts(struct isp_device *isp)383{384	isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);385}386 387/*388 * isp_core_init - ISP core settings389 * @isp: OMAP3 ISP device390 * @idle: Consider idle state.391 *392 * Set the power settings for the ISP and SBL bus and configure the HS/VS393 * interrupt source.394 *395 * We need to configure the HS/VS interrupt source before interrupts get396 * enabled, as the sensor might be free-running and the ISP default setting397 * (HS edge) would put an unnecessary burden on the CPU.398 */399static void isp_core_init(struct isp_device *isp, int idle)400{401	isp_reg_writel(isp,402		       ((idle ? ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY :403				ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY) <<404			ISP_SYSCONFIG_MIDLEMODE_SHIFT) |405			((isp->revision == ISP_REVISION_15_0) ?406			  ISP_SYSCONFIG_AUTOIDLE : 0),407		       OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);408 409	isp_reg_writel(isp,410		       (isp->autoidle ? ISPCTRL_SBL_AUTOIDLE : 0) |411		       ISPCTRL_SYNC_DETECT_VSRISE,412		       OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);413}414 415/*416 * Configure the bridge and lane shifter. Valid inputs are417 *418 * CCDC_INPUT_PARALLEL: Parallel interface419 * CCDC_INPUT_CSI2A: CSI2a receiver420 * CCDC_INPUT_CCP2B: CCP2b receiver421 * CCDC_INPUT_CSI2C: CSI2c receiver422 *423 * The bridge and lane shifter are configured according to the selected input424 * and the ISP platform data.425 */426void omap3isp_configure_bridge(struct isp_device *isp,427			       enum ccdc_input_entity input,428			       const struct isp_parallel_cfg *parcfg,429			       unsigned int shift, unsigned int bridge)430{431	u32 ispctrl_val;432 433	ispctrl_val  = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);434	ispctrl_val &= ~ISPCTRL_SHIFT_MASK;435	ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV;436	ispctrl_val &= ~ISPCTRL_PAR_SER_CLK_SEL_MASK;437	ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_MASK;438	ispctrl_val |= bridge;439 440	switch (input) {441	case CCDC_INPUT_PARALLEL:442		ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;443		ispctrl_val |= parcfg->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;444		shift += parcfg->data_lane_shift;445		break;446 447	case CCDC_INPUT_CSI2A:448		ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA;449		break;450 451	case CCDC_INPUT_CCP2B:452		ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB;453		break;454 455	case CCDC_INPUT_CSI2C:456		ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIC;457		break;458 459	default:460		return;461	}462 463	ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK;464 465	isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);466}467 468void omap3isp_hist_dma_done(struct isp_device *isp)469{470	if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||471	    omap3isp_stat_pcr_busy(&isp->isp_hist)) {472		/* Histogram cannot be enabled in this frame anymore */473		atomic_set(&isp->isp_hist.buf_err, 1);474		dev_dbg(isp->dev,475			"hist: Out of synchronization with CCDC. Ignoring next buffer.\n");476	}477}478 479static inline void __maybe_unused isp_isr_dbg(struct isp_device *isp,480					      u32 irqstatus)481{482	static const char *name[] = {483		"CSIA_IRQ",484		"res1",485		"res2",486		"CSIB_LCM_IRQ",487		"CSIB_IRQ",488		"res5",489		"res6",490		"res7",491		"CCDC_VD0_IRQ",492		"CCDC_VD1_IRQ",493		"CCDC_VD2_IRQ",494		"CCDC_ERR_IRQ",495		"H3A_AF_DONE_IRQ",496		"H3A_AWB_DONE_IRQ",497		"res14",498		"res15",499		"HIST_DONE_IRQ",500		"CCDC_LSC_DONE",501		"CCDC_LSC_PREFETCH_COMPLETED",502		"CCDC_LSC_PREFETCH_ERROR",503		"PRV_DONE_IRQ",504		"CBUFF_IRQ",505		"res22",506		"res23",507		"RSZ_DONE_IRQ",508		"OVF_IRQ",509		"res26",510		"res27",511		"MMU_ERR_IRQ",512		"OCP_ERR_IRQ",513		"SEC_ERR_IRQ",514		"HS_VS_IRQ",515	};516	int i;517 518	dev_dbg(isp->dev, "ISP IRQ: ");519 520	for (i = 0; i < ARRAY_SIZE(name); i++) {521		if ((1 << i) & irqstatus)522			printk(KERN_CONT "%s ", name[i]);523	}524	printk(KERN_CONT "\n");525}526 527static void isp_isr_sbl(struct isp_device *isp)528{529	struct device *dev = isp->dev;530	struct isp_pipeline *pipe;531	u32 sbl_pcr;532 533	/*534	 * Handle shared buffer logic overflows for video buffers.535	 * ISPSBL_PCR_CCDCPRV_2_RSZ_OVF can be safely ignored.536	 */537	sbl_pcr = isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);538	isp_reg_writel(isp, sbl_pcr, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);539	sbl_pcr &= ~ISPSBL_PCR_CCDCPRV_2_RSZ_OVF;540 541	if (sbl_pcr)542		dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr);543 544	if (sbl_pcr & ISPSBL_PCR_CSIB_WBL_OVF) {545		pipe = to_isp_pipeline(&isp->isp_ccp2.subdev.entity);546		if (pipe != NULL)547			pipe->error = true;548	}549 550	if (sbl_pcr & ISPSBL_PCR_CSIA_WBL_OVF) {551		pipe = to_isp_pipeline(&isp->isp_csi2a.subdev.entity);552		if (pipe != NULL)553			pipe->error = true;554	}555 556	if (sbl_pcr & ISPSBL_PCR_CCDC_WBL_OVF) {557		pipe = to_isp_pipeline(&isp->isp_ccdc.subdev.entity);558		if (pipe != NULL)559			pipe->error = true;560	}561 562	if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) {563		pipe = to_isp_pipeline(&isp->isp_prev.subdev.entity);564		if (pipe != NULL)565			pipe->error = true;566	}567 568	if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF569		       | ISPSBL_PCR_RSZ2_WBL_OVF570		       | ISPSBL_PCR_RSZ3_WBL_OVF571		       | ISPSBL_PCR_RSZ4_WBL_OVF)) {572		pipe = to_isp_pipeline(&isp->isp_res.subdev.entity);573		if (pipe != NULL)574			pipe->error = true;575	}576 577	if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF)578		omap3isp_stat_sbl_overflow(&isp->isp_af);579 580	if (sbl_pcr & ISPSBL_PCR_H3A_AEAWB_WBL_OVF)581		omap3isp_stat_sbl_overflow(&isp->isp_aewb);582}583 584/*585 * isp_isr - Interrupt Service Routine for Camera ISP module.586 * @irq: Not used currently.587 * @_isp: Pointer to the OMAP3 ISP device588 *589 * Handles the corresponding callback if plugged in.590 */591static irqreturn_t isp_isr(int irq, void *_isp)592{593	static const u32 ccdc_events = IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ |594				       IRQ0STATUS_CCDC_LSC_DONE_IRQ |595				       IRQ0STATUS_CCDC_VD0_IRQ |596				       IRQ0STATUS_CCDC_VD1_IRQ |597				       IRQ0STATUS_HS_VS_IRQ;598	struct isp_device *isp = _isp;599	u32 irqstatus;600 601	irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);602	isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);603 604	isp_isr_sbl(isp);605 606	if (irqstatus & IRQ0STATUS_CSIA_IRQ)607		omap3isp_csi2_isr(&isp->isp_csi2a);608 609	if (irqstatus & IRQ0STATUS_CSIB_IRQ)610		omap3isp_ccp2_isr(&isp->isp_ccp2);611 612	if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) {613		if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)614			omap3isp_preview_isr_frame_sync(&isp->isp_prev);615		if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)616			omap3isp_resizer_isr_frame_sync(&isp->isp_res);617		omap3isp_stat_isr_frame_sync(&isp->isp_aewb);618		omap3isp_stat_isr_frame_sync(&isp->isp_af);619		omap3isp_stat_isr_frame_sync(&isp->isp_hist);620	}621 622	if (irqstatus & ccdc_events)623		omap3isp_ccdc_isr(&isp->isp_ccdc, irqstatus & ccdc_events);624 625	if (irqstatus & IRQ0STATUS_PRV_DONE_IRQ) {626		if (isp->isp_prev.output & PREVIEW_OUTPUT_RESIZER)627			omap3isp_resizer_isr_frame_sync(&isp->isp_res);628		omap3isp_preview_isr(&isp->isp_prev);629	}630 631	if (irqstatus & IRQ0STATUS_RSZ_DONE_IRQ)632		omap3isp_resizer_isr(&isp->isp_res);633 634	if (irqstatus & IRQ0STATUS_H3A_AWB_DONE_IRQ)635		omap3isp_stat_isr(&isp->isp_aewb);636 637	if (irqstatus & IRQ0STATUS_H3A_AF_DONE_IRQ)638		omap3isp_stat_isr(&isp->isp_af);639 640	if (irqstatus & IRQ0STATUS_HIST_DONE_IRQ)641		omap3isp_stat_isr(&isp->isp_hist);642 643	omap3isp_flush(isp);644 645#if defined(DEBUG) && defined(ISP_ISR_DEBUG)646	isp_isr_dbg(isp, irqstatus);647#endif648 649	return IRQ_HANDLED;650}651 652static const struct media_device_ops isp_media_ops = {653	.link_notify = v4l2_pipeline_link_notify,654};655 656/* -----------------------------------------------------------------------------657 * Pipeline stream management658 */659 660/*661 * isp_pipeline_enable - Enable streaming on a pipeline662 * @pipe: ISP pipeline663 * @mode: Stream mode (single shot or continuous)664 *665 * Walk the entities chain starting at the pipeline output video node and start666 * all modules in the chain in the given mode.667 *668 * Return 0 if successful, or the return value of the failed video::s_stream669 * operation otherwise.670 */671static int isp_pipeline_enable(struct isp_pipeline *pipe,672			       enum isp_pipeline_stream_state mode)673{674	struct isp_device *isp = pipe->output->isp;675	struct media_entity *entity;676	struct media_pad *pad;677	struct v4l2_subdev *subdev;678	unsigned long flags;679	int ret;680 681	/* Refuse to start streaming if an entity included in the pipeline has682	 * crashed. This check must be performed before the loop below to avoid683	 * starting entities if the pipeline won't start anyway (those entities684	 * would then likely fail to stop, making the problem worse).685	 */686	if (media_entity_enum_intersects(&pipe->ent_enum, &isp->crashed))687		return -EIO;688 689	spin_lock_irqsave(&pipe->lock, flags);690	pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);691	spin_unlock_irqrestore(&pipe->lock, flags);692 693	pipe->do_propagation = false;694 695	mutex_lock(&isp->media_dev.graph_mutex);696 697	entity = &pipe->output->video.entity;698	while (1) {699		pad = &entity->pads[0];700		if (!(pad->flags & MEDIA_PAD_FL_SINK))701			break;702 703		pad = media_pad_remote_pad_first(pad);704		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))705			break;706 707		entity = pad->entity;708		subdev = media_entity_to_v4l2_subdev(entity);709 710		ret = v4l2_subdev_call(subdev, video, s_stream, mode);711		if (ret < 0 && ret != -ENOIOCTLCMD) {712			mutex_unlock(&isp->media_dev.graph_mutex);713			return ret;714		}715 716		if (subdev == &isp->isp_ccdc.subdev) {717			v4l2_subdev_call(&isp->isp_aewb.subdev, video,718					s_stream, mode);719			v4l2_subdev_call(&isp->isp_af.subdev, video,720					s_stream, mode);721			v4l2_subdev_call(&isp->isp_hist.subdev, video,722					s_stream, mode);723			pipe->do_propagation = true;724		}725 726		/* Stop at the first external sub-device. */727		if (subdev->dev != isp->dev)728			break;729	}730 731	mutex_unlock(&isp->media_dev.graph_mutex);732 733	return 0;734}735 736static int isp_pipeline_wait_resizer(struct isp_device *isp)737{738	return omap3isp_resizer_busy(&isp->isp_res);739}740 741static int isp_pipeline_wait_preview(struct isp_device *isp)742{743	return omap3isp_preview_busy(&isp->isp_prev);744}745 746static int isp_pipeline_wait_ccdc(struct isp_device *isp)747{748	return omap3isp_stat_busy(&isp->isp_af)749	    || omap3isp_stat_busy(&isp->isp_aewb)750	    || omap3isp_stat_busy(&isp->isp_hist)751	    || omap3isp_ccdc_busy(&isp->isp_ccdc);752}753 754#define ISP_STOP_TIMEOUT	msecs_to_jiffies(1000)755 756static int isp_pipeline_wait(struct isp_device *isp,757			     int(*busy)(struct isp_device *isp))758{759	unsigned long timeout = jiffies + ISP_STOP_TIMEOUT;760 761	while (!time_after(jiffies, timeout)) {762		if (!busy(isp))763			return 0;764	}765 766	return 1;767}768 769/*770 * isp_pipeline_disable - Disable streaming on a pipeline771 * @pipe: ISP pipeline772 *773 * Walk the entities chain starting at the pipeline output video node and stop774 * all modules in the chain. Wait synchronously for the modules to be stopped if775 * necessary.776 *777 * Return 0 if all modules have been properly stopped, or -ETIMEDOUT if a module778 * can't be stopped (in which case a software reset of the ISP is probably779 * necessary).780 */781static int isp_pipeline_disable(struct isp_pipeline *pipe)782{783	struct isp_device *isp = pipe->output->isp;784	struct media_entity *entity;785	struct media_pad *pad;786	struct v4l2_subdev *subdev;787	int failure = 0;788	int ret;789 790	/*791	 * We need to stop all the modules after CCDC first or they'll792	 * never stop since they may not get a full frame from CCDC.793	 */794	entity = &pipe->output->video.entity;795	while (1) {796		pad = &entity->pads[0];797		if (!(pad->flags & MEDIA_PAD_FL_SINK))798			break;799 800		pad = media_pad_remote_pad_first(pad);801		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))802			break;803 804		entity = pad->entity;805		subdev = media_entity_to_v4l2_subdev(entity);806 807		if (subdev == &isp->isp_ccdc.subdev) {808			v4l2_subdev_call(&isp->isp_aewb.subdev,809					 video, s_stream, 0);810			v4l2_subdev_call(&isp->isp_af.subdev,811					 video, s_stream, 0);812			v4l2_subdev_call(&isp->isp_hist.subdev,813					 video, s_stream, 0);814		}815 816		ret = v4l2_subdev_call(subdev, video, s_stream, 0);817 818		/* Stop at the first external sub-device. */819		if (subdev->dev != isp->dev)820			break;821 822		if (subdev == &isp->isp_res.subdev)823			ret |= isp_pipeline_wait(isp, isp_pipeline_wait_resizer);824		else if (subdev == &isp->isp_prev.subdev)825			ret |= isp_pipeline_wait(isp, isp_pipeline_wait_preview);826		else if (subdev == &isp->isp_ccdc.subdev)827			ret |= isp_pipeline_wait(isp, isp_pipeline_wait_ccdc);828 829		/* Handle stop failures. An entity that fails to stop can830		 * usually just be restarted. Flag the stop failure nonetheless831		 * to trigger an ISP reset the next time the device is released,832		 * just in case.833		 *834		 * The preview engine is a special case. A failure to stop can835		 * mean a hardware crash. When that happens the preview engine836		 * won't respond to read/write operations on the L4 bus anymore,837		 * resulting in a bus fault and a kernel oops next time it gets838		 * accessed. Mark it as crashed to prevent pipelines including839		 * it from being started.840		 */841		if (ret) {842			dev_info(isp->dev, "Unable to stop %s\n", subdev->name);843			isp->stop_failure = true;844			if (subdev == &isp->isp_prev.subdev)845				media_entity_enum_set(&isp->crashed,846						      &subdev->entity);847			failure = -ETIMEDOUT;848		}849	}850 851	return failure;852}853 854/*855 * omap3isp_pipeline_set_stream - Enable/disable streaming on a pipeline856 * @pipe: ISP pipeline857 * @state: Stream state (stopped, single shot or continuous)858 *859 * Set the pipeline to the given stream state. Pipelines can be started in860 * single-shot or continuous mode.861 *862 * Return 0 if successful, or the return value of the failed video::s_stream863 * operation otherwise. The pipeline state is not updated when the operation864 * fails, except when stopping the pipeline.865 */866int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,867				 enum isp_pipeline_stream_state state)868{869	int ret;870 871	if (state == ISP_PIPELINE_STREAM_STOPPED)872		ret = isp_pipeline_disable(pipe);873	else874		ret = isp_pipeline_enable(pipe, state);875 876	if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED)877		pipe->stream_state = state;878 879	return ret;880}881 882/*883 * omap3isp_pipeline_cancel_stream - Cancel stream on a pipeline884 * @pipe: ISP pipeline885 *886 * Cancelling a stream mark all buffers on all video nodes in the pipeline as887 * erroneous and makes sure no new buffer can be queued. This function is called888 * when a fatal error that prevents any further operation on the pipeline889 * occurs.890 */891void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe)892{893	if (pipe->input)894		omap3isp_video_cancel_stream(pipe->input);895	if (pipe->output)896		omap3isp_video_cancel_stream(pipe->output);897}898 899/*900 * isp_pipeline_resume - Resume streaming on a pipeline901 * @pipe: ISP pipeline902 *903 * Resume video output and input and re-enable pipeline.904 */905static void isp_pipeline_resume(struct isp_pipeline *pipe)906{907	int singleshot = pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT;908 909	omap3isp_video_resume(pipe->output, !singleshot);910	if (singleshot)911		omap3isp_video_resume(pipe->input, 0);912	isp_pipeline_enable(pipe, pipe->stream_state);913}914 915/*916 * isp_pipeline_suspend - Suspend streaming on a pipeline917 * @pipe: ISP pipeline918 *919 * Suspend pipeline.920 */921static void isp_pipeline_suspend(struct isp_pipeline *pipe)922{923	isp_pipeline_disable(pipe);924}925 926/*927 * isp_pipeline_is_last - Verify if entity has an enabled link to the output928 *			  video node929 * @me: ISP module's media entity930 *931 * Returns 1 if the entity has an enabled link to the output video node or 0932 * otherwise. It's true only while pipeline can have no more than one output933 * node.934 */935static int isp_pipeline_is_last(struct media_entity *me)936{937	struct isp_pipeline *pipe;938	struct media_pad *pad;939 940	pipe = to_isp_pipeline(me);941	if (!pipe || pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)942		return 0;943	pad = media_pad_remote_pad_first(&pipe->output->pad);944	return pad->entity == me;945}946 947/*948 * isp_suspend_module_pipeline - Suspend pipeline to which belongs the module949 * @me: ISP module's media entity950 *951 * Suspend the whole pipeline if module's entity has an enabled link to the952 * output video node. It works only while pipeline can have no more than one953 * output node.954 */955static void isp_suspend_module_pipeline(struct media_entity *me)956{957	if (isp_pipeline_is_last(me))958		isp_pipeline_suspend(to_isp_pipeline(me));959}960 961/*962 * isp_resume_module_pipeline - Resume pipeline to which belongs the module963 * @me: ISP module's media entity964 *965 * Resume the whole pipeline if module's entity has an enabled link to the966 * output video node. It works only while pipeline can have no more than one967 * output node.968 */969static void isp_resume_module_pipeline(struct media_entity *me)970{971	if (isp_pipeline_is_last(me))972		isp_pipeline_resume(to_isp_pipeline(me));973}974 975/*976 * isp_suspend_modules - Suspend ISP submodules.977 * @isp: OMAP3 ISP device978 *979 * Returns 0 if suspend left in idle state all the submodules properly,980 * or returns 1 if a general Reset is required to suspend the submodules.981 */982static int __maybe_unused isp_suspend_modules(struct isp_device *isp)983{984	unsigned long timeout;985 986	omap3isp_stat_suspend(&isp->isp_aewb);987	omap3isp_stat_suspend(&isp->isp_af);988	omap3isp_stat_suspend(&isp->isp_hist);989	isp_suspend_module_pipeline(&isp->isp_res.subdev.entity);990	isp_suspend_module_pipeline(&isp->isp_prev.subdev.entity);991	isp_suspend_module_pipeline(&isp->isp_ccdc.subdev.entity);992	isp_suspend_module_pipeline(&isp->isp_csi2a.subdev.entity);993	isp_suspend_module_pipeline(&isp->isp_ccp2.subdev.entity);994 995	timeout = jiffies + ISP_STOP_TIMEOUT;996	while (omap3isp_stat_busy(&isp->isp_af)997	    || omap3isp_stat_busy(&isp->isp_aewb)998	    || omap3isp_stat_busy(&isp->isp_hist)999	    || omap3isp_preview_busy(&isp->isp_prev)1000	    || omap3isp_resizer_busy(&isp->isp_res)1001	    || omap3isp_ccdc_busy(&isp->isp_ccdc)) {1002		if (time_after(jiffies, timeout)) {1003			dev_info(isp->dev, "can't stop modules.\n");1004			return 1;1005		}1006		msleep(1);1007	}1008 1009	return 0;1010}1011 1012/*1013 * isp_resume_modules - Resume ISP submodules.1014 * @isp: OMAP3 ISP device1015 */1016static void __maybe_unused isp_resume_modules(struct isp_device *isp)1017{1018	omap3isp_stat_resume(&isp->isp_aewb);1019	omap3isp_stat_resume(&isp->isp_af);1020	omap3isp_stat_resume(&isp->isp_hist);1021	isp_resume_module_pipeline(&isp->isp_res.subdev.entity);1022	isp_resume_module_pipeline(&isp->isp_prev.subdev.entity);1023	isp_resume_module_pipeline(&isp->isp_ccdc.subdev.entity);1024	isp_resume_module_pipeline(&isp->isp_csi2a.subdev.entity);1025	isp_resume_module_pipeline(&isp->isp_ccp2.subdev.entity);1026}1027 1028/*1029 * isp_reset - Reset ISP with a timeout wait for idle.1030 * @isp: OMAP3 ISP device1031 */1032static int isp_reset(struct isp_device *isp)1033{1034	unsigned long timeout = 0;1035 1036	isp_reg_writel(isp,1037		       isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG)1038		       | ISP_SYSCONFIG_SOFTRESET,1039		       OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);1040	while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN,1041			       ISP_SYSSTATUS) & 0x1)) {1042		if (timeout++ > 10000) {1043			dev_alert(isp->dev, "cannot reset ISP\n");1044			return -ETIMEDOUT;1045		}1046		udelay(1);1047	}1048 1049	isp->stop_failure = false;1050	media_entity_enum_zero(&isp->crashed);1051	return 0;1052}1053 1054/*1055 * isp_save_context - Saves the values of the ISP module registers.1056 * @isp: OMAP3 ISP device1057 * @reg_list: Structure containing pairs of register address and value to1058 *            modify on OMAP.1059 */1060static void1061isp_save_context(struct isp_device *isp, struct isp_reg *reg_list)1062{1063	struct isp_reg *next = reg_list;1064 1065	for (; next->reg != ISP_TOK_TERM; next++)1066		next->val = isp_reg_readl(isp, next->mmio_range, next->reg);1067}1068 1069/*1070 * isp_restore_context - Restores the values of the ISP module registers.1071 * @isp: OMAP3 ISP device1072 * @reg_list: Structure containing pairs of register address and value to1073 *            modify on OMAP.1074 */1075static void1076isp_restore_context(struct isp_device *isp, struct isp_reg *reg_list)1077{1078	struct isp_reg *next = reg_list;1079 1080	for (; next->reg != ISP_TOK_TERM; next++)1081		isp_reg_writel(isp, next->val, next->mmio_range, next->reg);1082}1083 1084/*1085 * isp_save_ctx - Saves ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.1086 * @isp: OMAP3 ISP device1087 *1088 * Routine for saving the context of each module in the ISP.1089 * CCDC, HIST, H3A, PREV, RESZ and MMU.1090 */1091static void isp_save_ctx(struct isp_device *isp)1092{1093	isp_save_context(isp, isp_reg_list);1094	omap_iommu_save_ctx(isp->dev);1095}1096 1097/*1098 * isp_restore_ctx - Restores ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.1099 * @isp: OMAP3 ISP device1100 *1101 * Routine for restoring the context of each module in the ISP.1102 * CCDC, HIST, H3A, PREV, RESZ and MMU.1103 */1104static void isp_restore_ctx(struct isp_device *isp)1105{1106	isp_restore_context(isp, isp_reg_list);1107	omap_iommu_restore_ctx(isp->dev);1108	omap3isp_ccdc_restore_context(isp);1109	omap3isp_preview_restore_context(isp);1110}1111 1112/* -----------------------------------------------------------------------------1113 * SBL resources management1114 */1115#define OMAP3_ISP_SBL_READ	(OMAP3_ISP_SBL_CSI1_READ | \1116				 OMAP3_ISP_SBL_CCDC_LSC_READ | \1117				 OMAP3_ISP_SBL_PREVIEW_READ | \1118				 OMAP3_ISP_SBL_RESIZER_READ)1119#define OMAP3_ISP_SBL_WRITE	(OMAP3_ISP_SBL_CSI1_WRITE | \1120				 OMAP3_ISP_SBL_CSI2A_WRITE | \1121				 OMAP3_ISP_SBL_CSI2C_WRITE | \1122				 OMAP3_ISP_SBL_CCDC_WRITE | \1123				 OMAP3_ISP_SBL_PREVIEW_WRITE)1124 1125void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res)1126{1127	u32 sbl = 0;1128 1129	isp->sbl_resources |= res;1130 1131	if (isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ)1132		sbl |= ISPCTRL_SBL_SHARED_RPORTA;1133 1134	if (isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ)1135		sbl |= ISPCTRL_SBL_SHARED_RPORTB;1136 1137	if (isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE)1138		sbl |= ISPCTRL_SBL_SHARED_WPORTC;1139 1140	if (isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE)1141		sbl |= ISPCTRL_SBL_WR0_RAM_EN;1142 1143	if (isp->sbl_resources & OMAP3_ISP_SBL_WRITE)1144		sbl |= ISPCTRL_SBL_WR1_RAM_EN;1145 1146	if (isp->sbl_resources & OMAP3_ISP_SBL_READ)1147		sbl |= ISPCTRL_SBL_RD_RAM_EN;1148 1149	isp_reg_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);1150}1151 1152void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res)1153{1154	u32 sbl = 0;1155 1156	isp->sbl_resources &= ~res;1157 1158	if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ))1159		sbl |= ISPCTRL_SBL_SHARED_RPORTA;1160 1161	if (!(isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ))1162		sbl |= ISPCTRL_SBL_SHARED_RPORTB;1163 1164	if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE))1165		sbl |= ISPCTRL_SBL_SHARED_WPORTC;1166 1167	if (!(isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE))1168		sbl |= ISPCTRL_SBL_WR0_RAM_EN;1169 1170	if (!(isp->sbl_resources & OMAP3_ISP_SBL_WRITE))1171		sbl |= ISPCTRL_SBL_WR1_RAM_EN;1172 1173	if (!(isp->sbl_resources & OMAP3_ISP_SBL_READ))1174		sbl |= ISPCTRL_SBL_RD_RAM_EN;1175 1176	isp_reg_clr(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);1177}1178 1179/*1180 * isp_module_sync_idle - Helper to sync module with its idle state1181 * @me: ISP submodule's media entity1182 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization1183 * @stopping: flag which tells module wants to stop1184 *1185 * This function checks if ISP submodule needs to wait for next interrupt. If1186 * yes, makes the caller to sleep while waiting for such event.1187 */1188int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,1189			      atomic_t *stopping)1190{1191	struct isp_pipeline *pipe = to_isp_pipeline(me);1192 1193	if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED ||1194	    (pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT &&1195	     !isp_pipeline_ready(pipe)))1196		return 0;1197 1198	/*1199	 * atomic_set() doesn't include memory barrier on ARM platform for SMP1200	 * scenario. We'll call it here to avoid race conditions.1201	 */1202	atomic_set(stopping, 1);1203	smp_mb();1204 1205	/*1206	 * If module is the last one, it's writing to memory. In this case,1207	 * it's necessary to check if the module is already paused due to1208	 * DMA queue underrun or if it has to wait for next interrupt to be1209	 * idle.1210	 * If it isn't the last one, the function won't sleep but *stopping1211	 * will still be set to warn next submodule caller's interrupt the1212	 * module wants to be idle.1213	 */1214	if (isp_pipeline_is_last(me)) {1215		struct isp_video *video = pipe->output;1216		unsigned long flags;1217		spin_lock_irqsave(&video->irqlock, flags);1218		if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {1219			spin_unlock_irqrestore(&video->irqlock, flags);1220			atomic_set(stopping, 0);1221			smp_mb();1222			return 0;1223		}1224		spin_unlock_irqrestore(&video->irqlock, flags);1225		if (!wait_event_timeout(*wait, !atomic_read(stopping),1226					msecs_to_jiffies(1000))) {1227			atomic_set(stopping, 0);1228			smp_mb();1229			return -ETIMEDOUT;1230		}1231	}1232 1233	return 0;1234}1235 1236/*1237 * omap3isp_module_sync_is_stopping - Helper to verify if module was stopping1238 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization1239 * @stopping: flag which tells module wants to stop1240 *1241 * This function checks if ISP submodule was stopping. In case of yes, it1242 * notices the caller by setting stopping to 0 and waking up the wait queue.1243 * Returns 1 if it was stopping or 0 otherwise.1244 */1245int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,1246				     atomic_t *stopping)1247{1248	if (atomic_cmpxchg(stopping, 1, 0)) {1249		wake_up(wait);1250		return 1;1251	}1252 1253	return 0;1254}1255 1256/* --------------------------------------------------------------------------1257 * Clock management1258 */1259 1260#define ISPCTRL_CLKS_MASK	(ISPCTRL_H3A_CLK_EN | \1261				 ISPCTRL_HIST_CLK_EN | \1262				 ISPCTRL_RSZ_CLK_EN | \1263				 (ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN) | \1264				 (ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN))1265 1266static void __isp_subclk_update(struct isp_device *isp)1267{1268	u32 clk = 0;1269 1270	/* AEWB and AF share the same clock. */1271	if (isp->subclk_resources &1272	    (OMAP3_ISP_SUBCLK_AEWB | OMAP3_ISP_SUBCLK_AF))1273		clk |= ISPCTRL_H3A_CLK_EN;1274 1275	if (isp->subclk_resources & OMAP3_ISP_SUBCLK_HIST)1276		clk |= ISPCTRL_HIST_CLK_EN;1277 1278	if (isp->subclk_resources & OMAP3_ISP_SUBCLK_RESIZER)1279		clk |= ISPCTRL_RSZ_CLK_EN;1280 1281	/* NOTE: For CCDC & Preview submodules, we need to affect internal1282	 *       RAM as well.1283	 */1284	if (isp->subclk_resources & OMAP3_ISP_SUBCLK_CCDC)1285		clk |= ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN;1286 1287	if (isp->subclk_resources & OMAP3_ISP_SUBCLK_PREVIEW)1288		clk |= ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN;1289 1290	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,1291			ISPCTRL_CLKS_MASK, clk);1292}1293 1294void omap3isp_subclk_enable(struct isp_device *isp,1295			    enum isp_subclk_resource res)1296{1297	isp->subclk_resources |= res;1298 1299	__isp_subclk_update(isp);1300}1301 1302void omap3isp_subclk_disable(struct isp_device *isp,1303			     enum isp_subclk_resource res)1304{1305	isp->subclk_resources &= ~res;1306 1307	__isp_subclk_update(isp);1308}1309 1310/*1311 * isp_enable_clocks - Enable ISP clocks1312 * @isp: OMAP3 ISP device1313 *1314 * Return 0 if successful, or clk_prepare_enable return value if any of them1315 * fails.1316 */1317static int isp_enable_clocks(struct isp_device *isp)1318{1319	int r;1320	unsigned long rate;1321 1322	r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_ICK]);1323	if (r) {1324		dev_err(isp->dev, "failed to enable cam_ick clock\n");1325		goto out_clk_enable_ick;1326	}1327	r = clk_set_rate(isp->clock[ISP_CLK_CAM_MCLK], CM_CAM_MCLK_HZ);1328	if (r) {1329		dev_err(isp->dev, "clk_set_rate for cam_mclk failed\n");1330		goto out_clk_enable_mclk;1331	}1332	r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_MCLK]);1333	if (r) {1334		dev_err(isp->dev, "failed to enable cam_mclk clock\n");1335		goto out_clk_enable_mclk;1336	}1337	rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);1338	if (rate != CM_CAM_MCLK_HZ)1339		dev_warn(isp->dev, "unexpected cam_mclk rate:\n"1340				   " expected : %d\n"1341				   " actual   : %ld\n", CM_CAM_MCLK_HZ, rate);1342	r = clk_prepare_enable(isp->clock[ISP_CLK_CSI2_FCK]);1343	if (r) {1344		dev_err(isp->dev, "failed to enable csi2_fck clock\n");1345		goto out_clk_enable_csi2_fclk;1346	}1347	return 0;1348 1349out_clk_enable_csi2_fclk:1350	clk_disable_unprepare(isp->clock[ISP_CLK_CAM_MCLK]);1351out_clk_enable_mclk:1352	clk_disable_unprepare(isp->clock[ISP_CLK_CAM_ICK]);1353out_clk_enable_ick:1354	return r;1355}1356 1357/*1358 * isp_disable_clocks - Disable ISP clocks1359 * @isp: OMAP3 ISP device1360 */1361static void isp_disable_clocks(struct isp_device *isp)1362{1363	clk_disable_unprepare(isp->clock[ISP_CLK_CAM_ICK]);1364	clk_disable_unprepare(isp->clock[ISP_CLK_CAM_MCLK]);1365	clk_disable_unprepare(isp->clock[ISP_CLK_CSI2_FCK]);1366}1367 1368static const char *isp_clocks[] = {1369	"cam_ick",1370	"cam_mclk",1371	"csi2_96m_fck",1372	"l3_ick",1373};1374 1375static int isp_get_clocks(struct isp_device *isp)1376{1377	struct clk *clk;1378	unsigned int i;1379 1380	for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {1381		clk = devm_clk_get(isp->dev, isp_clocks[i]);1382		if (IS_ERR(clk)) {1383			dev_err(isp->dev, "clk_get %s failed\n", isp_clocks[i]);1384			return PTR_ERR(clk);1385		}1386 1387		isp->clock[i] = clk;1388	}1389 1390	return 0;1391}1392 1393/*1394 * omap3isp_get - Acquire the ISP resource.1395 *1396 * Initializes the clocks for the first acquire.1397 *1398 * Increment the reference count on the ISP. If the first reference is taken,1399 * enable clocks and power-up all submodules.1400 *1401 * Return a pointer to the ISP device structure, or NULL if an error occurred.1402 */1403static struct isp_device *__omap3isp_get(struct isp_device *isp, bool irq)1404{1405	struct isp_device *__isp = isp;1406 1407	if (isp == NULL)1408		return NULL;1409 1410	mutex_lock(&isp->isp_mutex);1411	if (isp->ref_count > 0)1412		goto out;1413 1414	if (isp_enable_clocks(isp) < 0) {1415		__isp = NULL;1416		goto out;1417	}1418 1419	/* We don't want to restore context before saving it! */1420	if (isp->has_context)1421		isp_restore_ctx(isp);1422 1423	if (irq)1424		isp_enable_interrupts(isp);1425 1426out:1427	if (__isp != NULL)1428		isp->ref_count++;1429	mutex_unlock(&isp->isp_mutex);1430 1431	return __isp;1432}1433 1434struct isp_device *omap3isp_get(struct isp_device *isp)1435{1436	return __omap3isp_get(isp, true);1437}1438 1439/*1440 * omap3isp_put - Release the ISP1441 *1442 * Decrement the reference count on the ISP. If the last reference is released,1443 * power-down all submodules, disable clocks and free temporary buffers.1444 */1445static void __omap3isp_put(struct isp_device *isp, bool save_ctx)1446{1447	if (isp == NULL)1448		return;1449 1450	mutex_lock(&isp->isp_mutex);1451	BUG_ON(isp->ref_count == 0);1452	if (--isp->ref_count == 0) {1453		isp_disable_interrupts(isp);1454		if (save_ctx) {1455			isp_save_ctx(isp);1456			isp->has_context = 1;1457		}1458		/* Reset the ISP if an entity has failed to stop. This is the1459		 * only way to recover from such conditions.1460		 */1461		if (!media_entity_enum_empty(&isp->crashed) ||1462		    isp->stop_failure)1463			isp_reset(isp);1464		isp_disable_clocks(isp);1465	}1466	mutex_unlock(&isp->isp_mutex);1467}1468 1469void omap3isp_put(struct isp_device *isp)1470{1471	__omap3isp_put(isp, true);1472}1473 1474/* --------------------------------------------------------------------------1475 * Platform device driver1476 */1477 1478/*1479 * omap3isp_print_status - Prints the values of the ISP Control Module registers1480 * @isp: OMAP3 ISP device1481 */1482#define ISP_PRINT_REGISTER(isp, name)\1483	dev_dbg(isp->dev, "###ISP " #name "=0x%08x\n", \1484		isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_##name))1485#define SBL_PRINT_REGISTER(isp, name)\1486	dev_dbg(isp->dev, "###SBL " #name "=0x%08x\n", \1487		isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_##name))1488 1489void omap3isp_print_status(struct isp_device *isp)1490{1491	dev_dbg(isp->dev, "-------------ISP Register dump--------------\n");1492 1493	ISP_PRINT_REGISTER(isp, SYSCONFIG);1494	ISP_PRINT_REGISTER(isp, SYSSTATUS);1495	ISP_PRINT_REGISTER(isp, IRQ0ENABLE);1496	ISP_PRINT_REGISTER(isp, IRQ0STATUS);1497	ISP_PRINT_REGISTER(isp, TCTRL_GRESET_LENGTH);1498	ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_REPLAY);1499	ISP_PRINT_REGISTER(isp, CTRL);1500	ISP_PRINT_REGISTER(isp, TCTRL_CTRL);1501	ISP_PRINT_REGISTER(isp, TCTRL_FRAME);1502	ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_DELAY);1503	ISP_PRINT_REGISTER(isp, TCTRL_STRB_DELAY);1504	ISP_PRINT_REGISTER(isp, TCTRL_SHUT_DELAY);1505	ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_LENGTH);1506	ISP_PRINT_REGISTER(isp, TCTRL_STRB_LENGTH);1507	ISP_PRINT_REGISTER(isp, TCTRL_SHUT_LENGTH);1508 1509	SBL_PRINT_REGISTER(isp, PCR);1510	SBL_PRINT_REGISTER(isp, SDR_REQ_EXP);1511 1512	dev_dbg(isp->dev, "--------------------------------------------\n");1513}1514 1515#ifdef CONFIG_PM1516 1517/*1518 * Power management support.1519 *1520 * As the ISP can't properly handle an input video stream interruption on a non1521 * frame boundary, the ISP pipelines need to be stopped before sensors get1522 * suspended. However, as suspending the sensors can require a running clock,1523 * which can be provided by the ISP, the ISP can't be completely suspended1524 * before the sensor.1525 *1526 * To solve this problem power management support is split into prepare/complete1527 * and suspend/resume operations. The pipelines are stopped in prepare() and the1528 * ISP clocks get disabled in suspend(). Similarly, the clocks are re-enabled in1529 * resume(), and the pipelines are restarted in complete().1530 *1531 * TODO: PM dependencies between the ISP and sensors are not modelled explicitly1532 * yet.1533 */1534static int isp_pm_prepare(struct device *dev)1535{1536	struct isp_device *isp = dev_get_drvdata(dev);1537	int reset;1538 1539	WARN_ON(mutex_is_locked(&isp->isp_mutex));1540 1541	if (isp->ref_count == 0)1542		return 0;1543 1544	reset = isp_suspend_modules(isp);1545	isp_disable_interrupts(isp);1546	isp_save_ctx(isp);1547	if (reset)1548		isp_reset(isp);1549 1550	return 0;1551}1552 1553static int isp_pm_suspend(struct device *dev)1554{1555	struct isp_device *isp = dev_get_drvdata(dev);1556 1557	WARN_ON(mutex_is_locked(&isp->isp_mutex));1558 1559	if (isp->ref_count)1560		isp_disable_clocks(isp);1561 1562	return 0;1563}1564 1565static int isp_pm_resume(struct device *dev)1566{1567	struct isp_device *isp = dev_get_drvdata(dev);1568 1569	if (isp->ref_count == 0)1570		return 0;1571 1572	return isp_enable_clocks(isp);1573}1574 1575static void isp_pm_complete(struct device *dev)1576{1577	struct isp_device *isp = dev_get_drvdata(dev);1578 1579	if (isp->ref_count == 0)1580		return;1581 1582	isp_restore_ctx(isp);1583	isp_enable_interrupts(isp);1584	isp_resume_modules(isp);1585}1586 1587#else1588 1589#define isp_pm_prepare	NULL1590#define isp_pm_suspend	NULL1591#define isp_pm_resume	NULL1592#define isp_pm_complete	NULL1593 1594#endif /* CONFIG_PM */1595 1596static void isp_unregister_entities(struct isp_device *isp)1597{1598	media_device_unregister(&isp->media_dev);1599 1600	omap3isp_csi2_unregister_entities(&isp->isp_csi2a);1601	omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);1602	omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);1603	omap3isp_preview_unregister_entities(&isp->isp_prev);1604	omap3isp_resizer_unregister_entities(&isp->isp_res);1605	omap3isp_stat_unregister_entities(&isp->isp_aewb);1606	omap3isp_stat_unregister_entities(&isp->isp_af);1607	omap3isp_stat_unregister_entities(&isp->isp_hist);1608 1609	v4l2_device_unregister(&isp->v4l2_dev);1610	media_device_cleanup(&isp->media_dev);1611}1612 1613static int isp_link_entity(1614	struct isp_device *isp, struct media_entity *entity,1615	enum isp_interface_type interface)1616{1617	struct media_entity *input;1618	unsigned int flags;1619	unsigned int pad;1620	unsigned int i;1621 1622	/* Connect the sensor to the correct interface module.1623	 * Parallel sensors are connected directly to the CCDC, while1624	 * serial sensors are connected to the CSI2a, CCP2b or CSI2c1625	 * receiver through CSIPHY1 or CSIPHY2.1626	 */1627	switch (interface) {1628	case ISP_INTERFACE_PARALLEL:1629		input = &isp->isp_ccdc.subdev.entity;1630		pad = CCDC_PAD_SINK;1631		flags = 0;1632		break;1633 1634	case ISP_INTERFACE_CSI2A_PHY2:1635		input = &isp->isp_csi2a.subdev.entity;1636		pad = CSI2_PAD_SINK;1637		flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;1638		break;1639 1640	case ISP_INTERFACE_CCP2B_PHY1:1641	case ISP_INTERFACE_CCP2B_PHY2:1642		input = &isp->isp_ccp2.subdev.entity;1643		pad = CCP2_PAD_SINK;1644		flags = 0;1645		break;1646 1647	case ISP_INTERFACE_CSI2C_PHY1:1648		input = &isp->isp_csi2c.subdev.entity;1649		pad = CSI2_PAD_SINK;1650		flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;1651		break;1652 1653	default:1654		dev_err(isp->dev, "%s: invalid interface type %u\n", __func__,1655			interface);1656		return -EINVAL;1657	}1658 1659	/*1660	 * Not all interfaces are available on all revisions of the1661	 * ISP. The sub-devices of those interfaces aren't initialised1662	 * in such a case. Check this by ensuring the num_pads is1663	 * non-zero.1664	 */1665	if (!input->num_pads) {1666		dev_err(isp->dev, "%s: invalid input %u\n", entity->name,1667			interface);1668		return -EINVAL;1669	}1670 1671	for (i = 0; i < entity->num_pads; i++) {1672		if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE)1673			break;1674	}1675	if (i == entity->num_pads) {1676		dev_err(isp->dev, "%s: no source pad in external entity %s\n",1677			__func__, entity->name);1678		return -EINVAL;1679	}1680 1681	return media_create_pad_link(entity, i, input, pad, flags);1682}1683 1684static int isp_register_entities(struct isp_device *isp)1685{1686	int ret;1687 1688	isp->media_dev.dev = isp->dev;1689	strscpy(isp->media_dev.model, "TI OMAP3 ISP",1690		sizeof(isp->media_dev.model));1691	isp->media_dev.hw_revision = isp->revision;1692	isp->media_dev.ops = &isp_media_ops;1693	media_device_init(&isp->media_dev);1694 1695	isp->v4l2_dev.mdev = &isp->media_dev;1696	ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);1697	if (ret < 0) {1698		dev_err(isp->dev, "%s: V4L2 device registration failed (%d)\n",1699			__func__, ret);1700		goto done;1701	}1702 1703	/* Register internal entities */1704	ret = omap3isp_ccp2_register_entities(&isp->isp_ccp2, &isp->v4l2_dev);1705	if (ret < 0)1706		goto done;1707 1708	ret = omap3isp_csi2_register_entities(&isp->isp_csi2a, &isp->v4l2_dev);1709	if (ret < 0)1710		goto done;1711 1712	ret = omap3isp_ccdc_register_entities(&isp->isp_ccdc, &isp->v4l2_dev);1713	if (ret < 0)1714		goto done;1715 1716	ret = omap3isp_preview_register_entities(&isp->isp_prev,1717						 &isp->v4l2_dev);1718	if (ret < 0)1719		goto done;1720 1721	ret = omap3isp_resizer_register_entities(&isp->isp_res, &isp->v4l2_dev);1722	if (ret < 0)1723		goto done;1724 1725	ret = omap3isp_stat_register_entities(&isp->isp_aewb, &isp->v4l2_dev);1726	if (ret < 0)1727		goto done;1728 1729	ret = omap3isp_stat_register_entities(&isp->isp_af, &isp->v4l2_dev);1730	if (ret < 0)1731		goto done;1732 1733	ret = omap3isp_stat_register_entities(&isp->isp_hist, &isp->v4l2_dev);1734	if (ret < 0)1735		goto done;1736 1737done:1738	if (ret < 0)1739		isp_unregister_entities(isp);1740 1741	return ret;1742}1743 1744/*1745 * isp_create_links() - Create links for internal and external ISP entities1746 * @isp : Pointer to ISP device1747 *1748 * This function creates all links between ISP internal and external entities.1749 *1750 * Return: A negative error code on failure or zero on success. Possible error1751 * codes are those returned by media_create_pad_link().1752 */1753static int isp_create_links(struct isp_device *isp)1754{1755	int ret;1756 1757	/* Create links between entities and video nodes. */1758	ret = media_create_pad_link(1759			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,1760			&isp->isp_csi2a.video_out.video.entity, 0, 0);1761	if (ret < 0)1762		return ret;1763 1764	ret = media_create_pad_link(1765			&isp->isp_ccp2.video_in.video.entity, 0,1766			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SINK, 0);1767	if (ret < 0)1768		return ret;1769 1770	ret = media_create_pad_link(1771			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,1772			&isp->isp_ccdc.video_out.video.entity, 0, 0);1773	if (ret < 0)1774		return ret;1775 1776	ret = media_create_pad_link(1777			&isp->isp_prev.video_in.video.entity, 0,1778			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);1779	if (ret < 0)1780		return ret;1781 1782	ret = media_create_pad_link(1783			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,1784			&isp->isp_prev.video_out.video.entity, 0, 0);1785	if (ret < 0)1786		return ret;1787 1788	ret = media_create_pad_link(1789			&isp->isp_res.video_in.video.entity, 0,1790			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);1791	if (ret < 0)1792		return ret;1793 1794	ret = media_create_pad_link(1795			&isp->isp_res.subdev.entity, RESZ_PAD_SOURCE,1796			&isp->isp_res.video_out.video.entity, 0, 0);1797 1798	if (ret < 0)1799		return ret;1800 1801	/* Create links between entities. */1802	ret = media_create_pad_link(1803			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,1804			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);1805	if (ret < 0)1806		return ret;1807 1808	ret = media_create_pad_link(1809			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,1810			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);1811	if (ret < 0)1812		return ret;1813 1814	ret = media_create_pad_link(1815			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,1816			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);1817	if (ret < 0)1818		return ret;1819 1820	ret = media_create_pad_link(1821			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,1822			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);1823	if (ret < 0)1824		return ret;1825 1826	ret = media_create_pad_link(1827			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,1828			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);1829	if (ret < 0)1830		return ret;1831 1832	ret = media_create_pad_link(1833			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,1834			&isp->isp_aewb.subdev.entity, 0,1835			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);1836	if (ret < 0)1837		return ret;1838 1839	ret = media_create_pad_link(1840			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,1841			&isp->isp_af.subdev.entity, 0,1842			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);1843	if (ret < 0)1844		return ret;1845 1846	ret = media_create_pad_link(1847			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,1848			&isp->isp_hist.subdev.entity, 0,1849			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);1850	if (ret < 0)1851		return ret;1852 1853	return 0;1854}1855 1856static void isp_cleanup_modules(struct isp_device *isp)1857{1858	omap3isp_h3a_aewb_cleanup(isp);1859	omap3isp_h3a_af_cleanup(isp);1860	omap3isp_hist_cleanup(isp);1861	omap3isp_resizer_cleanup(isp);1862	omap3isp_preview_cleanup(isp);1863	omap3isp_ccdc_cleanup(isp);1864	omap3isp_ccp2_cleanup(isp);1865	omap3isp_csi2_cleanup(isp);1866	omap3isp_csiphy_cleanup(isp);1867}1868 1869static int isp_initialize_modules(struct isp_device *isp)1870{1871	int ret;1872 1873	ret = omap3isp_csiphy_init(isp);1874	if (ret < 0) {1875		dev_err(isp->dev, "CSI PHY initialization failed\n");1876		return ret;1877	}1878 1879	ret = omap3isp_csi2_init(isp);1880	if (ret < 0) {1881		dev_err(isp->dev, "CSI2 initialization failed\n");1882		goto error_csi2;1883	}1884 1885	ret = omap3isp_ccp2_init(isp);1886	if (ret < 0) {1887		dev_err_probe(isp->dev, ret, "CCP2 initialization failed\n");1888		goto error_ccp2;1889	}1890 1891	ret = omap3isp_ccdc_init(isp);1892	if (ret < 0) {1893		dev_err(isp->dev, "CCDC initialization failed\n");1894		goto error_ccdc;1895	}1896 1897	ret = omap3isp_preview_init(isp);1898	if (ret < 0) {1899		dev_err(isp->dev, "Preview initialization failed\n");1900		goto error_preview;1901	}1902 1903	ret = omap3isp_resizer_init(isp);1904	if (ret < 0) {1905		dev_err(isp->dev, "Resizer initialization failed\n");1906		goto error_resizer;1907	}1908 1909	ret = omap3isp_hist_init(isp);1910	if (ret < 0) {1911		dev_err(isp->dev, "Histogram initialization failed\n");1912		goto error_hist;1913	}1914 1915	ret = omap3isp_h3a_aewb_init(isp);1916	if (ret < 0) {1917		dev_err(isp->dev, "H3A AEWB initialization failed\n");1918		goto error_h3a_aewb;1919	}1920 1921	ret = omap3isp_h3a_af_init(isp);1922	if (ret < 0) {1923		dev_err(isp->dev, "H3A AF initialization failed\n");1924		goto error_h3a_af;1925	}1926 1927	return 0;1928 1929error_h3a_af:1930	omap3isp_h3a_aewb_cleanup(isp);1931error_h3a_aewb:1932	omap3isp_hist_cleanup(isp);1933error_hist:1934	omap3isp_resizer_cleanup(isp);1935error_resizer:1936	omap3isp_preview_cleanup(isp);1937error_preview:1938	omap3isp_ccdc_cleanup(isp);1939error_ccdc:1940	omap3isp_ccp2_cleanup(isp);1941error_ccp2:1942	omap3isp_csi2_cleanup(isp);1943error_csi2:1944	omap3isp_csiphy_cleanup(isp);1945 1946	return ret;1947}1948 1949static void isp_detach_iommu(struct isp_device *isp)1950{1951#ifdef CONFIG_ARM_DMA_USE_IOMMU1952	arm_iommu_detach_device(isp->dev);1953	arm_iommu_release_mapping(isp->mapping);1954	isp->mapping = NULL;1955#endif1956}1957 1958static int isp_attach_iommu(struct isp_device *isp)1959{1960#ifdef CONFIG_ARM_DMA_USE_IOMMU1961	struct dma_iommu_mapping *mapping;1962	int ret;1963 1964	/*1965	 * Create the ARM mapping, used by the ARM DMA mapping core to allocate1966	 * VAs. This will allocate a corresponding IOMMU domain.1967	 */1968	mapping = arm_iommu_create_mapping(isp->dev, SZ_1G, SZ_2G);1969	if (IS_ERR(mapping)) {1970		dev_err(isp->dev, "failed to create ARM IOMMU mapping\n");1971		return PTR_ERR(mapping);1972	}1973 1974	isp->mapping = mapping;1975 1976	/* Attach the ARM VA mapping to the device. */1977	ret = arm_iommu_attach_device(isp->dev, mapping);1978	if (ret < 0) {1979		dev_err(isp->dev, "failed to attach device to VA mapping\n");1980		goto error;1981	}1982 1983	return 0;1984 1985error:1986	arm_iommu_release_mapping(isp->mapping);1987	isp->mapping = NULL;1988	return ret;1989#else1990	return -ENODEV;1991#endif1992}1993 1994/*1995 * isp_remove - Remove ISP platform device1996 * @pdev: Pointer to ISP platform device1997 *1998 * Always returns 0.1999 */2000static void isp_remove(struct platform_device *pdev)2001{2002	struct isp_device *isp = platform_get_drvdata(pdev);2003 2004	v4l2_async_nf_unregister(&isp->notifier);2005	v4l2_async_nf_cleanup(&isp->notifier);2006	isp_unregister_entities(isp);2007	isp_cleanup_modules(isp);2008	isp_xclk_cleanup(isp);2009 2010	__omap3isp_get(isp, false);2011	isp_detach_iommu(isp);2012	__omap3isp_put(isp, false);2013 2014	media_entity_enum_cleanup(&isp->crashed);2015 2016	kfree(isp);2017}2018 2019enum isp_of_phy {2020	ISP_OF_PHY_PARALLEL = 0,2021	ISP_OF_PHY_CSIPHY1,2022	ISP_OF_PHY_CSIPHY2,2023};2024 2025static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,2026				     struct v4l2_subdev *sd,2027				     struct v4l2_async_connection *asc)2028{2029	struct isp_device *isp = container_of(async, struct isp_device,2030					      notifier);2031	struct isp_bus_cfg *bus_cfg =2032		&container_of(asc, struct isp_async_subdev, asd)->bus;2033	int ret;2034 2035	mutex_lock(&isp->media_dev.graph_mutex);2036	ret = isp_link_entity(isp, &sd->entity, bus_cfg->interface);2037	mutex_unlock(&isp->media_dev.graph_mutex);2038 2039	return ret;2040}2041 2042static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)2043{2044	struct isp_device *isp = container_of(async, struct isp_device,2045					      notifier);2046	int ret;2047 2048	mutex_lock(&isp->media_dev.graph_mutex);2049	ret = media_entity_enum_init(&isp->crashed, &isp->media_dev);2050	mutex_unlock(&isp->media_dev.graph_mutex);2051	if (ret)2052		return ret;2053 2054	ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);2055	if (ret < 0)2056		return ret;2057 2058	return media_device_register(&isp->media_dev);2059}2060 2061static void isp_parse_of_parallel_endpoint(struct device *dev,2062					   struct v4l2_fwnode_endpoint *vep,2063					   struct isp_bus_cfg *buscfg)2064{2065	buscfg->interface = ISP_INTERFACE_PARALLEL;2066	buscfg->bus.parallel.data_lane_shift = vep->bus.parallel.data_shift;2067	buscfg->bus.parallel.clk_pol =2068		!!(vep->bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING);2069	buscfg->bus.parallel.hs_pol =2070		!!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);2071	buscfg->bus.parallel.vs_pol =2072		!!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);2073	buscfg->bus.parallel.fld_pol =2074		!!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);2075	buscfg->bus.parallel.data_pol =2076		!!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);2077	buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656;2078}2079 2080static void isp_parse_of_csi2_endpoint(struct device *dev,2081				       struct v4l2_fwnode_endpoint *vep,2082				       struct isp_bus_cfg *buscfg)2083{2084	unsigned int i;2085 2086	buscfg->bus.csi2.lanecfg.clk.pos = vep->bus.mipi_csi2.clock_lane;2087	buscfg->bus.csi2.lanecfg.clk.pol =2088		vep->bus.mipi_csi2.lane_polarities[0];2089	dev_dbg(dev, "clock lane polarity %u, pos %u\n",2090		buscfg->bus.csi2.lanecfg.clk.pol,2091		buscfg->bus.csi2.lanecfg.clk.pos);2092 2093	buscfg->bus.csi2.num_data_lanes = vep->bus.mipi_csi2.num_data_lanes;2094 2095	for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) {2096		buscfg->bus.csi2.lanecfg.data[i].pos =2097			vep->bus.mipi_csi2.data_lanes[i];2098		buscfg->bus.csi2.lanecfg.data[i].pol =2099			vep->bus.mipi_csi2.lane_polarities[i + 1];2100		dev_dbg(dev,2101			"data lane %u polarity %u, pos %u\n", i,2102			buscfg->bus.csi2.lanecfg.data[i].pol,2103			buscfg->bus.csi2.lanecfg.data[i].pos);2104	}2105	/*2106	 * FIXME: now we assume the CRC is always there. Implement a way to2107	 * obtain this information from the sensor. Frame descriptors, perhaps?2108	 */2109	buscfg->bus.csi2.crc = 1;2110}2111 2112static void isp_parse_of_csi1_endpoint(struct device *dev,2113				       struct v4l2_fwnode_endpoint *vep,2114				       struct isp_bus_cfg *buscfg)2115{2116	buscfg->bus.ccp2.lanecfg.clk.pos = vep->bus.mipi_csi1.clock_lane;2117	buscfg->bus.ccp2.lanecfg.clk.pol = vep->bus.mipi_csi1.lane_polarity[0];2118	dev_dbg(dev, "clock lane polarity %u, pos %u\n",2119		buscfg->bus.ccp2.lanecfg.clk.pol,2120	buscfg->bus.ccp2.lanecfg.clk.pos);2121 2122	buscfg->bus.ccp2.lanecfg.data[0].pos = vep->bus.mipi_csi1.data_lane;2123	buscfg->bus.ccp2.lanecfg.data[0].pol =2124		vep->bus.mipi_csi1.lane_polarity[1];2125 2126	dev_dbg(dev, "data lane polarity %u, pos %u\n",2127		buscfg->bus.ccp2.lanecfg.data[0].pol,2128		buscfg->bus.ccp2.lanecfg.data[0].pos);2129 2130	buscfg->bus.ccp2.strobe_clk_pol = vep->bus.mipi_csi1.clock_inv;2131	buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe;2132	buscfg->bus.ccp2.ccp2_mode = vep->bus_type == V4L2_MBUS_CCP2;2133	buscfg->bus.ccp2.vp_clk_pol = 1;2134 2135	buscfg->bus.ccp2.crc = 1;2136}2137 2138static struct {2139	u32 phy;2140	u32 csi2_if;2141	u32 csi1_if;2142} isp_bus_interfaces[2] = {2143	{ ISP_OF_PHY_CSIPHY1,2144	  ISP_INTERFACE_CSI2C_PHY1, ISP_INTERFACE_CCP2B_PHY1 },2145	{ ISP_OF_PHY_CSIPHY2,2146	  ISP_INTERFACE_CSI2A_PHY2, ISP_INTERFACE_CCP2B_PHY2 },2147};2148 2149static int isp_parse_of_endpoints(struct isp_device *isp)2150{2151	struct fwnode_handle *ep;2152	struct isp_async_subdev *isd = NULL;2153	unsigned int i;2154 2155	ep = fwnode_graph_get_endpoint_by_id(2156		dev_fwnode(isp->dev), ISP_OF_PHY_PARALLEL, 0,2157		FWNODE_GRAPH_ENDPOINT_NEXT);2158 2159	if (ep) {2160		struct v4l2_fwnode_endpoint vep = {2161			.bus_type = V4L2_MBUS_PARALLEL2162		};2163		int ret;2164 2165		dev_dbg(isp->dev, "parsing parallel interface\n");2166 2167		ret = v4l2_fwnode_endpoint_parse(ep, &vep);2168 2169		if (!ret) {2170			isd = v4l2_async_nf_add_fwnode_remote(&isp->notifier,2171							      ep, struct2172							      isp_async_subdev);2173			if (!IS_ERR(isd))2174				isp_parse_of_parallel_endpoint(isp->dev, &vep, &isd->bus);2175		}2176 2177		fwnode_handle_put(ep);2178	}2179 2180	for (i = 0; i < ARRAY_SIZE(isp_bus_interfaces); i++) {2181		struct v4l2_fwnode_endpoint vep = {2182			.bus_type = V4L2_MBUS_CSI2_DPHY2183		};2184		int ret;2185 2186		ep = fwnode_graph_get_endpoint_by_id(2187			dev_fwnode(isp->dev), isp_bus_interfaces[i].phy, 0,2188			FWNODE_GRAPH_ENDPOINT_NEXT);2189 2190		if (!ep)2191			continue;2192 2193		dev_dbg(isp->dev, "parsing serial interface %u, node %pOF\n", i,2194			to_of_node(ep));2195 2196		ret = v4l2_fwnode_endpoint_parse(ep, &vep);2197		if (ret == -ENXIO) {2198			vep = (struct v4l2_fwnode_endpoint)2199				{ .bus_type = V4L2_MBUS_CSI1 };2200			ret = v4l2_fwnode_endpoint_parse(ep, &vep);2201 2202			if (ret == -ENXIO) {2203				vep = (struct v4l2_fwnode_endpoint)2204					{ .bus_type = V4L2_MBUS_CCP2 };2205				ret = v4l2_fwnode_endpoint_parse(ep, &vep);2206			}2207		}2208 2209		if (!ret) {2210			isd = v4l2_async_nf_add_fwnode_remote(&isp->notifier,2211							      ep,2212							      struct2213							      isp_async_subdev);2214 2215			if (!IS_ERR(isd)) {2216				switch (vep.bus_type) {2217				case V4L2_MBUS_CSI2_DPHY:2218					isd->bus.interface =2219						isp_bus_interfaces[i].csi2_if;2220					isp_parse_of_csi2_endpoint(isp->dev, &vep, &isd->bus);2221					break;2222				case V4L2_MBUS_CSI1:2223				case V4L2_MBUS_CCP2:2224					isd->bus.interface =2225						isp_bus_interfaces[i].csi1_if;2226					isp_parse_of_csi1_endpoint(isp->dev, &vep,2227								   &isd->bus);2228					break;2229				default:2230					break;2231				}2232			}2233		}2234 2235		fwnode_handle_put(ep);2236	}2237 2238	return 0;2239}2240 2241static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = {2242	.bound = isp_subdev_notifier_bound,2243	.complete = isp_subdev_notifier_complete,2244};2245 2246/*2247 * isp_probe - Probe ISP platform device2248 * @pdev: Pointer to ISP platform device2249 *2250 * Returns 0 if successful,2251 *   -ENOMEM if no memory available,2252 *   -ENODEV if no platform device resources found2253 *     or no space for remapping registers,2254 *   -EINVAL if couldn't install ISR,2255 *   or clk_get return error value.2256 */2257static int isp_probe(struct platform_device *pdev)2258{2259	struct isp_device *isp;2260	struct resource *mem;2261	int ret;2262	int i, m;2263 2264	isp = kzalloc(sizeof(*isp), GFP_KERNEL);2265	if (!isp) {2266		dev_err(&pdev->dev, "could not allocate memory\n");2267		return -ENOMEM;2268	}2269 2270	ret = fwnode_property_read_u32(of_fwnode_handle(pdev->dev.of_node),2271				       "ti,phy-type", &isp->phy_type);2272	if (ret)2273		goto error_release_isp;2274 2275	isp->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,2276						      "syscon");2277	if (IS_ERR(isp->syscon)) {2278		ret = PTR_ERR(isp->syscon);2279		goto error_release_isp;2280	}2281 2282	ret = of_property_read_u32_index(pdev->dev.of_node,2283					 "syscon", 1, &isp->syscon_offset);2284	if (ret)2285		goto error_release_isp;2286 2287	isp->autoidle = autoidle;2288 2289	mutex_init(&isp->isp_mutex);2290	spin_lock_init(&isp->stat_lock);2291	isp->dev = &pdev->dev;2292 2293	isp->ref_count = 0;2294 2295	ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32));2296	if (ret)2297		goto error;2298 2299	platform_set_drvdata(pdev, isp);2300 2301	/* Regulators */2302	isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1");2303	if (IS_ERR(isp->isp_csiphy1.vdd)) {2304		ret = PTR_ERR(isp->isp_csiphy1.vdd);2305		goto error;2306	}2307 2308	isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2");2309	if (IS_ERR(isp->isp_csiphy2.vdd)) {2310		ret = PTR_ERR(isp->isp_csiphy2.vdd);2311		goto error;2312	}2313 2314	/* Clocks2315	 *2316	 * The ISP clock tree is revision-dependent. We thus need to enable ICLK2317	 * manually to read the revision before calling __omap3isp_get().2318	 *2319	 * Start by mapping the ISP MMIO area, which is in two pieces.2320	 * The ISP IOMMU is in between. Map both now, and fill in the2321	 * ISP revision specific portions a little later in the2322	 * function.2323	 */2324	for (i = 0; i < 2; i++) {2325		unsigned int map_idx = i ? OMAP3_ISP_IOMEM_CSI2A_REGS1 : 0;2326 2327		isp->mmio_base[map_idx] =2328			devm_platform_get_and_ioremap_resource(pdev, i, &mem);2329		if (IS_ERR(isp->mmio_base[map_idx])) {2330			ret = PTR_ERR(isp->mmio_base[map_idx]);2331			goto error;2332		}2333	}2334 2335	ret = isp_get_clocks(isp);2336	if (ret < 0)2337		goto error;2338 2339	ret = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);2340	if (ret < 0)2341		goto error;2342 2343	isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);2344	dev_info(isp->dev, "Revision %d.%d found\n",2345		 (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);2346 2347	clk_disable(isp->clock[ISP_CLK_CAM_ICK]);2348 2349	if (__omap3isp_get(isp, false) == NULL) {2350		ret = -ENODEV;2351		goto error;2352	}2353 2354	ret = isp_reset(isp);2355	if (ret < 0)2356		goto error_isp;2357 2358	ret = isp_xclk_init(isp);2359	if (ret < 0)2360		goto error_isp;2361 2362	/* Memory resources */2363	for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++)2364		if (isp->revision == isp_res_maps[m].isp_rev)2365			break;2366 2367	if (m == ARRAY_SIZE(isp_res_maps)) {2368		dev_err(isp->dev, "No resource map found for ISP rev %d.%d\n",2369			(isp->revision & 0xf0) >> 4, isp->revision & 0xf);2370		ret = -ENODEV;2371		goto error_isp;2372	}2373 2374	for (i = 1; i < OMAP3_ISP_IOMEM_CSI2A_REGS1; i++)2375		isp->mmio_base[i] =2376			isp->mmio_base[0] + isp_res_maps[m].offset[i];2377 2378	for (i = OMAP3_ISP_IOMEM_CSIPHY2; i < OMAP3_ISP_IOMEM_LAST; i++)2379		isp->mmio_base[i] =2380			isp->mmio_base[OMAP3_ISP_IOMEM_CSI2A_REGS1]2381			+ isp_res_maps[m].offset[i];2382 2383	isp->mmio_hist_base_phys =2384		mem->start + isp_res_maps[m].offset[OMAP3_ISP_IOMEM_HIST];2385 2386	/* IOMMU */2387	ret = isp_attach_iommu(isp);2388	if (ret < 0) {2389		dev_err(&pdev->dev, "unable to attach to IOMMU\n");2390		goto error_isp;2391	}2392 2393	/* Interrupt */2394	ret = platform_get_irq(pdev, 0);2395	if (ret < 0)2396		goto error_iommu;2397	isp->irq_num = ret;2398 2399	if (devm_request_irq(isp->dev, isp->irq_num, isp_isr, IRQF_SHARED,2400			     "OMAP3 ISP", isp)) {2401		dev_err(isp->dev, "Unable to request IRQ\n");2402		ret = -EINVAL;2403		goto error_iommu;2404	}2405 2406	/* Entities */2407	ret = isp_initialize_modules(isp);2408	if (ret < 0)2409		goto error_iommu;2410 2411	ret = isp_register_entities(isp);2412	if (ret < 0)2413		goto error_modules;2414 2415	ret = isp_create_links(isp);2416	if (ret < 0)2417		goto error_register_entities;2418 2419	isp->notifier.ops = &isp_subdev_notifier_ops;2420 2421	v4l2_async_nf_init(&isp->notifier, &isp->v4l2_dev);2422 2423	ret = isp_parse_of_endpoints(isp);2424	if (ret < 0)2425		goto error_register_entities;2426 2427	ret = v4l2_async_nf_register(&isp->notifier);2428	if (ret)2429		goto error_register_entities;2430 2431	isp_core_init(isp, 1);2432	omap3isp_put(isp);2433 2434	return 0;2435 2436error_register_entities:2437	v4l2_async_nf_cleanup(&isp->notifier);2438	isp_unregister_entities(isp);2439error_modules:2440	isp_cleanup_modules(isp);2441error_iommu:2442	isp_detach_iommu(isp);2443error_isp:2444	isp_xclk_cleanup(isp);2445	__omap3isp_put(isp, false);2446error:2447	mutex_destroy(&isp->isp_mutex);2448error_release_isp:2449	kfree(isp);2450 2451	return ret;2452}2453 2454static const struct dev_pm_ops omap3isp_pm_ops = {2455	.prepare = isp_pm_prepare,2456	.suspend = isp_pm_suspend,2457	.resume = isp_pm_resume,2458	.complete = isp_pm_complete,2459};2460 2461static const struct platform_device_id omap3isp_id_table[] = {2462	{ "omap3isp", 0 },2463	{ },2464};2465MODULE_DEVICE_TABLE(platform, omap3isp_id_table);2466 2467static const struct of_device_id omap3isp_of_table[] = {2468	{ .compatible = "ti,omap3-isp" },2469	{ },2470};2471MODULE_DEVICE_TABLE(of, omap3isp_of_table);2472 2473static struct platform_driver omap3isp_driver = {2474	.probe = isp_probe,2475	.remove_new = isp_remove,2476	.id_table = omap3isp_id_table,2477	.driver = {2478		.name = "omap3isp",2479		.pm	= &omap3isp_pm_ops,2480		.of_match_table = omap3isp_of_table,2481	},2482};2483 2484module_platform_driver(omap3isp_driver);2485 2486MODULE_AUTHOR("Nokia Corporation");2487MODULE_DESCRIPTION("TI OMAP3 ISP driver");2488MODULE_LICENSE("GPL");2489MODULE_VERSION(ISP_VIDEO_DRIVER_VERSION);2490