linux/drivers/media/platform/ti/cal/cal.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * TI Camera Access Layer (CAL)
   4 *
   5 * Copyright (c) 2015-2020 Texas Instruments Inc.
   6 *
   7 * Authors:
   8 *      Benoit Parrot <bparrot@ti.com>
   9 *      Laurent Pinchart <laurent.pinchart@ideasonboard.com>
  10 */
  11#ifndef __TI_CAL_H__
  12#define __TI_CAL_H__
  13
  14#include <linux/bitfield.h>
  15#include <linux/io.h>
  16#include <linux/list.h>
  17#include <linux/mutex.h>
  18#include <linux/spinlock.h>
  19#include <linux/videodev2.h>
  20#include <linux/wait.h>
  21
  22#include <media/media-device.h>
  23#include <media/v4l2-async.h>
  24#include <media/v4l2-ctrls.h>
  25#include <media/v4l2-dev.h>
  26#include <media/v4l2-device.h>
  27#include <media/v4l2-fwnode.h>
  28#include <media/v4l2-subdev.h>
  29#include <media/videobuf2-v4l2.h>
  30
  31#define CAL_MODULE_NAME                 "cal"
  32#define CAL_MAX_NUM_CONTEXT             8
  33#define CAL_NUM_CSI2_PORTS              2
  34
  35/*
  36 * The width is limited by the size of the CAL_WR_DMA_XSIZE_j.XSIZE field,
  37 * expressed in multiples of 64 bits. The height is limited by the size of the
  38 * CAL_CSI2_CTXi_j.CTXi_LINES and CAL_WR_DMA_CTRL_j.YSIZE fields, expressed in
  39 * lines.
  40 */
  41#define CAL_MIN_WIDTH_BYTES             16
  42#define CAL_MAX_WIDTH_BYTES             (8192 * 8)
  43#define CAL_MIN_HEIGHT_LINES            1
  44#define CAL_MAX_HEIGHT_LINES            16383
  45
  46#define CAL_CAMERARX_PAD_SINK           0
  47#define CAL_CAMERARX_PAD_FIRST_SOURCE   1
  48#define CAL_CAMERARX_NUM_SOURCE_PADS    1
  49#define CAL_CAMERARX_NUM_PADS           (1 + CAL_CAMERARX_NUM_SOURCE_PADS)
  50
  51static inline bool cal_rx_pad_is_sink(u32 pad)
  52{
  53        /* Camera RX has 1 sink pad, and N source pads */
  54        return pad == 0;
  55}
  56
  57static inline bool cal_rx_pad_is_source(u32 pad)
  58{
  59        /* Camera RX has 1 sink pad, and N source pads */
  60        return pad >= CAL_CAMERARX_PAD_FIRST_SOURCE &&
  61               pad <= CAL_CAMERARX_NUM_SOURCE_PADS;
  62}
  63
  64struct device;
  65struct device_node;
  66struct resource;
  67struct regmap;
  68struct regmap_fied;
  69
  70/* CTRL_CORE_CAMERRX_CONTROL register field id */
  71enum cal_camerarx_field {
  72        F_CTRLCLKEN,
  73        F_CAMMODE,
  74        F_LANEENABLE,
  75        F_CSI_MODE,
  76        F_MAX_FIELDS,
  77};
  78
  79enum cal_dma_state {
  80        CAL_DMA_RUNNING,
  81        CAL_DMA_STOP_REQUESTED,
  82        CAL_DMA_STOP_PENDING,
  83        CAL_DMA_STOPPED,
  84};
  85
  86struct cal_format_info {
  87        u32     fourcc;
  88        u32     code;
  89        /* Bits per pixel */
  90        u8      bpp;
  91        bool    meta;
  92};
  93
  94/* buffer for one video frame */
  95struct cal_buffer {
  96        /* common v4l buffer stuff -- must be first */
  97        struct vb2_v4l2_buffer  vb;
  98        struct list_head        list;
  99};
 100
 101/**
 102 * struct cal_dmaqueue - Queue of DMA buffers
 103 */
 104struct cal_dmaqueue {
 105        /**
 106         * @lock: Protects all fields in the cal_dmaqueue.
 107         */
 108        spinlock_t              lock;
 109
 110        /**
 111         * @queue: Buffers queued to the driver and waiting for DMA processing.
 112         * Buffers are added to the list by the vb2 .buffer_queue() operation,
 113         * and move to @pending when they are scheduled for the next frame.
 114         */
 115        struct list_head        queue;
 116        /**
 117         * @pending: Buffer provided to the hardware to DMA the next frame.
 118         * Will move to @active at the end of the current frame.
 119         */
 120        struct cal_buffer       *pending;
 121        /**
 122         * @active: Buffer being DMA'ed to for the current frame. Will be
 123         * retired and given back to vb2 at the end of the current frame if
 124         * a @pending buffer has been scheduled to replace it.
 125         */
 126        struct cal_buffer       *active;
 127
 128        /** @state: State of the DMA engine. */
 129        enum cal_dma_state      state;
 130        /** @wait: Wait queue to signal a @state transition to CAL_DMA_STOPPED. */
 131        struct wait_queue_head  wait;
 132};
 133
 134struct cal_camerarx_data {
 135        struct {
 136                unsigned int lsb;
 137                unsigned int msb;
 138        } fields[F_MAX_FIELDS];
 139        unsigned int num_lanes;
 140};
 141
 142struct cal_data {
 143        const struct cal_camerarx_data *camerarx;
 144        unsigned int num_csi2_phy;
 145        unsigned int flags;
 146};
 147
 148/*
 149 * The Camera Adaptation Layer (CAL) module is paired with one or more complex
 150 * I/O PHYs (CAMERARX). It contains multiple instances of CSI-2, processing and
 151 * DMA contexts.
 152 *
 153 * The cal_dev structure represents the whole subsystem, including the CAL and
 154 * the CAMERARX instances. Instances of struct cal_dev are named cal through the
 155 * driver.
 156 *
 157 * The cal_camerarx structure represents one CAMERARX instance. Instances of
 158 * cal_camerarx are named phy through the driver.
 159 *
 160 * The cal_ctx structure represents the combination of one CSI-2 context, one
 161 * processing context and one DMA context. Instance of struct cal_ctx are named
 162 * ctx through the driver.
 163 */
 164
 165struct cal_camerarx {
 166        void __iomem            *base;
 167        struct resource         *res;
 168        struct regmap_field     *fields[F_MAX_FIELDS];
 169
 170        struct cal_dev          *cal;
 171        unsigned int            instance;
 172
 173        struct v4l2_fwnode_endpoint     endpoint;
 174        struct device_node      *source_ep_node;
 175        struct device_node      *source_node;
 176        struct v4l2_subdev      *source;
 177        struct media_pipeline   pipe;
 178
 179        struct v4l2_subdev      subdev;
 180        struct media_pad        pads[CAL_CAMERARX_NUM_PADS];
 181        struct v4l2_mbus_framefmt       formats[CAL_CAMERARX_NUM_PADS];
 182
 183        /*
 184         * Lock for camerarx ops. Protects:
 185         * - formats
 186         * - enable_count
 187         */
 188        struct mutex            mutex;
 189
 190        unsigned int            enable_count;
 191};
 192
 193struct cal_dev {
 194        struct clk              *fclk;
 195        int                     irq;
 196        void __iomem            *base;
 197        struct resource         *res;
 198        struct device           *dev;
 199
 200        const struct cal_data   *data;
 201        u32                     revision;
 202
 203        /* Control Module handle */
 204        struct regmap           *syscon_camerrx;
 205        u32                     syscon_camerrx_offset;
 206
 207        /* Camera Core Module handle */
 208        struct cal_camerarx     *phy[CAL_NUM_CSI2_PORTS];
 209
 210        u32 num_contexts;
 211        struct cal_ctx          *ctx[CAL_MAX_NUM_CONTEXT];
 212
 213        struct media_device     mdev;
 214        struct v4l2_device      v4l2_dev;
 215        struct v4l2_async_notifier notifier;
 216
 217        unsigned long           reserved_pix_proc_mask;
 218};
 219
 220/*
 221 * There is one cal_ctx structure for each camera core context.
 222 */
 223struct cal_ctx {
 224        struct v4l2_ctrl_handler ctrl_handler;
 225        struct video_device     vdev;
 226        struct media_pad        pad;
 227
 228        struct cal_dev          *cal;
 229        struct cal_camerarx     *phy;
 230
 231        /* v4l2_ioctl mutex */
 232        struct mutex            mutex;
 233
 234        struct cal_dmaqueue     dma;
 235
 236        /* video capture */
 237        const struct cal_format_info    *fmtinfo;
 238        /* Used to store current pixel format */
 239        struct v4l2_format      v_fmt;
 240
 241        /* Current subdev enumerated format (legacy) */
 242        const struct cal_format_info    **active_fmt;
 243        unsigned int            num_active_fmt;
 244
 245        unsigned int            sequence;
 246        struct vb2_queue        vb_vidq;
 247        u8                      dma_ctx;
 248        u8                      cport;
 249        u8                      csi2_ctx;
 250        u8                      pix_proc;
 251        u8                      vc;
 252        u8                      datatype;
 253
 254        bool                    use_pix_proc;
 255};
 256
 257extern unsigned int cal_debug;
 258extern int cal_video_nr;
 259extern bool cal_mc_api;
 260
 261#define cal_dbg(level, cal, fmt, arg...)                                \
 262        do {                                                            \
 263                if (cal_debug >= (level))                               \
 264                        dev_printk(KERN_DEBUG, (cal)->dev, fmt, ##arg); \
 265        } while (0)
 266#define cal_info(cal, fmt, arg...)                                      \
 267        dev_info((cal)->dev, fmt, ##arg)
 268#define cal_err(cal, fmt, arg...)                                       \
 269        dev_err((cal)->dev, fmt, ##arg)
 270
 271#define ctx_dbg(level, ctx, fmt, arg...)                                \
 272        cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
 273#define ctx_info(ctx, fmt, arg...)                                      \
 274        cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
 275#define ctx_err(ctx, fmt, arg...)                                       \
 276        cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
 277
 278#define phy_dbg(level, phy, fmt, arg...)                                \
 279        cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
 280#define phy_info(phy, fmt, arg...)                                      \
 281        cal_info((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
 282#define phy_err(phy, fmt, arg...)                                       \
 283        cal_err((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
 284
 285static inline u32 cal_read(struct cal_dev *cal, u32 offset)
 286{
 287        return ioread32(cal->base + offset);
 288}
 289
 290static inline void cal_write(struct cal_dev *cal, u32 offset, u32 val)
 291{
 292        iowrite32(val, cal->base + offset);
 293}
 294
 295static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
 296{
 297        return FIELD_GET(mask, cal_read(cal, offset));
 298}
 299
 300static inline void cal_write_field(struct cal_dev *cal, u32 offset, u32 value,
 301                                   u32 mask)
 302{
 303        u32 val = cal_read(cal, offset);
 304
 305        val &= ~mask;
 306        val |= (value << __ffs(mask)) & mask;
 307        cal_write(cal, offset, val);
 308}
 309
 310static inline void cal_set_field(u32 *valp, u32 field, u32 mask)
 311{
 312        u32 val = *valp;
 313
 314        val &= ~mask;
 315        val |= (field << __ffs(mask)) & mask;
 316        *valp = val;
 317}
 318
 319extern const struct cal_format_info cal_formats[];
 320extern const unsigned int cal_num_formats;
 321const struct cal_format_info *cal_format_by_fourcc(u32 fourcc);
 322const struct cal_format_info *cal_format_by_code(u32 code);
 323
 324void cal_quickdump_regs(struct cal_dev *cal);
 325
 326void cal_camerarx_disable(struct cal_camerarx *phy);
 327void cal_camerarx_i913_errata(struct cal_camerarx *phy);
 328struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
 329                                         unsigned int instance);
 330void cal_camerarx_destroy(struct cal_camerarx *phy);
 331
 332int cal_ctx_prepare(struct cal_ctx *ctx);
 333void cal_ctx_unprepare(struct cal_ctx *ctx);
 334void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr);
 335void cal_ctx_start(struct cal_ctx *ctx);
 336void cal_ctx_stop(struct cal_ctx *ctx);
 337
 338int cal_ctx_v4l2_register(struct cal_ctx *ctx);
 339void cal_ctx_v4l2_unregister(struct cal_ctx *ctx);
 340int cal_ctx_v4l2_init(struct cal_ctx *ctx);
 341void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx);
 342
 343#endif /* __TI_CAL_H__ */
 344