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  * @alpha:		Alpha component to fill in for supported pixel formats
183  */
184 struct rvin_dev {
185 	struct device *dev;
186 	void __iomem *base;
187 	const struct rvin_info *info;
188 
189 	struct video_device vdev;
190 	struct v4l2_device v4l2_dev;
191 	struct v4l2_ctrl_handler ctrl_handler;
192 	struct v4l2_async_notifier notifier;
193 
194 	struct rvin_parallel_entity *parallel;
195 
196 	struct rvin_group *group;
197 	unsigned int id;
198 	struct media_pad pad;
199 
200 	struct mutex lock;
201 	struct vb2_queue queue;
202 	void *scratch;
203 	dma_addr_t scratch_phys;
204 
205 	spinlock_t qlock;
206 	struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];
207 	struct list_head buf_list;
208 	unsigned int sequence;
209 	enum rvin_dma_state state;
210 
211 	bool is_csi;
212 
213 	u32 mbus_code;
214 	struct v4l2_pix_format format;
215 
216 	struct v4l2_rect crop;
217 	struct v4l2_rect compose;
218 	struct v4l2_rect source;
219 	v4l2_std_id std;
220 
221 	unsigned int alpha;
222 };
223 
224 #define vin_to_source(vin)		((vin)->parallel->subdev)
225 
226 /* Debug */
227 #define vin_dbg(d, fmt, arg...)		dev_dbg(d->dev, fmt, ##arg)
228 #define vin_info(d, fmt, arg...)	dev_info(d->dev, fmt, ##arg)
229 #define vin_warn(d, fmt, arg...)	dev_warn(d->dev, fmt, ##arg)
230 #define vin_err(d, fmt, arg...)		dev_err(d->dev, fmt, ##arg)
231 
232 /**
233  * struct rvin_group - VIN CSI2 group information
234  * @refcount:		number of VIN instances using the group
235  *
236  * @mdev:		media device which represents the group
237  *
238  * @lock:		protects the count, notifier, vin and csi members
239  * @count:		number of enabled VIN instances found in DT
240  * @notifier:		group notifier for CSI-2 async subdevices
241  * @vin:		VIN instances which are part of the group
242  * @csi:		array of pairs of fwnode and subdev pointers
243  *			to all CSI-2 subdevices.
244  */
245 struct rvin_group {
246 	struct kref refcount;
247 
248 	struct media_device mdev;
249 
250 	struct mutex lock;
251 	unsigned int count;
252 	struct v4l2_async_notifier notifier;
253 	struct rvin_dev *vin[RCAR_VIN_NUM];
254 
255 	struct {
256 		struct fwnode_handle *fwnode;
257 		struct v4l2_subdev *subdev;
258 	} csi[RVIN_CSI_MAX];
259 };
260 
261 int rvin_dma_register(struct rvin_dev *vin, int irq);
262 void rvin_dma_unregister(struct rvin_dev *vin);
263 
264 int rvin_v4l2_register(struct rvin_dev *vin);
265 void rvin_v4l2_unregister(struct rvin_dev *vin);
266 
267 const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
268 						       u32 pixelformat);
269 
270 
271 /* Cropping, composing and scaling */
272 void rvin_crop_scale_comp(struct rvin_dev *vin);
273 
274 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
275 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha);
276 
277 #endif
278