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