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