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/v4l2-fwnode.h>
23#include <media/videobuf2-v4l2.h>
24
25/* Number of HW buffers */
26#define HW_BUFFER_NUM 3
27
28/* Address alignment mask for HW buffers */
29#define HW_BUFFER_MASK 0x7f
30
31/* Max number on VIN instances that can be in a system */
32#define RCAR_VIN_NUM 8
33
34struct rvin_group;
35
36enum model_id {
37	RCAR_H1,
38	RCAR_M1,
39	RCAR_GEN2,
40	RCAR_GEN3,
41};
42
43enum rvin_csi_id {
44	RVIN_CSI20,
45	RVIN_CSI21,
46	RVIN_CSI40,
47	RVIN_CSI41,
48	RVIN_CSI_MAX,
49};
50
51/**
52 * STOPPED  - No operation in progress
53 * STARTING - Capture starting up
54 * RUNNING  - Operation in progress have buffers
55 * STOPPING - Stopping operation
56 */
57enum rvin_dma_state {
58	STOPPED = 0,
59	STARTING,
60	RUNNING,
61	STOPPING,
62};
63
64/**
65 * enum rvin_buffer_type
66 *
67 * Describes how a buffer is given to the hardware. To be able
68 * to capture SEQ_TB/BT it's needed to capture to the same vb2
69 * buffer twice so the type of buffer needs to be kept.
70 *
71 * FULL - One capture fills the whole vb2 buffer
72 * HALF_TOP - One capture fills the top half of the vb2 buffer
73 * HALF_BOTTOM - One capture fills the bottom half of the vb2 buffer
74 */
75enum rvin_buffer_type {
76	FULL,
77	HALF_TOP,
78	HALF_BOTTOM,
79};
80
81/**
82 * struct rvin_video_format - Data format stored in memory
83 * @fourcc:	Pixelformat
84 * @bpp:	Bytes per pixel
85 */
86struct rvin_video_format {
87	u32 fourcc;
88	u8 bpp;
89};
90
91/**
92 * struct rvin_parallel_entity - Parallel video input endpoint descriptor
93 * @asd:	sub-device descriptor for async framework
94 * @subdev:	subdevice matched using async framework
95 * @mbus_type:	media bus type
96 * @bus:	media bus parallel configuration
97 * @source_pad:	source pad of remote subdevice
98 * @sink_pad:	sink pad of remote subdevice
99 *
100 */
101struct rvin_parallel_entity {
102	struct v4l2_async_subdev asd;
103	struct v4l2_subdev *subdev;
104
105	enum v4l2_mbus_type mbus_type;
106	struct v4l2_fwnode_bus_parallel bus;
107
108	unsigned int source_pad;
109	unsigned int sink_pad;
110};
111
112/**
113 * struct rvin_group_route - describes a route from a channel of a
114 *	CSI-2 receiver to a VIN
115 *
116 * @csi:	CSI-2 receiver ID.
117 * @channel:	Output channel of the CSI-2 receiver.
118 * @vin:	VIN ID.
119 * @mask:	Bitmask of the different CHSEL register values that
120 *		allow for a route from @csi + @chan to @vin.
121 *
122 * .. note::
123 *	Each R-Car CSI-2 receiver has four output channels facing the VIN
124 *	devices, each channel can carry one CSI-2 Virtual Channel (VC).
125 *	There is no correlation between channel number and CSI-2 VC. It's
126 *	up to the CSI-2 receiver driver to configure which VC is output
127 *	on which channel, the VIN devices only care about output channels.
128 *
129 *	There are in some cases multiple CHSEL register settings which would
130 *	allow for the same route from @csi + @channel to @vin. For example
131 *	on R-Car H3 both the CHSEL values 0 and 3 allow for a route from
132 *	CSI40/VC0 to VIN0. All possible CHSEL values for a route need to be
133 *	recorded as a bitmask in @mask, in this example bit 0 and 3 should
134 *	be set.
135 */
136struct rvin_group_route {
137	enum rvin_csi_id csi;
138	unsigned int channel;
139	unsigned int vin;
140	unsigned int mask;
141};
142
143/**
144 * struct rvin_info - Information about the particular VIN implementation
145 * @model:		VIN model
146 * @use_mc:		use media controller instead of controlling subdevice
147 * @nv12:		support outputing NV12 pixel format
148 * @max_width:		max input width the VIN supports
149 * @max_height:		max input height the VIN supports
150 * @routes:		list of possible routes from the CSI-2 recivers to
151 *			all VINs. The list mush be NULL terminated.
152 */
153struct rvin_info {
154	enum model_id model;
155	bool use_mc;
156	bool nv12;
157
158	unsigned int max_width;
159	unsigned int max_height;
160	const struct rvin_group_route *routes;
161};
162
163/**
164 * struct rvin_dev - Renesas VIN device structure
165 * @dev:		(OF) device
166 * @base:		device I/O register space remapped to virtual memory
167 * @info:		info about VIN instance
168 *
169 * @vdev:		V4L2 video device associated with VIN
170 * @v4l2_dev:		V4L2 device
171 * @ctrl_handler:	V4L2 control handler
172 * @notifier:		V4L2 asynchronous subdevs notifier
173 *
174 * @parallel:		parallel input subdevice descriptor
175 *
176 * @group:		Gen3 CSI group
177 * @id:			Gen3 group id for this VIN
178 * @pad:		media pad for the video device entity
179 *
180 * @lock:		protects @queue
181 * @queue:		vb2 buffers queue
182 * @scratch:		cpu address for scratch buffer
183 * @scratch_phys:	physical address of the scratch buffer
184 *
185 * @qlock:		protects @buf_hw, @buf_list, @sequence and @state
186 * @buf_hw:		Keeps track of buffers given to HW slot
187 * @buf_list:		list of queued buffers
188 * @sequence:		V4L2 buffers sequence number
189 * @state:		keeps track of operation state
190 *
191 * @is_csi:		flag to mark the VIN as using a CSI-2 subdevice
192 *
193 * @mbus_code:		media bus format code
194 * @format:		active V4L2 pixel format
195 *
196 * @crop:		active cropping
197 * @compose:		active composing
198 * @src_rect:		active size of the video source
199 * @std:		active video standard of the video source
200 *
201 * @alpha:		Alpha component to fill in for supported pixel formats
202 */
203struct rvin_dev {
204	struct device *dev;
205	void __iomem *base;
206	const struct rvin_info *info;
207
208	struct video_device vdev;
209	struct v4l2_device v4l2_dev;
210	struct v4l2_ctrl_handler ctrl_handler;
211	struct v4l2_async_notifier notifier;
212
213	struct rvin_parallel_entity *parallel;
214
215	struct rvin_group *group;
216	unsigned int id;
217	struct media_pad pad;
218
219	struct mutex lock;
220	struct vb2_queue queue;
221	void *scratch;
222	dma_addr_t scratch_phys;
223
224	spinlock_t qlock;
225	struct {
226		struct vb2_v4l2_buffer *buffer;
227		enum rvin_buffer_type type;
228		dma_addr_t phys;
229	} buf_hw[HW_BUFFER_NUM];
230	struct list_head buf_list;
231	unsigned int sequence;
232	enum rvin_dma_state state;
233
234	bool is_csi;
235
236	u32 mbus_code;
237	struct v4l2_pix_format format;
238
239	struct v4l2_rect crop;
240	struct v4l2_rect compose;
241	struct v4l2_rect src_rect;
242	v4l2_std_id std;
243
244	unsigned int alpha;
245};
246
247#define vin_to_source(vin)		((vin)->parallel->subdev)
248
249/* Debug */
250#define vin_dbg(d, fmt, arg...)		dev_dbg(d->dev, fmt, ##arg)
251#define vin_info(d, fmt, arg...)	dev_info(d->dev, fmt, ##arg)
252#define vin_warn(d, fmt, arg...)	dev_warn(d->dev, fmt, ##arg)
253#define vin_err(d, fmt, arg...)		dev_err(d->dev, fmt, ##arg)
254
255/**
256 * struct rvin_group - VIN CSI2 group information
257 * @refcount:		number of VIN instances using the group
258 *
259 * @mdev:		media device which represents the group
260 *
261 * @lock:		protects the count, notifier, vin and csi members
262 * @count:		number of enabled VIN instances found in DT
263 * @notifier:		group notifier for CSI-2 async subdevices
264 * @vin:		VIN instances which are part of the group
265 * @csi:		array of pairs of fwnode and subdev pointers
266 *			to all CSI-2 subdevices.
267 */
268struct rvin_group {
269	struct kref refcount;
270
271	struct media_device mdev;
272
273	struct mutex lock;
274	unsigned int count;
275	struct v4l2_async_notifier notifier;
276	struct rvin_dev *vin[RCAR_VIN_NUM];
277
278	struct {
279		struct fwnode_handle *fwnode;
280		struct v4l2_subdev *subdev;
281	} csi[RVIN_CSI_MAX];
282};
283
284int rvin_dma_register(struct rvin_dev *vin, int irq);
285void rvin_dma_unregister(struct rvin_dev *vin);
286
287int rvin_v4l2_register(struct rvin_dev *vin);
288void rvin_v4l2_unregister(struct rvin_dev *vin);
289
290const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
291						       u32 pixelformat);
292
293
294/* Cropping, composing and scaling */
295void rvin_crop_scale_comp(struct rvin_dev *vin);
296
297int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
298void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha);
299
300#endif
301