321 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/*3 * Driver for Renesas R-Car VIN4 *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 Damm9 *10 * Based on the soc-camera rcar_vin driver11 */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 327 28/* Address alignment mask for HW buffers */29#define HW_BUFFER_MASK 0x7f30 31/* Max number on VIN instances that can be in a system */32#define RCAR_VIN_NUM 3233 34struct rvin_dev;35struct rvin_group;36 37enum model_id {38 RCAR_H1,39 RCAR_M1,40 RCAR_GEN2,41 RCAR_GEN3,42};43 44enum rvin_csi_id {45 RVIN_CSI20,46 RVIN_CSI21,47 RVIN_CSI40,48 RVIN_CSI41,49 RVIN_CSI_MAX,50};51 52enum 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 states66 * @STOPPED: No operation in progress67 * @STARTING: Capture starting up68 * @RUNNING: Operation in progress have buffers69 * @STOPPING: Stopping operation70 * @SUSPENDED: Capture is suspended71 */72enum rvin_dma_state {73 STOPPED = 0,74 STARTING,75 RUNNING,76 STOPPING,77 SUSPENDED,78};79 80/**81 * enum rvin_buffer_type82 *83 * Describes how a buffer is given to the hardware. To be able84 * to capture SEQ_TB/BT it's needed to capture to the same vb285 * buffer twice so the type of buffer needs to be kept.86 *87 * @FULL: One capture fills the whole vb2 buffer88 * @HALF_TOP: One capture fills the top half of the vb2 buffer89 * @HALF_BOTTOM: One capture fills the bottom half of the vb2 buffer90 */91enum rvin_buffer_type {92 FULL,93 HALF_TOP,94 HALF_BOTTOM,95};96 97/**98 * struct rvin_video_format - Data format stored in memory99 * @fourcc: Pixelformat100 * @bpp: Bytes per pixel101 */102struct rvin_video_format {103 u32 fourcc;104 u8 bpp;105};106 107/**108 * struct rvin_parallel_entity - Parallel video input endpoint descriptor109 * @asc: async connection descriptor for async framework110 * @subdev: subdevice matched using async framework111 * @mbus_type: media bus type112 * @bus: media bus parallel configuration113 * @source_pad: source pad of remote subdevice114 * @sink_pad: sink pad of remote subdevice115 *116 */117struct 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 a130 * CSI-2 receiver to a VIN131 *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 VIN138 * devices, each channel can carry one CSI-2 Virtual Channel (VC).139 * There is no correlation between channel number and CSI-2 VC. It's140 * up to the CSI-2 receiver driver to configure which VC is output141 * on which channel, the VIN devices only care about output channels.142 */143struct 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 implementation151 * @model: VIN model152 * @use_mc: use media controller instead of controlling subdevice153 * @use_isp: the VIN is connected to the ISP and not to the CSI-2154 * @nv12: support outputing NV12 pixel format155 * @max_width: max input width the VIN supports156 * @max_height: max input height the VIN supports157 * @routes: list of possible routes from the CSI-2 recivers to158 * all VINs. The list mush be NULL terminated.159 * @scaler: Optional scaler160 */161struct 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 structure175 * @dev: (OF) device176 * @base: device I/O register space remapped to virtual memory177 * @info: info about VIN instance178 *179 * @vdev: V4L2 video device associated with VIN180 * @v4l2_dev: V4L2 device181 * @ctrl_handler: V4L2 control handler182 * @notifier: V4L2 asynchronous subdevs notifier183 *184 * @parallel: parallel input subdevice descriptor185 *186 * @group: Gen3 CSI group187 * @id: Gen3 group id for this VIN188 * @pad: media pad for the video device entity189 *190 * @lock: protects @queue191 * @queue: vb2 buffers queue192 * @scratch: cpu address for scratch buffer193 * @scratch_phys: physical address of the scratch buffer194 *195 * @qlock: protects @buf_hw, @buf_list, @sequence and @state196 * @buf_hw: Keeps track of buffers given to HW slot197 * @buf_list: list of queued buffers198 * @sequence: V4L2 buffers sequence number199 * @state: keeps track of operation state200 *201 * @is_csi: flag to mark the VIN as using a CSI-2 subdevice202 * @chsel: Cached value of the current CSI-2 channel selection203 *204 * @mbus_code: media bus format code205 * @format: active V4L2 pixel format206 *207 * @crop: active cropping208 * @compose: active composing209 * @scaler: Optional scaler210 * @std: active video standard of the video source211 *212 * @alpha: Alpha component to fill in for supported pixel formats213 */214struct 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 information269 * @refcount: number of VIN instances using the group270 *271 * @mdev: media device which represents the group272 *273 * @lock: protects the count, notifier, vin and csi members274 * @count: number of enabled VIN instances found in DT275 * @notifier: group notifier for CSI-2 async connections276 * @vin: VIN instances which are part of the group277 * @link_setup: Callback to create all links for the media graph278 * @remotes: array of pairs of async connection and subdev pointers279 * to all remote subdevices.280 */281struct 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 299int rvin_dma_register(struct rvin_dev *vin, int irq);300void rvin_dma_unregister(struct rvin_dev *vin);301 302int rvin_v4l2_register(struct rvin_dev *vin);303void rvin_v4l2_unregister(struct rvin_dev *vin);304 305const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,306 u32 pixelformat);307 308 309/* Cropping, composing and scaling */310void rvin_scaler_gen2(struct rvin_dev *vin);311void rvin_scaler_gen3(struct rvin_dev *vin);312void rvin_crop_scale_comp(struct rvin_dev *vin);313 314int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);315void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha);316 317int rvin_start_streaming(struct rvin_dev *vin);318void rvin_stop_streaming(struct rvin_dev *vin);319 320#endif321