1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Driver for Renesas R-Car VIN
4  *
5  * Copyright (C) 2016 Renesas Electronics Corp.
6  * Copyright (C) 2011-2013 Renesas Solutions Corp.
7  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8  * Copyright (C) 2008 Magnus Damm
9  *
10  * Based on the soc-camera rcar_vin driver
11  */
12 
13 #ifndef __RCAR_VIN__
14 #define __RCAR_VIN__
15 
16 #include <linux/kref.h>
17 
18 #include <media/v4l2-async.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-dev.h>
21 #include <media/v4l2-device.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 8
32 
33 struct rvin_group;
34 
35 enum model_id {
36 	RCAR_H1,
37 	RCAR_M1,
38 	RCAR_GEN2,
39 	RCAR_GEN3,
40 };
41 
42 enum rvin_csi_id {
43 	RVIN_CSI20,
44 	RVIN_CSI21,
45 	RVIN_CSI40,
46 	RVIN_CSI41,
47 	RVIN_CSI_MAX,
48 };
49 
50 /**
51  * STOPPED  - No operation in progress
52  * STARTING - Capture starting up
53  * RUNNING  - Operation in progress have buffers
54  * STOPPING - Stopping operation
55  */
56 enum rvin_dma_state {
57 	STOPPED = 0,
58 	STARTING,
59 	RUNNING,
60 	STOPPING,
61 };
62 
63 /**
64  * struct rvin_video_format - Data format stored in memory
65  * @fourcc:	Pixelformat
66  * @bpp:	Bytes per pixel
67  */
68 struct rvin_video_format {
69 	u32 fourcc;
70 	u8 bpp;
71 };
72 
73 /**
74  * struct rvin_parallel_entity - Parallel video input endpoint descriptor
75  * @asd:	sub-device descriptor for async framework
76  * @subdev:	subdevice matched using async framework
77  * @mbus_type:	media bus type
78  * @mbus_flags:	media bus configuration flags
79  * @source_pad:	source pad of remote subdevice
80  * @sink_pad:	sink pad of remote subdevice
81  *
82  */
83 struct rvin_parallel_entity {
84 	struct v4l2_async_subdev asd;
85 	struct v4l2_subdev *subdev;
86 
87 	enum v4l2_mbus_type mbus_type;
88 	unsigned int mbus_flags;
89 
90 	unsigned int source_pad;
91 	unsigned int sink_pad;
92 };
93 
94 /**
95  * struct rvin_group_route - describes a route from a channel of a
96  *	CSI-2 receiver to a VIN
97  *
98  * @csi:	CSI-2 receiver ID.
99  * @channel:	Output channel of the CSI-2 receiver.
100  * @vin:	VIN ID.
101  * @mask:	Bitmask of the different CHSEL register values that
102  *		allow for a route from @csi + @chan to @vin.
103  *
104  * .. note::
105  *	Each R-Car CSI-2 receiver has four output channels facing the VIN
106  *	devices, each channel can carry one CSI-2 Virtual Channel (VC).
107  *	There is no correlation between channel number and CSI-2 VC. It's
108  *	up to the CSI-2 receiver driver to configure which VC is output
109  *	on which channel, the VIN devices only care about output channels.
110  *
111  *	There are in some cases multiple CHSEL register settings which would
112  *	allow for the same route from @csi + @channel to @vin. For example
113  *	on R-Car H3 both the CHSEL values 0 and 3 allow for a route from
114  *	CSI40/VC0 to VIN0. All possible CHSEL values for a route need to be
115  *	recorded as a bitmask in @mask, in this example bit 0 and 3 should
116  *	be set.
117  */
118 struct rvin_group_route {
119 	enum rvin_csi_id csi;
120 	unsigned int channel;
121 	unsigned int vin;
122 	unsigned int mask;
123 };
124 
125 /**
126  * struct rvin_info - Information about the particular VIN implementation
127  * @model:		VIN model
128  * @use_mc:		use media controller instead of controlling subdevice
129  * @max_width:		max input width the VIN supports
130  * @max_height:		max input height the VIN supports
131  * @routes:		list of possible routes from the CSI-2 recivers to
132  *			all VINs. The list mush be NULL terminated.
133  */
134 struct rvin_info {
135 	enum model_id model;
136 	bool use_mc;
137 
138 	unsigned int max_width;
139 	unsigned int max_height;
140 	const struct rvin_group_route *routes;
141 };
142 
143 /**
144  * struct rvin_dev - Renesas VIN device structure
145  * @dev:		(OF) device
146  * @base:		device I/O register space remapped to virtual memory
147  * @info:		info about VIN instance
148  *
149  * @vdev:		V4L2 video device associated with VIN
150  * @v4l2_dev:		V4L2 device
151  * @ctrl_handler:	V4L2 control handler
152  * @notifier:		V4L2 asynchronous subdevs notifier
153  *
154  * @parallel:		parallel input subdevice descriptor
155  *
156  * @group:		Gen3 CSI group
157  * @id:			Gen3 group id for this VIN
158  * @pad:		media pad for the video device entity
159  *
160  * @lock:		protects @queue
161  * @queue:		vb2 buffers queue
162  * @scratch:		cpu address for scratch buffer
163  * @scratch_phys:	physical address of the scratch buffer
164  *
165  * @qlock:		protects @queue_buf, @buf_list, @sequence
166  *			@state
167  * @queue_buf:		Keeps track of buffers given to HW slot
168  * @buf_list:		list of queued buffers
169  * @sequence:		V4L2 buffers sequence number
170  * @state:		keeps track of operation state
171  *
172  * @is_csi:		flag to mark the VIN as using a CSI-2 subdevice
173  *
174  * @mbus_code:		media bus format code
175  * @format:		active V4L2 pixel format
176  *
177  * @crop:		active cropping
178  * @compose:		active composing
179  * @source:		active size of the video source
180  * @std:		active video standard of the video source
181  */
182 struct rvin_dev {
183 	struct device *dev;
184 	void __iomem *base;
185 	const struct rvin_info *info;
186 
187 	struct video_device vdev;
188 	struct v4l2_device v4l2_dev;
189 	struct v4l2_ctrl_handler ctrl_handler;
190 	struct v4l2_async_notifier notifier;
191 
192 	struct rvin_parallel_entity *parallel;
193 
194 	struct rvin_group *group;
195 	unsigned int id;
196 	struct media_pad pad;
197 
198 	struct mutex lock;
199 	struct vb2_queue queue;
200 	void *scratch;
201 	dma_addr_t scratch_phys;
202 
203 	spinlock_t qlock;
204 	struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];
205 	struct list_head buf_list;
206 	unsigned int sequence;
207 	enum rvin_dma_state state;
208 
209 	bool is_csi;
210 
211 	u32 mbus_code;
212 	struct v4l2_pix_format format;
213 
214 	struct v4l2_rect crop;
215 	struct v4l2_rect compose;
216 	struct v4l2_rect source;
217 	v4l2_std_id std;
218 };
219 
220 #define vin_to_source(vin)		((vin)->parallel->subdev)
221 
222 /* Debug */
223 #define vin_dbg(d, fmt, arg...)		dev_dbg(d->dev, fmt, ##arg)
224 #define vin_info(d, fmt, arg...)	dev_info(d->dev, fmt, ##arg)
225 #define vin_warn(d, fmt, arg...)	dev_warn(d->dev, fmt, ##arg)
226 #define vin_err(d, fmt, arg...)		dev_err(d->dev, fmt, ##arg)
227 
228 /**
229  * struct rvin_group - VIN CSI2 group information
230  * @refcount:		number of VIN instances using the group
231  *
232  * @mdev:		media device which represents the group
233  *
234  * @lock:		protects the count, notifier, vin and csi members
235  * @count:		number of enabled VIN instances found in DT
236  * @notifier:		group notifier for CSI-2 async subdevices
237  * @vin:		VIN instances which are part of the group
238  * @csi:		array of pairs of fwnode and subdev pointers
239  *			to all CSI-2 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 	struct rvin_dev *vin[RCAR_VIN_NUM];
250 
251 	struct {
252 		struct fwnode_handle *fwnode;
253 		struct v4l2_subdev *subdev;
254 	} csi[RVIN_CSI_MAX];
255 };
256 
257 int rvin_dma_register(struct rvin_dev *vin, int irq);
258 void rvin_dma_unregister(struct rvin_dev *vin);
259 
260 int rvin_v4l2_register(struct rvin_dev *vin);
261 void rvin_v4l2_unregister(struct rvin_dev *vin);
262 
263 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
264 
265 /* Cropping, composing and scaling */
266 void rvin_crop_scale_comp(struct rvin_dev *vin);
267 
268 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
269 
270 #endif
271