18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Driver for Renesas R-Car VIN 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2016 Renesas Electronics Corp. 68c2ecf20Sopenharmony_ci * Copyright (C) 2011-2013 Renesas Solutions Corp. 78c2ecf20Sopenharmony_ci * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com> 88c2ecf20Sopenharmony_ci * Copyright (C) 2008 Magnus Damm 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Based on the soc-camera rcar_vin driver 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef __RCAR_VIN__ 148c2ecf20Sopenharmony_ci#define __RCAR_VIN__ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include <linux/kref.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <media/v4l2-async.h> 198c2ecf20Sopenharmony_ci#include <media/v4l2-ctrls.h> 208c2ecf20Sopenharmony_ci#include <media/v4l2-dev.h> 218c2ecf20Sopenharmony_ci#include <media/v4l2-device.h> 228c2ecf20Sopenharmony_ci#include <media/v4l2-fwnode.h> 238c2ecf20Sopenharmony_ci#include <media/videobuf2-v4l2.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/* Number of HW buffers */ 268c2ecf20Sopenharmony_ci#define HW_BUFFER_NUM 3 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* Address alignment mask for HW buffers */ 298c2ecf20Sopenharmony_ci#define HW_BUFFER_MASK 0x7f 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* Max number on VIN instances that can be in a system */ 328c2ecf20Sopenharmony_ci#define RCAR_VIN_NUM 8 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistruct rvin_group; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cienum model_id { 378c2ecf20Sopenharmony_ci RCAR_H1, 388c2ecf20Sopenharmony_ci RCAR_M1, 398c2ecf20Sopenharmony_ci RCAR_GEN2, 408c2ecf20Sopenharmony_ci RCAR_GEN3, 418c2ecf20Sopenharmony_ci}; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cienum rvin_csi_id { 448c2ecf20Sopenharmony_ci RVIN_CSI20, 458c2ecf20Sopenharmony_ci RVIN_CSI21, 468c2ecf20Sopenharmony_ci RVIN_CSI40, 478c2ecf20Sopenharmony_ci RVIN_CSI41, 488c2ecf20Sopenharmony_ci RVIN_CSI_MAX, 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/** 528c2ecf20Sopenharmony_ci * STOPPED - No operation in progress 538c2ecf20Sopenharmony_ci * STARTING - Capture starting up 548c2ecf20Sopenharmony_ci * RUNNING - Operation in progress have buffers 558c2ecf20Sopenharmony_ci * STOPPING - Stopping operation 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_cienum rvin_dma_state { 588c2ecf20Sopenharmony_ci STOPPED = 0, 598c2ecf20Sopenharmony_ci STARTING, 608c2ecf20Sopenharmony_ci RUNNING, 618c2ecf20Sopenharmony_ci STOPPING, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/** 658c2ecf20Sopenharmony_ci * enum rvin_buffer_type 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * Describes how a buffer is given to the hardware. To be able 688c2ecf20Sopenharmony_ci * to capture SEQ_TB/BT it's needed to capture to the same vb2 698c2ecf20Sopenharmony_ci * buffer twice so the type of buffer needs to be kept. 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * FULL - One capture fills the whole vb2 buffer 728c2ecf20Sopenharmony_ci * HALF_TOP - One capture fills the top half of the vb2 buffer 738c2ecf20Sopenharmony_ci * HALF_BOTTOM - One capture fills the bottom half of the vb2 buffer 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_cienum rvin_buffer_type { 768c2ecf20Sopenharmony_ci FULL, 778c2ecf20Sopenharmony_ci HALF_TOP, 788c2ecf20Sopenharmony_ci HALF_BOTTOM, 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/** 828c2ecf20Sopenharmony_ci * struct rvin_video_format - Data format stored in memory 838c2ecf20Sopenharmony_ci * @fourcc: Pixelformat 848c2ecf20Sopenharmony_ci * @bpp: Bytes per pixel 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_cistruct rvin_video_format { 878c2ecf20Sopenharmony_ci u32 fourcc; 888c2ecf20Sopenharmony_ci u8 bpp; 898c2ecf20Sopenharmony_ci}; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/** 928c2ecf20Sopenharmony_ci * struct rvin_parallel_entity - Parallel video input endpoint descriptor 938c2ecf20Sopenharmony_ci * @asd: sub-device descriptor for async framework 948c2ecf20Sopenharmony_ci * @subdev: subdevice matched using async framework 958c2ecf20Sopenharmony_ci * @mbus_type: media bus type 968c2ecf20Sopenharmony_ci * @bus: media bus parallel configuration 978c2ecf20Sopenharmony_ci * @source_pad: source pad of remote subdevice 988c2ecf20Sopenharmony_ci * @sink_pad: sink pad of remote subdevice 998c2ecf20Sopenharmony_ci * 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_cistruct rvin_parallel_entity { 1028c2ecf20Sopenharmony_ci struct v4l2_async_subdev asd; 1038c2ecf20Sopenharmony_ci struct v4l2_subdev *subdev; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci enum v4l2_mbus_type mbus_type; 1068c2ecf20Sopenharmony_ci struct v4l2_fwnode_bus_parallel bus; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci unsigned int source_pad; 1098c2ecf20Sopenharmony_ci unsigned int sink_pad; 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/** 1138c2ecf20Sopenharmony_ci * struct rvin_group_route - describes a route from a channel of a 1148c2ecf20Sopenharmony_ci * CSI-2 receiver to a VIN 1158c2ecf20Sopenharmony_ci * 1168c2ecf20Sopenharmony_ci * @csi: CSI-2 receiver ID. 1178c2ecf20Sopenharmony_ci * @channel: Output channel of the CSI-2 receiver. 1188c2ecf20Sopenharmony_ci * @vin: VIN ID. 1198c2ecf20Sopenharmony_ci * @mask: Bitmask of the different CHSEL register values that 1208c2ecf20Sopenharmony_ci * allow for a route from @csi + @chan to @vin. 1218c2ecf20Sopenharmony_ci * 1228c2ecf20Sopenharmony_ci * .. note:: 1238c2ecf20Sopenharmony_ci * Each R-Car CSI-2 receiver has four output channels facing the VIN 1248c2ecf20Sopenharmony_ci * devices, each channel can carry one CSI-2 Virtual Channel (VC). 1258c2ecf20Sopenharmony_ci * There is no correlation between channel number and CSI-2 VC. It's 1268c2ecf20Sopenharmony_ci * up to the CSI-2 receiver driver to configure which VC is output 1278c2ecf20Sopenharmony_ci * on which channel, the VIN devices only care about output channels. 1288c2ecf20Sopenharmony_ci * 1298c2ecf20Sopenharmony_ci * There are in some cases multiple CHSEL register settings which would 1308c2ecf20Sopenharmony_ci * allow for the same route from @csi + @channel to @vin. For example 1318c2ecf20Sopenharmony_ci * on R-Car H3 both the CHSEL values 0 and 3 allow for a route from 1328c2ecf20Sopenharmony_ci * CSI40/VC0 to VIN0. All possible CHSEL values for a route need to be 1338c2ecf20Sopenharmony_ci * recorded as a bitmask in @mask, in this example bit 0 and 3 should 1348c2ecf20Sopenharmony_ci * be set. 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_cistruct rvin_group_route { 1378c2ecf20Sopenharmony_ci enum rvin_csi_id csi; 1388c2ecf20Sopenharmony_ci unsigned int channel; 1398c2ecf20Sopenharmony_ci unsigned int vin; 1408c2ecf20Sopenharmony_ci unsigned int mask; 1418c2ecf20Sopenharmony_ci}; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/** 1448c2ecf20Sopenharmony_ci * struct rvin_info - Information about the particular VIN implementation 1458c2ecf20Sopenharmony_ci * @model: VIN model 1468c2ecf20Sopenharmony_ci * @use_mc: use media controller instead of controlling subdevice 1478c2ecf20Sopenharmony_ci * @nv12: support outputing NV12 pixel format 1488c2ecf20Sopenharmony_ci * @max_width: max input width the VIN supports 1498c2ecf20Sopenharmony_ci * @max_height: max input height the VIN supports 1508c2ecf20Sopenharmony_ci * @routes: list of possible routes from the CSI-2 recivers to 1518c2ecf20Sopenharmony_ci * all VINs. The list mush be NULL terminated. 1528c2ecf20Sopenharmony_ci */ 1538c2ecf20Sopenharmony_cistruct rvin_info { 1548c2ecf20Sopenharmony_ci enum model_id model; 1558c2ecf20Sopenharmony_ci bool use_mc; 1568c2ecf20Sopenharmony_ci bool nv12; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci unsigned int max_width; 1598c2ecf20Sopenharmony_ci unsigned int max_height; 1608c2ecf20Sopenharmony_ci const struct rvin_group_route *routes; 1618c2ecf20Sopenharmony_ci}; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci/** 1648c2ecf20Sopenharmony_ci * struct rvin_dev - Renesas VIN device structure 1658c2ecf20Sopenharmony_ci * @dev: (OF) device 1668c2ecf20Sopenharmony_ci * @base: device I/O register space remapped to virtual memory 1678c2ecf20Sopenharmony_ci * @info: info about VIN instance 1688c2ecf20Sopenharmony_ci * 1698c2ecf20Sopenharmony_ci * @vdev: V4L2 video device associated with VIN 1708c2ecf20Sopenharmony_ci * @v4l2_dev: V4L2 device 1718c2ecf20Sopenharmony_ci * @ctrl_handler: V4L2 control handler 1728c2ecf20Sopenharmony_ci * @notifier: V4L2 asynchronous subdevs notifier 1738c2ecf20Sopenharmony_ci * 1748c2ecf20Sopenharmony_ci * @parallel: parallel input subdevice descriptor 1758c2ecf20Sopenharmony_ci * 1768c2ecf20Sopenharmony_ci * @group: Gen3 CSI group 1778c2ecf20Sopenharmony_ci * @id: Gen3 group id for this VIN 1788c2ecf20Sopenharmony_ci * @pad: media pad for the video device entity 1798c2ecf20Sopenharmony_ci * 1808c2ecf20Sopenharmony_ci * @lock: protects @queue 1818c2ecf20Sopenharmony_ci * @queue: vb2 buffers queue 1828c2ecf20Sopenharmony_ci * @scratch: cpu address for scratch buffer 1838c2ecf20Sopenharmony_ci * @scratch_phys: physical address of the scratch buffer 1848c2ecf20Sopenharmony_ci * 1858c2ecf20Sopenharmony_ci * @qlock: protects @buf_hw, @buf_list, @sequence and @state 1868c2ecf20Sopenharmony_ci * @buf_hw: Keeps track of buffers given to HW slot 1878c2ecf20Sopenharmony_ci * @buf_list: list of queued buffers 1888c2ecf20Sopenharmony_ci * @sequence: V4L2 buffers sequence number 1898c2ecf20Sopenharmony_ci * @state: keeps track of operation state 1908c2ecf20Sopenharmony_ci * 1918c2ecf20Sopenharmony_ci * @is_csi: flag to mark the VIN as using a CSI-2 subdevice 1928c2ecf20Sopenharmony_ci * 1938c2ecf20Sopenharmony_ci * @mbus_code: media bus format code 1948c2ecf20Sopenharmony_ci * @format: active V4L2 pixel format 1958c2ecf20Sopenharmony_ci * 1968c2ecf20Sopenharmony_ci * @crop: active cropping 1978c2ecf20Sopenharmony_ci * @compose: active composing 1988c2ecf20Sopenharmony_ci * @src_rect: active size of the video source 1998c2ecf20Sopenharmony_ci * @std: active video standard of the video source 2008c2ecf20Sopenharmony_ci * 2018c2ecf20Sopenharmony_ci * @alpha: Alpha component to fill in for supported pixel formats 2028c2ecf20Sopenharmony_ci */ 2038c2ecf20Sopenharmony_cistruct rvin_dev { 2048c2ecf20Sopenharmony_ci struct device *dev; 2058c2ecf20Sopenharmony_ci void __iomem *base; 2068c2ecf20Sopenharmony_ci const struct rvin_info *info; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci struct video_device vdev; 2098c2ecf20Sopenharmony_ci struct v4l2_device v4l2_dev; 2108c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler ctrl_handler; 2118c2ecf20Sopenharmony_ci struct v4l2_async_notifier notifier; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci struct rvin_parallel_entity *parallel; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci struct rvin_group *group; 2168c2ecf20Sopenharmony_ci unsigned int id; 2178c2ecf20Sopenharmony_ci struct media_pad pad; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci struct mutex lock; 2208c2ecf20Sopenharmony_ci struct vb2_queue queue; 2218c2ecf20Sopenharmony_ci void *scratch; 2228c2ecf20Sopenharmony_ci dma_addr_t scratch_phys; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci spinlock_t qlock; 2258c2ecf20Sopenharmony_ci struct { 2268c2ecf20Sopenharmony_ci struct vb2_v4l2_buffer *buffer; 2278c2ecf20Sopenharmony_ci enum rvin_buffer_type type; 2288c2ecf20Sopenharmony_ci dma_addr_t phys; 2298c2ecf20Sopenharmony_ci } buf_hw[HW_BUFFER_NUM]; 2308c2ecf20Sopenharmony_ci struct list_head buf_list; 2318c2ecf20Sopenharmony_ci unsigned int sequence; 2328c2ecf20Sopenharmony_ci enum rvin_dma_state state; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci bool is_csi; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci u32 mbus_code; 2378c2ecf20Sopenharmony_ci struct v4l2_pix_format format; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci struct v4l2_rect crop; 2408c2ecf20Sopenharmony_ci struct v4l2_rect compose; 2418c2ecf20Sopenharmony_ci struct v4l2_rect src_rect; 2428c2ecf20Sopenharmony_ci v4l2_std_id std; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci unsigned int alpha; 2458c2ecf20Sopenharmony_ci}; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci#define vin_to_source(vin) ((vin)->parallel->subdev) 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci/* Debug */ 2508c2ecf20Sopenharmony_ci#define vin_dbg(d, fmt, arg...) dev_dbg(d->dev, fmt, ##arg) 2518c2ecf20Sopenharmony_ci#define vin_info(d, fmt, arg...) dev_info(d->dev, fmt, ##arg) 2528c2ecf20Sopenharmony_ci#define vin_warn(d, fmt, arg...) dev_warn(d->dev, fmt, ##arg) 2538c2ecf20Sopenharmony_ci#define vin_err(d, fmt, arg...) dev_err(d->dev, fmt, ##arg) 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci/** 2568c2ecf20Sopenharmony_ci * struct rvin_group - VIN CSI2 group information 2578c2ecf20Sopenharmony_ci * @refcount: number of VIN instances using the group 2588c2ecf20Sopenharmony_ci * 2598c2ecf20Sopenharmony_ci * @mdev: media device which represents the group 2608c2ecf20Sopenharmony_ci * 2618c2ecf20Sopenharmony_ci * @lock: protects the count, notifier, vin and csi members 2628c2ecf20Sopenharmony_ci * @count: number of enabled VIN instances found in DT 2638c2ecf20Sopenharmony_ci * @notifier: group notifier for CSI-2 async subdevices 2648c2ecf20Sopenharmony_ci * @vin: VIN instances which are part of the group 2658c2ecf20Sopenharmony_ci * @csi: array of pairs of fwnode and subdev pointers 2668c2ecf20Sopenharmony_ci * to all CSI-2 subdevices. 2678c2ecf20Sopenharmony_ci */ 2688c2ecf20Sopenharmony_cistruct rvin_group { 2698c2ecf20Sopenharmony_ci struct kref refcount; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci struct media_device mdev; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci struct mutex lock; 2748c2ecf20Sopenharmony_ci unsigned int count; 2758c2ecf20Sopenharmony_ci struct v4l2_async_notifier notifier; 2768c2ecf20Sopenharmony_ci struct rvin_dev *vin[RCAR_VIN_NUM]; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci struct { 2798c2ecf20Sopenharmony_ci struct fwnode_handle *fwnode; 2808c2ecf20Sopenharmony_ci struct v4l2_subdev *subdev; 2818c2ecf20Sopenharmony_ci } csi[RVIN_CSI_MAX]; 2828c2ecf20Sopenharmony_ci}; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ciint rvin_dma_register(struct rvin_dev *vin, int irq); 2858c2ecf20Sopenharmony_civoid rvin_dma_unregister(struct rvin_dev *vin); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ciint rvin_v4l2_register(struct rvin_dev *vin); 2888c2ecf20Sopenharmony_civoid rvin_v4l2_unregister(struct rvin_dev *vin); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ciconst struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin, 2918c2ecf20Sopenharmony_ci u32 pixelformat); 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci/* Cropping, composing and scaling */ 2958c2ecf20Sopenharmony_civoid rvin_crop_scale_comp(struct rvin_dev *vin); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ciint rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel); 2988c2ecf20Sopenharmony_civoid rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci#endif 301