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