brintos

brintos / linux-shallow public Read only

0
0
Text · 34.9 KiB · d949172 Raw
1157 lines · c
1// SPDX-License-Identifier: (GPL-2.0+ OR MIT)2/*3 * Rockchip ISP1 Driver - ISP Subdevice4 *5 * Copyright (C) 2019 Collabora, Ltd.6 *7 * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.8 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.9 */10 11#include <linux/iopoll.h>12#include <linux/pm_runtime.h>13#include <linux/regmap.h>14#include <linux/videodev2.h>15#include <linux/vmalloc.h>16 17#include <media/v4l2-event.h>18 19#include "rkisp1-common.h"20 21#define RKISP1_DEF_SINK_PAD_FMT MEDIA_BUS_FMT_SRGGB10_1X1022#define RKISP1_DEF_SRC_PAD_FMT MEDIA_BUS_FMT_YUYV8_2X823 24#define RKISP1_ISP_DEV_NAME	RKISP1_DRIVER_NAME "_isp"25 26/*27 * NOTE: MIPI controller and input MUX are also configured in this file.28 * This is because ISP Subdev describes not only ISP submodule (input size,29 * format, output size, format), but also a virtual route device.30 */31 32/*33 * There are many variables named with format/frame in below code,34 * please see here for their meaning.35 * Cropping in the sink pad defines the image region from the sensor.36 * Cropping in the source pad defines the region for the Image Stabilizer (IS)37 *38 * Cropping regions of ISP39 *40 * +---------------------------------------------------------+41 * | Sensor image                                            |42 * | +---------------------------------------------------+   |43 * | | CIF_ISP_ACQ (for black level)                     |   |44 * | | sink pad format                                   |   |45 * | | +--------------------------------------------+    |   |46 * | | |    CIF_ISP_OUT                             |    |   |47 * | | |    sink pad crop                           |    |   |48 * | | |    +---------------------------------+     |    |   |49 * | | |    |   CIF_ISP_IS                    |     |    |   |50 * | | |    |   source pad crop and format    |     |    |   |51 * | | |    +---------------------------------+     |    |   |52 * | | +--------------------------------------------+    |   |53 * | +---------------------------------------------------+   |54 * +---------------------------------------------------------+55 */56 57/* -----------------------------------------------------------------------------58 * Media block control (i.MX8MP only)59 */60 61#define ISP_DEWARP_CONTROL				0x013862 63#define ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY	BIT(22)64#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_RISING	(0 << 20)65#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_NEGATIVE	(1 << 20)66#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE	(2 << 20)67#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_FALLING	(3 << 20)68#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK	GENMASK(21, 20)69#define ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE	BIT(19)70#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt)	((dt) << 13)71#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK	GENMASK(18, 13)72 73#define ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY	BIT(12)74#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_RISING	(0 << 10)75#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_NEGATIVE	(1 << 10)76#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE	(2 << 10)77#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_FALLING	(3 << 10)78#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK	GENMASK(11, 10)79#define ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE	BIT(9)80#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt)	((dt) << 3)81#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK	GENMASK(8, 3)82 83#define ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE		BIT(1)84#define ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE		BIT(0)85 86static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,87				struct media_pad *source)88{89	struct v4l2_subdev *source_sd;90	struct v4l2_mbus_frame_desc fd;91	unsigned int dt;92	u32 mask;93	u32 val;94	int ret;95 96	/*97	 * Configure and enable the gasket with the CSI-2 data type. Set the98	 * vsync polarity as active high, as that is what the ISP is configured99	 * to expect in ISP_ACQ_PROP. Enable left justification, as the i.MX8MP100	 * ISP has a 16-bit wide input and expects data to be left-aligned.101	 */102 103	source_sd = media_entity_to_v4l2_subdev(source->entity);104	ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,105			       source->index, &fd);106	if (ret) {107		dev_err(rkisp1->dev,108			"failed to get frame descriptor from '%s':%u: %d\n",109			source_sd->name, 0, ret);110		return ret;111	}112 113	if (fd.num_entries != 1) {114		dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",115			source_sd->name, 0);116		return -EINVAL;117	}118 119	dt = fd.entry[0].bus.csi2.dt;120 121	if (rkisp1->gasket_id == 0) {122		mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY123		     | ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK124		     | ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE125		     | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK126		     | ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;127		val = ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE128		    | ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE129		    | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt);130	} else {131		mask = ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY132		     | ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK133		     | ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE134		     | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK135		     | ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;136		val = ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE137		    | ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE138		    | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt);139	}140 141	regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);142 143	return 0;144}145 146static void rkisp1_gasket_disable(struct rkisp1_device *rkisp1)147{148	u32 mask;149	u32 val;150 151	if (rkisp1->gasket_id == 1) {152		mask = ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE153		     | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK154		     | ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;155		val = ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;156	} else {157		mask = ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE158		     | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK159		     | ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;160		val = ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;161	}162 163	regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);164}165 166/* ----------------------------------------------------------------------------167 * Camera Interface registers configurations168 */169 170/*171 * Image Stabilization.172 * This should only be called when configuring CIF173 * or at the frame end interrupt174 */175static void rkisp1_config_ism(struct rkisp1_isp *isp,176			      const struct v4l2_subdev_state *sd_state)177{178	const struct v4l2_rect *src_crop =179		v4l2_subdev_state_get_crop(sd_state,180					   RKISP1_ISP_PAD_SOURCE_VIDEO);181	struct rkisp1_device *rkisp1 = isp->rkisp1;182	u32 val;183 184	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_RECENTER, 0);185	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_MAX_DX, 0);186	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_MAX_DY, 0);187	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_DISPLACE, 0);188	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_H_OFFS, src_crop->left);189	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_V_OFFS, src_crop->top);190	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_H_SIZE, src_crop->width);191	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_V_SIZE, src_crop->height);192 193	/* IS(Image Stabilization) is always on, working as output crop */194	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IS_CTRL, 1);195	val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);196	val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD;197	rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val);198}199 200/*201 * configure ISP blocks with input format, size......202 */203static int rkisp1_config_isp(struct rkisp1_isp *isp,204			     const struct v4l2_subdev_state *sd_state,205			     enum v4l2_mbus_type mbus_type, u32 mbus_flags)206{207	struct rkisp1_device *rkisp1 = isp->rkisp1;208	u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, acq_prop = 0;209	const struct rkisp1_mbus_info *sink_fmt;210	const struct rkisp1_mbus_info *src_fmt;211	const struct v4l2_mbus_framefmt *src_frm;212	const struct v4l2_mbus_framefmt *sink_frm;213	const struct v4l2_rect *sink_crop;214 215	sink_frm = v4l2_subdev_state_get_format(sd_state,216						RKISP1_ISP_PAD_SINK_VIDEO);217	sink_crop = v4l2_subdev_state_get_crop(sd_state,218					       RKISP1_ISP_PAD_SINK_VIDEO);219	src_frm = v4l2_subdev_state_get_format(sd_state,220					       RKISP1_ISP_PAD_SOURCE_VIDEO);221 222	sink_fmt = rkisp1_mbus_info_get_by_code(sink_frm->code);223	src_fmt = rkisp1_mbus_info_get_by_code(src_frm->code);224 225	if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {226		acq_mult = 1;227		if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {228			if (mbus_type == V4L2_MBUS_BT656)229				isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656;230			else231				isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT;232		} else {233			rkisp1_write(rkisp1, RKISP1_CIF_ISP_DEMOSAIC,234				     RKISP1_CIF_ISP_DEMOSAIC_TH(0xc));235 236			if (mbus_type == V4L2_MBUS_BT656)237				isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656;238			else239				isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601;240		}241	} else if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_YUV) {242		acq_mult = 2;243		if (mbus_type == V4L2_MBUS_CSI2_DPHY) {244			isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;245		} else {246			if (mbus_type == V4L2_MBUS_BT656)247				isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656;248			else249				isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;250		}251 252		irq_mask |= RKISP1_CIF_ISP_DATA_LOSS;253	}254 255	/* Set up input acquisition properties */256	if (mbus_type == V4L2_MBUS_BT656 || mbus_type == V4L2_MBUS_PARALLEL) {257		if (mbus_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)258			acq_prop |= RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE;259 260		switch (sink_fmt->bus_width) {261		case 8:262			acq_prop |= RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;263			break;264		case 10:265			acq_prop |= RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;266			break;267		case 12:268			acq_prop |= RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B;269			break;270		default:271			dev_err(rkisp1->dev, "Invalid bus width %u\n",272				sink_fmt->bus_width);273			return -EINVAL;274		}275	}276 277	if (mbus_type == V4L2_MBUS_PARALLEL) {278		if (mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)279			acq_prop |= RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW;280 281		if (mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)282			acq_prop |= RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW;283	}284 285	rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, isp_ctrl);286	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ACQ_PROP,287		     acq_prop | sink_fmt->yuv_seq |288		     RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(sink_fmt->bayer_pat) |289		     RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL);290	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ACQ_NR_FRAMES, 0);291 292	/* Acquisition Size */293	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ACQ_H_OFFS, 0);294	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ACQ_V_OFFS, 0);295	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ACQ_H_SIZE,296		     acq_mult * sink_frm->width);297	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ACQ_V_SIZE, sink_frm->height);298 299	/* ISP Out Area */300	rkisp1_write(rkisp1, RKISP1_CIF_ISP_OUT_H_OFFS, sink_crop->left);301	rkisp1_write(rkisp1, RKISP1_CIF_ISP_OUT_V_OFFS, sink_crop->top);302	rkisp1_write(rkisp1, RKISP1_CIF_ISP_OUT_H_SIZE, sink_crop->width);303	rkisp1_write(rkisp1, RKISP1_CIF_ISP_OUT_V_SIZE, sink_crop->height);304 305	irq_mask |= RKISP1_CIF_ISP_FRAME | RKISP1_CIF_ISP_V_START |306		    RKISP1_CIF_ISP_PIC_SIZE_ERROR;307	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, irq_mask);308 309	if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {310		rkisp1_params_disable(&rkisp1->params);311	} else {312		const struct v4l2_mbus_framefmt *src_frm;313 314		src_frm = v4l2_subdev_state_get_format(sd_state,315						       RKISP1_ISP_PAD_SOURCE_VIDEO);316		rkisp1_params_pre_configure(&rkisp1->params, sink_fmt->bayer_pat,317					    src_frm->quantization,318					    src_frm->ycbcr_enc);319	}320 321	isp->sink_fmt = sink_fmt;322 323	return 0;324}325 326/* Configure MUX */327static void rkisp1_config_path(struct rkisp1_isp *isp,328			       enum v4l2_mbus_type mbus_type)329{330	struct rkisp1_device *rkisp1 = isp->rkisp1;331	u32 dpcl = rkisp1_read(rkisp1, RKISP1_CIF_VI_DPCL);332 333	if (mbus_type == V4L2_MBUS_BT656 || mbus_type == V4L2_MBUS_PARALLEL)334		dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL;335	else if (mbus_type == V4L2_MBUS_CSI2_DPHY)336		dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_MIPI;337 338	rkisp1_write(rkisp1, RKISP1_CIF_VI_DPCL, dpcl);339}340 341/* Hardware configure Entry */342static int rkisp1_config_cif(struct rkisp1_isp *isp,343			     struct v4l2_subdev_state *sd_state,344			     enum v4l2_mbus_type mbus_type, u32 mbus_flags)345{346	int ret;347 348	ret = rkisp1_config_isp(isp, sd_state, mbus_type, mbus_flags);349	if (ret)350		return ret;351 352	rkisp1_config_path(isp, mbus_type);353	rkisp1_config_ism(isp, sd_state);354 355	return 0;356}357 358static void rkisp1_isp_stop(struct rkisp1_isp *isp)359{360	struct rkisp1_device *rkisp1 = isp->rkisp1;361	u32 val;362 363	/*364	 * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->365	 * Stop ISP(isp) ->wait for ISP isp off366	 */367 368	/* Mask MI and ISP interrupts */369	rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0);370	rkisp1_write(rkisp1, RKISP1_CIF_MI_IMSC, 0);371 372	/* Flush posted writes */373	rkisp1_read(rkisp1, RKISP1_CIF_MI_IMSC);374 375	/*376	 * Wait until the IRQ handler has ended. The IRQ handler may get called377	 * even after this, but it will return immediately as the MI and ISP378	 * interrupts have been masked.379	 */380	synchronize_irq(rkisp1->irqs[RKISP1_IRQ_ISP]);381	if (rkisp1->irqs[RKISP1_IRQ_ISP] != rkisp1->irqs[RKISP1_IRQ_MI])382		synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MI]);383 384	/* Clear MI and ISP interrupt status */385	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0);386	rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, ~0);387 388	/* stop ISP */389	val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);390	val &= ~(RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE |391		 RKISP1_CIF_ISP_CTRL_ISP_ENABLE);392	rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val);393 394	val = rkisp1_read(rkisp1,	RKISP1_CIF_ISP_CTRL);395	rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL,396		     val | RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);397 398	readx_poll_timeout(readl, rkisp1->base_addr + RKISP1_CIF_ISP_RIS,399			   val, val & RKISP1_CIF_ISP_OFF, 20, 100);400	rkisp1_write(rkisp1, RKISP1_CIF_VI_IRCL,401		     RKISP1_CIF_VI_IRCL_MIPI_SW_RST |402		     RKISP1_CIF_VI_IRCL_ISP_SW_RST);403	rkisp1_write(rkisp1, RKISP1_CIF_VI_IRCL, 0x0);404 405	if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP)406		rkisp1_gasket_disable(rkisp1);407}408 409static void rkisp1_config_clk(struct rkisp1_isp *isp)410{411	struct rkisp1_device *rkisp1 = isp->rkisp1;412 413	u32 val = RKISP1_CIF_VI_ICCL_ISP_CLK | RKISP1_CIF_VI_ICCL_CP_CLK |414		  RKISP1_CIF_VI_ICCL_MRSZ_CLK | RKISP1_CIF_VI_ICCL_SRSZ_CLK |415		  RKISP1_CIF_VI_ICCL_JPEG_CLK | RKISP1_CIF_VI_ICCL_MI_CLK |416		  RKISP1_CIF_VI_ICCL_IE_CLK | RKISP1_CIF_VI_ICCL_MIPI_CLK |417		  RKISP1_CIF_VI_ICCL_DCROP_CLK;418 419	rkisp1_write(rkisp1, RKISP1_CIF_VI_ICCL, val);420 421	/* ensure sp and mp can run at the same time in V12 */422	if (rkisp1->info->isp_ver == RKISP1_V12) {423		val = RKISP1_CIF_CLK_CTRL_MI_Y12 | RKISP1_CIF_CLK_CTRL_MI_SP |424		      RKISP1_CIF_CLK_CTRL_MI_RAW0 | RKISP1_CIF_CLK_CTRL_MI_RAW1 |425		      RKISP1_CIF_CLK_CTRL_MI_READ | RKISP1_CIF_CLK_CTRL_MI_RAWRD |426		      RKISP1_CIF_CLK_CTRL_CP | RKISP1_CIF_CLK_CTRL_IE;427		rkisp1_write(rkisp1, RKISP1_CIF_VI_ISP_CLK_CTRL_V12, val);428	}429}430 431static int rkisp1_isp_start(struct rkisp1_isp *isp,432			    const struct v4l2_subdev_state *sd_state,433			    struct media_pad *source)434{435	struct rkisp1_device *rkisp1 = isp->rkisp1;436	const struct v4l2_mbus_framefmt *src_fmt;437	const struct rkisp1_mbus_info *src_info;438	u32 val;439	int ret;440 441	rkisp1_config_clk(isp);442 443	if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP) {444		ret = rkisp1_gasket_enable(rkisp1, source);445		if (ret)446			return ret;447	}448 449	/* Activate ISP */450	val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);451	val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |452	       RKISP1_CIF_ISP_CTRL_ISP_ENABLE |453	       RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE;454	rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val);455 456	src_fmt = v4l2_subdev_state_get_format(sd_state,457					       RKISP1_ISP_PAD_SOURCE_VIDEO);458	src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);459 460	if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)461		rkisp1_params_post_configure(&rkisp1->params);462 463	return 0;464}465 466/* ----------------------------------------------------------------------------467 * Subdev pad operations468 */469 470static inline struct rkisp1_isp *to_rkisp1_isp(struct v4l2_subdev *sd)471{472	return container_of(sd, struct rkisp1_isp, sd);473}474 475static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd,476				     struct v4l2_subdev_state *sd_state,477				     struct v4l2_subdev_mbus_code_enum *code)478{479	unsigned int i, dir;480	int pos = 0;481 482	if (code->pad == RKISP1_ISP_PAD_SINK_VIDEO) {483		dir = RKISP1_ISP_SD_SINK;484	} else if (code->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) {485		dir = RKISP1_ISP_SD_SRC;486	} else {487		if (code->index > 0)488			return -EINVAL;489		code->code = MEDIA_BUS_FMT_METADATA_FIXED;490		return 0;491	}492 493	for (i = 0; ; i++) {494		const struct rkisp1_mbus_info *fmt =495			rkisp1_mbus_info_get_by_index(i);496 497		if (!fmt)498			return -EINVAL;499 500		if (fmt->direction & dir)501			pos++;502 503		if (code->index == pos - 1) {504			code->code = fmt->mbus_code;505			if (fmt->pixel_enc == V4L2_PIXEL_ENC_YUV &&506			    dir == RKISP1_ISP_SD_SRC)507				code->flags =508					V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION;509			return 0;510		}511	}512 513	return -EINVAL;514}515 516static int rkisp1_isp_enum_frame_size(struct v4l2_subdev *sd,517				      struct v4l2_subdev_state *sd_state,518				      struct v4l2_subdev_frame_size_enum *fse)519{520	struct rkisp1_isp *isp = to_rkisp1_isp(sd);521	const struct rkisp1_mbus_info *mbus_info;522 523	if (fse->pad == RKISP1_ISP_PAD_SINK_PARAMS ||524	    fse->pad == RKISP1_ISP_PAD_SOURCE_STATS)525		return -ENOTTY;526 527	if (fse->index > 0)528		return -EINVAL;529 530	mbus_info = rkisp1_mbus_info_get_by_code(fse->code);531	if (!mbus_info)532		return -EINVAL;533 534	if (!(mbus_info->direction & RKISP1_ISP_SD_SINK) &&535	    fse->pad == RKISP1_ISP_PAD_SINK_VIDEO)536		return -EINVAL;537 538	if (!(mbus_info->direction & RKISP1_ISP_SD_SRC) &&539	    fse->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)540		return -EINVAL;541 542	fse->min_width = RKISP1_ISP_MIN_WIDTH;543	fse->max_width = isp->rkisp1->info->max_width;544	fse->min_height = RKISP1_ISP_MIN_HEIGHT;545	fse->max_height = isp->rkisp1->info->max_height;546 547	return 0;548}549 550static int rkisp1_isp_init_state(struct v4l2_subdev *sd,551				 struct v4l2_subdev_state *sd_state)552{553	struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;554	struct v4l2_rect *sink_crop, *src_crop;555 556	/* Video. */557	sink_fmt = v4l2_subdev_state_get_format(sd_state,558						RKISP1_ISP_PAD_SINK_VIDEO);559	sink_fmt->width = RKISP1_DEFAULT_WIDTH;560	sink_fmt->height = RKISP1_DEFAULT_HEIGHT;561	sink_fmt->field = V4L2_FIELD_NONE;562	sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;563	sink_fmt->colorspace = V4L2_COLORSPACE_RAW;564	sink_fmt->xfer_func = V4L2_XFER_FUNC_NONE;565	sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;566	sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;567 568	sink_crop = v4l2_subdev_state_get_crop(sd_state,569					       RKISP1_ISP_PAD_SINK_VIDEO);570	sink_crop->width = RKISP1_DEFAULT_WIDTH;571	sink_crop->height = RKISP1_DEFAULT_HEIGHT;572	sink_crop->left = 0;573	sink_crop->top = 0;574 575	src_fmt = v4l2_subdev_state_get_format(sd_state,576					       RKISP1_ISP_PAD_SOURCE_VIDEO);577	*src_fmt = *sink_fmt;578	src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;579	src_fmt->colorspace = V4L2_COLORSPACE_SRGB;580	src_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;581	src_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;582	src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;583 584	src_crop = v4l2_subdev_state_get_crop(sd_state,585					      RKISP1_ISP_PAD_SOURCE_VIDEO);586	*src_crop = *sink_crop;587 588	/* Parameters and statistics. */589	sink_fmt = v4l2_subdev_state_get_format(sd_state,590						RKISP1_ISP_PAD_SINK_PARAMS);591	src_fmt = v4l2_subdev_state_get_format(sd_state,592					       RKISP1_ISP_PAD_SOURCE_STATS);593	sink_fmt->width = 0;594	sink_fmt->height = 0;595	sink_fmt->field = V4L2_FIELD_NONE;596	sink_fmt->code = MEDIA_BUS_FMT_METADATA_FIXED;597	*src_fmt = *sink_fmt;598 599	return 0;600}601 602static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,603				   struct v4l2_subdev_state *sd_state,604				   struct v4l2_mbus_framefmt *format)605{606	const struct rkisp1_mbus_info *sink_info;607	const struct rkisp1_mbus_info *src_info;608	struct v4l2_mbus_framefmt *sink_fmt;609	struct v4l2_mbus_framefmt *src_fmt;610	const struct v4l2_rect *src_crop;611	bool set_csc;612 613	sink_fmt = v4l2_subdev_state_get_format(sd_state,614						RKISP1_ISP_PAD_SINK_VIDEO);615	src_fmt = v4l2_subdev_state_get_format(sd_state,616					       RKISP1_ISP_PAD_SOURCE_VIDEO);617	src_crop = v4l2_subdev_state_get_crop(sd_state,618					      RKISP1_ISP_PAD_SOURCE_VIDEO);619 620	/*621	 * Media bus code. The ISP can operate in pass-through mode (Bayer in,622	 * Bayer out or YUV in, YUV out) or process Bayer data to YUV, but623	 * can't convert from YUV to Bayer.624	 */625	sink_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);626 627	src_fmt->code = format->code;628	src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);629	if (!src_info || !(src_info->direction & RKISP1_ISP_SD_SRC)) {630		src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;631		src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);632	}633 634	if (sink_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&635	    src_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {636		src_fmt->code = sink_fmt->code;637		src_info = sink_info;638	}639 640	/*641	 * The source width and height must be identical to the source crop642	 * size.643	 */644	src_fmt->width  = src_crop->width;645	src_fmt->height = src_crop->height;646 647	/*648	 * Copy the color space for the sink pad. When converting from Bayer to649	 * YUV, default to a limited quantization range.650	 */651	src_fmt->colorspace = sink_fmt->colorspace;652	src_fmt->xfer_func = sink_fmt->xfer_func;653	src_fmt->ycbcr_enc = sink_fmt->ycbcr_enc;654 655	if (sink_info->pixel_enc == V4L2_PIXEL_ENC_BAYER &&656	    src_info->pixel_enc == V4L2_PIXEL_ENC_YUV)657		src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;658	else659		src_fmt->quantization = sink_fmt->quantization;660 661	/*662	 * Allow setting the source color space fields when the SET_CSC flag is663	 * set and the source format is YUV. If the sink format is YUV, don't664	 * set the color primaries, transfer function or YCbCr encoding as the665	 * ISP is bypassed in that case and passes YUV data through without666	 * modifications.667	 *668	 * The color primaries and transfer function are configured through the669	 * cross-talk matrix and tone curve respectively. Settings for those670	 * hardware blocks are conveyed through the ISP parameters buffer, as671	 * they need to combine color space information with other image tuning672	 * characteristics and can't thus be computed by the kernel based on the673	 * color space. The source pad colorspace and xfer_func fields are thus674	 * ignored by the driver, but can be set by userspace to propagate675	 * accurate color space information down the pipeline.676	 */677	set_csc = format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC;678 679	if (set_csc && src_info->pixel_enc == V4L2_PIXEL_ENC_YUV) {680		if (sink_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {681			if (format->colorspace != V4L2_COLORSPACE_DEFAULT)682				src_fmt->colorspace = format->colorspace;683			if (format->xfer_func != V4L2_XFER_FUNC_DEFAULT)684				src_fmt->xfer_func = format->xfer_func;685			if (format->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT)686				src_fmt->ycbcr_enc = format->ycbcr_enc;687		}688 689		if (format->quantization != V4L2_QUANTIZATION_DEFAULT)690			src_fmt->quantization = format->quantization;691	}692 693	*format = *src_fmt;694 695	/*696	 * Restore the SET_CSC flag if it was set to indicate support for the697	 * CSC setting API.698	 */699	if (set_csc)700		format->flags |= V4L2_MBUS_FRAMEFMT_SET_CSC;701}702 703static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,704				    struct v4l2_subdev_state *sd_state,705				    struct v4l2_rect *r)706{707	struct v4l2_mbus_framefmt *src_fmt;708	const struct v4l2_rect *sink_crop;709	struct v4l2_rect *src_crop;710 711	src_crop = v4l2_subdev_state_get_crop(sd_state,712					      RKISP1_ISP_PAD_SOURCE_VIDEO);713	sink_crop = v4l2_subdev_state_get_crop(sd_state,714					       RKISP1_ISP_PAD_SINK_VIDEO);715 716	src_crop->left = ALIGN(r->left, 2);717	src_crop->width = ALIGN(r->width, 2);718	src_crop->top = r->top;719	src_crop->height = r->height;720	rkisp1_sd_adjust_crop_rect(src_crop, sink_crop);721 722	*r = *src_crop;723 724	/* Propagate to out format */725	src_fmt = v4l2_subdev_state_get_format(sd_state,726					       RKISP1_ISP_PAD_SOURCE_VIDEO);727	rkisp1_isp_set_src_fmt(isp, sd_state, src_fmt);728}729 730static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,731				     struct v4l2_subdev_state *sd_state,732				     struct v4l2_rect *r)733{734	struct v4l2_rect *sink_crop, *src_crop;735	const struct v4l2_mbus_framefmt *sink_fmt;736 737	sink_crop = v4l2_subdev_state_get_crop(sd_state,738					       RKISP1_ISP_PAD_SINK_VIDEO);739	sink_fmt = v4l2_subdev_state_get_format(sd_state,740						RKISP1_ISP_PAD_SINK_VIDEO);741 742	sink_crop->left = ALIGN(r->left, 2);743	sink_crop->width = ALIGN(r->width, 2);744	sink_crop->top = r->top;745	sink_crop->height = r->height;746	rkisp1_sd_adjust_crop(sink_crop, sink_fmt);747 748	*r = *sink_crop;749 750	/* Propagate to out crop */751	src_crop = v4l2_subdev_state_get_crop(sd_state,752					      RKISP1_ISP_PAD_SOURCE_VIDEO);753	rkisp1_isp_set_src_crop(isp, sd_state, src_crop);754}755 756static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,757				    struct v4l2_subdev_state *sd_state,758				    struct v4l2_mbus_framefmt *format)759{760	const struct rkisp1_mbus_info *mbus_info;761	struct v4l2_mbus_framefmt *sink_fmt;762	struct v4l2_rect *sink_crop;763	bool is_yuv;764 765	sink_fmt = v4l2_subdev_state_get_format(sd_state,766						RKISP1_ISP_PAD_SINK_VIDEO);767	sink_fmt->code = format->code;768	mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);769	if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) {770		sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;771		mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);772	}773 774	sink_fmt->width = clamp_t(u32, format->width,775				  RKISP1_ISP_MIN_WIDTH,776				  isp->rkisp1->info->max_width);777	sink_fmt->height = clamp_t(u32, format->height,778				   RKISP1_ISP_MIN_HEIGHT,779				   isp->rkisp1->info->max_height);780 781	/*782	 * Adjust the color space fields. Accept any color primaries and783	 * transfer function for both YUV and Bayer. For YUV any YCbCr encoding784	 * and quantization range is also accepted. For Bayer formats, the YCbCr785	 * encoding isn't applicable, and the quantization range can only be786	 * full.787	 */788	is_yuv = mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV;789 790	sink_fmt->colorspace = format->colorspace ? :791			       (is_yuv ? V4L2_COLORSPACE_SRGB :792				V4L2_COLORSPACE_RAW);793	sink_fmt->xfer_func = format->xfer_func ? :794			      V4L2_MAP_XFER_FUNC_DEFAULT(sink_fmt->colorspace);795	if (is_yuv) {796		sink_fmt->ycbcr_enc = format->ycbcr_enc ? :797			V4L2_MAP_YCBCR_ENC_DEFAULT(sink_fmt->colorspace);798		sink_fmt->quantization = format->quantization ? :799			V4L2_MAP_QUANTIZATION_DEFAULT(false, sink_fmt->colorspace,800						      sink_fmt->ycbcr_enc);801	} else {802		/*803		 * The YCbCr encoding isn't applicable for non-YUV formats, but804		 * V4L2 has no "no encoding" value. Hardcode it to Rec. 601, it805		 * should be ignored by userspace.806		 */807		sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;808		sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;809	}810 811	*format = *sink_fmt;812 813	/* Propagate to in crop */814	sink_crop = v4l2_subdev_state_get_crop(sd_state,815					       RKISP1_ISP_PAD_SINK_VIDEO);816	rkisp1_isp_set_sink_crop(isp, sd_state, sink_crop);817}818 819static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,820			      struct v4l2_subdev_state *sd_state,821			      struct v4l2_subdev_format *fmt)822{823	struct rkisp1_isp *isp = to_rkisp1_isp(sd);824 825	if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO)826		rkisp1_isp_set_sink_fmt(isp, sd_state, &fmt->format);827	else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)828		rkisp1_isp_set_src_fmt(isp, sd_state, &fmt->format);829	else830		fmt->format = *v4l2_subdev_state_get_format(sd_state,831							    fmt->pad);832 833	return 0;834}835 836static int rkisp1_isp_get_selection(struct v4l2_subdev *sd,837				    struct v4l2_subdev_state *sd_state,838				    struct v4l2_subdev_selection *sel)839{840	int ret = 0;841 842	if (sel->pad != RKISP1_ISP_PAD_SOURCE_VIDEO &&843	    sel->pad != RKISP1_ISP_PAD_SINK_VIDEO)844		return -EINVAL;845 846	switch (sel->target) {847	case V4L2_SEL_TGT_CROP_BOUNDS:848		if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) {849			struct v4l2_mbus_framefmt *fmt;850 851			fmt = v4l2_subdev_state_get_format(sd_state, sel->pad);852			sel->r.height = fmt->height;853			sel->r.width = fmt->width;854			sel->r.left = 0;855			sel->r.top = 0;856		} else {857			sel->r = *v4l2_subdev_state_get_crop(sd_state,858							     RKISP1_ISP_PAD_SINK_VIDEO);859		}860		break;861 862	case V4L2_SEL_TGT_CROP:863		sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad);864		break;865 866	default:867		ret = -EINVAL;868		break;869	}870 871	return ret;872}873 874static int rkisp1_isp_set_selection(struct v4l2_subdev *sd,875				    struct v4l2_subdev_state *sd_state,876				    struct v4l2_subdev_selection *sel)877{878	struct rkisp1_isp *isp = to_rkisp1_isp(sd);879	int ret = 0;880 881	if (sel->target != V4L2_SEL_TGT_CROP)882		return -EINVAL;883 884	dev_dbg(isp->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,885		sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);886 887	if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO)888		rkisp1_isp_set_sink_crop(isp, sd_state, &sel->r);889	else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)890		rkisp1_isp_set_src_crop(isp, sd_state, &sel->r);891	else892		ret = -EINVAL;893 894	return ret;895}896 897static int rkisp1_subdev_link_validate(struct media_link *link)898{899	if (link->sink->index == RKISP1_ISP_PAD_SINK_PARAMS)900		return 0;901 902	return v4l2_subdev_link_validate(link);903}904 905static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = {906	.enum_mbus_code = rkisp1_isp_enum_mbus_code,907	.enum_frame_size = rkisp1_isp_enum_frame_size,908	.get_selection = rkisp1_isp_get_selection,909	.set_selection = rkisp1_isp_set_selection,910	.get_fmt = v4l2_subdev_get_fmt,911	.set_fmt = rkisp1_isp_set_fmt,912	.link_validate = v4l2_subdev_link_validate_default,913};914 915/* ----------------------------------------------------------------------------916 * Stream operations917 */918 919static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)920{921	struct rkisp1_isp *isp = to_rkisp1_isp(sd);922	struct rkisp1_device *rkisp1 = isp->rkisp1;923	struct v4l2_subdev_state *sd_state;924	struct media_pad *source_pad;925	struct media_pad *sink_pad;926	enum v4l2_mbus_type mbus_type;927	u32 mbus_flags;928	int ret;929 930	if (!enable) {931		v4l2_subdev_call(rkisp1->source, video, s_stream, false);932		rkisp1_isp_stop(isp);933		return 0;934	}935 936	sink_pad = &isp->pads[RKISP1_ISP_PAD_SINK_VIDEO];937	source_pad = media_pad_remote_pad_unique(sink_pad);938	if (IS_ERR(source_pad)) {939		dev_dbg(rkisp1->dev, "Failed to get source for ISP: %ld\n",940			PTR_ERR(source_pad));941		return -EPIPE;942	}943 944	rkisp1->source = media_entity_to_v4l2_subdev(source_pad->entity);945	if (!rkisp1->source) {946		/* This should really not happen, so is not worth a message. */947		return -EPIPE;948	}949 950	if (rkisp1->source == &rkisp1->csi.sd) {951		mbus_type = V4L2_MBUS_CSI2_DPHY;952		mbus_flags = 0;953	} else {954		const struct rkisp1_sensor_async *asd;955		struct v4l2_async_connection *asc;956 957		asc = v4l2_async_connection_unique(rkisp1->source);958		if (!asc)959			return -EPIPE;960 961		asd = container_of(asc, struct rkisp1_sensor_async, asd);962 963		mbus_type = asd->mbus_type;964		mbus_flags = asd->mbus_flags;965	}966 967	isp->frame_sequence = -1;968 969	sd_state = v4l2_subdev_lock_and_get_active_state(sd);970 971	ret = rkisp1_config_cif(isp, sd_state, mbus_type, mbus_flags);972	if (ret)973		goto out_unlock;974 975	ret = rkisp1_isp_start(isp, sd_state, source_pad);976	if (ret)977		goto out_unlock;978 979	ret = v4l2_subdev_call(rkisp1->source, video, s_stream, true);980	if (ret) {981		rkisp1_isp_stop(isp);982		goto out_unlock;983	}984 985out_unlock:986	v4l2_subdev_unlock_state(sd_state);987	return ret;988}989 990static int rkisp1_isp_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh,991			       struct v4l2_event_subscription *sub)992{993	if (sub->type != V4L2_EVENT_FRAME_SYNC)994		return -EINVAL;995 996	/* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */997	if (sub->id != 0)998		return -EINVAL;999 1000	return v4l2_event_subscribe(fh, sub, 0, NULL);1001}1002 1003static const struct media_entity_operations rkisp1_isp_media_ops = {1004	.link_validate = rkisp1_subdev_link_validate,1005};1006 1007static const struct v4l2_subdev_video_ops rkisp1_isp_video_ops = {1008	.s_stream = rkisp1_isp_s_stream,1009};1010 1011static const struct v4l2_subdev_core_ops rkisp1_isp_core_ops = {1012	.subscribe_event = rkisp1_isp_subs_evt,1013	.unsubscribe_event = v4l2_event_subdev_unsubscribe,1014};1015 1016static const struct v4l2_subdev_ops rkisp1_isp_ops = {1017	.core = &rkisp1_isp_core_ops,1018	.video = &rkisp1_isp_video_ops,1019	.pad = &rkisp1_isp_pad_ops,1020};1021 1022static const struct v4l2_subdev_internal_ops rkisp1_isp_internal_ops = {1023	.init_state = rkisp1_isp_init_state,1024};1025 1026int rkisp1_isp_register(struct rkisp1_device *rkisp1)1027{1028	struct rkisp1_isp *isp = &rkisp1->isp;1029	struct media_pad *pads = isp->pads;1030	struct v4l2_subdev *sd = &isp->sd;1031	int ret;1032 1033	isp->rkisp1 = rkisp1;1034 1035	v4l2_subdev_init(sd, &rkisp1_isp_ops);1036	sd->internal_ops = &rkisp1_isp_internal_ops;1037	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;1038	sd->entity.ops = &rkisp1_isp_media_ops;1039	sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;1040	sd->owner = THIS_MODULE;1041	strscpy(sd->name, RKISP1_ISP_DEV_NAME, sizeof(sd->name));1042 1043	pads[RKISP1_ISP_PAD_SINK_VIDEO].flags = MEDIA_PAD_FL_SINK |1044						MEDIA_PAD_FL_MUST_CONNECT;1045	pads[RKISP1_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;1046	pads[RKISP1_ISP_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;1047	pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;1048 1049	ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX, pads);1050	if (ret)1051		goto err_entity_cleanup;1052 1053	ret = v4l2_subdev_init_finalize(sd);1054	if (ret)1055		goto err_subdev_cleanup;1056 1057	ret = v4l2_device_register_subdev(&rkisp1->v4l2_dev, sd);1058	if (ret) {1059		dev_err(rkisp1->dev, "Failed to register isp subdev\n");1060		goto err_subdev_cleanup;1061	}1062 1063	return 0;1064 1065err_subdev_cleanup:1066	v4l2_subdev_cleanup(sd);1067err_entity_cleanup:1068	media_entity_cleanup(&sd->entity);1069	isp->sd.v4l2_dev = NULL;1070	return ret;1071}1072 1073void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)1074{1075	struct rkisp1_isp *isp = &rkisp1->isp;1076 1077	if (!isp->sd.v4l2_dev)1078		return;1079 1080	v4l2_device_unregister_subdev(&isp->sd);1081	v4l2_subdev_cleanup(&isp->sd);1082	media_entity_cleanup(&isp->sd.entity);1083}1084 1085/* ----------------------------------------------------------------------------1086 * Interrupt handlers1087 */1088 1089static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)1090{1091	struct v4l2_event event = {1092		.type = V4L2_EVENT_FRAME_SYNC,1093	};1094 1095	event.u.frame_sync.frame_sequence = isp->frame_sequence;1096	v4l2_event_queue(isp->sd.devnode, &event);1097}1098 1099irqreturn_t rkisp1_isp_isr(int irq, void *ctx)1100{1101	struct device *dev = ctx;1102	struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);1103	u32 status, isp_err;1104 1105	if (!rkisp1->irqs_enabled)1106		return IRQ_NONE;1107 1108	status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);1109	if (!status)1110		return IRQ_NONE;1111 1112	rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, status);1113 1114	/* Vertical sync signal, starting generating new frame */1115	if (status & RKISP1_CIF_ISP_V_START) {1116		rkisp1->isp.frame_sequence++;1117		rkisp1_isp_queue_event_sof(&rkisp1->isp);1118		if (status & RKISP1_CIF_ISP_FRAME) {1119			WARN_ONCE(1, "irq delay is too long, buffers might not be in sync\n");1120			rkisp1->debug.irq_delay++;1121		}1122	}1123	if (status & RKISP1_CIF_ISP_PIC_SIZE_ERROR) {1124		/* Clear pic_size_error */1125		isp_err = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ERR);1126		if (isp_err & RKISP1_CIF_ISP_ERR_INFORM_SIZE)1127			rkisp1->debug.inform_size_error++;1128		if (isp_err & RKISP1_CIF_ISP_ERR_IS_SIZE)1129			rkisp1->debug.img_stabilization_size_error++;1130		if (isp_err & RKISP1_CIF_ISP_ERR_OUTFORM_SIZE)1131			rkisp1->debug.outform_size_error++;1132		rkisp1_write(rkisp1, RKISP1_CIF_ISP_ERR_CLR, isp_err);1133	} else if (status & RKISP1_CIF_ISP_DATA_LOSS) {1134		/* keep track of data_loss in debugfs */1135		rkisp1->debug.data_loss++;1136	}1137 1138	if (status & RKISP1_CIF_ISP_FRAME) {1139		u32 isp_ris;1140 1141		rkisp1->debug.complete_frames++;1142 1143		/* New frame from the sensor received */1144		isp_ris = rkisp1_read(rkisp1, RKISP1_CIF_ISP_RIS);1145		if (isp_ris & RKISP1_STATS_MEAS_MASK)1146			rkisp1_stats_isr(&rkisp1->stats, isp_ris);1147		/*1148		 * Then update changed configs. Some of them involve1149		 * lot of register writes. Do those only one per frame.1150		 * Do the updates in the order of the processing flow.1151		 */1152		rkisp1_params_isr(rkisp1);1153	}1154 1155	return IRQ_HANDLED;1156}1157