1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * Copyright (C) 2016 NextThing Co 4 * Copyright (C) 2016-2019 Bootlin 5 * 6 * Author: Maxime Ripard <maxime.ripard@bootlin.com> 7 */ 8 9 #ifndef _SUN4I_CSI_H_ 10 #define _SUN4I_CSI_H_ 11 12 #include <media/media-device.h> 13 #include <media/v4l2-async.h> 14 #include <media/v4l2-dev.h> 15 #include <media/v4l2-device.h> 16 #include <media/v4l2-fwnode.h> 17 #include <media/videobuf2-core.h> 18 19 #define CSI_EN_REG 0x00 20 21 #define CSI_CFG_REG 0x04 22 #define CSI_CFG_INPUT_FMT(fmt) ((fmt) << 20) 23 #define CSI_CFG_OUTPUT_FMT(fmt) ((fmt) << 16) 24 #define CSI_CFG_YUV_DATA_SEQ(seq) ((seq) << 8) 25 #define CSI_CFG_VREF_POL(pol) ((pol) << 2) 26 #define CSI_CFG_HREF_POL(pol) ((pol) << 1) 27 #define CSI_CFG_PCLK_POL(pol) ((pol) << 0) 28 29 #define CSI_CPT_CTRL_REG 0x08 30 #define CSI_CPT_CTRL_VIDEO_START BIT(1) 31 #define CSI_CPT_CTRL_IMAGE_START BIT(0) 32 33 #define CSI_BUF_ADDR_REG(fifo, buf) (0x10 + (0x8 * (fifo)) + (0x4 * (buf))) 34 35 #define CSI_BUF_CTRL_REG 0x28 36 #define CSI_BUF_CTRL_DBN BIT(2) 37 #define CSI_BUF_CTRL_DBS BIT(1) 38 #define CSI_BUF_CTRL_DBE BIT(0) 39 40 #define CSI_INT_EN_REG 0x30 41 #define CSI_INT_FRM_DONE BIT(1) 42 #define CSI_INT_CPT_DONE BIT(0) 43 44 #define CSI_INT_STA_REG 0x34 45 46 #define CSI_WIN_CTRL_W_REG 0x40 47 #define CSI_WIN_CTRL_W_ACTIVE(w) ((w) << 16) 48 49 #define CSI_WIN_CTRL_H_REG 0x44 50 #define CSI_WIN_CTRL_H_ACTIVE(h) ((h) << 16) 51 52 #define CSI_BUF_LEN_REG 0x48 53 54 #define CSI_MAX_BUFFER 2 55 #define CSI_MAX_HEIGHT 8192U 56 #define CSI_MAX_WIDTH 8192U 57 58 enum csi_input { 59 CSI_INPUT_RAW = 0, 60 CSI_INPUT_BT656 = 2, 61 CSI_INPUT_YUV = 3, 62 }; 63 64 enum csi_output_raw { 65 CSI_OUTPUT_RAW_PASSTHROUGH = 0, 66 }; 67 68 enum csi_output_yuv { 69 CSI_OUTPUT_YUV_422_PLANAR = 0, 70 CSI_OUTPUT_YUV_420_PLANAR = 1, 71 CSI_OUTPUT_YUV_422_UV = 4, 72 CSI_OUTPUT_YUV_420_UV = 5, 73 CSI_OUTPUT_YUV_422_MACRO = 8, 74 CSI_OUTPUT_YUV_420_MACRO = 9, 75 }; 76 77 enum csi_yuv_data_seq { 78 CSI_YUV_DATA_SEQ_YUYV = 0, 79 CSI_YUV_DATA_SEQ_YVYU = 1, 80 CSI_YUV_DATA_SEQ_UYVY = 2, 81 CSI_YUV_DATA_SEQ_VYUY = 3, 82 }; 83 84 enum csi_subdev_pads { 85 CSI_SUBDEV_SINK, 86 CSI_SUBDEV_SOURCE, 87 88 CSI_SUBDEV_PADS, 89 }; 90 91 extern const struct v4l2_subdev_ops sun4i_csi_subdev_ops; 92 93 struct sun4i_csi_format { 94 u32 mbus; 95 u32 fourcc; 96 enum csi_input input; 97 u32 output; 98 unsigned int num_planes; 99 u8 bpp[3]; 100 unsigned int hsub; 101 unsigned int vsub; 102 }; 103 104 const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc, 105 const u32 *mbus); 106 107 struct sun4i_csi { 108 /* Device resources */ 109 struct device *dev; 110 111 const struct sun4i_csi_traits *traits; 112 113 void __iomem *regs; 114 struct clk *bus_clk; 115 struct clk *isp_clk; 116 struct clk *ram_clk; 117 struct reset_control *rst; 118 119 struct vb2_v4l2_buffer *current_buf[CSI_MAX_BUFFER]; 120 121 struct { 122 size_t size; 123 void *vaddr; 124 dma_addr_t paddr; 125 } scratch; 126 127 struct v4l2_fwnode_bus_parallel bus; 128 129 /* Main Device */ 130 struct v4l2_device v4l; 131 struct media_device mdev; 132 struct video_device vdev; 133 struct media_pad vdev_pad; 134 struct v4l2_pix_format_mplane fmt; 135 136 /* Local subdev */ 137 struct v4l2_subdev subdev; 138 struct media_pad subdev_pads[CSI_SUBDEV_PADS]; 139 struct v4l2_mbus_framefmt subdev_fmt; 140 141 /* V4L2 Async variables */ 142 struct v4l2_async_notifier notifier; 143 struct v4l2_subdev *src_subdev; 144 int src_pad; 145 146 /* V4L2 variables */ 147 struct mutex lock; 148 149 /* Videobuf2 */ 150 struct vb2_queue queue; 151 struct list_head buf_list; 152 spinlock_t qlock; 153 unsigned int sequence; 154 }; 155 156 int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq); 157 void sun4i_csi_dma_unregister(struct sun4i_csi *csi); 158 159 int sun4i_csi_v4l2_register(struct sun4i_csi *csi); 160 161 #endif /* _SUN4I_CSI_H_ */ 162