Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: bcm2835-unicam: Add support for CCP2/CSI2 camera interface

Add a driver for the Unicam camera receiver block on BCM283x processors.
It is represented as two video device nodes: unicam-image and
unicam-embedded which are connected to an internal subdev (named
unicam-subdev) in order to manage streams routing.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Co-developed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Co-developed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
[Sakari Ailus: Squash fixes by Laurent.]
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

authored by

Dave Stevenson and committed by
Hans Verkuil
392cd78d 05a9eadb

+3019
+1
MAINTAINERS
··· 4039 4039 L: linux-media@vger.kernel.org 4040 4040 S: Maintained 4041 4041 F: Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml 4042 + F: drivers/media/platform/bcm2835/ 4042 4043 4043 4044 BROADCOM BCM47XX MIPS ARCHITECTURE 4044 4045 M: Hauke Mehrtens <hauke@hauke-m.de>
+1
drivers/media/platform/Kconfig
··· 67 67 source "drivers/media/platform/amphion/Kconfig" 68 68 source "drivers/media/platform/aspeed/Kconfig" 69 69 source "drivers/media/platform/atmel/Kconfig" 70 + source "drivers/media/platform/broadcom/Kconfig" 70 71 source "drivers/media/platform/cadence/Kconfig" 71 72 source "drivers/media/platform/chips-media/Kconfig" 72 73 source "drivers/media/platform/intel/Kconfig"
+1
drivers/media/platform/Makefile
··· 10 10 obj-y += amphion/ 11 11 obj-y += aspeed/ 12 12 obj-y += atmel/ 13 + obj-y += broadcom/ 13 14 obj-y += cadence/ 14 15 obj-y += chips-media/ 15 16 obj-y += intel/
+23
drivers/media/platform/broadcom/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + config VIDEO_BCM2835_UNICAM 4 + tristate "Broadcom BCM283x/BCM271x Unicam video capture driver" 5 + depends on ARCH_BCM2835 || COMPILE_TEST 6 + depends on PM 7 + depends on VIDEO_DEV 8 + select MEDIA_CONTROLLER 9 + select V4L2_FWNODE 10 + select VIDEO_V4L2_SUBDEV_API 11 + select VIDEOBUF2_DMA_CONTIG 12 + help 13 + Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver. 14 + This is a V4L2 driver that controls the CSI-2 receiver directly, 15 + independently from the VC4 firmware. 16 + 17 + This driver is mutually exclusive with the use of bcm2835-camera. The 18 + firmware will disable all access to the peripheral from within the 19 + firmware if it finds a DT node using it, and bcm2835-camera will 20 + therefore fail to probe. 21 + 22 + To compile this driver as a module, choose M here. The module will be 23 + called bcm2835-unicam.
+3
drivers/media/platform/broadcom/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o
+246
drivers/media/platform/broadcom/bcm2835-unicam-regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + /* 4 + * Copyright (C) 2017-2020 Raspberry Pi Trading. 5 + * Dave Stevenson <dave.stevenson@raspberrypi.com> 6 + */ 7 + 8 + #ifndef VC4_REGS_UNICAM_H 9 + #define VC4_REGS_UNICAM_H 10 + 11 + #include <linux/bits.h> 12 + 13 + /* 14 + * The following values are taken from files found within the code drop 15 + * made by Broadcom for the BCM21553 Graphics Driver, predominantly in 16 + * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h. 17 + * They have been modified to be only the register offset. 18 + */ 19 + #define UNICAM_CTRL 0x000 20 + #define UNICAM_STA 0x004 21 + #define UNICAM_ANA 0x008 22 + #define UNICAM_PRI 0x00c 23 + #define UNICAM_CLK 0x010 24 + #define UNICAM_CLT 0x014 25 + #define UNICAM_DAT0 0x018 26 + #define UNICAM_DAT1 0x01c 27 + #define UNICAM_DAT2 0x020 28 + #define UNICAM_DAT3 0x024 29 + #define UNICAM_DLT 0x028 30 + #define UNICAM_CMP0 0x02c 31 + #define UNICAM_CMP1 0x030 32 + #define UNICAM_CAP0 0x034 33 + #define UNICAM_CAP1 0x038 34 + #define UNICAM_ICTL 0x100 35 + #define UNICAM_ISTA 0x104 36 + #define UNICAM_IDI0 0x108 37 + #define UNICAM_IPIPE 0x10c 38 + #define UNICAM_IBSA0 0x110 39 + #define UNICAM_IBEA0 0x114 40 + #define UNICAM_IBLS 0x118 41 + #define UNICAM_IBWP 0x11c 42 + #define UNICAM_IHWIN 0x120 43 + #define UNICAM_IHSTA 0x124 44 + #define UNICAM_IVWIN 0x128 45 + #define UNICAM_IVSTA 0x12c 46 + #define UNICAM_ICC 0x130 47 + #define UNICAM_ICS 0x134 48 + #define UNICAM_IDC 0x138 49 + #define UNICAM_IDPO 0x13c 50 + #define UNICAM_IDCA 0x140 51 + #define UNICAM_IDCD 0x144 52 + #define UNICAM_IDS 0x148 53 + #define UNICAM_DCS 0x200 54 + #define UNICAM_DBSA0 0x204 55 + #define UNICAM_DBEA0 0x208 56 + #define UNICAM_DBWP 0x20c 57 + #define UNICAM_DBCTL 0x300 58 + #define UNICAM_IBSA1 0x304 59 + #define UNICAM_IBEA1 0x308 60 + #define UNICAM_IDI1 0x30c 61 + #define UNICAM_DBSA1 0x310 62 + #define UNICAM_DBEA1 0x314 63 + #define UNICAM_MISC 0x400 64 + 65 + /* 66 + * The following bitmasks are from the kernel released by Broadcom 67 + * for Android - https://android.googlesource.com/kernel/bcm/ 68 + * The Rhea, Hawaii, and Java chips all contain the same VideoCore4 69 + * Unicam block as BCM2835, as defined in eg 70 + * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar. 71 + * Values reworked to use the kernel BIT and GENMASK macros. 72 + * 73 + * Some of the bit mnenomics have been amended to match the datasheet. 74 + */ 75 + /* UNICAM_CTRL Register */ 76 + #define UNICAM_CPE BIT(0) 77 + #define UNICAM_MEM BIT(1) 78 + #define UNICAM_CPR BIT(2) 79 + #define UNICAM_CPM_MASK GENMASK(3, 3) 80 + #define UNICAM_CPM_CSI2 0 81 + #define UNICAM_CPM_CCP2 1 82 + #define UNICAM_SOE BIT(4) 83 + #define UNICAM_DCM_MASK GENMASK(5, 5) 84 + #define UNICAM_DCM_STROBE 0 85 + #define UNICAM_DCM_DATA 1 86 + #define UNICAM_SLS BIT(6) 87 + #define UNICAM_PFT_MASK GENMASK(11, 8) 88 + #define UNICAM_OET_MASK GENMASK(20, 12) 89 + 90 + /* UNICAM_STA Register */ 91 + #define UNICAM_SYN BIT(0) 92 + #define UNICAM_CS BIT(1) 93 + #define UNICAM_SBE BIT(2) 94 + #define UNICAM_PBE BIT(3) 95 + #define UNICAM_HOE BIT(4) 96 + #define UNICAM_PLE BIT(5) 97 + #define UNICAM_SSC BIT(6) 98 + #define UNICAM_CRCE BIT(7) 99 + #define UNICAM_OES BIT(8) 100 + #define UNICAM_IFO BIT(9) 101 + #define UNICAM_OFO BIT(10) 102 + #define UNICAM_BFO BIT(11) 103 + #define UNICAM_DL BIT(12) 104 + #define UNICAM_PS BIT(13) 105 + #define UNICAM_IS BIT(14) 106 + #define UNICAM_PI0 BIT(15) 107 + #define UNICAM_PI1 BIT(16) 108 + #define UNICAM_FSI_S BIT(17) 109 + #define UNICAM_FEI_S BIT(18) 110 + #define UNICAM_LCI_S BIT(19) 111 + #define UNICAM_BUF0_RDY BIT(20) 112 + #define UNICAM_BUF0_NO BIT(21) 113 + #define UNICAM_BUF1_RDY BIT(22) 114 + #define UNICAM_BUF1_NO BIT(23) 115 + #define UNICAM_DI BIT(24) 116 + 117 + #define UNICAM_STA_MASK_ALL \ 118 + (UNICAM_SBE | UNICAM_PBE | UNICAM_HOE | UNICAM_PLE | UNICAM_SSC | \ 119 + UNICAM_CRCE | UNICAM_IFO | UNICAM_OFO | UNICAM_DL | UNICAM_PS | \ 120 + UNICAM_PI0 | UNICAM_PI1) 121 + 122 + /* UNICAM_ANA Register */ 123 + #define UNICAM_APD BIT(0) 124 + #define UNICAM_BPD BIT(1) 125 + #define UNICAM_AR BIT(2) 126 + #define UNICAM_DDL BIT(3) 127 + #define UNICAM_CTATADJ_MASK GENMASK(7, 4) 128 + #define UNICAM_PTATADJ_MASK GENMASK(11, 8) 129 + 130 + /* UNICAM_PRI Register */ 131 + #define UNICAM_PE BIT(0) 132 + #define UNICAM_PT_MASK GENMASK(2, 1) 133 + #define UNICAM_NP_MASK GENMASK(7, 4) 134 + #define UNICAM_PP_MASK GENMASK(11, 8) 135 + #define UNICAM_BS_MASK GENMASK(15, 12) 136 + #define UNICAM_BL_MASK GENMASK(17, 16) 137 + 138 + /* UNICAM_CLK Register */ 139 + #define UNICAM_CLE BIT(0) 140 + #define UNICAM_CLPD BIT(1) 141 + #define UNICAM_CLLPE BIT(2) 142 + #define UNICAM_CLHSE BIT(3) 143 + #define UNICAM_CLTRE BIT(4) 144 + #define UNICAM_CLAC_MASK GENMASK(8, 5) 145 + #define UNICAM_CLSTE BIT(29) 146 + 147 + /* UNICAM_CLT Register */ 148 + #define UNICAM_CLT1_MASK GENMASK(7, 0) 149 + #define UNICAM_CLT2_MASK GENMASK(15, 8) 150 + 151 + /* UNICAM_DATn Registers */ 152 + #define UNICAM_DLE BIT(0) 153 + #define UNICAM_DLPD BIT(1) 154 + #define UNICAM_DLLPE BIT(2) 155 + #define UNICAM_DLHSE BIT(3) 156 + #define UNICAM_DLTRE BIT(4) 157 + #define UNICAM_DLSM BIT(5) 158 + #define UNICAM_DLFO BIT(28) 159 + #define UNICAM_DLSTE BIT(29) 160 + 161 + #define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE | UNICAM_DLFO) 162 + 163 + /* UNICAM_DLT Register */ 164 + #define UNICAM_DLT1_MASK GENMASK(7, 0) 165 + #define UNICAM_DLT2_MASK GENMASK(15, 8) 166 + #define UNICAM_DLT3_MASK GENMASK(23, 16) 167 + 168 + /* UNICAM_ICTL Register */ 169 + #define UNICAM_FSIE BIT(0) 170 + #define UNICAM_FEIE BIT(1) 171 + #define UNICAM_IBOB BIT(2) 172 + #define UNICAM_FCM BIT(3) 173 + #define UNICAM_TFC BIT(4) 174 + #define UNICAM_LIP_MASK GENMASK(6, 5) 175 + #define UNICAM_LCIE_MASK GENMASK(28, 16) 176 + 177 + /* UNICAM_IDI0/1 Register */ 178 + #define UNICAM_ID0_MASK GENMASK(7, 0) 179 + #define UNICAM_ID1_MASK GENMASK(15, 8) 180 + #define UNICAM_ID2_MASK GENMASK(23, 16) 181 + #define UNICAM_ID3_MASK GENMASK(31, 24) 182 + 183 + /* UNICAM_ISTA Register */ 184 + #define UNICAM_FSI BIT(0) 185 + #define UNICAM_FEI BIT(1) 186 + #define UNICAM_LCI BIT(2) 187 + 188 + #define UNICAM_ISTA_MASK_ALL (UNICAM_FSI | UNICAM_FEI | UNICAM_LCI) 189 + 190 + /* UNICAM_IPIPE Register */ 191 + #define UNICAM_PUM_MASK GENMASK(2, 0) 192 + /* Unpacking modes */ 193 + #define UNICAM_PUM_NONE 0 194 + #define UNICAM_PUM_UNPACK6 1 195 + #define UNICAM_PUM_UNPACK7 2 196 + #define UNICAM_PUM_UNPACK8 3 197 + #define UNICAM_PUM_UNPACK10 4 198 + #define UNICAM_PUM_UNPACK12 5 199 + #define UNICAM_PUM_UNPACK14 6 200 + #define UNICAM_PUM_UNPACK16 7 201 + #define UNICAM_DDM_MASK GENMASK(6, 3) 202 + #define UNICAM_PPM_MASK GENMASK(9, 7) 203 + /* Packing modes */ 204 + #define UNICAM_PPM_NONE 0 205 + #define UNICAM_PPM_PACK8 1 206 + #define UNICAM_PPM_PACK10 2 207 + #define UNICAM_PPM_PACK12 3 208 + #define UNICAM_PPM_PACK14 4 209 + #define UNICAM_PPM_PACK16 5 210 + #define UNICAM_DEM_MASK GENMASK(11, 10) 211 + #define UNICAM_DEBL_MASK GENMASK(14, 12) 212 + #define UNICAM_ICM_MASK GENMASK(16, 15) 213 + #define UNICAM_IDM_MASK GENMASK(17, 17) 214 + 215 + /* UNICAM_ICC Register */ 216 + #define UNICAM_ICFL_MASK GENMASK(4, 0) 217 + #define UNICAM_ICFH_MASK GENMASK(9, 5) 218 + #define UNICAM_ICST_MASK GENMASK(12, 10) 219 + #define UNICAM_ICLT_MASK GENMASK(15, 13) 220 + #define UNICAM_ICLL_MASK GENMASK(31, 16) 221 + 222 + /* UNICAM_DCS Register */ 223 + #define UNICAM_DIE BIT(0) 224 + #define UNICAM_DIM BIT(1) 225 + #define UNICAM_DBOB BIT(3) 226 + #define UNICAM_FDE BIT(4) 227 + #define UNICAM_LDP BIT(5) 228 + #define UNICAM_EDL_MASK GENMASK(15, 8) 229 + 230 + /* UNICAM_DBCTL Register */ 231 + #define UNICAM_DBEN BIT(0) 232 + #define UNICAM_BUF0_IE BIT(1) 233 + #define UNICAM_BUF1_IE BIT(2) 234 + 235 + /* UNICAM_CMP[0,1] register */ 236 + #define UNICAM_PCE BIT(31) 237 + #define UNICAM_GI BIT(9) 238 + #define UNICAM_CPH BIT(8) 239 + #define UNICAM_PCVC_MASK GENMASK(7, 6) 240 + #define UNICAM_PCDT_MASK GENMASK(5, 0) 241 + 242 + /* UNICAM_MISC register */ 243 + #define UNICAM_FL0 BIT(6) 244 + #define UNICAM_FL1 BIT(9) 245 + 246 + #endif
+2744
drivers/media/platform/broadcom/bcm2835-unicam.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * BCM283x / BCM271x Unicam Capture Driver 4 + * 5 + * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd. 6 + * Copyright (C) 2024 - Ideas on Board 7 + * 8 + * Dave Stevenson <dave.stevenson@raspberrypi.com> 9 + * 10 + * Based on TI am437x driver by 11 + * Benoit Parrot <bparrot@ti.com> 12 + * Lad, Prabhakar <prabhakar.csengg@gmail.com> 13 + * 14 + * and TI CAL camera interface driver by 15 + * Benoit Parrot <bparrot@ti.com> 16 + * 17 + * 18 + * There are two camera drivers in the kernel for BCM283x - this one and 19 + * bcm2835-camera (currently in staging). 20 + * 21 + * This driver directly controls the Unicam peripheral - there is no 22 + * involvement with the VideoCore firmware. Unicam receives CSI-2 or CCP2 data 23 + * and writes it into SDRAM. The only potential processing options are to 24 + * repack Bayer data into an alternate format, and applying windowing. The 25 + * repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P to 26 + * V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12, but 27 + * not generically up to V4L2_PIX_FMT_Sxxxx16. Support for windowing may be 28 + * added later. 29 + * 30 + * It should be possible to connect this driver to any sensor with a suitable 31 + * output interface and V4L2 subdevice driver. 32 + */ 33 + 34 + #include <linux/clk.h> 35 + #include <linux/delay.h> 36 + #include <linux/device.h> 37 + #include <linux/dma-mapping.h> 38 + #include <linux/err.h> 39 + #include <linux/interrupt.h> 40 + #include <linux/io.h> 41 + #include <linux/module.h> 42 + #include <linux/of.h> 43 + #include <linux/of_device.h> 44 + #include <linux/platform_device.h> 45 + #include <linux/pm_runtime.h> 46 + #include <linux/slab.h> 47 + #include <linux/videodev2.h> 48 + 49 + #include <media/mipi-csi2.h> 50 + #include <media/v4l2-async.h> 51 + #include <media/v4l2-common.h> 52 + #include <media/v4l2-dev.h> 53 + #include <media/v4l2-device.h> 54 + #include <media/v4l2-event.h> 55 + #include <media/v4l2-ioctl.h> 56 + #include <media/v4l2-fwnode.h> 57 + #include <media/v4l2-mc.h> 58 + #include <media/videobuf2-dma-contig.h> 59 + 60 + #include "bcm2835-unicam-regs.h" 61 + 62 + #define UNICAM_MODULE_NAME "unicam" 63 + 64 + /* 65 + * Unicam must request a minimum of 250Mhz from the VPU clock. 66 + * Otherwise the input FIFOs overrun and cause image corruption. 67 + */ 68 + #define UNICAM_MIN_VPU_CLOCK_RATE (250 * 1000 * 1000) 69 + 70 + /* Unicam has an internal DMA alignment constraint of 16 bytes for each line. */ 71 + #define UNICAM_DMA_BPL_ALIGNMENT 16 72 + 73 + /* 74 + * The image stride is stored in a 16 bit register, and needs to be aligned to 75 + * the DMA constraint. As the ISP in the same SoC has a 32 bytes alignment 76 + * constraint on its input, set the image stride alignment to 32 bytes here as 77 + * well to avoid incompatible configurations. 78 + */ 79 + #define UNICAM_IMAGE_BPL_ALIGNMENT 32 80 + #define UNICAM_IMAGE_MAX_BPL ((1U << 16) - UNICAM_IMAGE_BPL_ALIGNMENT) 81 + 82 + /* 83 + * Max width is therefore determined by the max stride divided by the number of 84 + * bits per pixel. Take 32bpp as a worst case. No imposed limit on the height, 85 + * so adopt a square image for want of anything better. 86 + */ 87 + #define UNICAM_IMAGE_MIN_WIDTH 16 88 + #define UNICAM_IMAGE_MIN_HEIGHT 16 89 + #define UNICAM_IMAGE_MAX_WIDTH (UNICAM_IMAGE_MAX_BPL / 4) 90 + #define UNICAM_IMAGE_MAX_HEIGHT UNICAM_IMAGE_MAX_WIDTH 91 + 92 + /* 93 + * There's no intrinsic limits on the width and height for embedded data. Use 94 + * the same maximum values as for the image, to avoid overflows in the image 95 + * size computation. 96 + */ 97 + #define UNICAM_META_MIN_WIDTH 1 98 + #define UNICAM_META_MIN_HEIGHT 1 99 + #define UNICAM_META_MAX_WIDTH UNICAM_IMAGE_MAX_WIDTH 100 + #define UNICAM_META_MAX_HEIGHT UNICAM_IMAGE_MAX_HEIGHT 101 + 102 + /* 103 + * Size of the dummy buffer. Can be any size really, but the DMA 104 + * allocation works in units of page sizes. 105 + */ 106 + #define UNICAM_DUMMY_BUF_SIZE PAGE_SIZE 107 + 108 + enum unicam_pad { 109 + UNICAM_SD_PAD_SINK, 110 + UNICAM_SD_PAD_SOURCE_IMAGE, 111 + UNICAM_SD_PAD_SOURCE_METADATA, 112 + UNICAM_SD_NUM_PADS 113 + }; 114 + 115 + enum unicam_node_type { 116 + UNICAM_IMAGE_NODE, 117 + UNICAM_METADATA_NODE, 118 + UNICAM_MAX_NODES 119 + }; 120 + 121 + /* 122 + * struct unicam_format_info - Unicam media bus format information 123 + * @fourcc: V4L2 pixel format FCC identifier. 0 if n/a. 124 + * @unpacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded 125 + * out to 16bpp. 0 if n/a. 126 + * @code: V4L2 media bus format code. 127 + * @depth: Bits per pixel as delivered from the source. 128 + * @csi_dt: CSI data type. 129 + * @unpack: PUM value when unpacking to @unpacked_fourcc 130 + */ 131 + struct unicam_format_info { 132 + u32 fourcc; 133 + u32 unpacked_fourcc; 134 + u32 code; 135 + u8 depth; 136 + u8 csi_dt; 137 + u8 unpack; 138 + }; 139 + 140 + struct unicam_buffer { 141 + struct vb2_v4l2_buffer vb; 142 + struct list_head list; 143 + dma_addr_t dma_addr; 144 + unsigned int size; 145 + }; 146 + 147 + static inline struct unicam_buffer *to_unicam_buffer(struct vb2_buffer *vb) 148 + { 149 + return container_of(vb, struct unicam_buffer, vb.vb2_buf); 150 + } 151 + 152 + struct unicam_node { 153 + bool registered; 154 + unsigned int id; 155 + 156 + /* Pointer to the current v4l2_buffer */ 157 + struct unicam_buffer *cur_frm; 158 + /* Pointer to the next v4l2_buffer */ 159 + struct unicam_buffer *next_frm; 160 + /* Used to store current pixel format */ 161 + struct v4l2_format fmt; 162 + /* Buffer queue used in video-buf */ 163 + struct vb2_queue buffer_queue; 164 + /* Queue of filled frames */ 165 + struct list_head dma_queue; 166 + /* IRQ lock for DMA queue */ 167 + spinlock_t dma_queue_lock; 168 + /* Identifies video device for this channel */ 169 + struct video_device video_dev; 170 + /* Pointer to the parent handle */ 171 + struct unicam_device *dev; 172 + struct media_pad pad; 173 + /* 174 + * Dummy buffer intended to be used by unicam 175 + * if we have no other queued buffers to swap to. 176 + */ 177 + struct unicam_buffer dummy_buf; 178 + void *dummy_buf_cpu_addr; 179 + }; 180 + 181 + struct unicam_device { 182 + struct kref kref; 183 + 184 + /* peripheral base address */ 185 + void __iomem *base; 186 + /* clock gating base address */ 187 + void __iomem *clk_gate_base; 188 + /* lp clock handle */ 189 + struct clk *clock; 190 + /* vpu clock handle */ 191 + struct clk *vpu_clock; 192 + /* V4l2 device */ 193 + struct v4l2_device v4l2_dev; 194 + struct media_device mdev; 195 + 196 + /* parent device */ 197 + struct device *dev; 198 + /* subdevice async notifier */ 199 + struct v4l2_async_notifier notifier; 200 + unsigned int sequence; 201 + 202 + /* Sensor node */ 203 + struct { 204 + struct v4l2_subdev *subdev; 205 + struct media_pad *pad; 206 + } sensor; 207 + 208 + /* Internal subdev */ 209 + struct { 210 + struct v4l2_subdev sd; 211 + struct media_pad pads[UNICAM_SD_NUM_PADS]; 212 + unsigned int enabled_streams; 213 + } subdev; 214 + 215 + enum v4l2_mbus_type bus_type; 216 + /* 217 + * Stores bus.mipi_csi2.flags for CSI2 sensors, or 218 + * bus.mipi_csi1.strobe for CCP2. 219 + */ 220 + unsigned int bus_flags; 221 + unsigned int max_data_lanes; 222 + 223 + struct { 224 + struct media_pipeline pipe; 225 + unsigned int num_data_lanes; 226 + unsigned int nodes; 227 + } pipe; 228 + 229 + /* Lock used for the video devices of both nodes */ 230 + struct mutex lock; 231 + struct unicam_node node[UNICAM_MAX_NODES]; 232 + }; 233 + 234 + static inline struct unicam_device * 235 + notifier_to_unicam_device(struct v4l2_async_notifier *notifier) 236 + { 237 + return container_of(notifier, struct unicam_device, notifier); 238 + } 239 + 240 + static inline struct unicam_device * 241 + sd_to_unicam_device(struct v4l2_subdev *sd) 242 + { 243 + return container_of(sd, struct unicam_device, subdev.sd); 244 + } 245 + 246 + static void unicam_release(struct kref *kref) 247 + { 248 + struct unicam_device *unicam = 249 + container_of(kref, struct unicam_device, kref); 250 + 251 + if (unicam->mdev.dev) 252 + media_device_cleanup(&unicam->mdev); 253 + 254 + mutex_destroy(&unicam->lock); 255 + kfree(unicam); 256 + } 257 + 258 + static struct unicam_device *unicam_get(struct unicam_device *unicam) 259 + { 260 + kref_get(&unicam->kref); 261 + 262 + return unicam; 263 + } 264 + 265 + static void unicam_put(struct unicam_device *unicam) 266 + { 267 + kref_put(&unicam->kref, unicam_release); 268 + } 269 + 270 + /* ----------------------------------------------------------------------------- 271 + * Misc helper functions 272 + */ 273 + 274 + static inline bool unicam_sd_pad_is_source(u32 pad) 275 + { 276 + /* Camera RX has 1 sink pad, and N source pads */ 277 + return pad != UNICAM_SD_PAD_SINK; 278 + } 279 + 280 + static inline bool is_metadata_node(struct unicam_node *node) 281 + { 282 + return node->video_dev.device_caps & V4L2_CAP_META_CAPTURE; 283 + } 284 + 285 + static inline bool is_image_node(struct unicam_node *node) 286 + { 287 + return node->video_dev.device_caps & V4L2_CAP_VIDEO_CAPTURE; 288 + } 289 + 290 + /* ----------------------------------------------------------------------------- 291 + * Format data table and helper functions 292 + */ 293 + 294 + static const struct v4l2_mbus_framefmt unicam_default_image_format = { 295 + .width = 640, 296 + .height = 480, 297 + .code = MEDIA_BUS_FMT_UYVY8_1X16, 298 + .field = V4L2_FIELD_NONE, 299 + .colorspace = V4L2_COLORSPACE_SRGB, 300 + .ycbcr_enc = V4L2_YCBCR_ENC_601, 301 + .quantization = V4L2_QUANTIZATION_LIM_RANGE, 302 + .xfer_func = V4L2_XFER_FUNC_SRGB, 303 + .flags = 0, 304 + }; 305 + 306 + static const struct v4l2_mbus_framefmt unicam_default_meta_format = { 307 + .width = 640, 308 + .height = 2, 309 + .code = MEDIA_BUS_FMT_META_8, 310 + .field = V4L2_FIELD_NONE, 311 + }; 312 + 313 + static const struct unicam_format_info unicam_image_formats[] = { 314 + /* YUV Formats */ 315 + { 316 + .fourcc = V4L2_PIX_FMT_YUYV, 317 + .code = MEDIA_BUS_FMT_YUYV8_1X16, 318 + .depth = 16, 319 + .csi_dt = MIPI_CSI2_DT_YUV422_8B, 320 + }, { 321 + .fourcc = V4L2_PIX_FMT_UYVY, 322 + .code = MEDIA_BUS_FMT_UYVY8_1X16, 323 + .depth = 16, 324 + .csi_dt = MIPI_CSI2_DT_YUV422_8B, 325 + }, { 326 + .fourcc = V4L2_PIX_FMT_YVYU, 327 + .code = MEDIA_BUS_FMT_YVYU8_1X16, 328 + .depth = 16, 329 + .csi_dt = MIPI_CSI2_DT_YUV422_8B, 330 + }, { 331 + .fourcc = V4L2_PIX_FMT_VYUY, 332 + .code = MEDIA_BUS_FMT_VYUY8_1X16, 333 + .depth = 16, 334 + .csi_dt = MIPI_CSI2_DT_YUV422_8B, 335 + }, { 336 + /* RGB Formats */ 337 + .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 338 + .code = MEDIA_BUS_FMT_RGB565_1X16, 339 + .depth = 16, 340 + .csi_dt = MIPI_CSI2_DT_RGB565, 341 + }, { 342 + .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ 343 + .code = MEDIA_BUS_FMT_RGB888_1X24, 344 + .depth = 24, 345 + .csi_dt = MIPI_CSI2_DT_RGB888, 346 + }, { 347 + .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ 348 + .code = MEDIA_BUS_FMT_BGR888_1X24, 349 + .depth = 24, 350 + .csi_dt = MIPI_CSI2_DT_RGB888, 351 + }, { 352 + /* Bayer Formats */ 353 + .fourcc = V4L2_PIX_FMT_SBGGR8, 354 + .code = MEDIA_BUS_FMT_SBGGR8_1X8, 355 + .depth = 8, 356 + .csi_dt = MIPI_CSI2_DT_RAW8, 357 + }, { 358 + .fourcc = V4L2_PIX_FMT_SGBRG8, 359 + .code = MEDIA_BUS_FMT_SGBRG8_1X8, 360 + .depth = 8, 361 + .csi_dt = MIPI_CSI2_DT_RAW8, 362 + }, { 363 + .fourcc = V4L2_PIX_FMT_SGRBG8, 364 + .code = MEDIA_BUS_FMT_SGRBG8_1X8, 365 + .depth = 8, 366 + .csi_dt = MIPI_CSI2_DT_RAW8, 367 + }, { 368 + .fourcc = V4L2_PIX_FMT_SRGGB8, 369 + .code = MEDIA_BUS_FMT_SRGGB8_1X8, 370 + .depth = 8, 371 + .csi_dt = MIPI_CSI2_DT_RAW8, 372 + }, { 373 + .fourcc = V4L2_PIX_FMT_SBGGR10P, 374 + .unpacked_fourcc = V4L2_PIX_FMT_SBGGR10, 375 + .code = MEDIA_BUS_FMT_SBGGR10_1X10, 376 + .depth = 10, 377 + .csi_dt = MIPI_CSI2_DT_RAW10, 378 + .unpack = UNICAM_PUM_UNPACK10, 379 + }, { 380 + .fourcc = V4L2_PIX_FMT_SGBRG10P, 381 + .unpacked_fourcc = V4L2_PIX_FMT_SGBRG10, 382 + .code = MEDIA_BUS_FMT_SGBRG10_1X10, 383 + .depth = 10, 384 + .csi_dt = MIPI_CSI2_DT_RAW10, 385 + .unpack = UNICAM_PUM_UNPACK10, 386 + }, { 387 + .fourcc = V4L2_PIX_FMT_SGRBG10P, 388 + .unpacked_fourcc = V4L2_PIX_FMT_SGRBG10, 389 + .code = MEDIA_BUS_FMT_SGRBG10_1X10, 390 + .depth = 10, 391 + .csi_dt = MIPI_CSI2_DT_RAW10, 392 + .unpack = UNICAM_PUM_UNPACK10, 393 + }, { 394 + .fourcc = V4L2_PIX_FMT_SRGGB10P, 395 + .unpacked_fourcc = V4L2_PIX_FMT_SRGGB10, 396 + .code = MEDIA_BUS_FMT_SRGGB10_1X10, 397 + .depth = 10, 398 + .csi_dt = MIPI_CSI2_DT_RAW10, 399 + .unpack = UNICAM_PUM_UNPACK10, 400 + }, { 401 + .fourcc = V4L2_PIX_FMT_SBGGR12P, 402 + .unpacked_fourcc = V4L2_PIX_FMT_SBGGR12, 403 + .code = MEDIA_BUS_FMT_SBGGR12_1X12, 404 + .depth = 12, 405 + .csi_dt = MIPI_CSI2_DT_RAW12, 406 + .unpack = UNICAM_PUM_UNPACK12, 407 + }, { 408 + .fourcc = V4L2_PIX_FMT_SGBRG12P, 409 + .unpacked_fourcc = V4L2_PIX_FMT_SGBRG12, 410 + .code = MEDIA_BUS_FMT_SGBRG12_1X12, 411 + .depth = 12, 412 + .csi_dt = MIPI_CSI2_DT_RAW12, 413 + .unpack = UNICAM_PUM_UNPACK12, 414 + }, { 415 + .fourcc = V4L2_PIX_FMT_SGRBG12P, 416 + .unpacked_fourcc = V4L2_PIX_FMT_SGRBG12, 417 + .code = MEDIA_BUS_FMT_SGRBG12_1X12, 418 + .depth = 12, 419 + .csi_dt = MIPI_CSI2_DT_RAW12, 420 + .unpack = UNICAM_PUM_UNPACK12, 421 + }, { 422 + .fourcc = V4L2_PIX_FMT_SRGGB12P, 423 + .unpacked_fourcc = V4L2_PIX_FMT_SRGGB12, 424 + .code = MEDIA_BUS_FMT_SRGGB12_1X12, 425 + .depth = 12, 426 + .csi_dt = MIPI_CSI2_DT_RAW12, 427 + .unpack = UNICAM_PUM_UNPACK12, 428 + }, { 429 + .fourcc = V4L2_PIX_FMT_SBGGR14P, 430 + .unpacked_fourcc = V4L2_PIX_FMT_SBGGR14, 431 + .code = MEDIA_BUS_FMT_SBGGR14_1X14, 432 + .depth = 14, 433 + .csi_dt = MIPI_CSI2_DT_RAW14, 434 + .unpack = UNICAM_PUM_UNPACK14, 435 + }, { 436 + .fourcc = V4L2_PIX_FMT_SGBRG14P, 437 + .unpacked_fourcc = V4L2_PIX_FMT_SGBRG14, 438 + .code = MEDIA_BUS_FMT_SGBRG14_1X14, 439 + .depth = 14, 440 + .csi_dt = MIPI_CSI2_DT_RAW14, 441 + .unpack = UNICAM_PUM_UNPACK14, 442 + }, { 443 + .fourcc = V4L2_PIX_FMT_SGRBG14P, 444 + .unpacked_fourcc = V4L2_PIX_FMT_SGRBG14, 445 + .code = MEDIA_BUS_FMT_SGRBG14_1X14, 446 + .depth = 14, 447 + .csi_dt = MIPI_CSI2_DT_RAW14, 448 + .unpack = UNICAM_PUM_UNPACK14, 449 + }, { 450 + .fourcc = V4L2_PIX_FMT_SRGGB14P, 451 + .unpacked_fourcc = V4L2_PIX_FMT_SRGGB14, 452 + .code = MEDIA_BUS_FMT_SRGGB14_1X14, 453 + .depth = 14, 454 + .csi_dt = MIPI_CSI2_DT_RAW14, 455 + .unpack = UNICAM_PUM_UNPACK14, 456 + }, { 457 + /* 16 bit Bayer formats could be supported. */ 458 + 459 + /* Greyscale formats */ 460 + .fourcc = V4L2_PIX_FMT_GREY, 461 + .code = MEDIA_BUS_FMT_Y8_1X8, 462 + .depth = 8, 463 + .csi_dt = MIPI_CSI2_DT_RAW8, 464 + }, { 465 + .fourcc = V4L2_PIX_FMT_Y10P, 466 + .unpacked_fourcc = V4L2_PIX_FMT_Y10, 467 + .code = MEDIA_BUS_FMT_Y10_1X10, 468 + .depth = 10, 469 + .csi_dt = MIPI_CSI2_DT_RAW10, 470 + .unpack = UNICAM_PUM_UNPACK10, 471 + }, { 472 + .fourcc = V4L2_PIX_FMT_Y12P, 473 + .unpacked_fourcc = V4L2_PIX_FMT_Y12, 474 + .code = MEDIA_BUS_FMT_Y12_1X12, 475 + .depth = 12, 476 + .csi_dt = MIPI_CSI2_DT_RAW12, 477 + .unpack = UNICAM_PUM_UNPACK12, 478 + }, { 479 + .fourcc = V4L2_PIX_FMT_Y14P, 480 + .unpacked_fourcc = V4L2_PIX_FMT_Y14, 481 + .code = MEDIA_BUS_FMT_Y14_1X14, 482 + .depth = 14, 483 + .csi_dt = MIPI_CSI2_DT_RAW14, 484 + .unpack = UNICAM_PUM_UNPACK14, 485 + }, 486 + }; 487 + 488 + static const struct unicam_format_info unicam_meta_formats[] = { 489 + { 490 + .fourcc = V4L2_META_FMT_GENERIC_8, 491 + .code = MEDIA_BUS_FMT_META_8, 492 + .depth = 8, 493 + }, { 494 + .fourcc = V4L2_META_FMT_GENERIC_CSI2_10, 495 + .code = MEDIA_BUS_FMT_META_10, 496 + .depth = 10, 497 + }, { 498 + .fourcc = V4L2_META_FMT_GENERIC_CSI2_12, 499 + .code = MEDIA_BUS_FMT_META_12, 500 + .depth = 12, 501 + }, { 502 + .fourcc = V4L2_META_FMT_GENERIC_CSI2_14, 503 + .code = MEDIA_BUS_FMT_META_14, 504 + .depth = 14, 505 + }, 506 + }; 507 + 508 + /* Format setup functions */ 509 + static const struct unicam_format_info * 510 + unicam_find_format_by_code(u32 code, u32 pad) 511 + { 512 + const struct unicam_format_info *formats; 513 + unsigned int num_formats; 514 + unsigned int i; 515 + 516 + if (pad == UNICAM_SD_PAD_SOURCE_IMAGE) { 517 + formats = unicam_image_formats; 518 + num_formats = ARRAY_SIZE(unicam_image_formats); 519 + } else { 520 + formats = unicam_meta_formats; 521 + num_formats = ARRAY_SIZE(unicam_meta_formats); 522 + } 523 + 524 + for (i = 0; i < num_formats; i++) { 525 + if (formats[i].code == code) 526 + return &formats[i]; 527 + } 528 + 529 + return NULL; 530 + } 531 + 532 + static const struct unicam_format_info * 533 + unicam_find_format_by_fourcc(u32 fourcc, u32 pad) 534 + { 535 + const struct unicam_format_info *formats; 536 + unsigned int num_formats; 537 + unsigned int i; 538 + 539 + if (pad == UNICAM_SD_PAD_SOURCE_IMAGE) { 540 + formats = unicam_image_formats; 541 + num_formats = ARRAY_SIZE(unicam_image_formats); 542 + } else { 543 + formats = unicam_meta_formats; 544 + num_formats = ARRAY_SIZE(unicam_meta_formats); 545 + } 546 + 547 + for (i = 0; i < num_formats; ++i) { 548 + if (formats[i].fourcc == fourcc) 549 + return &formats[i]; 550 + } 551 + 552 + return NULL; 553 + } 554 + 555 + static void unicam_calc_image_size_bpl(struct unicam_device *unicam, 556 + const struct unicam_format_info *fmtinfo, 557 + struct v4l2_pix_format *pix) 558 + { 559 + u32 min_bpl; 560 + 561 + v4l_bound_align_image(&pix->width, UNICAM_IMAGE_MIN_WIDTH, 562 + UNICAM_IMAGE_MAX_WIDTH, 2, 563 + &pix->height, UNICAM_IMAGE_MIN_HEIGHT, 564 + UNICAM_IMAGE_MAX_HEIGHT, 0, 0); 565 + 566 + /* Unpacking always goes to 16bpp */ 567 + if (pix->pixelformat == fmtinfo->unpacked_fourcc) 568 + min_bpl = pix->width * 2; 569 + else 570 + min_bpl = pix->width * fmtinfo->depth / 8; 571 + min_bpl = ALIGN(min_bpl, UNICAM_IMAGE_BPL_ALIGNMENT); 572 + 573 + pix->bytesperline = ALIGN(pix->bytesperline, UNICAM_IMAGE_BPL_ALIGNMENT); 574 + pix->bytesperline = clamp_t(unsigned int, pix->bytesperline, min_bpl, 575 + UNICAM_IMAGE_MAX_BPL); 576 + 577 + pix->sizeimage = pix->height * pix->bytesperline; 578 + } 579 + 580 + static void unicam_calc_meta_size_bpl(struct unicam_device *unicam, 581 + const struct unicam_format_info *fmtinfo, 582 + struct v4l2_meta_format *meta) 583 + { 584 + v4l_bound_align_image(&meta->width, UNICAM_META_MIN_WIDTH, 585 + UNICAM_META_MAX_WIDTH, 0, 586 + &meta->height, UNICAM_META_MIN_HEIGHT, 587 + UNICAM_META_MAX_HEIGHT, 0, 0); 588 + 589 + meta->bytesperline = ALIGN(meta->width * fmtinfo->depth / 8, 590 + UNICAM_DMA_BPL_ALIGNMENT); 591 + meta->buffersize = meta->height * meta->bytesperline; 592 + } 593 + 594 + /* ----------------------------------------------------------------------------- 595 + * Hardware handling 596 + */ 597 + 598 + static inline void unicam_clk_write(struct unicam_device *unicam, u32 val) 599 + { 600 + /* Pass the CM_PASSWORD along with the value. */ 601 + writel(val | 0x5a000000, unicam->clk_gate_base); 602 + } 603 + 604 + static inline u32 unicam_reg_read(struct unicam_device *unicam, u32 offset) 605 + { 606 + return readl(unicam->base + offset); 607 + } 608 + 609 + static inline void unicam_reg_write(struct unicam_device *unicam, u32 offset, u32 val) 610 + { 611 + writel(val, unicam->base + offset); 612 + } 613 + 614 + static inline int unicam_get_field(u32 value, u32 mask) 615 + { 616 + return (value & mask) >> __ffs(mask); 617 + } 618 + 619 + static inline void unicam_set_field(u32 *valp, u32 field, u32 mask) 620 + { 621 + u32 val = *valp; 622 + 623 + val &= ~mask; 624 + val |= (field << __ffs(mask)) & mask; 625 + *valp = val; 626 + } 627 + 628 + static inline void unicam_reg_write_field(struct unicam_device *unicam, u32 offset, 629 + u32 field, u32 mask) 630 + { 631 + u32 val = unicam_reg_read(unicam, offset); 632 + 633 + unicam_set_field(&val, field, mask); 634 + unicam_reg_write(unicam, offset, val); 635 + } 636 + 637 + static void unicam_wr_dma_addr(struct unicam_node *node, 638 + struct unicam_buffer *buf) 639 + { 640 + dma_addr_t endaddr = buf->dma_addr + buf->size; 641 + 642 + if (node->id == UNICAM_IMAGE_NODE) { 643 + unicam_reg_write(node->dev, UNICAM_IBSA0, buf->dma_addr); 644 + unicam_reg_write(node->dev, UNICAM_IBEA0, endaddr); 645 + } else { 646 + unicam_reg_write(node->dev, UNICAM_DBSA0, buf->dma_addr); 647 + unicam_reg_write(node->dev, UNICAM_DBEA0, endaddr); 648 + } 649 + } 650 + 651 + static unsigned int unicam_get_lines_done(struct unicam_device *unicam) 652 + { 653 + struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; 654 + unsigned int stride = node->fmt.fmt.pix.bytesperline; 655 + struct unicam_buffer *frm = node->cur_frm; 656 + dma_addr_t cur_addr; 657 + 658 + if (!frm) 659 + return 0; 660 + 661 + cur_addr = unicam_reg_read(unicam, UNICAM_IBWP); 662 + return (unsigned int)(cur_addr - frm->dma_addr) / stride; 663 + } 664 + 665 + static void unicam_schedule_next_buffer(struct unicam_node *node) 666 + { 667 + struct unicam_buffer *buf; 668 + 669 + buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); 670 + node->next_frm = buf; 671 + list_del(&buf->list); 672 + 673 + unicam_wr_dma_addr(node, buf); 674 + } 675 + 676 + static void unicam_schedule_dummy_buffer(struct unicam_node *node) 677 + { 678 + int node_id = is_image_node(node) ? UNICAM_IMAGE_NODE : UNICAM_METADATA_NODE; 679 + 680 + dev_dbg(node->dev->dev, "Scheduling dummy buffer for node %d\n", node_id); 681 + 682 + unicam_wr_dma_addr(node, &node->dummy_buf); 683 + 684 + node->next_frm = NULL; 685 + } 686 + 687 + static void unicam_process_buffer_complete(struct unicam_node *node, 688 + unsigned int sequence) 689 + { 690 + node->cur_frm->vb.field = node->fmt.fmt.pix.field; 691 + node->cur_frm->vb.sequence = sequence; 692 + 693 + vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); 694 + } 695 + 696 + static void unicam_queue_event_sof(struct unicam_device *unicam) 697 + { 698 + struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; 699 + struct v4l2_event event = { 700 + .type = V4L2_EVENT_FRAME_SYNC, 701 + .u.frame_sync.frame_sequence = unicam->sequence, 702 + }; 703 + 704 + v4l2_event_queue(&node->video_dev, &event); 705 + } 706 + 707 + static irqreturn_t unicam_isr(int irq, void *dev) 708 + { 709 + struct unicam_device *unicam = dev; 710 + unsigned int lines_done = unicam_get_lines_done(dev); 711 + unsigned int sequence = unicam->sequence; 712 + unsigned int i; 713 + u32 ista, sta; 714 + bool fe; 715 + u64 ts; 716 + 717 + sta = unicam_reg_read(unicam, UNICAM_STA); 718 + /* Write value back to clear the interrupts */ 719 + unicam_reg_write(unicam, UNICAM_STA, sta); 720 + 721 + ista = unicam_reg_read(unicam, UNICAM_ISTA); 722 + /* Write value back to clear the interrupts */ 723 + unicam_reg_write(unicam, UNICAM_ISTA, ista); 724 + 725 + dev_dbg(unicam->dev, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d\n", 726 + ista, sta, sequence, lines_done); 727 + 728 + if (!(sta & (UNICAM_IS | UNICAM_PI0))) 729 + return IRQ_HANDLED; 730 + 731 + /* 732 + * Look for either the Frame End interrupt or the Packet Capture status 733 + * to signal a frame end. 734 + */ 735 + fe = ista & UNICAM_FEI || sta & UNICAM_PI0; 736 + 737 + /* 738 + * We must run the frame end handler first. If we have a valid next_frm 739 + * and we get a simultaneout FE + FS interrupt, running the FS handler 740 + * first would null out the next_frm ptr and we would have lost the 741 + * buffer forever. 742 + */ 743 + if (fe) { 744 + /* 745 + * Ensure we have swapped buffers already as we can't 746 + * stop the peripheral. If no buffer is available, use a 747 + * dummy buffer to dump out frames until we get a new buffer 748 + * to use. 749 + */ 750 + for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { 751 + struct unicam_node *node = &unicam->node[i]; 752 + 753 + if (!vb2_start_streaming_called(&node->buffer_queue)) 754 + continue; 755 + 756 + /* 757 + * If cur_frm == next_frm, it means we have not had 758 + * a chance to swap buffers, likely due to having 759 + * multiple interrupts occurring simultaneously (like FE 760 + * + FS + LS). In this case, we cannot signal the buffer 761 + * as complete, as the HW will reuse that buffer. 762 + */ 763 + if (node->cur_frm && node->cur_frm != node->next_frm) 764 + unicam_process_buffer_complete(node, sequence); 765 + node->cur_frm = node->next_frm; 766 + } 767 + unicam->sequence++; 768 + } 769 + 770 + if (ista & UNICAM_FSI) { 771 + /* 772 + * Timestamp is to be when the first data byte was captured, 773 + * aka frame start. 774 + */ 775 + ts = ktime_get_ns(); 776 + for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { 777 + struct unicam_node *node = &unicam->node[i]; 778 + 779 + if (!vb2_start_streaming_called(&node->buffer_queue)) 780 + continue; 781 + 782 + if (node->cur_frm) 783 + node->cur_frm->vb.vb2_buf.timestamp = ts; 784 + else 785 + dev_dbg(unicam->v4l2_dev.dev, 786 + "ISR: [%d] Dropping frame, buffer not available at FS\n", 787 + i); 788 + /* 789 + * Set the next frame output to go to a dummy frame 790 + * if we have not managed to obtain another frame 791 + * from the queue. 792 + */ 793 + unicam_schedule_dummy_buffer(node); 794 + } 795 + 796 + unicam_queue_event_sof(unicam); 797 + } 798 + 799 + /* 800 + * Cannot swap buffer at frame end, there may be a race condition 801 + * where the HW does not actually swap it if the new frame has 802 + * already started. 803 + */ 804 + if (ista & (UNICAM_FSI | UNICAM_LCI) && !fe) { 805 + for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { 806 + struct unicam_node *node = &unicam->node[i]; 807 + 808 + if (!vb2_start_streaming_called(&node->buffer_queue)) 809 + continue; 810 + 811 + spin_lock(&node->dma_queue_lock); 812 + if (!list_empty(&node->dma_queue) && !node->next_frm) 813 + unicam_schedule_next_buffer(node); 814 + spin_unlock(&node->dma_queue_lock); 815 + } 816 + } 817 + 818 + if (unicam_reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) { 819 + /* Switch out of trigger mode if selected */ 820 + unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC); 821 + unicam_reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM); 822 + } 823 + return IRQ_HANDLED; 824 + } 825 + 826 + static void unicam_set_packing_config(struct unicam_device *unicam, 827 + const struct unicam_format_info *fmtinfo) 828 + { 829 + struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; 830 + u32 pack, unpack; 831 + u32 val; 832 + 833 + if (node->fmt.fmt.pix.pixelformat == fmtinfo->fourcc) { 834 + unpack = UNICAM_PUM_NONE; 835 + pack = UNICAM_PPM_NONE; 836 + } else { 837 + unpack = fmtinfo->unpack; 838 + /* Repacking is always to 16bpp */ 839 + pack = UNICAM_PPM_PACK16; 840 + } 841 + 842 + val = 0; 843 + unicam_set_field(&val, unpack, UNICAM_PUM_MASK); 844 + unicam_set_field(&val, pack, UNICAM_PPM_MASK); 845 + unicam_reg_write(unicam, UNICAM_IPIPE, val); 846 + } 847 + 848 + static void unicam_cfg_image_id(struct unicam_device *unicam, u8 vc, u8 dt) 849 + { 850 + if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { 851 + /* CSI2 mode */ 852 + unicam_reg_write(unicam, UNICAM_IDI0, (vc << 6) | dt); 853 + } else { 854 + /* CCP2 mode */ 855 + unicam_reg_write(unicam, UNICAM_IDI0, 0x80 | dt); 856 + } 857 + } 858 + 859 + static void unicam_enable_ed(struct unicam_device *unicam) 860 + { 861 + u32 val = unicam_reg_read(unicam, UNICAM_DCS); 862 + 863 + unicam_set_field(&val, 2, UNICAM_EDL_MASK); 864 + /* Do not wrap at the end of the embedded data buffer */ 865 + unicam_set_field(&val, 0, UNICAM_DBOB); 866 + 867 + unicam_reg_write(unicam, UNICAM_DCS, val); 868 + } 869 + 870 + static int unicam_get_image_vc_dt(struct unicam_device *unicam, 871 + struct v4l2_subdev_state *state, 872 + u8 *vc, u8 *dt) 873 + { 874 + struct v4l2_mbus_frame_desc fd; 875 + u32 stream; 876 + int ret; 877 + 878 + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, 879 + UNICAM_SD_PAD_SOURCE_IMAGE, 880 + 0, NULL, &stream); 881 + if (ret) 882 + return ret; 883 + 884 + ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_frame_desc, 885 + unicam->sensor.pad->index, &fd); 886 + if (ret) 887 + return ret; 888 + 889 + /* Only CSI-2 supports DTs. */ 890 + if (fd.type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) 891 + return -EINVAL; 892 + 893 + for (unsigned int i = 0; i < fd.num_entries; ++i) { 894 + const struct v4l2_mbus_frame_desc_entry *fde = &fd.entry[i]; 895 + 896 + if (fde->stream == stream) { 897 + *vc = fde->bus.csi2.vc; 898 + *dt = fde->bus.csi2.dt; 899 + return 0; 900 + } 901 + } 902 + 903 + return -EINVAL; 904 + } 905 + 906 + static void unicam_start_rx(struct unicam_device *unicam, 907 + struct v4l2_subdev_state *state) 908 + { 909 + struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; 910 + const struct unicam_format_info *fmtinfo; 911 + const struct v4l2_mbus_framefmt *fmt; 912 + unsigned int line_int_freq; 913 + u8 vc, dt; 914 + u32 val; 915 + int ret; 916 + 917 + fmt = v4l2_subdev_state_get_format(state, UNICAM_SD_PAD_SOURCE_IMAGE, 0); 918 + fmtinfo = unicam_find_format_by_code(fmt->code, 919 + UNICAM_SD_PAD_SOURCE_IMAGE); 920 + if (WARN_ON(!fmtinfo)) 921 + return; 922 + 923 + /* 924 + * Enable lane clocks. The register is structured as follows: 925 + * 926 + * [9:8] - DAT3 927 + * [7:6] - DAT2 928 + * [5:4] - DAT1 929 + * [3:2] - DAT0 930 + * [1:0] - CLK 931 + * 932 + * Enabled lane must be set to b01, and disabled lanes to b00. The clock 933 + * lane is always enabled. 934 + */ 935 + val = 0x155 & GENMASK(unicam->pipe.num_data_lanes * 2 + 1, 0); 936 + unicam_clk_write(unicam, val); 937 + 938 + /* Basic init */ 939 + unicam_reg_write(unicam, UNICAM_CTRL, UNICAM_MEM); 940 + 941 + /* Enable analogue control, and leave in reset. */ 942 + val = UNICAM_AR; 943 + unicam_set_field(&val, 7, UNICAM_CTATADJ_MASK); 944 + unicam_set_field(&val, 7, UNICAM_PTATADJ_MASK); 945 + unicam_reg_write(unicam, UNICAM_ANA, val); 946 + usleep_range(1000, 2000); 947 + 948 + /* Come out of reset */ 949 + unicam_reg_write_field(unicam, UNICAM_ANA, 0, UNICAM_AR); 950 + 951 + /* Peripheral reset */ 952 + unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_CPR); 953 + unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPR); 954 + 955 + unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPE); 956 + 957 + /* Enable Rx control. */ 958 + val = unicam_reg_read(unicam, UNICAM_CTRL); 959 + if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { 960 + unicam_set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK); 961 + unicam_set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK); 962 + } else { 963 + unicam_set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK); 964 + unicam_set_field(&val, unicam->bus_flags, UNICAM_DCM_MASK); 965 + } 966 + /* Packet framer timeout */ 967 + unicam_set_field(&val, 0xf, UNICAM_PFT_MASK); 968 + unicam_set_field(&val, 128, UNICAM_OET_MASK); 969 + unicam_reg_write(unicam, UNICAM_CTRL, val); 970 + 971 + unicam_reg_write(unicam, UNICAM_IHWIN, 0); 972 + unicam_reg_write(unicam, UNICAM_IVWIN, 0); 973 + 974 + /* AXI bus access QoS setup */ 975 + val = unicam_reg_read(unicam, UNICAM_PRI); 976 + unicam_set_field(&val, 0, UNICAM_BL_MASK); 977 + unicam_set_field(&val, 0, UNICAM_BS_MASK); 978 + unicam_set_field(&val, 0xe, UNICAM_PP_MASK); 979 + unicam_set_field(&val, 8, UNICAM_NP_MASK); 980 + unicam_set_field(&val, 2, UNICAM_PT_MASK); 981 + unicam_set_field(&val, 1, UNICAM_PE); 982 + unicam_reg_write(unicam, UNICAM_PRI, val); 983 + 984 + unicam_reg_write_field(unicam, UNICAM_ANA, 0, UNICAM_DDL); 985 + 986 + /* Always start in trigger frame capture mode (UNICAM_FCM set) */ 987 + val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB; 988 + line_int_freq = max(fmt->height >> 2, 128); 989 + unicam_set_field(&val, line_int_freq, UNICAM_LCIE_MASK); 990 + unicam_reg_write(unicam, UNICAM_ICTL, val); 991 + unicam_reg_write(unicam, UNICAM_STA, UNICAM_STA_MASK_ALL); 992 + unicam_reg_write(unicam, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL); 993 + 994 + /* tclk_term_en */ 995 + unicam_reg_write_field(unicam, UNICAM_CLT, 2, UNICAM_CLT1_MASK); 996 + /* tclk_settle */ 997 + unicam_reg_write_field(unicam, UNICAM_CLT, 6, UNICAM_CLT2_MASK); 998 + /* td_term_en */ 999 + unicam_reg_write_field(unicam, UNICAM_DLT, 2, UNICAM_DLT1_MASK); 1000 + /* ths_settle */ 1001 + unicam_reg_write_field(unicam, UNICAM_DLT, 6, UNICAM_DLT2_MASK); 1002 + /* trx_enable */ 1003 + unicam_reg_write_field(unicam, UNICAM_DLT, 0, UNICAM_DLT3_MASK); 1004 + 1005 + unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_SOE); 1006 + 1007 + /* Packet compare setup - required to avoid missing frame ends */ 1008 + val = 0; 1009 + unicam_set_field(&val, 1, UNICAM_PCE); 1010 + unicam_set_field(&val, 1, UNICAM_GI); 1011 + unicam_set_field(&val, 1, UNICAM_CPH); 1012 + unicam_set_field(&val, 0, UNICAM_PCVC_MASK); 1013 + unicam_set_field(&val, 1, UNICAM_PCDT_MASK); 1014 + unicam_reg_write(unicam, UNICAM_CMP0, val); 1015 + 1016 + /* Enable clock lane and set up terminations */ 1017 + val = 0; 1018 + if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { 1019 + /* CSI2 */ 1020 + unicam_set_field(&val, 1, UNICAM_CLE); 1021 + unicam_set_field(&val, 1, UNICAM_CLLPE); 1022 + if (!(unicam->bus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) { 1023 + unicam_set_field(&val, 1, UNICAM_CLTRE); 1024 + unicam_set_field(&val, 1, UNICAM_CLHSE); 1025 + } 1026 + } else { 1027 + /* CCP2 */ 1028 + unicam_set_field(&val, 1, UNICAM_CLE); 1029 + unicam_set_field(&val, 1, UNICAM_CLHSE); 1030 + unicam_set_field(&val, 1, UNICAM_CLTRE); 1031 + } 1032 + unicam_reg_write(unicam, UNICAM_CLK, val); 1033 + 1034 + /* 1035 + * Enable required data lanes with appropriate terminations. 1036 + * The same value needs to be written to UNICAM_DATn registers for 1037 + * the active lanes, and 0 for inactive ones. 1038 + */ 1039 + val = 0; 1040 + if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { 1041 + /* CSI2 */ 1042 + unicam_set_field(&val, 1, UNICAM_DLE); 1043 + unicam_set_field(&val, 1, UNICAM_DLLPE); 1044 + if (!(unicam->bus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) { 1045 + unicam_set_field(&val, 1, UNICAM_DLTRE); 1046 + unicam_set_field(&val, 1, UNICAM_DLHSE); 1047 + } 1048 + } else { 1049 + /* CCP2 */ 1050 + unicam_set_field(&val, 1, UNICAM_DLE); 1051 + unicam_set_field(&val, 1, UNICAM_DLHSE); 1052 + unicam_set_field(&val, 1, UNICAM_DLTRE); 1053 + } 1054 + unicam_reg_write(unicam, UNICAM_DAT0, val); 1055 + 1056 + if (unicam->pipe.num_data_lanes == 1) 1057 + val = 0; 1058 + unicam_reg_write(unicam, UNICAM_DAT1, val); 1059 + 1060 + if (unicam->max_data_lanes > 2) { 1061 + /* 1062 + * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the 1063 + * instance supports more than 2 data lanes. 1064 + */ 1065 + if (unicam->pipe.num_data_lanes == 2) 1066 + val = 0; 1067 + unicam_reg_write(unicam, UNICAM_DAT2, val); 1068 + 1069 + if (unicam->pipe.num_data_lanes == 3) 1070 + val = 0; 1071 + unicam_reg_write(unicam, UNICAM_DAT3, val); 1072 + } 1073 + 1074 + unicam_reg_write(unicam, UNICAM_IBLS, 1075 + node->fmt.fmt.pix.bytesperline); 1076 + unicam_wr_dma_addr(node, node->cur_frm); 1077 + unicam_set_packing_config(unicam, fmtinfo); 1078 + 1079 + ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt); 1080 + if (ret) { 1081 + /* 1082 + * If the source doesn't support frame descriptors, default to 1083 + * VC 0 and use the DT corresponding to the format. 1084 + */ 1085 + vc = 0; 1086 + dt = fmtinfo->csi_dt; 1087 + } 1088 + 1089 + unicam_cfg_image_id(unicam, vc, dt); 1090 + 1091 + val = unicam_reg_read(unicam, UNICAM_MISC); 1092 + unicam_set_field(&val, 1, UNICAM_FL0); 1093 + unicam_set_field(&val, 1, UNICAM_FL1); 1094 + unicam_reg_write(unicam, UNICAM_MISC, val); 1095 + 1096 + /* Enable peripheral */ 1097 + unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_CPE); 1098 + 1099 + /* Load image pointers */ 1100 + unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_LIP_MASK); 1101 + 1102 + /* 1103 + * Enable trigger only for the first frame to 1104 + * sync correctly to the FS from the source. 1105 + */ 1106 + unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC); 1107 + } 1108 + 1109 + static void unicam_start_metadata(struct unicam_device *unicam) 1110 + { 1111 + struct unicam_node *node = &unicam->node[UNICAM_METADATA_NODE]; 1112 + 1113 + unicam_enable_ed(unicam); 1114 + unicam_wr_dma_addr(node, node->cur_frm); 1115 + unicam_reg_write_field(unicam, UNICAM_DCS, 1, UNICAM_LDP); 1116 + } 1117 + 1118 + static void unicam_disable(struct unicam_device *unicam) 1119 + { 1120 + /* Analogue lane control disable */ 1121 + unicam_reg_write_field(unicam, UNICAM_ANA, 1, UNICAM_DDL); 1122 + 1123 + /* Stop the output engine */ 1124 + unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_SOE); 1125 + 1126 + /* Disable the data lanes. */ 1127 + unicam_reg_write(unicam, UNICAM_DAT0, 0); 1128 + unicam_reg_write(unicam, UNICAM_DAT1, 0); 1129 + 1130 + if (unicam->max_data_lanes > 2) { 1131 + unicam_reg_write(unicam, UNICAM_DAT2, 0); 1132 + unicam_reg_write(unicam, UNICAM_DAT3, 0); 1133 + } 1134 + 1135 + /* Peripheral reset */ 1136 + unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_CPR); 1137 + usleep_range(50, 100); 1138 + unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPR); 1139 + 1140 + /* Disable peripheral */ 1141 + unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPE); 1142 + 1143 + /* Clear ED setup */ 1144 + unicam_reg_write(unicam, UNICAM_DCS, 0); 1145 + 1146 + /* Disable all lane clocks */ 1147 + unicam_clk_write(unicam, 0); 1148 + } 1149 + 1150 + /* ----------------------------------------------------------------------------- 1151 + * V4L2 subdev operations 1152 + */ 1153 + 1154 + static int __unicam_subdev_set_routing(struct v4l2_subdev *sd, 1155 + struct v4l2_subdev_state *state, 1156 + struct v4l2_subdev_krouting *routing) 1157 + { 1158 + struct v4l2_subdev_route *route; 1159 + int ret; 1160 + 1161 + ret = v4l2_subdev_routing_validate(sd, routing, 1162 + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); 1163 + if (ret) 1164 + return ret; 1165 + 1166 + ret = v4l2_subdev_set_routing(sd, state, routing); 1167 + if (ret) 1168 + return ret; 1169 + 1170 + for_each_active_route(&state->routing, route) { 1171 + const struct v4l2_mbus_framefmt *def_fmt; 1172 + struct v4l2_mbus_framefmt *fmt; 1173 + 1174 + if (route->source_pad == UNICAM_SD_PAD_SOURCE_IMAGE) 1175 + def_fmt = &unicam_default_image_format; 1176 + else 1177 + def_fmt = &unicam_default_meta_format; 1178 + 1179 + fmt = v4l2_subdev_state_get_format(state, route->sink_pad, 1180 + route->sink_stream); 1181 + *fmt = *def_fmt; 1182 + fmt = v4l2_subdev_state_get_format(state, route->source_pad, 1183 + route->source_stream); 1184 + *fmt = *def_fmt; 1185 + } 1186 + 1187 + return 0; 1188 + } 1189 + 1190 + static int unicam_subdev_init_state(struct v4l2_subdev *sd, 1191 + struct v4l2_subdev_state *state) 1192 + { 1193 + struct v4l2_subdev_route routes[] = { 1194 + { 1195 + .sink_pad = UNICAM_SD_PAD_SINK, 1196 + .sink_stream = 0, 1197 + .source_pad = UNICAM_SD_PAD_SOURCE_IMAGE, 1198 + .source_stream = 0, 1199 + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, 1200 + }, 1201 + }; 1202 + 1203 + struct v4l2_subdev_krouting routing = { 1204 + .len_routes = ARRAY_SIZE(routes), 1205 + .num_routes = ARRAY_SIZE(routes), 1206 + .routes = routes, 1207 + }; 1208 + 1209 + /* Initialize routing to single route to the fist source pad. */ 1210 + return __unicam_subdev_set_routing(sd, state, &routing); 1211 + } 1212 + 1213 + static int unicam_subdev_enum_mbus_code(struct v4l2_subdev *sd, 1214 + struct v4l2_subdev_state *state, 1215 + struct v4l2_subdev_mbus_code_enum *code) 1216 + { 1217 + u32 pad, stream; 1218 + int ret; 1219 + 1220 + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, 1221 + code->pad, code->stream, 1222 + &pad, &stream); 1223 + if (ret) 1224 + return ret; 1225 + 1226 + if (unicam_sd_pad_is_source(code->pad)) { 1227 + /* No transcoding, source and sink codes must match. */ 1228 + const struct v4l2_mbus_framefmt *fmt; 1229 + 1230 + fmt = v4l2_subdev_state_get_format(state, pad, stream); 1231 + if (!fmt) 1232 + return -EINVAL; 1233 + 1234 + if (code->index > 0) 1235 + return -EINVAL; 1236 + 1237 + code->code = fmt->code; 1238 + } else { 1239 + const struct unicam_format_info *formats; 1240 + unsigned int num_formats; 1241 + 1242 + if (pad == UNICAM_SD_PAD_SOURCE_IMAGE) { 1243 + formats = unicam_image_formats; 1244 + num_formats = ARRAY_SIZE(unicam_image_formats); 1245 + } else { 1246 + formats = unicam_meta_formats; 1247 + num_formats = ARRAY_SIZE(unicam_meta_formats); 1248 + } 1249 + 1250 + if (code->index >= num_formats) 1251 + return -EINVAL; 1252 + 1253 + code->code = formats[code->index].code; 1254 + } 1255 + 1256 + return 0; 1257 + } 1258 + 1259 + static int unicam_subdev_enum_frame_size(struct v4l2_subdev *sd, 1260 + struct v4l2_subdev_state *state, 1261 + struct v4l2_subdev_frame_size_enum *fse) 1262 + { 1263 + u32 pad, stream; 1264 + int ret; 1265 + 1266 + if (fse->index > 0) 1267 + return -EINVAL; 1268 + 1269 + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, fse->pad, 1270 + fse->stream, &pad, 1271 + &stream); 1272 + if (ret) 1273 + return ret; 1274 + 1275 + if (unicam_sd_pad_is_source(fse->pad)) { 1276 + /* No transcoding, source and sink formats must match. */ 1277 + const struct v4l2_mbus_framefmt *fmt; 1278 + 1279 + fmt = v4l2_subdev_state_get_format(state, pad, stream); 1280 + if (!fmt) 1281 + return -EINVAL; 1282 + 1283 + if (fse->code != fmt->code) 1284 + return -EINVAL; 1285 + 1286 + fse->min_width = fmt->width; 1287 + fse->max_width = fmt->width; 1288 + fse->min_height = fmt->height; 1289 + fse->max_height = fmt->height; 1290 + } else { 1291 + const struct unicam_format_info *fmtinfo; 1292 + 1293 + fmtinfo = unicam_find_format_by_code(fse->code, pad); 1294 + if (!fmtinfo) 1295 + return -EINVAL; 1296 + 1297 + if (pad == UNICAM_SD_PAD_SOURCE_IMAGE) { 1298 + fse->min_width = UNICAM_IMAGE_MIN_WIDTH; 1299 + fse->max_width = UNICAM_IMAGE_MAX_WIDTH; 1300 + fse->min_height = UNICAM_IMAGE_MIN_HEIGHT; 1301 + fse->max_height = UNICAM_IMAGE_MAX_HEIGHT; 1302 + } else { 1303 + fse->min_width = UNICAM_META_MIN_WIDTH; 1304 + fse->max_width = UNICAM_META_MAX_WIDTH; 1305 + fse->min_height = UNICAM_META_MIN_HEIGHT; 1306 + fse->max_height = UNICAM_META_MAX_HEIGHT; 1307 + } 1308 + } 1309 + 1310 + return 0; 1311 + } 1312 + 1313 + static int unicam_subdev_set_format(struct v4l2_subdev *sd, 1314 + struct v4l2_subdev_state *state, 1315 + struct v4l2_subdev_format *format) 1316 + { 1317 + struct unicam_device *unicam = sd_to_unicam_device(sd); 1318 + struct v4l2_mbus_framefmt *sink_format, *source_format; 1319 + const struct unicam_format_info *fmtinfo; 1320 + u32 source_pad, source_stream; 1321 + int ret; 1322 + 1323 + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && 1324 + unicam->subdev.enabled_streams) 1325 + return -EBUSY; 1326 + 1327 + /* No transcoding, source and sink formats must match. */ 1328 + if (unicam_sd_pad_is_source(format->pad)) 1329 + return v4l2_subdev_get_fmt(sd, state, format); 1330 + 1331 + /* 1332 + * Allowed formats for the stream on the sink pad depend on what source 1333 + * pad the stream is routed to. Find the corresponding source pad and 1334 + * use it to validate the media bus code. 1335 + */ 1336 + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, 1337 + format->pad, format->stream, 1338 + &source_pad, &source_stream); 1339 + if (ret) 1340 + return ret; 1341 + 1342 + fmtinfo = unicam_find_format_by_code(format->format.code, source_pad); 1343 + if (!fmtinfo) { 1344 + fmtinfo = source_pad == UNICAM_SD_PAD_SOURCE_IMAGE 1345 + ? &unicam_image_formats[0] : &unicam_meta_formats[0]; 1346 + format->format.code = fmtinfo->code; 1347 + } 1348 + 1349 + if (source_pad == UNICAM_SD_PAD_SOURCE_IMAGE) { 1350 + format->format.width = clamp_t(unsigned int, 1351 + format->format.width, 1352 + UNICAM_IMAGE_MIN_WIDTH, 1353 + UNICAM_IMAGE_MAX_WIDTH); 1354 + format->format.height = clamp_t(unsigned int, 1355 + format->format.height, 1356 + UNICAM_IMAGE_MIN_HEIGHT, 1357 + UNICAM_IMAGE_MAX_HEIGHT); 1358 + format->format.field = V4L2_FIELD_NONE; 1359 + } else { 1360 + format->format.width = clamp_t(unsigned int, 1361 + format->format.width, 1362 + UNICAM_META_MIN_WIDTH, 1363 + UNICAM_META_MAX_WIDTH); 1364 + format->format.height = clamp_t(unsigned int, 1365 + format->format.height, 1366 + UNICAM_META_MIN_HEIGHT, 1367 + UNICAM_META_MAX_HEIGHT); 1368 + format->format.field = V4L2_FIELD_NONE; 1369 + 1370 + /* Colorspace don't apply to metadata. */ 1371 + format->format.colorspace = 0; 1372 + format->format.ycbcr_enc = 0; 1373 + format->format.quantization = 0; 1374 + format->format.xfer_func = 0; 1375 + } 1376 + 1377 + sink_format = v4l2_subdev_state_get_format(state, format->pad, 1378 + format->stream); 1379 + source_format = v4l2_subdev_state_get_format(state, source_pad, 1380 + source_stream); 1381 + *sink_format = format->format; 1382 + *source_format = format->format; 1383 + 1384 + return 0; 1385 + } 1386 + 1387 + static int unicam_subdev_set_routing(struct v4l2_subdev *sd, 1388 + struct v4l2_subdev_state *state, 1389 + enum v4l2_subdev_format_whence which, 1390 + struct v4l2_subdev_krouting *routing) 1391 + { 1392 + struct unicam_device *unicam = sd_to_unicam_device(sd); 1393 + 1394 + if (which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->subdev.enabled_streams) 1395 + return -EBUSY; 1396 + 1397 + return __unicam_subdev_set_routing(sd, state, routing); 1398 + } 1399 + 1400 + static int unicam_sd_enable_streams(struct v4l2_subdev *sd, 1401 + struct v4l2_subdev_state *state, u32 pad, 1402 + u64 streams_mask) 1403 + { 1404 + struct unicam_device *unicam = sd_to_unicam_device(sd); 1405 + u32 other_pad, other_stream; 1406 + int ret; 1407 + 1408 + if (!unicam->subdev.enabled_streams) { 1409 + /* Configure and start Unicam. */ 1410 + unicam->sequence = 0; 1411 + 1412 + if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) 1413 + unicam_start_metadata(unicam); 1414 + 1415 + unicam_start_rx(unicam, state); 1416 + } 1417 + 1418 + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0, 1419 + &other_pad, &other_stream); 1420 + if (ret) 1421 + return ret; 1422 + 1423 + ret = v4l2_subdev_enable_streams(unicam->sensor.subdev, 1424 + unicam->sensor.pad->index, 1425 + BIT(other_stream)); 1426 + if (ret) { 1427 + dev_err(unicam->dev, "stream on failed in subdev\n"); 1428 + return ret; 1429 + } 1430 + 1431 + unicam->subdev.enabled_streams |= BIT(other_stream); 1432 + 1433 + return 0; 1434 + } 1435 + 1436 + static int unicam_sd_disable_streams(struct v4l2_subdev *sd, 1437 + struct v4l2_subdev_state *state, u32 pad, 1438 + u64 streams_mask) 1439 + { 1440 + struct unicam_device *unicam = sd_to_unicam_device(sd); 1441 + u32 other_pad, other_stream; 1442 + int ret; 1443 + 1444 + ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0, 1445 + &other_pad, &other_stream); 1446 + if (ret) 1447 + return ret; 1448 + 1449 + v4l2_subdev_disable_streams(unicam->sensor.subdev, 1450 + unicam->sensor.pad->index, 1451 + BIT(other_stream)); 1452 + 1453 + unicam->subdev.enabled_streams &= ~BIT(other_stream); 1454 + 1455 + if (!unicam->subdev.enabled_streams) 1456 + unicam_disable(unicam); 1457 + 1458 + return 0; 1459 + } 1460 + 1461 + static const struct v4l2_subdev_pad_ops unicam_subdev_pad_ops = { 1462 + .enum_mbus_code = unicam_subdev_enum_mbus_code, 1463 + .enum_frame_size = unicam_subdev_enum_frame_size, 1464 + .get_fmt = v4l2_subdev_get_fmt, 1465 + .set_fmt = unicam_subdev_set_format, 1466 + .set_routing = unicam_subdev_set_routing, 1467 + .enable_streams = unicam_sd_enable_streams, 1468 + .disable_streams = unicam_sd_disable_streams, 1469 + }; 1470 + 1471 + static const struct v4l2_subdev_ops unicam_subdev_ops = { 1472 + .pad = &unicam_subdev_pad_ops, 1473 + }; 1474 + 1475 + static const struct v4l2_subdev_internal_ops unicam_subdev_internal_ops = { 1476 + .init_state = unicam_subdev_init_state, 1477 + }; 1478 + 1479 + static const struct media_entity_operations unicam_subdev_media_ops = { 1480 + .link_validate = v4l2_subdev_link_validate, 1481 + .has_pad_interdep = v4l2_subdev_has_pad_interdep, 1482 + }; 1483 + 1484 + static int unicam_subdev_init(struct unicam_device *unicam) 1485 + { 1486 + struct v4l2_subdev *sd = &unicam->subdev.sd; 1487 + int ret; 1488 + 1489 + v4l2_subdev_init(sd, &unicam_subdev_ops); 1490 + sd->internal_ops = &unicam_subdev_internal_ops; 1491 + v4l2_set_subdevdata(sd, unicam); 1492 + 1493 + sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 1494 + sd->entity.ops = &unicam_subdev_media_ops; 1495 + sd->dev = unicam->dev; 1496 + sd->owner = THIS_MODULE; 1497 + sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; 1498 + 1499 + strscpy(sd->name, "unicam", sizeof(sd->name)); 1500 + 1501 + unicam->subdev.pads[UNICAM_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1502 + unicam->subdev.pads[UNICAM_SD_PAD_SOURCE_IMAGE].flags = MEDIA_PAD_FL_SOURCE; 1503 + unicam->subdev.pads[UNICAM_SD_PAD_SOURCE_METADATA].flags = MEDIA_PAD_FL_SOURCE; 1504 + 1505 + ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(unicam->subdev.pads), 1506 + unicam->subdev.pads); 1507 + if (ret) { 1508 + dev_err(unicam->dev, "Failed to initialize media entity: %d\n", 1509 + ret); 1510 + return ret; 1511 + } 1512 + 1513 + ret = v4l2_subdev_init_finalize(sd); 1514 + if (ret) { 1515 + dev_err(unicam->dev, "Failed to initialize subdev: %d\n", ret); 1516 + goto err_entity; 1517 + } 1518 + 1519 + ret = v4l2_device_register_subdev(&unicam->v4l2_dev, sd); 1520 + if (ret) { 1521 + dev_err(unicam->dev, "Failed to register subdev: %d\n", ret); 1522 + goto err_subdev; 1523 + } 1524 + 1525 + return 0; 1526 + 1527 + err_subdev: 1528 + v4l2_subdev_cleanup(sd); 1529 + err_entity: 1530 + media_entity_cleanup(&sd->entity); 1531 + return ret; 1532 + } 1533 + 1534 + static void unicam_subdev_cleanup(struct unicam_device *unicam) 1535 + { 1536 + v4l2_subdev_cleanup(&unicam->subdev.sd); 1537 + media_entity_cleanup(&unicam->subdev.sd.entity); 1538 + } 1539 + 1540 + /* ----------------------------------------------------------------------------- 1541 + * Videobuf2 queue operations 1542 + */ 1543 + 1544 + static int unicam_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 1545 + unsigned int *nplanes, unsigned int sizes[], 1546 + struct device *alloc_devs[]) 1547 + { 1548 + struct unicam_node *node = vb2_get_drv_priv(vq); 1549 + u32 size = is_image_node(node) ? node->fmt.fmt.pix.sizeimage 1550 + : node->fmt.fmt.meta.buffersize; 1551 + 1552 + if (*nplanes) { 1553 + if (sizes[0] < size) { 1554 + dev_dbg(node->dev->dev, "sizes[0] %i < size %u\n", 1555 + sizes[0], size); 1556 + return -EINVAL; 1557 + } 1558 + size = sizes[0]; 1559 + } 1560 + 1561 + *nplanes = 1; 1562 + sizes[0] = size; 1563 + 1564 + return 0; 1565 + } 1566 + 1567 + static int unicam_buffer_prepare(struct vb2_buffer *vb) 1568 + { 1569 + struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); 1570 + struct unicam_buffer *buf = to_unicam_buffer(vb); 1571 + u32 size = is_image_node(node) ? node->fmt.fmt.pix.sizeimage 1572 + : node->fmt.fmt.meta.buffersize; 1573 + 1574 + if (vb2_plane_size(vb, 0) < size) { 1575 + dev_dbg(node->dev->dev, 1576 + "data will not fit into plane (%lu < %u)\n", 1577 + vb2_plane_size(vb, 0), size); 1578 + return -EINVAL; 1579 + } 1580 + 1581 + buf->dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); 1582 + buf->size = size; 1583 + 1584 + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); 1585 + 1586 + return 0; 1587 + } 1588 + 1589 + static void unicam_return_buffers(struct unicam_node *node, 1590 + enum vb2_buffer_state state) 1591 + { 1592 + struct unicam_buffer *buf, *tmp; 1593 + 1594 + list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) { 1595 + list_del(&buf->list); 1596 + vb2_buffer_done(&buf->vb.vb2_buf, state); 1597 + } 1598 + 1599 + if (node->cur_frm) 1600 + vb2_buffer_done(&node->cur_frm->vb.vb2_buf, 1601 + state); 1602 + if (node->next_frm && node->cur_frm != node->next_frm) 1603 + vb2_buffer_done(&node->next_frm->vb.vb2_buf, 1604 + state); 1605 + 1606 + node->cur_frm = NULL; 1607 + node->next_frm = NULL; 1608 + } 1609 + 1610 + static int unicam_num_data_lanes(struct unicam_device *unicam) 1611 + { 1612 + struct v4l2_mbus_config mbus_config = { 0 }; 1613 + unsigned int num_data_lanes; 1614 + int ret; 1615 + 1616 + if (unicam->bus_type != V4L2_MBUS_CSI2_DPHY) 1617 + return unicam->max_data_lanes; 1618 + 1619 + ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_mbus_config, 1620 + unicam->sensor.pad->index, &mbus_config); 1621 + if (ret == -ENOIOCTLCMD) 1622 + return unicam->max_data_lanes; 1623 + 1624 + if (ret < 0) { 1625 + dev_err(unicam->dev, "Failed to get mbus config: %d\n", ret); 1626 + return ret; 1627 + } 1628 + 1629 + num_data_lanes = mbus_config.bus.mipi_csi2.num_data_lanes; 1630 + 1631 + if (num_data_lanes != 1 && num_data_lanes != 2 && num_data_lanes != 4) { 1632 + dev_err(unicam->dev, 1633 + "Device %s has requested %u data lanes, invalid\n", 1634 + unicam->sensor.subdev->name, num_data_lanes); 1635 + return -EINVAL; 1636 + } 1637 + 1638 + if (num_data_lanes > unicam->max_data_lanes) { 1639 + dev_err(unicam->dev, 1640 + "Device %s has requested %u data lanes, >%u configured in DT\n", 1641 + unicam->sensor.subdev->name, num_data_lanes, 1642 + unicam->max_data_lanes); 1643 + return -EINVAL; 1644 + } 1645 + 1646 + return num_data_lanes; 1647 + } 1648 + 1649 + static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count) 1650 + { 1651 + struct unicam_node *node = vb2_get_drv_priv(vq); 1652 + struct unicam_device *unicam = node->dev; 1653 + struct unicam_buffer *buf; 1654 + struct media_pipeline_pad_iter iter; 1655 + struct media_pad *pad; 1656 + unsigned long flags; 1657 + int ret; 1658 + 1659 + dev_dbg(unicam->dev, "Starting stream on %s device\n", 1660 + is_metadata_node(node) ? "metadata" : "image"); 1661 + 1662 + /* 1663 + * Start the pipeline. This validates all links, and populates the 1664 + * pipeline structure. 1665 + */ 1666 + ret = video_device_pipeline_start(&node->video_dev, &unicam->pipe.pipe); 1667 + if (ret < 0) { 1668 + dev_dbg(unicam->dev, "Failed to start media pipeline: %d\n", ret); 1669 + goto err_buffers; 1670 + } 1671 + 1672 + /* 1673 + * Determine which video nodes are included in the pipeline, and get the 1674 + * number of data lanes. 1675 + */ 1676 + if (unicam->pipe.pipe.start_count == 1) { 1677 + unicam->pipe.nodes = 0; 1678 + 1679 + media_pipeline_for_each_pad(&unicam->pipe.pipe, &iter, pad) { 1680 + if (pad->entity != &unicam->subdev.sd.entity) 1681 + continue; 1682 + 1683 + if (pad->index == UNICAM_SD_PAD_SOURCE_IMAGE) 1684 + unicam->pipe.nodes |= BIT(UNICAM_IMAGE_NODE); 1685 + else if (pad->index == UNICAM_SD_PAD_SOURCE_METADATA) 1686 + unicam->pipe.nodes |= BIT(UNICAM_METADATA_NODE); 1687 + } 1688 + 1689 + if (!(unicam->pipe.nodes & BIT(UNICAM_IMAGE_NODE))) { 1690 + dev_dbg(unicam->dev, 1691 + "Pipeline does not include image node\n"); 1692 + ret = -EPIPE; 1693 + goto err_pipeline; 1694 + } 1695 + 1696 + ret = unicam_num_data_lanes(unicam); 1697 + if (ret < 0) 1698 + goto err_pipeline; 1699 + 1700 + unicam->pipe.num_data_lanes = ret; 1701 + 1702 + dev_dbg(unicam->dev, "Running with %u data lanes, nodes %u\n", 1703 + unicam->pipe.num_data_lanes, unicam->pipe.nodes); 1704 + } 1705 + 1706 + /* Arm the node with the first buffer from the DMA queue. */ 1707 + spin_lock_irqsave(&node->dma_queue_lock, flags); 1708 + buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); 1709 + node->cur_frm = buf; 1710 + node->next_frm = buf; 1711 + list_del(&buf->list); 1712 + spin_unlock_irqrestore(&node->dma_queue_lock, flags); 1713 + 1714 + /* 1715 + * Wait for all the video devices in the pipeline to have been started 1716 + * before starting the hardware. In the general case, this would 1717 + * prevent capturing multiple streams independently. However, the 1718 + * Unicam DMA engines are not generic, they have been designed to 1719 + * capture image data and embedded data from the same camera sensor. 1720 + * Not only does the main use case not benefit from independent 1721 + * capture, it requires proper synchronization of the streams at start 1722 + * time. 1723 + */ 1724 + if (unicam->pipe.pipe.start_count < hweight32(unicam->pipe.nodes)) 1725 + return 0; 1726 + 1727 + ret = pm_runtime_resume_and_get(unicam->dev); 1728 + if (ret < 0) { 1729 + dev_err(unicam->dev, "PM runtime resume failed: %d\n", ret); 1730 + goto err_pipeline; 1731 + } 1732 + 1733 + /* Enable the streams on the source. */ 1734 + ret = v4l2_subdev_enable_streams(&unicam->subdev.sd, 1735 + UNICAM_SD_PAD_SOURCE_IMAGE, 1736 + BIT(0)); 1737 + if (ret < 0) { 1738 + dev_err(unicam->dev, "stream on failed in subdev\n"); 1739 + goto err_pm_put; 1740 + } 1741 + 1742 + if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) { 1743 + ret = v4l2_subdev_enable_streams(&unicam->subdev.sd, 1744 + UNICAM_SD_PAD_SOURCE_METADATA, 1745 + BIT(0)); 1746 + if (ret < 0) { 1747 + dev_err(unicam->dev, "stream on failed in subdev\n"); 1748 + goto err_disable_streams; 1749 + } 1750 + } 1751 + 1752 + return 0; 1753 + 1754 + err_disable_streams: 1755 + v4l2_subdev_disable_streams(&unicam->subdev.sd, 1756 + UNICAM_SD_PAD_SOURCE_IMAGE, BIT(0)); 1757 + err_pm_put: 1758 + pm_runtime_put_sync(unicam->dev); 1759 + err_pipeline: 1760 + video_device_pipeline_stop(&node->video_dev); 1761 + err_buffers: 1762 + unicam_return_buffers(node, VB2_BUF_STATE_QUEUED); 1763 + return ret; 1764 + } 1765 + 1766 + static void unicam_stop_streaming(struct vb2_queue *vq) 1767 + { 1768 + struct unicam_node *node = vb2_get_drv_priv(vq); 1769 + struct unicam_device *unicam = node->dev; 1770 + 1771 + /* Stop the hardware when the first video device gets stopped. */ 1772 + if (unicam->pipe.pipe.start_count == hweight32(unicam->pipe.nodes)) { 1773 + if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) 1774 + v4l2_subdev_disable_streams(&unicam->subdev.sd, 1775 + UNICAM_SD_PAD_SOURCE_METADATA, 1776 + BIT(0)); 1777 + 1778 + v4l2_subdev_disable_streams(&unicam->subdev.sd, 1779 + UNICAM_SD_PAD_SOURCE_IMAGE, 1780 + BIT(0)); 1781 + 1782 + pm_runtime_put(unicam->dev); 1783 + } 1784 + 1785 + video_device_pipeline_stop(&node->video_dev); 1786 + 1787 + /* Clear all queued buffers for the node */ 1788 + unicam_return_buffers(node, VB2_BUF_STATE_ERROR); 1789 + } 1790 + 1791 + static void unicam_buffer_queue(struct vb2_buffer *vb) 1792 + { 1793 + struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); 1794 + struct unicam_buffer *buf = to_unicam_buffer(vb); 1795 + 1796 + spin_lock_irq(&node->dma_queue_lock); 1797 + list_add_tail(&buf->list, &node->dma_queue); 1798 + spin_unlock_irq(&node->dma_queue_lock); 1799 + } 1800 + 1801 + static const struct vb2_ops unicam_video_qops = { 1802 + .queue_setup = unicam_queue_setup, 1803 + .wait_prepare = vb2_ops_wait_prepare, 1804 + .wait_finish = vb2_ops_wait_finish, 1805 + .buf_prepare = unicam_buffer_prepare, 1806 + .start_streaming = unicam_start_streaming, 1807 + .stop_streaming = unicam_stop_streaming, 1808 + .buf_queue = unicam_buffer_queue, 1809 + }; 1810 + 1811 + /* ----------------------------------------------------------------------------- 1812 + * V4L2 video device operations 1813 + */ 1814 + 1815 + static int unicam_querycap(struct file *file, void *priv, 1816 + struct v4l2_capability *cap) 1817 + { 1818 + strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); 1819 + strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); 1820 + 1821 + cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE; 1822 + 1823 + return 0; 1824 + } 1825 + 1826 + static int unicam_enum_fmt_vid(struct file *file, void *priv, 1827 + struct v4l2_fmtdesc *f) 1828 + { 1829 + unsigned int index; 1830 + unsigned int i; 1831 + 1832 + for (i = 0, index = 0; i < ARRAY_SIZE(unicam_image_formats); i++) { 1833 + if (f->mbus_code && unicam_image_formats[i].code != f->mbus_code) 1834 + continue; 1835 + 1836 + if (index == f->index) { 1837 + f->pixelformat = unicam_image_formats[i].fourcc; 1838 + return 0; 1839 + } 1840 + 1841 + index++; 1842 + 1843 + if (!unicam_image_formats[i].unpacked_fourcc) 1844 + continue; 1845 + 1846 + if (index == f->index) { 1847 + f->pixelformat = unicam_image_formats[i].unpacked_fourcc; 1848 + return 0; 1849 + } 1850 + 1851 + index++; 1852 + } 1853 + 1854 + return -EINVAL; 1855 + } 1856 + 1857 + static int unicam_g_fmt_vid(struct file *file, void *priv, 1858 + struct v4l2_format *f) 1859 + { 1860 + struct unicam_node *node = video_drvdata(file); 1861 + 1862 + *f = node->fmt; 1863 + 1864 + return 0; 1865 + } 1866 + 1867 + static void __unicam_try_fmt_vid(struct unicam_node *node, 1868 + struct v4l2_pix_format *pix) 1869 + { 1870 + const struct unicam_format_info *fmtinfo; 1871 + 1872 + /* 1873 + * Default to the first format if the requested pixel format code isn't 1874 + * supported. 1875 + */ 1876 + fmtinfo = unicam_find_format_by_fourcc(pix->pixelformat, 1877 + UNICAM_SD_PAD_SOURCE_IMAGE); 1878 + if (!fmtinfo) { 1879 + fmtinfo = &unicam_image_formats[0]; 1880 + pix->pixelformat = fmtinfo->fourcc; 1881 + } 1882 + 1883 + unicam_calc_image_size_bpl(node->dev, fmtinfo, pix); 1884 + 1885 + if (pix->field == V4L2_FIELD_ANY) 1886 + pix->field = V4L2_FIELD_NONE; 1887 + } 1888 + 1889 + static int unicam_try_fmt_vid(struct file *file, void *priv, 1890 + struct v4l2_format *f) 1891 + { 1892 + struct unicam_node *node = video_drvdata(file); 1893 + 1894 + __unicam_try_fmt_vid(node, &f->fmt.pix); 1895 + return 0; 1896 + } 1897 + 1898 + static int unicam_s_fmt_vid(struct file *file, void *priv, 1899 + struct v4l2_format *f) 1900 + { 1901 + struct unicam_node *node = video_drvdata(file); 1902 + 1903 + if (vb2_is_busy(&node->buffer_queue)) 1904 + return -EBUSY; 1905 + 1906 + __unicam_try_fmt_vid(node, &f->fmt.pix); 1907 + node->fmt = *f; 1908 + 1909 + return 0; 1910 + } 1911 + 1912 + static int unicam_enum_fmt_meta(struct file *file, void *priv, 1913 + struct v4l2_fmtdesc *f) 1914 + { 1915 + unsigned int i, index; 1916 + 1917 + for (i = 0, index = 0; i < ARRAY_SIZE(unicam_meta_formats); i++) { 1918 + if (f->mbus_code && unicam_meta_formats[i].code != f->mbus_code) 1919 + continue; 1920 + 1921 + if (index == f->index) { 1922 + f->pixelformat = unicam_meta_formats[i].fourcc; 1923 + f->type = V4L2_BUF_TYPE_META_CAPTURE; 1924 + f->flags = V4L2_FMT_FLAG_META_LINE_BASED; 1925 + return 0; 1926 + } 1927 + 1928 + index++; 1929 + } 1930 + 1931 + return -EINVAL; 1932 + } 1933 + 1934 + static int unicam_g_fmt_meta(struct file *file, void *priv, 1935 + struct v4l2_format *f) 1936 + { 1937 + struct unicam_node *node = video_drvdata(file); 1938 + 1939 + f->fmt.meta = node->fmt.fmt.meta; 1940 + 1941 + return 0; 1942 + } 1943 + 1944 + static const struct unicam_format_info * 1945 + __unicam_try_fmt_meta(struct unicam_node *node, struct v4l2_meta_format *meta) 1946 + { 1947 + const struct unicam_format_info *fmtinfo; 1948 + 1949 + /* 1950 + * Default to the first format if the requested pixel format code isn't 1951 + * supported. 1952 + */ 1953 + fmtinfo = unicam_find_format_by_fourcc(meta->dataformat, 1954 + UNICAM_SD_PAD_SOURCE_METADATA); 1955 + if (!fmtinfo) { 1956 + fmtinfo = &unicam_meta_formats[0]; 1957 + meta->dataformat = fmtinfo->fourcc; 1958 + } 1959 + 1960 + unicam_calc_meta_size_bpl(node->dev, fmtinfo, meta); 1961 + 1962 + return fmtinfo; 1963 + } 1964 + 1965 + static int unicam_try_fmt_meta(struct file *file, void *priv, 1966 + struct v4l2_format *f) 1967 + { 1968 + struct unicam_node *node = video_drvdata(file); 1969 + 1970 + __unicam_try_fmt_meta(node, &f->fmt.meta); 1971 + return 0; 1972 + } 1973 + 1974 + static int unicam_s_fmt_meta(struct file *file, void *priv, 1975 + struct v4l2_format *f) 1976 + { 1977 + struct unicam_node *node = video_drvdata(file); 1978 + 1979 + if (vb2_is_busy(&node->buffer_queue)) 1980 + return -EBUSY; 1981 + 1982 + __unicam_try_fmt_meta(node, &f->fmt.meta); 1983 + node->fmt = *f; 1984 + 1985 + return 0; 1986 + } 1987 + 1988 + static int unicam_enum_framesizes(struct file *file, void *fh, 1989 + struct v4l2_frmsizeenum *fsize) 1990 + { 1991 + struct unicam_node *node = video_drvdata(file); 1992 + int ret = -EINVAL; 1993 + 1994 + if (fsize->index > 0) 1995 + return ret; 1996 + 1997 + if (is_image_node(node)) { 1998 + if (!unicam_find_format_by_fourcc(fsize->pixel_format, 1999 + UNICAM_SD_PAD_SOURCE_IMAGE)) 2000 + return ret; 2001 + 2002 + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 2003 + fsize->stepwise.min_width = UNICAM_IMAGE_MIN_WIDTH; 2004 + fsize->stepwise.max_width = UNICAM_IMAGE_MAX_WIDTH; 2005 + fsize->stepwise.step_width = 1; 2006 + fsize->stepwise.min_height = UNICAM_IMAGE_MIN_HEIGHT; 2007 + fsize->stepwise.max_height = UNICAM_IMAGE_MAX_HEIGHT; 2008 + fsize->stepwise.step_height = 1; 2009 + } else { 2010 + if (!unicam_find_format_by_fourcc(fsize->pixel_format, 2011 + UNICAM_SD_PAD_SOURCE_METADATA)) 2012 + return ret; 2013 + 2014 + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 2015 + fsize->stepwise.min_width = UNICAM_META_MIN_WIDTH; 2016 + fsize->stepwise.max_width = UNICAM_META_MAX_WIDTH; 2017 + fsize->stepwise.step_width = 1; 2018 + fsize->stepwise.min_height = UNICAM_META_MIN_HEIGHT; 2019 + fsize->stepwise.max_height = UNICAM_META_MAX_HEIGHT; 2020 + fsize->stepwise.step_height = 1; 2021 + } 2022 + 2023 + return 0; 2024 + } 2025 + 2026 + static int unicam_log_status(struct file *file, void *fh) 2027 + { 2028 + struct unicam_node *node = video_drvdata(file); 2029 + struct unicam_device *unicam = node->dev; 2030 + u32 reg; 2031 + 2032 + /* status for sub devices */ 2033 + v4l2_device_call_all(&unicam->v4l2_dev, 0, core, log_status); 2034 + 2035 + dev_info(unicam->dev, "-----Receiver status-----\n"); 2036 + dev_info(unicam->dev, "V4L2 width/height: %ux%u\n", 2037 + node->fmt.fmt.pix.width, node->fmt.fmt.pix.height); 2038 + dev_info(unicam->dev, "V4L2 format: %08x\n", 2039 + node->fmt.fmt.pix.pixelformat); 2040 + reg = unicam_reg_read(unicam, UNICAM_IPIPE); 2041 + dev_info(unicam->dev, "Unpacking/packing: %u / %u\n", 2042 + unicam_get_field(reg, UNICAM_PUM_MASK), 2043 + unicam_get_field(reg, UNICAM_PPM_MASK)); 2044 + dev_info(unicam->dev, "----Live data----\n"); 2045 + dev_info(unicam->dev, "Programmed stride: %4u\n", 2046 + unicam_reg_read(unicam, UNICAM_IBLS)); 2047 + dev_info(unicam->dev, "Detected resolution: %ux%u\n", 2048 + unicam_reg_read(unicam, UNICAM_IHSTA), 2049 + unicam_reg_read(unicam, UNICAM_IVSTA)); 2050 + dev_info(unicam->dev, "Write pointer: %08x\n", 2051 + unicam_reg_read(unicam, UNICAM_IBWP)); 2052 + 2053 + return 0; 2054 + } 2055 + 2056 + static int unicam_subscribe_event(struct v4l2_fh *fh, 2057 + const struct v4l2_event_subscription *sub) 2058 + { 2059 + switch (sub->type) { 2060 + case V4L2_EVENT_FRAME_SYNC: 2061 + return v4l2_event_subscribe(fh, sub, 2, NULL); 2062 + default: 2063 + return -EINVAL; 2064 + } 2065 + } 2066 + 2067 + static const struct v4l2_ioctl_ops unicam_ioctl_ops = { 2068 + .vidioc_querycap = unicam_querycap, 2069 + 2070 + .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid, 2071 + .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid, 2072 + .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid, 2073 + .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid, 2074 + 2075 + .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta, 2076 + .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta, 2077 + .vidioc_try_fmt_meta_cap = unicam_try_fmt_meta, 2078 + .vidioc_s_fmt_meta_cap = unicam_s_fmt_meta, 2079 + 2080 + .vidioc_enum_framesizes = unicam_enum_framesizes, 2081 + 2082 + .vidioc_reqbufs = vb2_ioctl_reqbufs, 2083 + .vidioc_create_bufs = vb2_ioctl_create_bufs, 2084 + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 2085 + .vidioc_querybuf = vb2_ioctl_querybuf, 2086 + .vidioc_qbuf = vb2_ioctl_qbuf, 2087 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 2088 + .vidioc_expbuf = vb2_ioctl_expbuf, 2089 + .vidioc_streamon = vb2_ioctl_streamon, 2090 + .vidioc_streamoff = vb2_ioctl_streamoff, 2091 + 2092 + .vidioc_log_status = unicam_log_status, 2093 + .vidioc_subscribe_event = unicam_subscribe_event, 2094 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 2095 + }; 2096 + 2097 + /* unicam capture driver file operations */ 2098 + static const struct v4l2_file_operations unicam_fops = { 2099 + .owner = THIS_MODULE, 2100 + .open = v4l2_fh_open, 2101 + .release = vb2_fop_release, 2102 + .poll = vb2_fop_poll, 2103 + .unlocked_ioctl = video_ioctl2, 2104 + .mmap = vb2_fop_mmap, 2105 + }; 2106 + 2107 + static int unicam_video_link_validate(struct media_link *link) 2108 + { 2109 + struct video_device *vdev = 2110 + media_entity_to_video_device(link->sink->entity); 2111 + struct v4l2_subdev *sd = 2112 + media_entity_to_v4l2_subdev(link->source->entity); 2113 + struct unicam_node *node = video_get_drvdata(vdev); 2114 + const u32 pad = is_image_node(node) ? UNICAM_SD_PAD_SOURCE_IMAGE 2115 + : UNICAM_SD_PAD_SOURCE_METADATA; 2116 + const struct v4l2_mbus_framefmt *format; 2117 + struct v4l2_subdev_state *state; 2118 + int ret = 0; 2119 + 2120 + state = v4l2_subdev_lock_and_get_active_state(sd); 2121 + 2122 + format = v4l2_subdev_state_get_format(state, pad, 0); 2123 + if (!format) { 2124 + ret = -EINVAL; 2125 + goto out; 2126 + } 2127 + 2128 + if (is_image_node(node)) { 2129 + const struct v4l2_pix_format *fmt = &node->fmt.fmt.pix; 2130 + const struct unicam_format_info *fmtinfo; 2131 + 2132 + fmtinfo = unicam_find_format_by_fourcc(fmt->pixelformat, 2133 + UNICAM_SD_PAD_SOURCE_IMAGE); 2134 + if (WARN_ON(!fmtinfo)) { 2135 + ret = -EPIPE; 2136 + goto out; 2137 + } 2138 + 2139 + if (fmtinfo->code != format->code || 2140 + fmt->height != format->height || 2141 + fmt->width != format->width || 2142 + fmt->field != format->field) { 2143 + dev_dbg(node->dev->dev, 2144 + "image: (%u x %u) 0x%08x %s != (%u x %u) 0x%08x %s\n", 2145 + fmt->width, fmt->height, fmtinfo->code, 2146 + v4l2_field_names[fmt->field], 2147 + format->width, format->height, format->code, 2148 + v4l2_field_names[format->field]); 2149 + ret = -EPIPE; 2150 + } 2151 + } else { 2152 + const struct v4l2_meta_format *fmt = &node->fmt.fmt.meta; 2153 + 2154 + const struct unicam_format_info *fmtinfo; 2155 + 2156 + fmtinfo = unicam_find_format_by_fourcc(fmt->dataformat, 2157 + UNICAM_SD_PAD_SOURCE_METADATA); 2158 + if (WARN_ON(!fmtinfo)) { 2159 + ret = -EPIPE; 2160 + goto out; 2161 + } 2162 + 2163 + if (fmtinfo->code != format->code || 2164 + fmt->height != format->height || 2165 + fmt->width != format->width) { 2166 + dev_dbg(node->dev->dev, 2167 + "meta: (%u x %u) 0x%04x != (%u x %u) 0x%04x\n", 2168 + fmt->width, fmt->height, fmtinfo->code, 2169 + format->width, format->height, format->code); 2170 + ret = -EPIPE; 2171 + } 2172 + } 2173 + 2174 + out: 2175 + v4l2_subdev_unlock_state(state); 2176 + return ret; 2177 + } 2178 + 2179 + static const struct media_entity_operations unicam_video_media_ops = { 2180 + .link_validate = unicam_video_link_validate, 2181 + }; 2182 + 2183 + static void unicam_node_release(struct video_device *vdev) 2184 + { 2185 + struct unicam_node *node = video_get_drvdata(vdev); 2186 + 2187 + unicam_put(node->dev); 2188 + } 2189 + 2190 + static void unicam_set_default_format(struct unicam_node *node) 2191 + { 2192 + if (is_image_node(node)) { 2193 + struct v4l2_pix_format *fmt = &node->fmt.fmt.pix; 2194 + const struct unicam_format_info *fmtinfo = 2195 + &unicam_image_formats[0]; 2196 + 2197 + node->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2198 + 2199 + v4l2_fill_pix_format(fmt, &unicam_default_image_format); 2200 + fmt->pixelformat = fmtinfo->fourcc; 2201 + unicam_calc_image_size_bpl(node->dev, fmtinfo, fmt); 2202 + } else { 2203 + struct v4l2_meta_format *fmt = &node->fmt.fmt.meta; 2204 + const struct unicam_format_info *fmtinfo = 2205 + &unicam_meta_formats[0]; 2206 + 2207 + node->fmt.type = V4L2_BUF_TYPE_META_CAPTURE; 2208 + 2209 + fmt->dataformat = fmtinfo->fourcc; 2210 + fmt->width = unicam_default_meta_format.width; 2211 + fmt->height = unicam_default_meta_format.height; 2212 + unicam_calc_meta_size_bpl(node->dev, fmtinfo, fmt); 2213 + } 2214 + } 2215 + 2216 + static int unicam_register_node(struct unicam_device *unicam, 2217 + enum unicam_node_type type) 2218 + { 2219 + const u32 pad_index = type == UNICAM_IMAGE_NODE 2220 + ? UNICAM_SD_PAD_SOURCE_IMAGE 2221 + : UNICAM_SD_PAD_SOURCE_METADATA; 2222 + struct unicam_node *node = &unicam->node[type]; 2223 + struct video_device *vdev = &node->video_dev; 2224 + struct vb2_queue *q = &node->buffer_queue; 2225 + int ret; 2226 + 2227 + node->dev = unicam_get(unicam); 2228 + node->id = type; 2229 + 2230 + spin_lock_init(&node->dma_queue_lock); 2231 + 2232 + INIT_LIST_HEAD(&node->dma_queue); 2233 + 2234 + /* Initialize the videobuf2 queue. */ 2235 + q->type = type == UNICAM_IMAGE_NODE ? V4L2_BUF_TYPE_VIDEO_CAPTURE 2236 + : V4L2_BUF_TYPE_META_CAPTURE; 2237 + q->io_modes = VB2_MMAP | VB2_DMABUF; 2238 + q->drv_priv = node; 2239 + q->ops = &unicam_video_qops; 2240 + q->mem_ops = &vb2_dma_contig_memops; 2241 + q->buf_struct_size = sizeof(struct unicam_buffer); 2242 + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 2243 + q->lock = &unicam->lock; 2244 + q->min_queued_buffers = 1; 2245 + q->dev = unicam->dev; 2246 + 2247 + ret = vb2_queue_init(q); 2248 + if (ret) { 2249 + dev_err(unicam->dev, "vb2_queue_init() failed\n"); 2250 + goto err_unicam_put; 2251 + } 2252 + 2253 + /* Initialize the video device. */ 2254 + vdev->release = unicam_node_release; 2255 + vdev->fops = &unicam_fops; 2256 + vdev->ioctl_ops = &unicam_ioctl_ops; 2257 + vdev->v4l2_dev = &unicam->v4l2_dev; 2258 + vdev->vfl_dir = VFL_DIR_RX; 2259 + vdev->queue = q; 2260 + vdev->lock = &unicam->lock; 2261 + vdev->device_caps = type == UNICAM_IMAGE_NODE 2262 + ? V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_META_CAPTURE; 2263 + vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_IO_MC; 2264 + vdev->entity.ops = &unicam_video_media_ops; 2265 + 2266 + snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, 2267 + type == UNICAM_IMAGE_NODE ? "image" : "embedded"); 2268 + 2269 + video_set_drvdata(vdev, node); 2270 + 2271 + if (type == UNICAM_IMAGE_NODE) 2272 + vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; 2273 + 2274 + node->pad.flags = MEDIA_PAD_FL_SINK; 2275 + 2276 + ret = media_entity_pads_init(&vdev->entity, 1, &node->pad); 2277 + if (ret) 2278 + goto err_unicam_put; 2279 + 2280 + node->dummy_buf.size = UNICAM_DUMMY_BUF_SIZE; 2281 + node->dummy_buf_cpu_addr = dma_alloc_coherent(unicam->dev, 2282 + node->dummy_buf.size, 2283 + &node->dummy_buf.dma_addr, 2284 + GFP_KERNEL); 2285 + if (!node->dummy_buf_cpu_addr) { 2286 + dev_err(unicam->dev, "Unable to allocate dummy buffer.\n"); 2287 + ret = -ENOMEM; 2288 + goto err_entity_cleanup; 2289 + } 2290 + 2291 + unicam_set_default_format(node); 2292 + 2293 + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 2294 + if (ret) { 2295 + dev_err(unicam->dev, "Unable to register video device %s\n", 2296 + vdev->name); 2297 + goto err_dma_free; 2298 + } 2299 + 2300 + node->registered = true; 2301 + 2302 + ret = media_create_pad_link(&unicam->subdev.sd.entity, 2303 + pad_index, 2304 + &node->video_dev.entity, 2305 + 0, 2306 + MEDIA_LNK_FL_ENABLED | 2307 + MEDIA_LNK_FL_IMMUTABLE); 2308 + if (ret) { 2309 + /* 2310 + * No need for cleanup, the caller will unregister the 2311 + * video device, which will drop the reference on the 2312 + * device and trigger the cleanup. 2313 + */ 2314 + dev_err(unicam->dev, "Unable to create pad link for %s\n", 2315 + unicam->sensor.subdev->name); 2316 + return ret; 2317 + } 2318 + 2319 + return 0; 2320 + 2321 + err_dma_free: 2322 + dma_free_coherent(unicam->dev, node->dummy_buf.size, 2323 + node->dummy_buf_cpu_addr, 2324 + node->dummy_buf.dma_addr); 2325 + err_entity_cleanup: 2326 + media_entity_cleanup(&vdev->entity); 2327 + err_unicam_put: 2328 + unicam_put(unicam); 2329 + return ret; 2330 + } 2331 + 2332 + static void unicam_unregister_nodes(struct unicam_device *unicam) 2333 + { 2334 + unsigned int i; 2335 + 2336 + for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { 2337 + struct unicam_node *node = &unicam->node[i]; 2338 + 2339 + if (node->registered) { 2340 + vb2_video_unregister_device(&node->video_dev); 2341 + node->registered = false; 2342 + } 2343 + 2344 + if (node->dummy_buf_cpu_addr) 2345 + dma_free_coherent(unicam->dev, node->dummy_buf.size, 2346 + node->dummy_buf_cpu_addr, 2347 + node->dummy_buf.dma_addr); 2348 + } 2349 + } 2350 + 2351 + /* ----------------------------------------------------------------------------- 2352 + * Power management 2353 + */ 2354 + 2355 + static int unicam_runtime_resume(struct device *dev) 2356 + { 2357 + struct unicam_device *unicam = dev_get_drvdata(dev); 2358 + int ret; 2359 + 2360 + ret = clk_set_min_rate(unicam->vpu_clock, UNICAM_MIN_VPU_CLOCK_RATE); 2361 + if (ret) { 2362 + dev_err(unicam->dev, "failed to set up VPU clock\n"); 2363 + return ret; 2364 + } 2365 + 2366 + ret = clk_prepare_enable(unicam->vpu_clock); 2367 + if (ret) { 2368 + dev_err(unicam->dev, "Failed to enable VPU clock: %d\n", ret); 2369 + goto err_vpu_clock; 2370 + } 2371 + 2372 + ret = clk_set_rate(unicam->clock, 100 * 1000 * 1000); 2373 + if (ret) { 2374 + dev_err(unicam->dev, "failed to set up CSI clock\n"); 2375 + goto err_vpu_prepare; 2376 + } 2377 + 2378 + ret = clk_prepare_enable(unicam->clock); 2379 + if (ret) { 2380 + dev_err(unicam->dev, "Failed to enable CSI clock: %d\n", ret); 2381 + goto err_vpu_prepare; 2382 + } 2383 + 2384 + return 0; 2385 + 2386 + err_vpu_prepare: 2387 + clk_disable_unprepare(unicam->vpu_clock); 2388 + err_vpu_clock: 2389 + if (clk_set_min_rate(unicam->vpu_clock, 0)) 2390 + dev_err(unicam->dev, "failed to reset the VPU clock\n"); 2391 + 2392 + return ret; 2393 + } 2394 + 2395 + static int unicam_runtime_suspend(struct device *dev) 2396 + { 2397 + struct unicam_device *unicam = dev_get_drvdata(dev); 2398 + 2399 + clk_disable_unprepare(unicam->clock); 2400 + 2401 + if (clk_set_min_rate(unicam->vpu_clock, 0)) 2402 + dev_err(unicam->dev, "failed to reset the VPU clock\n"); 2403 + 2404 + clk_disable_unprepare(unicam->vpu_clock); 2405 + 2406 + return 0; 2407 + } 2408 + 2409 + static const struct dev_pm_ops unicam_pm_ops = { 2410 + RUNTIME_PM_OPS(unicam_runtime_suspend, unicam_runtime_resume, NULL) 2411 + }; 2412 + 2413 + /* ----------------------------------------------------------------------------- 2414 + * V4L2 async notifier 2415 + */ 2416 + 2417 + static int unicam_async_bound(struct v4l2_async_notifier *notifier, 2418 + struct v4l2_subdev *subdev, 2419 + struct v4l2_async_connection *asc) 2420 + { 2421 + struct unicam_device *unicam = notifier_to_unicam_device(notifier); 2422 + struct media_pad *sink = &unicam->subdev.pads[UNICAM_SD_PAD_SINK]; 2423 + struct media_pad *source; 2424 + int ret; 2425 + 2426 + dev_dbg(unicam->dev, "Using sensor %s for capture\n", 2427 + subdev->name); 2428 + 2429 + ret = v4l2_create_fwnode_links_to_pad(subdev, sink, MEDIA_LNK_FL_ENABLED | 2430 + MEDIA_LNK_FL_IMMUTABLE); 2431 + if (ret) 2432 + return ret; 2433 + 2434 + source = media_pad_remote_pad_unique(sink); 2435 + if (!source) { 2436 + dev_err(unicam->dev, "No connected sensor pad\n"); 2437 + return -ENOTCONN; 2438 + } 2439 + 2440 + unicam->sensor.subdev = subdev; 2441 + unicam->sensor.pad = source; 2442 + 2443 + return 0; 2444 + } 2445 + 2446 + static int unicam_async_complete(struct v4l2_async_notifier *notifier) 2447 + { 2448 + struct unicam_device *unicam = notifier_to_unicam_device(notifier); 2449 + int ret; 2450 + 2451 + ret = unicam_register_node(unicam, UNICAM_IMAGE_NODE); 2452 + if (ret) { 2453 + dev_err(unicam->dev, "Unable to register image video device.\n"); 2454 + goto unregister; 2455 + } 2456 + 2457 + ret = unicam_register_node(unicam, UNICAM_METADATA_NODE); 2458 + if (ret) { 2459 + dev_err(unicam->dev, "Unable to register metadata video device.\n"); 2460 + goto unregister; 2461 + } 2462 + 2463 + ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev); 2464 + if (ret) { 2465 + dev_err(unicam->dev, "Unable to register subdev nodes.\n"); 2466 + goto unregister; 2467 + } 2468 + 2469 + return 0; 2470 + 2471 + unregister: 2472 + unicam_unregister_nodes(unicam); 2473 + unicam_put(unicam); 2474 + 2475 + return ret; 2476 + } 2477 + 2478 + static const struct v4l2_async_notifier_operations unicam_async_ops = { 2479 + .bound = unicam_async_bound, 2480 + .complete = unicam_async_complete, 2481 + }; 2482 + 2483 + static int unicam_async_nf_init(struct unicam_device *unicam) 2484 + { 2485 + struct v4l2_fwnode_endpoint ep = { }; 2486 + struct fwnode_handle *ep_handle; 2487 + struct v4l2_async_connection *asc; 2488 + int ret; 2489 + 2490 + ret = of_property_read_u32(unicam->dev->of_node, "brcm,num-data-lanes", 2491 + &unicam->max_data_lanes); 2492 + if (ret < 0) { 2493 + dev_err(unicam->dev, "Missing %s DT property\n", 2494 + "brcm,num-data-lanes"); 2495 + return -EINVAL; 2496 + } 2497 + 2498 + /* Get and parse the local endpoint. */ 2499 + ep_handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(unicam->dev), 0, 0, 2500 + FWNODE_GRAPH_ENDPOINT_NEXT); 2501 + if (!ep_handle) { 2502 + dev_err(unicam->dev, "No endpoint found\n"); 2503 + return -ENODEV; 2504 + } 2505 + 2506 + ret = v4l2_fwnode_endpoint_parse(ep_handle, &ep); 2507 + if (ret) { 2508 + dev_err(unicam->dev, "Failed to parse endpoint: %d\n", ret); 2509 + goto error; 2510 + } 2511 + 2512 + unicam->bus_type = ep.bus_type; 2513 + 2514 + switch (ep.bus_type) { 2515 + case V4L2_MBUS_CSI2_DPHY: { 2516 + unsigned int num_data_lanes = ep.bus.mipi_csi2.num_data_lanes; 2517 + 2518 + if (num_data_lanes != 1 && num_data_lanes != 2 && 2519 + num_data_lanes != 4) { 2520 + dev_err(unicam->dev, "%u data lanes not supported\n", 2521 + num_data_lanes); 2522 + ret = -EINVAL; 2523 + goto error; 2524 + } 2525 + 2526 + if (num_data_lanes > unicam->max_data_lanes) { 2527 + dev_err(unicam->dev, 2528 + "Endpoint uses %u data lanes when %u are supported\n", 2529 + num_data_lanes, unicam->max_data_lanes); 2530 + ret = -EINVAL; 2531 + goto error; 2532 + } 2533 + 2534 + unicam->max_data_lanes = num_data_lanes; 2535 + unicam->bus_flags = ep.bus.mipi_csi2.flags; 2536 + break; 2537 + } 2538 + 2539 + case V4L2_MBUS_CCP2: 2540 + unicam->max_data_lanes = 1; 2541 + unicam->bus_flags = ep.bus.mipi_csi1.strobe; 2542 + break; 2543 + 2544 + default: 2545 + /* Unsupported bus type */ 2546 + dev_err(unicam->dev, "Unsupported bus type %u\n", ep.bus_type); 2547 + ret = -EINVAL; 2548 + goto error; 2549 + } 2550 + 2551 + /* Initialize and register the async notifier. */ 2552 + v4l2_async_nf_init(&unicam->notifier, &unicam->v4l2_dev); 2553 + 2554 + asc = v4l2_async_nf_add_fwnode_remote(&unicam->notifier, ep_handle, 2555 + struct v4l2_async_connection); 2556 + fwnode_handle_put(ep_handle); 2557 + ep_handle = NULL; 2558 + 2559 + if (IS_ERR(asc)) { 2560 + ret = PTR_ERR(asc); 2561 + dev_err(unicam->dev, "Failed to add entry to notifier: %d\n", 2562 + ret); 2563 + goto error; 2564 + } 2565 + 2566 + unicam->notifier.ops = &unicam_async_ops; 2567 + 2568 + ret = v4l2_async_nf_register(&unicam->notifier); 2569 + if (ret) { 2570 + dev_err(unicam->dev, "Error registering device notifier: %d\n", 2571 + ret); 2572 + goto error; 2573 + } 2574 + 2575 + return 0; 2576 + 2577 + error: 2578 + fwnode_handle_put(ep_handle); 2579 + return ret; 2580 + } 2581 + 2582 + /* ----------------------------------------------------------------------------- 2583 + * Probe & remove 2584 + */ 2585 + 2586 + static int unicam_media_init(struct unicam_device *unicam) 2587 + { 2588 + int ret; 2589 + 2590 + unicam->mdev.dev = unicam->dev; 2591 + strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, 2592 + sizeof(unicam->mdev.model)); 2593 + unicam->mdev.hw_revision = 0; 2594 + 2595 + media_device_init(&unicam->mdev); 2596 + 2597 + unicam->v4l2_dev.mdev = &unicam->mdev; 2598 + 2599 + ret = v4l2_device_register(unicam->dev, &unicam->v4l2_dev); 2600 + if (ret < 0) { 2601 + dev_err(unicam->dev, "Unable to register v4l2 device\n"); 2602 + goto err_media_cleanup; 2603 + } 2604 + 2605 + ret = media_device_register(&unicam->mdev); 2606 + if (ret < 0) { 2607 + dev_err(unicam->dev, 2608 + "Unable to register media-controller device\n"); 2609 + goto err_v4l2_unregister; 2610 + } 2611 + 2612 + return 0; 2613 + 2614 + err_v4l2_unregister: 2615 + v4l2_device_unregister(&unicam->v4l2_dev); 2616 + err_media_cleanup: 2617 + media_device_cleanup(&unicam->mdev); 2618 + return ret; 2619 + } 2620 + 2621 + static int unicam_probe(struct platform_device *pdev) 2622 + { 2623 + struct unicam_device *unicam; 2624 + int ret; 2625 + 2626 + unicam = kzalloc(sizeof(*unicam), GFP_KERNEL); 2627 + if (!unicam) 2628 + return -ENOMEM; 2629 + 2630 + kref_init(&unicam->kref); 2631 + mutex_init(&unicam->lock); 2632 + 2633 + unicam->dev = &pdev->dev; 2634 + platform_set_drvdata(pdev, unicam); 2635 + 2636 + unicam->base = devm_platform_ioremap_resource_byname(pdev, "unicam"); 2637 + if (IS_ERR(unicam->base)) { 2638 + ret = PTR_ERR(unicam->base); 2639 + goto err_unicam_put; 2640 + } 2641 + 2642 + unicam->clk_gate_base = devm_platform_ioremap_resource_byname(pdev, "cmi"); 2643 + if (IS_ERR(unicam->clk_gate_base)) { 2644 + ret = PTR_ERR(unicam->clk_gate_base); 2645 + goto err_unicam_put; 2646 + } 2647 + 2648 + unicam->clock = devm_clk_get(&pdev->dev, "lp"); 2649 + if (IS_ERR(unicam->clock)) { 2650 + dev_err(unicam->dev, "Failed to get lp clock\n"); 2651 + ret = PTR_ERR(unicam->clock); 2652 + goto err_unicam_put; 2653 + } 2654 + 2655 + unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu"); 2656 + if (IS_ERR(unicam->vpu_clock)) { 2657 + dev_err(unicam->dev, "Failed to get vpu clock\n"); 2658 + ret = PTR_ERR(unicam->vpu_clock); 2659 + goto err_unicam_put; 2660 + } 2661 + 2662 + ret = platform_get_irq(pdev, 0); 2663 + if (ret <= 0) { 2664 + dev_err(&pdev->dev, "No IRQ resource\n"); 2665 + ret = -EINVAL; 2666 + goto err_unicam_put; 2667 + } 2668 + 2669 + ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, 2670 + "unicam_capture0", unicam); 2671 + if (ret) { 2672 + dev_err(&pdev->dev, "Unable to request interrupt\n"); 2673 + ret = -EINVAL; 2674 + goto err_unicam_put; 2675 + } 2676 + 2677 + /* Enable the block power domain. */ 2678 + pm_runtime_enable(&pdev->dev); 2679 + 2680 + ret = unicam_media_init(unicam); 2681 + if (ret) 2682 + goto err_pm_runtime; 2683 + 2684 + ret = unicam_subdev_init(unicam); 2685 + if (ret) 2686 + goto err_media_unregister; 2687 + 2688 + ret = unicam_async_nf_init(unicam); 2689 + if (ret) 2690 + goto err_subdev_unregister; 2691 + 2692 + return 0; 2693 + 2694 + err_subdev_unregister: 2695 + unicam_subdev_cleanup(unicam); 2696 + err_media_unregister: 2697 + media_device_unregister(&unicam->mdev); 2698 + err_pm_runtime: 2699 + pm_runtime_disable(&pdev->dev); 2700 + err_unicam_put: 2701 + unicam_put(unicam); 2702 + 2703 + return ret; 2704 + } 2705 + 2706 + static int unicam_remove(struct platform_device *pdev) 2707 + { 2708 + struct unicam_device *unicam = platform_get_drvdata(pdev); 2709 + 2710 + unicam_unregister_nodes(unicam); 2711 + v4l2_device_unregister(&unicam->v4l2_dev); 2712 + media_device_unregister(&unicam->mdev); 2713 + v4l2_async_nf_unregister(&unicam->notifier); 2714 + 2715 + unicam_subdev_cleanup(unicam); 2716 + 2717 + unicam_put(unicam); 2718 + 2719 + pm_runtime_disable(&pdev->dev); 2720 + 2721 + return 0; 2722 + } 2723 + 2724 + static const struct of_device_id unicam_of_match[] = { 2725 + { .compatible = "brcm,bcm2835-unicam", }, 2726 + { /* sentinel */ }, 2727 + }; 2728 + MODULE_DEVICE_TABLE(of, unicam_of_match); 2729 + 2730 + static struct platform_driver unicam_driver = { 2731 + .probe = unicam_probe, 2732 + .remove = unicam_remove, 2733 + .driver = { 2734 + .name = UNICAM_MODULE_NAME, 2735 + .pm = pm_ptr(&unicam_pm_ops), 2736 + .of_match_table = of_match_ptr(unicam_of_match), 2737 + }, 2738 + }; 2739 + 2740 + module_platform_driver(unicam_driver); 2741 + 2742 + MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>"); 2743 + MODULE_DESCRIPTION("BCM2835 Unicam driver"); 2744 + MODULE_LICENSE("GPL");