xref: /linux/drivers/media/platform/renesas/rcar-vin/rcar-vin.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Driver for Renesas R-Car VIN
4  *
5  * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
6  * Copyright (C) 2016 Renesas Electronics Corp.
7  * Copyright (C) 2011-2013 Renesas Solutions Corp.
8  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
9  * Copyright (C) 2008 Magnus Damm
10  */
11 
12 #ifndef __RCAR_VIN__
13 #define __RCAR_VIN__
14 
15 #include <linux/kref.h>
16 
17 #include <media/v4l2-async.h>
18 #include <media/v4l2-ctrls.h>
19 #include <media/v4l2-dev.h>
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-fwnode.h>
22 #include <media/videobuf2-v4l2.h>
23 
24 /* Number of HW buffers */
25 #define HW_BUFFER_NUM 3
26 
27 /* Address alignment mask for HW buffers */
28 #define HW_BUFFER_MASK 0x7f
29 
30 /* Max number on VIN instances that can be in a system */
31 #define RCAR_VIN_NUM 32
32 
33 struct rvin_dev;
34 struct rvin_group;
35 
36 enum model_id {
37 	RCAR_H1,
38 	RCAR_M1,
39 	RCAR_GEN2,
40 	RCAR_GEN3,
41 	RCAR_GEN4,
42 };
43 
44 enum rvin_csi_id {
45 	RVIN_CSI20,
46 	RVIN_CSI21,
47 	RVIN_CSI40,
48 	RVIN_CSI41,
49 	RVIN_CSI_MAX,
50 };
51 
52 enum rvin_isp_id {
53 	RVIN_ISP0,
54 	RVIN_ISP1,
55 	RVIN_ISP2,
56 	RVIN_ISP4,
57 	RVIN_ISP_MAX,
58 };
59 
60 #define RVIN_REMOTES_MAX \
61 	(((unsigned int)RVIN_CSI_MAX) > ((unsigned int)RVIN_ISP_MAX) ? \
62 	 (unsigned int)RVIN_CSI_MAX : (unsigned int)RVIN_ISP_MAX)
63 
64 /**
65  * struct rvin_video_format - Data format stored in memory
66  * @fourcc:	Pixelformat
67  * @bpp:	Bytes per pixel
68  */
69 struct rvin_video_format {
70 	u32 fourcc;
71 	u8 bpp;
72 };
73 
74 /**
75  * struct rvin_parallel_entity - Parallel video input endpoint descriptor
76  * @asc:	async connection descriptor for async framework
77  * @subdev:	subdevice matched using async framework
78  * @mbus_type:	media bus type
79  * @bus:	media bus parallel configuration
80  * @source_pad:	source pad of remote subdevice
81  */
82 struct rvin_parallel_entity {
83 	struct v4l2_async_connection *asc;
84 	struct v4l2_subdev *subdev;
85 
86 	enum v4l2_mbus_type mbus_type;
87 	struct v4l2_mbus_config_parallel bus;
88 
89 	unsigned int source_pad;
90 };
91 
92 /**
93  * struct rvin_group_route - describes a route from a channel of a
94  *	CSI-2 receiver to a VIN
95  *
96  * @master:	VIN group master ID.
97  * @csi:	CSI-2 receiver ID.
98  * @chsel:	CHSEL register values that connects VIN group to CSI-2.
99  *
100  * .. note::
101  *	Each R-Car CSI-2 receiver has four output channels facing the VIN
102  *	devices, each channel can carry one CSI-2 Virtual Channel (VC).
103  *	There is no correlation between channel number and CSI-2 VC. It's
104  *	up to the CSI-2 receiver driver to configure which VC is output
105  *	on which channel, the VIN devices only care about output channels.
106  */
107 struct rvin_group_route {
108 	unsigned int master;
109 	enum rvin_csi_id csi;
110 	unsigned int chsel;
111 };
112 
113 /**
114  * struct rvin_info - Information about the particular VIN implementation
115  * @model:		VIN model
116  * @use_isp:		the VIN is connected to the ISP and not to the CSI-2
117  * @nv12:		support outputting NV12 pixel format
118  * @raw10:		support outputting RAW10 pixel format
119  * @max_width:		max input width the VIN supports
120  * @max_height:		max input height the VIN supports
121  * @routes:		list of possible routes from the CSI-2 recivers to
122  *			all VINs. The list mush be NULL terminated.
123  * @scaler:		Optional scaler
124  */
125 struct rvin_info {
126 	enum model_id model;
127 	bool use_isp;
128 	bool nv12;
129 	bool raw10;
130 
131 	unsigned int max_width;
132 	unsigned int max_height;
133 	const struct rvin_group_route *routes;
134 	void (*scaler)(struct rvin_dev *vin);
135 };
136 
137 /**
138  * struct rvin_dev - Renesas VIN device structure
139  * @dev:		(OF) device
140  * @base:		device I/O register space remapped to virtual memory
141  * @info:		info about VIN instance
142  *
143  * @vdev:		V4L2 video device associated with VIN
144  * @v4l2_dev:		V4L2 device
145  * @ctrl_handler:	V4L2 control handler
146  *
147  * @parallel:		parallel input subdevice descriptor
148  *
149  * @group:		Gen3 CSI group
150  * @id:			Gen3 group id for this VIN
151  * @pad:		media pad for the video device entity
152  *
153  * @lock:		protects @queue
154  * @queue:		vb2 buffers queue
155  * @scratch:		cpu address for scratch buffer
156  * @scratch_phys:	physical address of the scratch buffer
157  *
158  * @qlock:		Protects @buf_hw, @buf_list, @sequence and @running
159  * @buf_hw:		Keeps track of buffers given to HW slot
160  * @buf_list:		list of queued buffers
161  * @sequence:		V4L2 buffers sequence number
162  * @running:		Keeps track of if the VIN is running
163  *
164  * @is_csi:		flag to mark the VIN as using a CSI-2 subdevice
165  * @chsel:		Cached value of the current CSI-2 channel selection
166  *
167  * @mbus_code:		media bus format code
168  * @format:		active V4L2 pixel format
169  *
170  * @crop:		active cropping
171  * @compose:		active composing
172  * @scaler:		Optional scaler
173  *
174  * @alpha:		Alpha component to fill in for supported pixel formats
175  */
176 struct rvin_dev {
177 	struct device *dev;
178 	void __iomem *base;
179 	const struct rvin_info *info;
180 
181 	struct video_device vdev;
182 	struct v4l2_device v4l2_dev;
183 	struct v4l2_ctrl_handler ctrl_handler;
184 
185 	struct rvin_parallel_entity parallel;
186 
187 	struct rvin_group *group;
188 	unsigned int id;
189 	struct media_pad pad;
190 
191 	struct mutex lock;
192 	struct vb2_queue queue;
193 	void *scratch;
194 	dma_addr_t scratch_phys;
195 
196 	spinlock_t qlock;
197 	struct {
198 		struct vb2_v4l2_buffer *buffer;
199 		dma_addr_t phys;
200 	} buf_hw[HW_BUFFER_NUM];
201 	struct list_head buf_list;
202 	unsigned int sequence;
203 	bool running;
204 
205 	bool is_csi;
206 	unsigned int chsel;
207 
208 	u32 mbus_code;
209 	struct v4l2_pix_format format;
210 
211 	struct v4l2_rect crop;
212 	struct v4l2_rect compose;
213 	void (*scaler)(struct rvin_dev *vin);
214 
215 	unsigned int alpha;
216 };
217 
218 #define vin_to_source(vin)		((vin)->parallel.subdev)
219 
220 /* Debug */
221 #define vin_dbg(d, fmt, arg...)		dev_dbg(d->dev, fmt, ##arg)
222 #define vin_info(d, fmt, arg...)	dev_info(d->dev, fmt, ##arg)
223 #define vin_warn(d, fmt, arg...)	dev_warn(d->dev, fmt, ##arg)
224 #define vin_err(d, fmt, arg...)		dev_err(d->dev, fmt, ##arg)
225 
226 /**
227  * struct rvin_group - VIN CSI2 group information
228  * @refcount:		number of VIN instances using the group
229  *
230  * @mdev:		media device which represents the group
231  *
232  * @lock:		protects the count, notifier, vin and csi members
233  * @count:		number of enabled VIN instances found in DT
234  * @notifier:		group notifier for CSI-2 async connections
235  * @info:		Platform dependent information about the VIN instances
236  * @vin:		VIN instances which are part of the group
237  * @link_setup:		Callback to create all links for the media graph
238  * @remotes:		array of pairs of async connection and subdev pointers
239  *			to all remote subdevices.
240  */
241 struct rvin_group {
242 	struct kref refcount;
243 
244 	struct media_device mdev;
245 
246 	struct mutex lock;
247 	unsigned int count;
248 	struct v4l2_async_notifier notifier;
249 	const struct rvin_info *info;
250 	struct rvin_dev *vin[RCAR_VIN_NUM];
251 
252 	int (*link_setup)(struct rvin_group *group);
253 
254 	struct {
255 		struct v4l2_async_connection *asc;
256 		struct v4l2_subdev *subdev;
257 	} remotes[RVIN_REMOTES_MAX];
258 };
259 
260 int rvin_dma_register(struct rvin_dev *vin, int irq);
261 void rvin_dma_unregister(struct rvin_dev *vin);
262 
263 int rvin_v4l2_register(struct rvin_dev *vin);
264 void rvin_v4l2_unregister(struct rvin_dev *vin);
265 
266 const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
267 						       u32 pixelformat);
268 
269 
270 /* Cropping, composing and scaling */
271 void rvin_scaler_gen2(struct rvin_dev *vin);
272 void rvin_scaler_gen3(struct rvin_dev *vin);
273 void rvin_crop_scale_comp(struct rvin_dev *vin);
274 
275 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
276 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha);
277 
278 int rvin_start_streaming(struct rvin_dev *vin);
279 void rvin_stop_streaming(struct rvin_dev *vin);
280 
281 #endif
282