xref: /linux/drivers/media/platform/rockchip/rkcif/rkcif-common.h (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Rockchip Camera Interface (CIF) Driver
4  *
5  * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
6  * Copyright (C) 2023 Mehdi Djait <mehdi.djait@bootlin.com>
7  * Copyright (C) 2025 Michael Riesch <michael.riesch@wolfvision.net>
8  * Copyright (C) 2025 Collabora, Ltd.
9  */
10 
11 #ifndef _RKCIF_COMMON_H
12 #define _RKCIF_COMMON_H
13 
14 #include <linux/clk.h>
15 #include <linux/mutex.h>
16 #include <linux/regmap.h>
17 
18 #include <media/media-device.h>
19 #include <media/media-entity.h>
20 #include <media/v4l2-common.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-fwnode.h>
23 #include <media/v4l2-mc.h>
24 #include <media/v4l2-subdev.h>
25 #include <media/videobuf2-v4l2.h>
26 
27 #include "rkcif-regs.h"
28 
29 #define RKCIF_DRIVER_NAME "rockchip-cif"
30 #define RKCIF_CLK_MAX	  4
31 
32 enum rkcif_format_type {
33 	RKCIF_FMT_TYPE_INVALID,
34 	RKCIF_FMT_TYPE_YUV,
35 	RKCIF_FMT_TYPE_RAW,
36 };
37 
38 enum rkcif_id_index {
39 	RKCIF_ID0,
40 	RKCIF_ID1,
41 	RKCIF_ID2,
42 	RKCIF_ID3,
43 	RKCIF_ID_MAX
44 };
45 
46 enum rkcif_interface_index {
47 	RKCIF_DVP,
48 	RKCIF_MIPI_BASE,
49 	RKCIF_MIPI1 = RKCIF_MIPI_BASE,
50 	RKCIF_MIPI2,
51 	RKCIF_MIPI3,
52 	RKCIF_MIPI4,
53 	RKCIF_MIPI5,
54 	RKCIF_MIPI6,
55 	RKCIF_MIPI_MAX,
56 	RKCIF_IF_MAX = RKCIF_MIPI_MAX
57 };
58 
59 enum rkcif_interface_pad_index {
60 	RKCIF_IF_PAD_SINK,
61 	RKCIF_IF_PAD_SRC,
62 	RKCIF_IF_PAD_MAX
63 };
64 
65 enum rkcif_interface_status {
66 	RKCIF_IF_INACTIVE,
67 	RKCIF_IF_ACTIVE,
68 };
69 
70 enum rkcif_interface_type {
71 	RKCIF_IF_INVALID,
72 	RKCIF_IF_DVP,
73 	RKCIF_IF_MIPI,
74 };
75 
76 enum rkcif_mipi_format_type {
77 	RKCIF_MIPI_TYPE_INVALID,
78 	RKCIF_MIPI_TYPE_RAW8,
79 	RKCIF_MIPI_TYPE_RAW10,
80 	RKCIF_MIPI_TYPE_RAW12,
81 	RKCIF_MIPI_TYPE_RGB888,
82 	RKCIF_MIPI_TYPE_YUV422SP,
83 	RKCIF_MIPI_TYPE_YUV420SP,
84 	RKCIF_MIPI_TYPE_YUV400,
85 };
86 
87 struct rkcif_buffer {
88 	struct vb2_v4l2_buffer vb;
89 	struct list_head queue;
90 	dma_addr_t buff_addr[VIDEO_MAX_PLANES];
91 	bool is_dummy;
92 };
93 
94 struct rkcif_dummy_buffer {
95 	struct rkcif_buffer buffer;
96 	void *vaddr;
97 	u32 size;
98 };
99 
100 enum rkcif_plane_index {
101 	RKCIF_PLANE_Y,
102 	RKCIF_PLANE_UV,
103 	RKCIF_PLANE_MAX
104 };
105 
106 struct rkcif_input_fmt {
107 	u32 mbus_code;
108 
109 	enum rkcif_format_type fmt_type;
110 	enum v4l2_field field;
111 
112 	union {
113 		u32 dvp_fmt_val;
114 	};
115 };
116 
117 struct rkcif_output_fmt {
118 	u32 fourcc;
119 	u32 mbus_code;
120 	u8 cplanes;
121 	u8 depth;
122 
123 	union {
124 		u32 dvp_fmt_val;
125 		struct {
126 			u8 dt;
127 			bool compact;
128 			enum rkcif_mipi_format_type type;
129 		} mipi;
130 	};
131 };
132 
133 struct rkcif_interface;
134 
135 struct rkcif_remote {
136 	struct v4l2_async_connection async_conn;
137 	struct v4l2_subdev *sd;
138 
139 	struct rkcif_interface *interface;
140 };
141 
142 struct rkcif_stream {
143 	enum rkcif_id_index id;
144 	struct rkcif_device *rkcif;
145 	struct rkcif_interface *interface;
146 	const struct rkcif_output_fmt *out_fmts;
147 	unsigned int out_fmts_num;
148 
149 	/* in ping-pong mode, two buffers can be provided to the HW */
150 	struct rkcif_buffer *buffers[2];
151 	int frame_idx;
152 	int frame_phase;
153 
154 	/* in case of no available buffer, HW can write to the dummy buffer */
155 	struct rkcif_dummy_buffer dummy;
156 
157 	bool stopping;
158 	wait_queue_head_t wq_stopped;
159 
160 	/* queue of available buffers plus spinlock that protects it */
161 	spinlock_t driver_queue_lock;
162 	struct list_head driver_queue;
163 
164 	/* lock used by the V4L2 core */
165 	struct mutex vlock;
166 
167 	struct media_pad pad;
168 	struct media_pipeline pipeline;
169 	struct v4l2_pix_format_mplane pix;
170 	struct vb2_queue buf_queue;
171 	struct video_device vdev;
172 
173 	void (*queue_buffer)(struct rkcif_stream *stream, unsigned int index);
174 	int (*start_streaming)(struct rkcif_stream *stream);
175 	void (*stop_streaming)(struct rkcif_stream *stream);
176 };
177 
178 struct rkcif_dvp {
179 	u32 dvp_clk_delay;
180 };
181 
182 struct rkcif_interface {
183 	enum rkcif_interface_type type;
184 	enum rkcif_interface_status status;
185 	enum rkcif_interface_index index;
186 	struct rkcif_device *rkcif;
187 	struct rkcif_remote *remote;
188 	struct rkcif_stream streams[RKCIF_ID_MAX];
189 	unsigned int streams_num;
190 	const struct rkcif_input_fmt *in_fmts;
191 	unsigned int in_fmts_num;
192 
193 	struct media_pad pads[RKCIF_IF_PAD_MAX];
194 	struct v4l2_fwnode_endpoint vep;
195 	struct v4l2_subdev sd;
196 
197 	union {
198 		struct rkcif_dvp dvp;
199 	};
200 
201 	void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top);
202 };
203 
204 struct rkcif_mipi_match_data {
205 	unsigned int mipi_num;
206 	unsigned int regs[RKCIF_MIPI_REGISTER_MAX];
207 	unsigned int regs_id[RKCIF_ID_MAX][RKCIF_MIPI_ID_REGISTER_MAX];
208 	u32 (*mipi_ctrl0)(struct rkcif_stream *stream,
209 			  const struct rkcif_output_fmt *active_out_fmt);
210 	struct {
211 		unsigned int offset;
212 	} blocks[RKCIF_MIPI_MAX - RKCIF_MIPI_BASE];
213 };
214 
215 struct rkcif_dvp_match_data {
216 	const struct rkcif_input_fmt *in_fmts;
217 	unsigned int in_fmts_num;
218 	const struct rkcif_output_fmt *out_fmts;
219 	unsigned int out_fmts_num;
220 	void (*setup)(struct rkcif_device *rkcif);
221 	bool has_scaler;
222 	bool has_ids;
223 	unsigned int regs[RKCIF_DVP_REGISTER_MAX];
224 };
225 
226 struct rkcif_match_data {
227 	const char *const *clks;
228 	unsigned int clks_num;
229 	const struct rkcif_dvp_match_data *dvp;
230 	const struct rkcif_mipi_match_data *mipi;
231 };
232 
233 struct rkcif_device {
234 	struct device *dev;
235 
236 	const struct rkcif_match_data *match_data;
237 	struct clk_bulk_data clks[RKCIF_CLK_MAX];
238 	unsigned int clks_num;
239 	struct regmap *grf;
240 	struct reset_control *reset;
241 	void __iomem *base_addr;
242 
243 	struct rkcif_interface interfaces[RKCIF_IF_MAX];
244 
245 	struct media_device media_dev;
246 	struct v4l2_device v4l2_dev;
247 	struct v4l2_async_notifier notifier;
248 };
249 
250 #endif
251