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_mbus_config_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