linux/drivers/media/platform/rcar-vin/rcar-vin.h
<<
>>
Prefs
   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