linux/drivers/media/platform/ti-vpe/vpe.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * TI VPE mem2mem driver, based on the virtual v4l2-mem2mem example driver
   4 *
   5 * Copyright (c) 2013 Texas Instruments Inc.
   6 * David Griego, <dagriego@biglakesoftware.com>
   7 * Dale Farnsworth, <dale@farnsworth.org>
   8 * Archit Taneja, <archit@ti.com>
   9 *
  10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
  11 * Pawel Osciak, <pawel@osciak.com>
  12 * Marek Szyprowski, <m.szyprowski@samsung.com>
  13 *
  14 * Based on the virtual v4l2-mem2mem example device
  15 */
  16
  17#include <linux/delay.h>
  18#include <linux/dma-mapping.h>
  19#include <linux/err.h>
  20#include <linux/fs.h>
  21#include <linux/interrupt.h>
  22#include <linux/io.h>
  23#include <linux/ioctl.h>
  24#include <linux/module.h>
  25#include <linux/of.h>
  26#include <linux/platform_device.h>
  27#include <linux/pm_runtime.h>
  28#include <linux/sched.h>
  29#include <linux/slab.h>
  30#include <linux/videodev2.h>
  31#include <linux/log2.h>
  32#include <linux/sizes.h>
  33
  34#include <media/v4l2-common.h>
  35#include <media/v4l2-ctrls.h>
  36#include <media/v4l2-device.h>
  37#include <media/v4l2-event.h>
  38#include <media/v4l2-ioctl.h>
  39#include <media/v4l2-mem2mem.h>
  40#include <media/videobuf2-v4l2.h>
  41#include <media/videobuf2-dma-contig.h>
  42
  43#include "vpdma.h"
  44#include "vpdma_priv.h"
  45#include "vpe_regs.h"
  46#include "sc.h"
  47#include "csc.h"
  48
  49#define VPE_MODULE_NAME "vpe"
  50
  51/* minimum and maximum frame sizes */
  52#define MIN_W           32
  53#define MIN_H           32
  54#define MAX_W           2048
  55#define MAX_H           2048
  56
  57/* required alignments */
  58#define S_ALIGN         0       /* multiple of 1 */
  59#define H_ALIGN         1       /* multiple of 2 */
  60
  61/* flags that indicate a format can be used for capture/output */
  62#define VPE_FMT_TYPE_CAPTURE    (1 << 0)
  63#define VPE_FMT_TYPE_OUTPUT     (1 << 1)
  64
  65/* used as plane indices */
  66#define VPE_MAX_PLANES  2
  67#define VPE_LUMA        0
  68#define VPE_CHROMA      1
  69
  70/* per m2m context info */
  71#define VPE_MAX_SRC_BUFS        3       /* need 3 src fields to de-interlace */
  72
  73#define VPE_DEF_BUFS_PER_JOB    1       /* default one buffer per batch job */
  74
  75/*
  76 * each VPE context can need up to 3 config descriptors, 7 input descriptors,
  77 * 3 output descriptors, and 10 control descriptors
  78 */
  79#define VPE_DESC_LIST_SIZE      (10 * VPDMA_DTD_DESC_SIZE +     \
  80                                        13 * VPDMA_CFD_CTD_DESC_SIZE)
  81
  82#define vpe_dbg(vpedev, fmt, arg...)    \
  83                dev_dbg((vpedev)->v4l2_dev.dev, fmt, ##arg)
  84#define vpe_err(vpedev, fmt, arg...)    \
  85                dev_err((vpedev)->v4l2_dev.dev, fmt, ##arg)
  86
  87struct vpe_us_coeffs {
  88        unsigned short  anchor_fid0_c0;
  89        unsigned short  anchor_fid0_c1;
  90        unsigned short  anchor_fid0_c2;
  91        unsigned short  anchor_fid0_c3;
  92        unsigned short  interp_fid0_c0;
  93        unsigned short  interp_fid0_c1;
  94        unsigned short  interp_fid0_c2;
  95        unsigned short  interp_fid0_c3;
  96        unsigned short  anchor_fid1_c0;
  97        unsigned short  anchor_fid1_c1;
  98        unsigned short  anchor_fid1_c2;
  99        unsigned short  anchor_fid1_c3;
 100        unsigned short  interp_fid1_c0;
 101        unsigned short  interp_fid1_c1;
 102        unsigned short  interp_fid1_c2;
 103        unsigned short  interp_fid1_c3;
 104};
 105
 106/*
 107 * Default upsampler coefficients
 108 */
 109static const struct vpe_us_coeffs us_coeffs[] = {
 110        {
 111                /* Coefficients for progressive input */
 112                0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8,
 113                0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8,
 114        },
 115        {
 116                /* Coefficients for Top Field Interlaced input */
 117                0x0051, 0x03D5, 0x3FE3, 0x3FF7, 0x3FB5, 0x02E9, 0x018F, 0x3FD3,
 118                /* Coefficients for Bottom Field Interlaced input */
 119                0x016B, 0x0247, 0x00B1, 0x3F9D, 0x3FCF, 0x03DB, 0x005D, 0x3FF9,
 120        },
 121};
 122
 123/*
 124 * the following registers are for configuring some of the parameters of the
 125 * motion and edge detection blocks inside DEI, these generally remain the same,
 126 * these could be passed later via userspace if some one needs to tweak these.
 127 */
 128struct vpe_dei_regs {
 129        unsigned long mdt_spacial_freq_thr_reg;         /* VPE_DEI_REG2 */
 130        unsigned long edi_config_reg;                   /* VPE_DEI_REG3 */
 131        unsigned long edi_lut_reg0;                     /* VPE_DEI_REG4 */
 132        unsigned long edi_lut_reg1;                     /* VPE_DEI_REG5 */
 133        unsigned long edi_lut_reg2;                     /* VPE_DEI_REG6 */
 134        unsigned long edi_lut_reg3;                     /* VPE_DEI_REG7 */
 135};
 136
 137/*
 138 * default expert DEI register values, unlikely to be modified.
 139 */
 140static const struct vpe_dei_regs dei_regs = {
 141        .mdt_spacial_freq_thr_reg = 0x020C0804u,
 142        .edi_config_reg = 0x0118100Cu,
 143        .edi_lut_reg0 = 0x08040200u,
 144        .edi_lut_reg1 = 0x1010100Cu,
 145        .edi_lut_reg2 = 0x10101010u,
 146        .edi_lut_reg3 = 0x10101010u,
 147};
 148
 149/*
 150 * The port_data structure contains per-port data.
 151 */
 152struct vpe_port_data {
 153        enum vpdma_channel channel;     /* VPDMA channel */
 154        u8      vb_index;               /* input frame f, f-1, f-2 index */
 155        u8      vb_part;                /* plane index for co-panar formats */
 156};
 157
 158/*
 159 * Define indices into the port_data tables
 160 */
 161#define VPE_PORT_LUMA1_IN       0
 162#define VPE_PORT_CHROMA1_IN     1
 163#define VPE_PORT_LUMA2_IN       2
 164#define VPE_PORT_CHROMA2_IN     3
 165#define VPE_PORT_LUMA3_IN       4
 166#define VPE_PORT_CHROMA3_IN     5
 167#define VPE_PORT_MV_IN          6
 168#define VPE_PORT_MV_OUT         7
 169#define VPE_PORT_LUMA_OUT       8
 170#define VPE_PORT_CHROMA_OUT     9
 171#define VPE_PORT_RGB_OUT        10
 172
 173static const struct vpe_port_data port_data[11] = {
 174        [VPE_PORT_LUMA1_IN] = {
 175                .channel        = VPE_CHAN_LUMA1_IN,
 176                .vb_index       = 0,
 177                .vb_part        = VPE_LUMA,
 178        },
 179        [VPE_PORT_CHROMA1_IN] = {
 180                .channel        = VPE_CHAN_CHROMA1_IN,
 181                .vb_index       = 0,
 182                .vb_part        = VPE_CHROMA,
 183        },
 184        [VPE_PORT_LUMA2_IN] = {
 185                .channel        = VPE_CHAN_LUMA2_IN,
 186                .vb_index       = 1,
 187                .vb_part        = VPE_LUMA,
 188        },
 189        [VPE_PORT_CHROMA2_IN] = {
 190                .channel        = VPE_CHAN_CHROMA2_IN,
 191                .vb_index       = 1,
 192                .vb_part        = VPE_CHROMA,
 193        },
 194        [VPE_PORT_LUMA3_IN] = {
 195                .channel        = VPE_CHAN_LUMA3_IN,
 196                .vb_index       = 2,
 197                .vb_part        = VPE_LUMA,
 198        },
 199        [VPE_PORT_CHROMA3_IN] = {
 200                .channel        = VPE_CHAN_CHROMA3_IN,
 201                .vb_index       = 2,
 202                .vb_part        = VPE_CHROMA,
 203        },
 204        [VPE_PORT_MV_IN] = {
 205                .channel        = VPE_CHAN_MV_IN,
 206        },
 207        [VPE_PORT_MV_OUT] = {
 208                .channel        = VPE_CHAN_MV_OUT,
 209        },
 210        [VPE_PORT_LUMA_OUT] = {
 211                .channel        = VPE_CHAN_LUMA_OUT,
 212                .vb_part        = VPE_LUMA,
 213        },
 214        [VPE_PORT_CHROMA_OUT] = {
 215                .channel        = VPE_CHAN_CHROMA_OUT,
 216                .vb_part        = VPE_CHROMA,
 217        },
 218        [VPE_PORT_RGB_OUT] = {
 219                .channel        = VPE_CHAN_RGB_OUT,
 220                .vb_part        = VPE_LUMA,
 221        },
 222};
 223
 224
 225/* driver info for each of the supported video formats */
 226struct vpe_fmt {
 227        u32     fourcc;                 /* standard format identifier */
 228        u8      types;                  /* CAPTURE and/or OUTPUT */
 229        u8      coplanar;               /* set for unpacked Luma and Chroma */
 230        /* vpdma format info for each plane */
 231        struct vpdma_data_format const *vpdma_fmt[VPE_MAX_PLANES];
 232};
 233
 234static struct vpe_fmt vpe_formats[] = {
 235        {
 236                .fourcc         = V4L2_PIX_FMT_NV16,
 237                .types          = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 238                .coplanar       = 1,
 239                .vpdma_fmt      = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y444],
 240                                    &vpdma_yuv_fmts[VPDMA_DATA_FMT_C444],
 241                                  },
 242        },
 243        {
 244                .fourcc         = V4L2_PIX_FMT_NV12,
 245                .types          = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 246                .coplanar       = 1,
 247                .vpdma_fmt      = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420],
 248                                    &vpdma_yuv_fmts[VPDMA_DATA_FMT_C420],
 249                                  },
 250        },
 251        {
 252                .fourcc         = V4L2_PIX_FMT_NV21,
 253                .types          = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 254                .coplanar       = 1,
 255                .vpdma_fmt      = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420],
 256                                    &vpdma_yuv_fmts[VPDMA_DATA_FMT_CB420],
 257                                  },
 258        },
 259        {
 260                .fourcc         = V4L2_PIX_FMT_YUYV,
 261                .types          = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 262                .coplanar       = 0,
 263                .vpdma_fmt      = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YCB422],
 264                                  },
 265        },
 266        {
 267                .fourcc         = V4L2_PIX_FMT_UYVY,
 268                .types          = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 269                .coplanar       = 0,
 270                .vpdma_fmt      = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CBY422],
 271                                  },
 272        },
 273        {
 274                .fourcc         = V4L2_PIX_FMT_RGB24,
 275                .types          = VPE_FMT_TYPE_CAPTURE,
 276                .coplanar       = 0,
 277                .vpdma_fmt      = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB24],
 278                                  },
 279        },
 280        {
 281                .fourcc         = V4L2_PIX_FMT_RGB32,
 282                .types          = VPE_FMT_TYPE_CAPTURE,
 283                .coplanar       = 0,
 284                .vpdma_fmt      = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ARGB32],
 285                                  },
 286        },
 287        {
 288                .fourcc         = V4L2_PIX_FMT_BGR24,
 289                .types          = VPE_FMT_TYPE_CAPTURE,
 290                .coplanar       = 0,
 291                .vpdma_fmt      = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_BGR24],
 292                                  },
 293        },
 294        {
 295                .fourcc         = V4L2_PIX_FMT_BGR32,
 296                .types          = VPE_FMT_TYPE_CAPTURE,
 297                .coplanar       = 0,
 298                .vpdma_fmt      = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32],
 299                                  },
 300        },
 301        {
 302                .fourcc         = V4L2_PIX_FMT_RGB565,
 303                .types          = VPE_FMT_TYPE_CAPTURE,
 304                .coplanar       = 0,
 305                .vpdma_fmt      = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB565],
 306                                  },
 307        },
 308        {
 309                .fourcc         = V4L2_PIX_FMT_RGB555,
 310                .types          = VPE_FMT_TYPE_CAPTURE,
 311                .coplanar       = 0,
 312                .vpdma_fmt      = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGBA16_5551],
 313                                  },
 314        },
 315};
 316
 317/*
 318 * per-queue, driver-specific private data.
 319 * there is one source queue and one destination queue for each m2m context.
 320 */
 321struct vpe_q_data {
 322        /* current v4l2 format info */
 323        struct v4l2_format      format;
 324        unsigned int            flags;
 325        struct v4l2_rect        c_rect;                         /* crop/compose rectangle */
 326        struct vpe_fmt          *fmt;                           /* format info */
 327};
 328
 329/* vpe_q_data flag bits */
 330#define Q_DATA_FRAME_1D                 BIT(0)
 331#define Q_DATA_MODE_TILED               BIT(1)
 332#define Q_DATA_INTERLACED_ALTERNATE     BIT(2)
 333#define Q_DATA_INTERLACED_SEQ_TB        BIT(3)
 334#define Q_DATA_INTERLACED_SEQ_BT        BIT(4)
 335
 336#define Q_IS_SEQ_XX             (Q_DATA_INTERLACED_SEQ_TB | \
 337                                Q_DATA_INTERLACED_SEQ_BT)
 338
 339#define Q_IS_INTERLACED         (Q_DATA_INTERLACED_ALTERNATE | \
 340                                Q_DATA_INTERLACED_SEQ_TB | \
 341                                Q_DATA_INTERLACED_SEQ_BT)
 342
 343enum {
 344        Q_DATA_SRC = 0,
 345        Q_DATA_DST = 1,
 346};
 347
 348/* find our format description corresponding to the passed v4l2_format */
 349static struct vpe_fmt *__find_format(u32 fourcc)
 350{
 351        struct vpe_fmt *fmt;
 352        unsigned int k;
 353
 354        for (k = 0; k < ARRAY_SIZE(vpe_formats); k++) {
 355                fmt = &vpe_formats[k];
 356                if (fmt->fourcc == fourcc)
 357                        return fmt;
 358        }
 359
 360        return NULL;
 361}
 362
 363static struct vpe_fmt *find_format(struct v4l2_format *f)
 364{
 365        return __find_format(f->fmt.pix.pixelformat);
 366}
 367
 368/*
 369 * there is one vpe_dev structure in the driver, it is shared by
 370 * all instances.
 371 */
 372struct vpe_dev {
 373        struct v4l2_device      v4l2_dev;
 374        struct video_device     vfd;
 375        struct v4l2_m2m_dev     *m2m_dev;
 376
 377        atomic_t                num_instances;  /* count of driver instances */
 378        dma_addr_t              loaded_mmrs;    /* shadow mmrs in device */
 379        struct mutex            dev_mutex;
 380        spinlock_t              lock;
 381
 382        int                     irq;
 383        void __iomem            *base;
 384        struct resource         *res;
 385
 386        struct vpdma_data       vpdma_data;
 387        struct vpdma_data       *vpdma;         /* vpdma data handle */
 388        struct sc_data          *sc;            /* scaler data handle */
 389        struct csc_data         *csc;           /* csc data handle */
 390};
 391
 392/*
 393 * There is one vpe_ctx structure for each m2m context.
 394 */
 395struct vpe_ctx {
 396        struct v4l2_fh          fh;
 397        struct vpe_dev          *dev;
 398        struct v4l2_ctrl_handler hdl;
 399
 400        unsigned int            field;                  /* current field */
 401        unsigned int            sequence;               /* current frame/field seq */
 402        unsigned int            aborting;               /* abort after next irq */
 403
 404        unsigned int            bufs_per_job;           /* input buffers per batch */
 405        unsigned int            bufs_completed;         /* bufs done in this batch */
 406
 407        struct vpe_q_data       q_data[2];              /* src & dst queue data */
 408        struct vb2_v4l2_buffer  *src_vbs[VPE_MAX_SRC_BUFS];
 409        struct vb2_v4l2_buffer  *dst_vb;
 410
 411        dma_addr_t              mv_buf_dma[2];          /* dma addrs of motion vector in/out bufs */
 412        void                    *mv_buf[2];             /* virtual addrs of motion vector bufs */
 413        size_t                  mv_buf_size;            /* current motion vector buffer size */
 414        struct vpdma_buf        mmr_adb;                /* shadow reg addr/data block */
 415        struct vpdma_buf        sc_coeff_h;             /* h coeff buffer */
 416        struct vpdma_buf        sc_coeff_v;             /* v coeff buffer */
 417        struct vpdma_desc_list  desc_list;              /* DMA descriptor list */
 418
 419        bool                    deinterlacing;          /* using de-interlacer */
 420        bool                    load_mmrs;              /* have new shadow reg values */
 421
 422        unsigned int            src_mv_buf_selector;
 423};
 424
 425
 426/*
 427 * M2M devices get 2 queues.
 428 * Return the queue given the type.
 429 */
 430static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
 431                                     enum v4l2_buf_type type)
 432{
 433        switch (type) {
 434        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 435        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
 436                return &ctx->q_data[Q_DATA_SRC];
 437        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 438        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 439                return &ctx->q_data[Q_DATA_DST];
 440        default:
 441                return NULL;
 442        }
 443        return NULL;
 444}
 445
 446static u32 read_reg(struct vpe_dev *dev, int offset)
 447{
 448        return ioread32(dev->base + offset);
 449}
 450
 451static void write_reg(struct vpe_dev *dev, int offset, u32 value)
 452{
 453        iowrite32(value, dev->base + offset);
 454}
 455
 456/* register field read/write helpers */
 457static int get_field(u32 value, u32 mask, int shift)
 458{
 459        return (value & (mask << shift)) >> shift;
 460}
 461
 462static int read_field_reg(struct vpe_dev *dev, int offset, u32 mask, int shift)
 463{
 464        return get_field(read_reg(dev, offset), mask, shift);
 465}
 466
 467static void write_field(u32 *valp, u32 field, u32 mask, int shift)
 468{
 469        u32 val = *valp;
 470
 471        val &= ~(mask << shift);
 472        val |= (field & mask) << shift;
 473        *valp = val;
 474}
 475
 476static void write_field_reg(struct vpe_dev *dev, int offset, u32 field,
 477                u32 mask, int shift)
 478{
 479        u32 val = read_reg(dev, offset);
 480
 481        write_field(&val, field, mask, shift);
 482
 483        write_reg(dev, offset, val);
 484}
 485
 486/*
 487 * DMA address/data block for the shadow registers
 488 */
 489struct vpe_mmr_adb {
 490        struct vpdma_adb_hdr    out_fmt_hdr;
 491        u32                     out_fmt_reg[1];
 492        u32                     out_fmt_pad[3];
 493        struct vpdma_adb_hdr    us1_hdr;
 494        u32                     us1_regs[8];
 495        struct vpdma_adb_hdr    us2_hdr;
 496        u32                     us2_regs[8];
 497        struct vpdma_adb_hdr    us3_hdr;
 498        u32                     us3_regs[8];
 499        struct vpdma_adb_hdr    dei_hdr;
 500        u32                     dei_regs[8];
 501        struct vpdma_adb_hdr    sc_hdr0;
 502        u32                     sc_regs0[7];
 503        u32                     sc_pad0[1];
 504        struct vpdma_adb_hdr    sc_hdr8;
 505        u32                     sc_regs8[6];
 506        u32                     sc_pad8[2];
 507        struct vpdma_adb_hdr    sc_hdr17;
 508        u32                     sc_regs17[9];
 509        u32                     sc_pad17[3];
 510        struct vpdma_adb_hdr    csc_hdr;
 511        u32                     csc_regs[6];
 512        u32                     csc_pad[2];
 513};
 514
 515#define GET_OFFSET_TOP(ctx, obj, reg)   \
 516        ((obj)->res->start - ctx->dev->res->start + reg)
 517
 518#define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a)   \
 519        VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a)
 520/*
 521 * Set the headers for all of the address/data block structures.
 522 */
 523static void init_adb_hdrs(struct vpe_ctx *ctx)
 524{
 525        VPE_SET_MMR_ADB_HDR(ctx, out_fmt_hdr, out_fmt_reg, VPE_CLK_FORMAT_SELECT);
 526        VPE_SET_MMR_ADB_HDR(ctx, us1_hdr, us1_regs, VPE_US1_R0);
 527        VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0);
 528        VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0);
 529        VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE);
 530        VPE_SET_MMR_ADB_HDR(ctx, sc_hdr0, sc_regs0,
 531                GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC0));
 532        VPE_SET_MMR_ADB_HDR(ctx, sc_hdr8, sc_regs8,
 533                GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC8));
 534        VPE_SET_MMR_ADB_HDR(ctx, sc_hdr17, sc_regs17,
 535                GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC17));
 536        VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs,
 537                GET_OFFSET_TOP(ctx, ctx->dev->csc, CSC_CSC00));
 538};
 539
 540/*
 541 * Allocate or re-allocate the motion vector DMA buffers
 542 * There are two buffers, one for input and one for output.
 543 * However, the roles are reversed after each field is processed.
 544 * In other words, after each field is processed, the previous
 545 * output (dst) MV buffer becomes the new input (src) MV buffer.
 546 */
 547static int realloc_mv_buffers(struct vpe_ctx *ctx, size_t size)
 548{
 549        struct device *dev = ctx->dev->v4l2_dev.dev;
 550
 551        if (ctx->mv_buf_size == size)
 552                return 0;
 553
 554        if (ctx->mv_buf[0])
 555                dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[0],
 556                        ctx->mv_buf_dma[0]);
 557
 558        if (ctx->mv_buf[1])
 559                dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[1],
 560                        ctx->mv_buf_dma[1]);
 561
 562        if (size == 0)
 563                return 0;
 564
 565        ctx->mv_buf[0] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[0],
 566                                GFP_KERNEL);
 567        if (!ctx->mv_buf[0]) {
 568                vpe_err(ctx->dev, "failed to allocate motion vector buffer\n");
 569                return -ENOMEM;
 570        }
 571
 572        ctx->mv_buf[1] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[1],
 573                                GFP_KERNEL);
 574        if (!ctx->mv_buf[1]) {
 575                vpe_err(ctx->dev, "failed to allocate motion vector buffer\n");
 576                dma_free_coherent(dev, size, ctx->mv_buf[0],
 577                        ctx->mv_buf_dma[0]);
 578
 579                return -ENOMEM;
 580        }
 581
 582        ctx->mv_buf_size = size;
 583        ctx->src_mv_buf_selector = 0;
 584
 585        return 0;
 586}
 587
 588static void free_mv_buffers(struct vpe_ctx *ctx)
 589{
 590        realloc_mv_buffers(ctx, 0);
 591}
 592
 593/*
 594 * While de-interlacing, we keep the two most recent input buffers
 595 * around.  This function frees those two buffers when we have
 596 * finished processing the current stream.
 597 */
 598static void free_vbs(struct vpe_ctx *ctx)
 599{
 600        struct vpe_dev *dev = ctx->dev;
 601        unsigned long flags;
 602
 603        if (ctx->src_vbs[2] == NULL)
 604                return;
 605
 606        spin_lock_irqsave(&dev->lock, flags);
 607        if (ctx->src_vbs[2]) {
 608                v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE);
 609                if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
 610                        v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE);
 611                ctx->src_vbs[2] = NULL;
 612                ctx->src_vbs[1] = NULL;
 613        }
 614        spin_unlock_irqrestore(&dev->lock, flags);
 615}
 616
 617/*
 618 * Enable or disable the VPE clocks
 619 */
 620static void vpe_set_clock_enable(struct vpe_dev *dev, bool on)
 621{
 622        u32 val = 0;
 623
 624        if (on)
 625                val = VPE_DATA_PATH_CLK_ENABLE | VPE_VPEDMA_CLK_ENABLE;
 626        write_reg(dev, VPE_CLK_ENABLE, val);
 627}
 628
 629static void vpe_top_reset(struct vpe_dev *dev)
 630{
 631
 632        write_field_reg(dev, VPE_CLK_RESET, 1, VPE_DATA_PATH_CLK_RESET_MASK,
 633                VPE_DATA_PATH_CLK_RESET_SHIFT);
 634
 635        usleep_range(100, 150);
 636
 637        write_field_reg(dev, VPE_CLK_RESET, 0, VPE_DATA_PATH_CLK_RESET_MASK,
 638                VPE_DATA_PATH_CLK_RESET_SHIFT);
 639}
 640
 641static void vpe_top_vpdma_reset(struct vpe_dev *dev)
 642{
 643        write_field_reg(dev, VPE_CLK_RESET, 1, VPE_VPDMA_CLK_RESET_MASK,
 644                VPE_VPDMA_CLK_RESET_SHIFT);
 645
 646        usleep_range(100, 150);
 647
 648        write_field_reg(dev, VPE_CLK_RESET, 0, VPE_VPDMA_CLK_RESET_MASK,
 649                VPE_VPDMA_CLK_RESET_SHIFT);
 650}
 651
 652/*
 653 * Load the correct of upsampler coefficients into the shadow MMRs
 654 */
 655static void set_us_coefficients(struct vpe_ctx *ctx)
 656{
 657        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 658        struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
 659        u32 *us1_reg = &mmr_adb->us1_regs[0];
 660        u32 *us2_reg = &mmr_adb->us2_regs[0];
 661        u32 *us3_reg = &mmr_adb->us3_regs[0];
 662        const unsigned short *cp, *end_cp;
 663
 664        cp = &us_coeffs[0].anchor_fid0_c0;
 665
 666        if (s_q_data->flags & Q_IS_INTERLACED)          /* interlaced */
 667                cp += sizeof(us_coeffs[0]) / sizeof(*cp);
 668
 669        end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp);
 670
 671        while (cp < end_cp) {
 672                write_field(us1_reg, *cp++, VPE_US_C0_MASK, VPE_US_C0_SHIFT);
 673                write_field(us1_reg, *cp++, VPE_US_C1_MASK, VPE_US_C1_SHIFT);
 674                *us2_reg++ = *us1_reg;
 675                *us3_reg++ = *us1_reg++;
 676        }
 677        ctx->load_mmrs = true;
 678}
 679
 680/*
 681 * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs.
 682 */
 683static void set_cfg_modes(struct vpe_ctx *ctx)
 684{
 685        struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt;
 686        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 687        u32 *us1_reg0 = &mmr_adb->us1_regs[0];
 688        u32 *us2_reg0 = &mmr_adb->us2_regs[0];
 689        u32 *us3_reg0 = &mmr_adb->us3_regs[0];
 690        int cfg_mode = 1;
 691
 692        /*
 693         * Cfg Mode 0: YUV420 source, enable upsampler, DEI is de-interlacing.
 694         * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing.
 695         */
 696
 697        if (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
 698            fmt->fourcc == V4L2_PIX_FMT_NV21)
 699                cfg_mode = 0;
 700
 701        write_field(us1_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
 702        write_field(us2_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
 703        write_field(us3_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
 704
 705        ctx->load_mmrs = true;
 706}
 707
 708static void set_line_modes(struct vpe_ctx *ctx)
 709{
 710        struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt;
 711        int line_mode = 1;
 712
 713        if (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
 714            fmt->fourcc == V4L2_PIX_FMT_NV21)
 715                line_mode = 0;          /* double lines to line buffer */
 716
 717        /* regs for now */
 718        vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN);
 719        vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN);
 720        vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA3_IN);
 721
 722        /* frame start for input luma */
 723        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 724                VPE_CHAN_LUMA1_IN);
 725        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 726                VPE_CHAN_LUMA2_IN);
 727        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 728                VPE_CHAN_LUMA3_IN);
 729
 730        /* frame start for input chroma */
 731        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 732                VPE_CHAN_CHROMA1_IN);
 733        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 734                VPE_CHAN_CHROMA2_IN);
 735        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 736                VPE_CHAN_CHROMA3_IN);
 737
 738        /* frame start for MV in client */
 739        vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
 740                VPE_CHAN_MV_IN);
 741}
 742
 743/*
 744 * Set the shadow registers that are modified when the source
 745 * format changes.
 746 */
 747static void set_src_registers(struct vpe_ctx *ctx)
 748{
 749        set_us_coefficients(ctx);
 750}
 751
 752/*
 753 * Set the shadow registers that are modified when the destination
 754 * format changes.
 755 */
 756static void set_dst_registers(struct vpe_ctx *ctx)
 757{
 758        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 759        struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt;
 760        const struct v4l2_format_info *finfo;
 761        u32 val = 0;
 762
 763        finfo = v4l2_format_info(fmt->fourcc);
 764        if (v4l2_is_format_rgb(finfo)) {
 765                val |= VPE_RGB_OUT_SELECT;
 766                vpdma_set_bg_color(ctx->dev->vpdma,
 767                        (struct vpdma_data_format *)fmt->vpdma_fmt[0], 0xff);
 768        } else if (fmt->fourcc == V4L2_PIX_FMT_NV16)
 769                val |= VPE_COLOR_SEPARATE_422;
 770
 771        /*
 772         * the source of CHR_DS and CSC is always the scaler, irrespective of
 773         * whether it's used or not
 774         */
 775        val |= VPE_DS_SRC_DEI_SCALER | VPE_CSC_SRC_DEI_SCALER;
 776
 777        if (fmt->fourcc != V4L2_PIX_FMT_NV12 &&
 778            fmt->fourcc != V4L2_PIX_FMT_NV21)
 779                val |= VPE_DS_BYPASS;
 780
 781        mmr_adb->out_fmt_reg[0] = val;
 782
 783        ctx->load_mmrs = true;
 784}
 785
 786/*
 787 * Set the de-interlacer shadow register values
 788 */
 789static void set_dei_regs(struct vpe_ctx *ctx)
 790{
 791        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 792        struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
 793        unsigned int src_h = s_q_data->c_rect.height;
 794        unsigned int src_w = s_q_data->c_rect.width;
 795        u32 *dei_mmr0 = &mmr_adb->dei_regs[0];
 796        bool deinterlace = true;
 797        u32 val = 0;
 798
 799        /*
 800         * according to TRM, we should set DEI in progressive bypass mode when
 801         * the input content is progressive, however, DEI is bypassed correctly
 802         * for both progressive and interlace content in interlace bypass mode.
 803         * It has been recommended not to use progressive bypass mode.
 804         */
 805        if (!(s_q_data->flags & Q_IS_INTERLACED) || !ctx->deinterlacing) {
 806                deinterlace = false;
 807                val = VPE_DEI_INTERLACE_BYPASS;
 808        }
 809
 810        src_h = deinterlace ? src_h * 2 : src_h;
 811
 812        val |= (src_h << VPE_DEI_HEIGHT_SHIFT) |
 813                (src_w << VPE_DEI_WIDTH_SHIFT) |
 814                VPE_DEI_FIELD_FLUSH;
 815
 816        *dei_mmr0 = val;
 817
 818        ctx->load_mmrs = true;
 819}
 820
 821static void set_dei_shadow_registers(struct vpe_ctx *ctx)
 822{
 823        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 824        u32 *dei_mmr = &mmr_adb->dei_regs[0];
 825        const struct vpe_dei_regs *cur = &dei_regs;
 826
 827        dei_mmr[2]  = cur->mdt_spacial_freq_thr_reg;
 828        dei_mmr[3]  = cur->edi_config_reg;
 829        dei_mmr[4]  = cur->edi_lut_reg0;
 830        dei_mmr[5]  = cur->edi_lut_reg1;
 831        dei_mmr[6]  = cur->edi_lut_reg2;
 832        dei_mmr[7]  = cur->edi_lut_reg3;
 833
 834        ctx->load_mmrs = true;
 835}
 836
 837static void config_edi_input_mode(struct vpe_ctx *ctx, int mode)
 838{
 839        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 840        u32 *edi_config_reg = &mmr_adb->dei_regs[3];
 841
 842        if (mode & 0x2)
 843                write_field(edi_config_reg, 1, 1, 2);   /* EDI_ENABLE_3D */
 844
 845        if (mode & 0x3)
 846                write_field(edi_config_reg, 1, 1, 3);   /* EDI_CHROMA_3D  */
 847
 848        write_field(edi_config_reg, mode, VPE_EDI_INP_MODE_MASK,
 849                VPE_EDI_INP_MODE_SHIFT);
 850
 851        ctx->load_mmrs = true;
 852}
 853
 854/*
 855 * Set the shadow registers whose values are modified when either the
 856 * source or destination format is changed.
 857 */
 858static int set_srcdst_params(struct vpe_ctx *ctx)
 859{
 860        struct vpe_q_data *s_q_data =  &ctx->q_data[Q_DATA_SRC];
 861        struct vpe_q_data *d_q_data =  &ctx->q_data[Q_DATA_DST];
 862        struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
 863        unsigned int src_w = s_q_data->c_rect.width;
 864        unsigned int src_h = s_q_data->c_rect.height;
 865        unsigned int dst_w = d_q_data->c_rect.width;
 866        unsigned int dst_h = d_q_data->c_rect.height;
 867        struct v4l2_pix_format_mplane *spix;
 868        size_t mv_buf_size;
 869        int ret;
 870
 871        ctx->sequence = 0;
 872        ctx->field = V4L2_FIELD_TOP;
 873        spix = &s_q_data->format.fmt.pix_mp;
 874
 875        if ((s_q_data->flags & Q_IS_INTERLACED) &&
 876                        !(d_q_data->flags & Q_IS_INTERLACED)) {
 877                int bytes_per_line;
 878                const struct vpdma_data_format *mv =
 879                        &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
 880
 881                /*
 882                 * we make sure that the source image has a 16 byte aligned
 883                 * stride, we need to do the same for the motion vector buffer
 884                 * by aligning it's stride to the next 16 byte boundary. this
 885                 * extra space will not be used by the de-interlacer, but will
 886                 * ensure that vpdma operates correctly
 887                 */
 888                bytes_per_line = ALIGN((spix->width * mv->depth) >> 3,
 889                                       VPDMA_STRIDE_ALIGN);
 890                mv_buf_size = bytes_per_line * spix->height;
 891
 892                ctx->deinterlacing = true;
 893                src_h <<= 1;
 894        } else {
 895                ctx->deinterlacing = false;
 896                mv_buf_size = 0;
 897        }
 898
 899        free_vbs(ctx);
 900        ctx->src_vbs[2] = ctx->src_vbs[1] = ctx->src_vbs[0] = NULL;
 901
 902        ret = realloc_mv_buffers(ctx, mv_buf_size);
 903        if (ret)
 904                return ret;
 905
 906        set_cfg_modes(ctx);
 907        set_dei_regs(ctx);
 908
 909        csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0],
 910                      &s_q_data->format, &d_q_data->format);
 911
 912        sc_set_hs_coeffs(ctx->dev->sc, ctx->sc_coeff_h.addr, src_w, dst_w);
 913        sc_set_vs_coeffs(ctx->dev->sc, ctx->sc_coeff_v.addr, src_h, dst_h);
 914
 915        sc_config_scaler(ctx->dev->sc, &mmr_adb->sc_regs0[0],
 916                &mmr_adb->sc_regs8[0], &mmr_adb->sc_regs17[0],
 917                src_w, src_h, dst_w, dst_h);
 918
 919        return 0;
 920}
 921
 922/*
 923 * mem2mem callbacks
 924 */
 925
 926/*
 927 * job_ready() - check whether an instance is ready to be scheduled to run
 928 */
 929static int job_ready(void *priv)
 930{
 931        struct vpe_ctx *ctx = priv;
 932
 933        /*
 934         * This check is needed as this might be called directly from driver
 935         * When called by m2m framework, this will always satisfy, but when
 936         * called from vpe_irq, this might fail. (src stream with zero buffers)
 937         */
 938        if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) <= 0 ||
 939                v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) <= 0)
 940                return 0;
 941
 942        return 1;
 943}
 944
 945static void job_abort(void *priv)
 946{
 947        struct vpe_ctx *ctx = priv;
 948
 949        /* Will cancel the transaction in the next interrupt handler */
 950        ctx->aborting = 1;
 951}
 952
 953static void vpe_dump_regs(struct vpe_dev *dev)
 954{
 955#define DUMPREG(r) vpe_dbg(dev, "%-35s %08x\n", #r, read_reg(dev, VPE_##r))
 956
 957        vpe_dbg(dev, "VPE Registers:\n");
 958
 959        DUMPREG(PID);
 960        DUMPREG(SYSCONFIG);
 961        DUMPREG(INT0_STATUS0_RAW);
 962        DUMPREG(INT0_STATUS0);
 963        DUMPREG(INT0_ENABLE0);
 964        DUMPREG(INT0_STATUS1_RAW);
 965        DUMPREG(INT0_STATUS1);
 966        DUMPREG(INT0_ENABLE1);
 967        DUMPREG(CLK_ENABLE);
 968        DUMPREG(CLK_RESET);
 969        DUMPREG(CLK_FORMAT_SELECT);
 970        DUMPREG(CLK_RANGE_MAP);
 971        DUMPREG(US1_R0);
 972        DUMPREG(US1_R1);
 973        DUMPREG(US1_R2);
 974        DUMPREG(US1_R3);
 975        DUMPREG(US1_R4);
 976        DUMPREG(US1_R5);
 977        DUMPREG(US1_R6);
 978        DUMPREG(US1_R7);
 979        DUMPREG(US2_R0);
 980        DUMPREG(US2_R1);
 981        DUMPREG(US2_R2);
 982        DUMPREG(US2_R3);
 983        DUMPREG(US2_R4);
 984        DUMPREG(US2_R5);
 985        DUMPREG(US2_R6);
 986        DUMPREG(US2_R7);
 987        DUMPREG(US3_R0);
 988        DUMPREG(US3_R1);
 989        DUMPREG(US3_R2);
 990        DUMPREG(US3_R3);
 991        DUMPREG(US3_R4);
 992        DUMPREG(US3_R5);
 993        DUMPREG(US3_R6);
 994        DUMPREG(US3_R7);
 995        DUMPREG(DEI_FRAME_SIZE);
 996        DUMPREG(MDT_BYPASS);
 997        DUMPREG(MDT_SF_THRESHOLD);
 998        DUMPREG(EDI_CONFIG);
 999        DUMPREG(DEI_EDI_LUT_R0);
1000        DUMPREG(DEI_EDI_LUT_R1);
1001        DUMPREG(DEI_EDI_LUT_R2);
1002        DUMPREG(DEI_EDI_LUT_R3);
1003        DUMPREG(DEI_FMD_WINDOW_R0);
1004        DUMPREG(DEI_FMD_WINDOW_R1);
1005        DUMPREG(DEI_FMD_CONTROL_R0);
1006        DUMPREG(DEI_FMD_CONTROL_R1);
1007        DUMPREG(DEI_FMD_STATUS_R0);
1008        DUMPREG(DEI_FMD_STATUS_R1);
1009        DUMPREG(DEI_FMD_STATUS_R2);
1010#undef DUMPREG
1011
1012        sc_dump_regs(dev->sc);
1013        csc_dump_regs(dev->csc);
1014}
1015
1016static void add_out_dtd(struct vpe_ctx *ctx, int port)
1017{
1018        struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST];
1019        const struct vpe_port_data *p_data = &port_data[port];
1020        struct vb2_buffer *vb = &ctx->dst_vb->vb2_buf;
1021        struct vpe_fmt *fmt = q_data->fmt;
1022        const struct vpdma_data_format *vpdma_fmt;
1023        int mv_buf_selector = !ctx->src_mv_buf_selector;
1024        struct v4l2_pix_format_mplane *pix;
1025        dma_addr_t dma_addr;
1026        u32 flags = 0;
1027        u32 offset = 0;
1028        u32 stride;
1029
1030        if (port == VPE_PORT_MV_OUT) {
1031                vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
1032                dma_addr = ctx->mv_buf_dma[mv_buf_selector];
1033                q_data = &ctx->q_data[Q_DATA_SRC];
1034                pix = &q_data->format.fmt.pix_mp;
1035                stride = ALIGN((pix->width * vpdma_fmt->depth) >> 3,
1036                               VPDMA_STRIDE_ALIGN);
1037        } else {
1038                /* to incorporate interleaved formats */
1039                int plane = fmt->coplanar ? p_data->vb_part : 0;
1040
1041                pix = &q_data->format.fmt.pix_mp;
1042                vpdma_fmt = fmt->vpdma_fmt[plane];
1043                /*
1044                 * If we are using a single plane buffer and
1045                 * we need to set a separate vpdma chroma channel.
1046                 */
1047                if (pix->num_planes == 1 && plane) {
1048                        dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1049                        /* Compute required offset */
1050                        offset = pix->plane_fmt[0].bytesperline * pix->height;
1051                } else {
1052                        dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
1053                        /* Use address as is, no offset */
1054                        offset = 0;
1055                }
1056                if (!dma_addr) {
1057                        vpe_err(ctx->dev,
1058                                "acquiring output buffer(%d) dma_addr failed\n",
1059                                port);
1060                        return;
1061                }
1062                /* Apply the offset */
1063                dma_addr += offset;
1064                stride = pix->plane_fmt[VPE_LUMA].bytesperline;
1065        }
1066
1067        if (q_data->flags & Q_DATA_FRAME_1D)
1068                flags |= VPDMA_DATA_FRAME_1D;
1069        if (q_data->flags & Q_DATA_MODE_TILED)
1070                flags |= VPDMA_DATA_MODE_TILED;
1071
1072        vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1,
1073                           MAX_W, MAX_H);
1074
1075        vpdma_add_out_dtd(&ctx->desc_list, pix->width,
1076                          stride, &q_data->c_rect,
1077                          vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1,
1078                          MAX_OUT_HEIGHT_REG1, p_data->channel, flags);
1079}
1080
1081static void add_in_dtd(struct vpe_ctx *ctx, int port)
1082{
1083        struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC];
1084        const struct vpe_port_data *p_data = &port_data[port];
1085        struct vb2_buffer *vb = &ctx->src_vbs[p_data->vb_index]->vb2_buf;
1086        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1087        struct vpe_fmt *fmt = q_data->fmt;
1088        struct v4l2_pix_format_mplane *pix;
1089        const struct vpdma_data_format *vpdma_fmt;
1090        int mv_buf_selector = ctx->src_mv_buf_selector;
1091        int field = vbuf->field == V4L2_FIELD_BOTTOM;
1092        int frame_width, frame_height;
1093        dma_addr_t dma_addr;
1094        u32 flags = 0;
1095        u32 offset = 0;
1096        u32 stride;
1097
1098        pix = &q_data->format.fmt.pix_mp;
1099        if (port == VPE_PORT_MV_IN) {
1100                vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
1101                dma_addr = ctx->mv_buf_dma[mv_buf_selector];
1102                stride = ALIGN((pix->width * vpdma_fmt->depth) >> 3,
1103                               VPDMA_STRIDE_ALIGN);
1104        } else {
1105                /* to incorporate interleaved formats */
1106                int plane = fmt->coplanar ? p_data->vb_part : 0;
1107
1108                vpdma_fmt = fmt->vpdma_fmt[plane];
1109                /*
1110                 * If we are using a single plane buffer and
1111                 * we need to set a separate vpdma chroma channel.
1112                 */
1113                if (pix->num_planes == 1 && plane) {
1114                        dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1115                        /* Compute required offset */
1116                        offset = pix->plane_fmt[0].bytesperline * pix->height;
1117                } else {
1118                        dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
1119                        /* Use address as is, no offset */
1120                        offset = 0;
1121                }
1122                if (!dma_addr) {
1123                        vpe_err(ctx->dev,
1124                                "acquiring output buffer(%d) dma_addr failed\n",
1125                                port);
1126                        return;
1127                }
1128                /* Apply the offset */
1129                dma_addr += offset;
1130                stride = pix->plane_fmt[VPE_LUMA].bytesperline;
1131
1132                /*
1133                 * field used in VPDMA desc  = 0 (top) / 1 (bottom)
1134                 * Use top or bottom field from same vb alternately
1135                 * For each de-interlacing operation, f,f-1,f-2 should be one
1136                 * of TBT or BTB
1137                 */
1138                if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB ||
1139                    q_data->flags & Q_DATA_INTERLACED_SEQ_BT) {
1140                        /* Select initial value based on format */
1141                        if (q_data->flags & Q_DATA_INTERLACED_SEQ_BT)
1142                                field = 1;
1143                        else
1144                                field = 0;
1145
1146                        /* Toggle for each vb_index and each operation */
1147                        field = (field + p_data->vb_index + ctx->sequence) % 2;
1148
1149                        if (field) {
1150                                int height = pix->height / 2;
1151                                int bpp;
1152
1153                                if (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
1154                                    fmt->fourcc == V4L2_PIX_FMT_NV21)
1155                                        bpp = 1;
1156                                else
1157                                        bpp = vpdma_fmt->depth >> 3;
1158
1159                                if (plane)
1160                                        height /= 2;
1161
1162                                dma_addr += pix->width * height * bpp;
1163                        }
1164                }
1165        }
1166
1167        if (q_data->flags & Q_DATA_FRAME_1D)
1168                flags |= VPDMA_DATA_FRAME_1D;
1169        if (q_data->flags & Q_DATA_MODE_TILED)
1170                flags |= VPDMA_DATA_MODE_TILED;
1171
1172        frame_width = q_data->c_rect.width;
1173        frame_height = q_data->c_rect.height;
1174
1175        if (p_data->vb_part && (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
1176                                fmt->fourcc == V4L2_PIX_FMT_NV21))
1177                frame_height /= 2;
1178
1179        vpdma_add_in_dtd(&ctx->desc_list, pix->width, stride,
1180                         &q_data->c_rect, vpdma_fmt, dma_addr,
1181                         p_data->channel, field, flags, frame_width,
1182                         frame_height, 0, 0);
1183}
1184
1185/*
1186 * Enable the expected IRQ sources
1187 */
1188static void enable_irqs(struct vpe_ctx *ctx)
1189{
1190        write_reg(ctx->dev, VPE_INT0_ENABLE0_SET, VPE_INT0_LIST0_COMPLETE);
1191        write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT |
1192                                VPE_DS1_UV_ERROR_INT);
1193
1194        vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, true);
1195}
1196
1197static void disable_irqs(struct vpe_ctx *ctx)
1198{
1199        write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff);
1200        write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff);
1201
1202        vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, false);
1203}
1204
1205/* device_run() - prepares and starts the device
1206 *
1207 * This function is only called when both the source and destination
1208 * buffers are in place.
1209 */
1210static void device_run(void *priv)
1211{
1212        struct vpe_ctx *ctx = priv;
1213        struct sc_data *sc = ctx->dev->sc;
1214        struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
1215        struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
1216        const struct v4l2_format_info *d_finfo;
1217
1218        d_finfo = v4l2_format_info(d_q_data->fmt->fourcc);
1219
1220        if (ctx->deinterlacing && s_q_data->flags & Q_IS_SEQ_XX &&
1221            ctx->sequence % 2 == 0) {
1222                /* When using SEQ_XX type buffers, each buffer has two fields
1223                 * each buffer has two fields (top & bottom)
1224                 * Removing one buffer is actually getting two fields
1225                 * Alternate between two operations:-
1226                 * Even : consume one field but DO NOT REMOVE from queue
1227                 * Odd : consume other field and REMOVE from queue
1228                 */
1229                ctx->src_vbs[0] = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1230                WARN_ON(ctx->src_vbs[0] == NULL);
1231        } else {
1232                ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1233                WARN_ON(ctx->src_vbs[0] == NULL);
1234        }
1235
1236        ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1237        WARN_ON(ctx->dst_vb == NULL);
1238
1239        if (ctx->deinterlacing) {
1240
1241                if (ctx->src_vbs[2] == NULL) {
1242                        ctx->src_vbs[2] = ctx->src_vbs[0];
1243                        WARN_ON(ctx->src_vbs[2] == NULL);
1244                        ctx->src_vbs[1] = ctx->src_vbs[0];
1245                        WARN_ON(ctx->src_vbs[1] == NULL);
1246                }
1247
1248                /*
1249                 * we have output the first 2 frames through line average, we
1250                 * now switch to EDI de-interlacer
1251                 */
1252                if (ctx->sequence == 2)
1253                        config_edi_input_mode(ctx, 0x3); /* EDI (Y + UV) */
1254        }
1255
1256        /* config descriptors */
1257        if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) {
1258                vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb);
1259                vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb);
1260
1261                set_line_modes(ctx);
1262
1263                ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr;
1264                ctx->load_mmrs = false;
1265        }
1266
1267        if (sc->loaded_coeff_h != ctx->sc_coeff_h.dma_addr ||
1268                        sc->load_coeff_h) {
1269                vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_h);
1270                vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT,
1271                        &ctx->sc_coeff_h, 0);
1272
1273                sc->loaded_coeff_h = ctx->sc_coeff_h.dma_addr;
1274                sc->load_coeff_h = false;
1275        }
1276
1277        if (sc->loaded_coeff_v != ctx->sc_coeff_v.dma_addr ||
1278                        sc->load_coeff_v) {
1279                vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_v);
1280                vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT,
1281                        &ctx->sc_coeff_v, SC_COEF_SRAM_SIZE >> 4);
1282
1283                sc->loaded_coeff_v = ctx->sc_coeff_v.dma_addr;
1284                sc->load_coeff_v = false;
1285        }
1286
1287        /* output data descriptors */
1288        if (ctx->deinterlacing)
1289                add_out_dtd(ctx, VPE_PORT_MV_OUT);
1290
1291        if (v4l2_is_format_rgb(d_finfo)) {
1292                add_out_dtd(ctx, VPE_PORT_RGB_OUT);
1293        } else {
1294                add_out_dtd(ctx, VPE_PORT_LUMA_OUT);
1295                if (d_q_data->fmt->coplanar)
1296                        add_out_dtd(ctx, VPE_PORT_CHROMA_OUT);
1297        }
1298
1299        /* input data descriptors */
1300        if (ctx->deinterlacing) {
1301                add_in_dtd(ctx, VPE_PORT_LUMA3_IN);
1302                add_in_dtd(ctx, VPE_PORT_CHROMA3_IN);
1303
1304                add_in_dtd(ctx, VPE_PORT_LUMA2_IN);
1305                add_in_dtd(ctx, VPE_PORT_CHROMA2_IN);
1306        }
1307
1308        add_in_dtd(ctx, VPE_PORT_LUMA1_IN);
1309        add_in_dtd(ctx, VPE_PORT_CHROMA1_IN);
1310
1311        if (ctx->deinterlacing)
1312                add_in_dtd(ctx, VPE_PORT_MV_IN);
1313
1314        /* sync on channel control descriptors for input ports */
1315        vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA1_IN);
1316        vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA1_IN);
1317
1318        if (ctx->deinterlacing) {
1319                vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1320                        VPE_CHAN_LUMA2_IN);
1321                vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1322                        VPE_CHAN_CHROMA2_IN);
1323
1324                vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1325                        VPE_CHAN_LUMA3_IN);
1326                vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1327                        VPE_CHAN_CHROMA3_IN);
1328
1329                vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_IN);
1330        }
1331
1332        /* sync on channel control descriptors for output ports */
1333        if (v4l2_is_format_rgb(d_finfo)) {
1334                vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1335                        VPE_CHAN_RGB_OUT);
1336        } else {
1337                vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1338                        VPE_CHAN_LUMA_OUT);
1339                if (d_q_data->fmt->coplanar)
1340                        vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
1341                                VPE_CHAN_CHROMA_OUT);
1342        }
1343
1344        if (ctx->deinterlacing)
1345                vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT);
1346
1347        enable_irqs(ctx);
1348
1349        vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf);
1350        vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list, 0);
1351}
1352
1353static void dei_error(struct vpe_ctx *ctx)
1354{
1355        dev_warn(ctx->dev->v4l2_dev.dev,
1356                "received DEI error interrupt\n");
1357}
1358
1359static void ds1_uv_error(struct vpe_ctx *ctx)
1360{
1361        dev_warn(ctx->dev->v4l2_dev.dev,
1362                "received downsampler error interrupt\n");
1363}
1364
1365static irqreturn_t vpe_irq(int irq_vpe, void *data)
1366{
1367        struct vpe_dev *dev = (struct vpe_dev *)data;
1368        struct vpe_ctx *ctx;
1369        struct vpe_q_data *d_q_data;
1370        struct vb2_v4l2_buffer *s_vb, *d_vb;
1371        unsigned long flags;
1372        u32 irqst0, irqst1;
1373        bool list_complete = false;
1374
1375        irqst0 = read_reg(dev, VPE_INT0_STATUS0);
1376        if (irqst0) {
1377                write_reg(dev, VPE_INT0_STATUS0_CLR, irqst0);
1378                vpe_dbg(dev, "INT0_STATUS0 = 0x%08x\n", irqst0);
1379        }
1380
1381        irqst1 = read_reg(dev, VPE_INT0_STATUS1);
1382        if (irqst1) {
1383                write_reg(dev, VPE_INT0_STATUS1_CLR, irqst1);
1384                vpe_dbg(dev, "INT0_STATUS1 = 0x%08x\n", irqst1);
1385        }
1386
1387        ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
1388        if (!ctx) {
1389                vpe_err(dev, "instance released before end of transaction\n");
1390                goto handled;
1391        }
1392
1393        if (irqst1) {
1394                if (irqst1 & VPE_DEI_ERROR_INT) {
1395                        irqst1 &= ~VPE_DEI_ERROR_INT;
1396                        dei_error(ctx);
1397                }
1398                if (irqst1 & VPE_DS1_UV_ERROR_INT) {
1399                        irqst1 &= ~VPE_DS1_UV_ERROR_INT;
1400                        ds1_uv_error(ctx);
1401                }
1402        }
1403
1404        if (irqst0) {
1405                if (irqst0 & VPE_INT0_LIST0_COMPLETE)
1406                        vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0);
1407
1408                irqst0 &= ~(VPE_INT0_LIST0_COMPLETE);
1409                list_complete = true;
1410        }
1411
1412        if (irqst0 | irqst1) {
1413                dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n",
1414                        irqst0, irqst1);
1415        }
1416
1417        /*
1418         * Setup next operation only when list complete IRQ occurs
1419         * otherwise, skip the following code
1420         */
1421        if (!list_complete)
1422                goto handled;
1423
1424        disable_irqs(ctx);
1425
1426        vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
1427        vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb);
1428        vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h);
1429        vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v);
1430
1431        vpdma_reset_desc_list(&ctx->desc_list);
1432
1433         /* the previous dst mv buffer becomes the next src mv buffer */
1434        ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector;
1435
1436        s_vb = ctx->src_vbs[0];
1437        d_vb = ctx->dst_vb;
1438
1439        d_vb->flags = s_vb->flags;
1440        d_vb->vb2_buf.timestamp = s_vb->vb2_buf.timestamp;
1441
1442        if (s_vb->flags & V4L2_BUF_FLAG_TIMECODE)
1443                d_vb->timecode = s_vb->timecode;
1444
1445        d_vb->sequence = ctx->sequence;
1446        s_vb->sequence = ctx->sequence;
1447
1448        d_q_data = &ctx->q_data[Q_DATA_DST];
1449        if (d_q_data->flags & Q_IS_INTERLACED) {
1450                d_vb->field = ctx->field;
1451                if (ctx->field == V4L2_FIELD_BOTTOM) {
1452                        ctx->sequence++;
1453                        ctx->field = V4L2_FIELD_TOP;
1454                } else {
1455                        WARN_ON(ctx->field != V4L2_FIELD_TOP);
1456                        ctx->field = V4L2_FIELD_BOTTOM;
1457                }
1458        } else {
1459                d_vb->field = V4L2_FIELD_NONE;
1460                ctx->sequence++;
1461        }
1462
1463        if (ctx->deinterlacing) {
1464                /*
1465                 * Allow source buffer to be dequeued only if it won't be used
1466                 * in the next iteration. All vbs are initialized to first
1467                 * buffer and we are shifting buffers every iteration, for the
1468                 * first two iterations, no buffer will be dequeued.
1469                 * This ensures that driver will keep (n-2)th (n-1)th and (n)th
1470                 * field when deinterlacing is enabled
1471                 */
1472                if (ctx->src_vbs[2] != ctx->src_vbs[1])
1473                        s_vb = ctx->src_vbs[2];
1474                else
1475                        s_vb = NULL;
1476        }
1477
1478        spin_lock_irqsave(&dev->lock, flags);
1479
1480        if (s_vb)
1481                v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE);
1482
1483        v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_DONE);
1484
1485        spin_unlock_irqrestore(&dev->lock, flags);
1486
1487        if (ctx->deinterlacing) {
1488                ctx->src_vbs[2] = ctx->src_vbs[1];
1489                ctx->src_vbs[1] = ctx->src_vbs[0];
1490        }
1491
1492        /*
1493         * Since the vb2_buf_done has already been called fir therse
1494         * buffer we can now NULL them out so that we won't try
1495         * to clean out stray pointer later on.
1496        */
1497        ctx->src_vbs[0] = NULL;
1498        ctx->dst_vb = NULL;
1499
1500        if (ctx->aborting)
1501                goto finished;
1502
1503        ctx->bufs_completed++;
1504        if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) {
1505                device_run(ctx);
1506                goto handled;
1507        }
1508
1509finished:
1510        vpe_dbg(ctx->dev, "finishing transaction\n");
1511        ctx->bufs_completed = 0;
1512        v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
1513handled:
1514        return IRQ_HANDLED;
1515}
1516
1517/*
1518 * video ioctls
1519 */
1520static int vpe_querycap(struct file *file, void *priv,
1521                        struct v4l2_capability *cap)
1522{
1523        strscpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver));
1524        strscpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card));
1525        snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1526                VPE_MODULE_NAME);
1527        return 0;
1528}
1529
1530static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type)
1531{
1532        int i, index;
1533        struct vpe_fmt *fmt = NULL;
1534
1535        index = 0;
1536        for (i = 0; i < ARRAY_SIZE(vpe_formats); ++i) {
1537                if (vpe_formats[i].types & type) {
1538                        if (index == f->index) {
1539                                fmt = &vpe_formats[i];
1540                                break;
1541                        }
1542                        index++;
1543                }
1544        }
1545
1546        if (!fmt)
1547                return -EINVAL;
1548
1549        f->pixelformat = fmt->fourcc;
1550        return 0;
1551}
1552
1553static int vpe_enum_fmt(struct file *file, void *priv,
1554                                struct v4l2_fmtdesc *f)
1555{
1556        if (V4L2_TYPE_IS_OUTPUT(f->type))
1557                return __enum_fmt(f, VPE_FMT_TYPE_OUTPUT);
1558
1559        return __enum_fmt(f, VPE_FMT_TYPE_CAPTURE);
1560}
1561
1562static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1563{
1564        struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1565        struct vpe_ctx *ctx = file->private_data;
1566        struct vb2_queue *vq;
1567        struct vpe_q_data *q_data;
1568
1569        vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
1570        if (!vq)
1571                return -EINVAL;
1572
1573        q_data = get_q_data(ctx, f->type);
1574        if (!q_data)
1575                return -EINVAL;
1576
1577        *f = q_data->format;
1578
1579        if (V4L2_TYPE_IS_CAPTURE(f->type)) {
1580                struct vpe_q_data *s_q_data;
1581                struct v4l2_pix_format_mplane *spix;
1582
1583                /* get colorimetry from the source queue */
1584                s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
1585                spix = &s_q_data->format.fmt.pix_mp;
1586
1587                pix->colorspace = spix->colorspace;
1588                pix->xfer_func = spix->xfer_func;
1589                pix->ycbcr_enc = spix->ycbcr_enc;
1590                pix->quantization = spix->quantization;
1591        }
1592
1593        return 0;
1594}
1595
1596static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1597                       struct vpe_fmt *fmt, int type)
1598{
1599        struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1600        struct v4l2_plane_pix_format *plane_fmt;
1601        unsigned int w_align;
1602        int i, depth, depth_bytes, height;
1603        unsigned int stride = 0;
1604        const struct v4l2_format_info *finfo;
1605
1606        if (!fmt || !(fmt->types & type)) {
1607                vpe_dbg(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
1608                        pix->pixelformat);
1609                fmt = __find_format(V4L2_PIX_FMT_YUYV);
1610        }
1611
1612        if (pix->field != V4L2_FIELD_NONE &&
1613            pix->field != V4L2_FIELD_ALTERNATE &&
1614            pix->field != V4L2_FIELD_SEQ_TB &&
1615            pix->field != V4L2_FIELD_SEQ_BT)
1616                pix->field = V4L2_FIELD_NONE;
1617
1618        depth = fmt->vpdma_fmt[VPE_LUMA]->depth;
1619
1620        /*
1621         * the line stride should 16 byte aligned for VPDMA to work, based on
1622         * the bytes per pixel, figure out how much the width should be aligned
1623         * to make sure line stride is 16 byte aligned
1624         */
1625        depth_bytes = depth >> 3;
1626
1627        if (depth_bytes == 3) {
1628                /*
1629                 * if bpp is 3(as in some RGB formats), the pixel width doesn't
1630                 * really help in ensuring line stride is 16 byte aligned
1631                 */
1632                w_align = 4;
1633        } else {
1634                /*
1635                 * for the remainder bpp(4, 2 and 1), the pixel width alignment
1636                 * can ensure a line stride alignment of 16 bytes. For example,
1637                 * if bpp is 2, then the line stride can be 16 byte aligned if
1638                 * the width is 8 byte aligned
1639                 */
1640
1641                /*
1642                 * HACK: using order_base_2() here causes lots of asm output
1643                 * errors with smatch, on i386:
1644                 * ./arch/x86/include/asm/bitops.h:457:22:
1645                 *               warning: asm output is not an lvalue
1646                 * Perhaps some gcc optimization is doing the wrong thing
1647                 * there.
1648                 * Let's get rid of them by doing the calculus on two steps
1649                 */
1650                w_align = roundup_pow_of_two(VPDMA_DESC_ALIGN / depth_bytes);
1651                w_align = ilog2(w_align);
1652        }
1653
1654        v4l_bound_align_image(&pix->width, MIN_W, MAX_W, w_align,
1655                              &pix->height, MIN_H, MAX_H, H_ALIGN,
1656                              S_ALIGN);
1657
1658        if (!pix->num_planes || pix->num_planes > 2)
1659                pix->num_planes = fmt->coplanar ? 2 : 1;
1660        else if (pix->num_planes > 1 && !fmt->coplanar)
1661                pix->num_planes = 1;
1662
1663        pix->pixelformat = fmt->fourcc;
1664        finfo = v4l2_format_info(fmt->fourcc);
1665
1666        /*
1667         * For the actual image parameters, we need to consider the field
1668         * height of the image for SEQ_XX buffers.
1669         */
1670        if (pix->field == V4L2_FIELD_SEQ_TB || pix->field == V4L2_FIELD_SEQ_BT)
1671                height = pix->height / 2;
1672        else
1673                height = pix->height;
1674
1675        if (!pix->colorspace) {
1676                if (v4l2_is_format_rgb(finfo)) {
1677                        pix->colorspace = V4L2_COLORSPACE_SRGB;
1678                } else {
1679                        if (height > 1280)      /* HD */
1680                                pix->colorspace = V4L2_COLORSPACE_REC709;
1681                        else                    /* SD */
1682                                pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1683                }
1684        }
1685
1686        for (i = 0; i < pix->num_planes; i++) {
1687                plane_fmt = &pix->plane_fmt[i];
1688                depth = fmt->vpdma_fmt[i]->depth;
1689
1690                stride = (pix->width * fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
1691                if (stride > plane_fmt->bytesperline)
1692                        plane_fmt->bytesperline = stride;
1693
1694                plane_fmt->bytesperline = clamp_t(u32, plane_fmt->bytesperline,
1695                                                  stride,
1696                                                  VPDMA_MAX_STRIDE);
1697
1698                plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline,
1699                                                VPDMA_STRIDE_ALIGN);
1700
1701                if (i == VPE_LUMA) {
1702                        plane_fmt->sizeimage = pix->height *
1703                                               plane_fmt->bytesperline;
1704
1705                        if (pix->num_planes == 1 && fmt->coplanar)
1706                                plane_fmt->sizeimage += pix->height *
1707                                        plane_fmt->bytesperline *
1708                                        fmt->vpdma_fmt[VPE_CHROMA]->depth >> 3;
1709
1710                } else { /* i == VIP_CHROMA */
1711                        plane_fmt->sizeimage = (pix->height *
1712                                               plane_fmt->bytesperline *
1713                                               depth) >> 3;
1714                }
1715        }
1716
1717        return 0;
1718}
1719
1720static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1721{
1722        struct vpe_ctx *ctx = file->private_data;
1723        struct vpe_fmt *fmt = find_format(f);
1724
1725        if (V4L2_TYPE_IS_OUTPUT(f->type))
1726                return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_OUTPUT);
1727        else
1728                return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_CAPTURE);
1729}
1730
1731static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
1732{
1733        struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1734        struct v4l2_pix_format_mplane *qpix;
1735        struct vpe_q_data *q_data;
1736        struct vb2_queue *vq;
1737
1738        vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
1739        if (!vq)
1740                return -EINVAL;
1741
1742        if (vb2_is_busy(vq)) {
1743                vpe_err(ctx->dev, "queue busy\n");
1744                return -EBUSY;
1745        }
1746
1747        q_data = get_q_data(ctx, f->type);
1748        if (!q_data)
1749                return -EINVAL;
1750
1751        qpix = &q_data->format.fmt.pix_mp;
1752        q_data->fmt             = find_format(f);
1753        q_data->format = *f;
1754
1755        q_data->c_rect.left     = 0;
1756        q_data->c_rect.top      = 0;
1757        q_data->c_rect.width    = pix->width;
1758        q_data->c_rect.height   = pix->height;
1759
1760        if (qpix->field == V4L2_FIELD_ALTERNATE)
1761                q_data->flags |= Q_DATA_INTERLACED_ALTERNATE;
1762        else if (qpix->field == V4L2_FIELD_SEQ_TB)
1763                q_data->flags |= Q_DATA_INTERLACED_SEQ_TB;
1764        else if (qpix->field == V4L2_FIELD_SEQ_BT)
1765                q_data->flags |= Q_DATA_INTERLACED_SEQ_BT;
1766        else
1767                q_data->flags &= ~Q_IS_INTERLACED;
1768
1769        /* the crop height is halved for the case of SEQ_XX buffers */
1770        if (q_data->flags & Q_IS_SEQ_XX)
1771                q_data->c_rect.height /= 2;
1772
1773        vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d",
1774                f->type, pix->width, pix->height, pix->pixelformat,
1775                pix->plane_fmt[0].bytesperline);
1776        if (pix->num_planes == 2)
1777                vpe_dbg(ctx->dev, " bpl_uv %d\n",
1778                        pix->plane_fmt[1].bytesperline);
1779
1780        return 0;
1781}
1782
1783static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
1784{
1785        int ret;
1786        struct vpe_ctx *ctx = file->private_data;
1787
1788        ret = vpe_try_fmt(file, priv, f);
1789        if (ret)
1790                return ret;
1791
1792        ret = __vpe_s_fmt(ctx, f);
1793        if (ret)
1794                return ret;
1795
1796        if (V4L2_TYPE_IS_OUTPUT(f->type))
1797                set_src_registers(ctx);
1798        else
1799                set_dst_registers(ctx);
1800
1801        return set_srcdst_params(ctx);
1802}
1803
1804static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
1805{
1806        struct vpe_q_data *q_data;
1807        struct v4l2_pix_format_mplane *pix;
1808        int height;
1809
1810        if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
1811            (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
1812                return -EINVAL;
1813
1814        q_data = get_q_data(ctx, s->type);
1815        if (!q_data)
1816                return -EINVAL;
1817
1818        pix = &q_data->format.fmt.pix_mp;
1819
1820        switch (s->target) {
1821        case V4L2_SEL_TGT_COMPOSE:
1822                /*
1823                 * COMPOSE target is only valid for capture buffer type, return
1824                 * error for output buffer type
1825                 */
1826                if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1827                        return -EINVAL;
1828                break;
1829        case V4L2_SEL_TGT_CROP:
1830                /*
1831                 * CROP target is only valid for output buffer type, return
1832                 * error for capture buffer type
1833                 */
1834                if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1835                        return -EINVAL;
1836                break;
1837        /*
1838         * bound and default crop/compose targets are invalid targets to
1839         * try/set
1840         */
1841        default:
1842                return -EINVAL;
1843        }
1844
1845        /*
1846         * For SEQ_XX buffers, crop height should be less than the height of
1847         * the field height, not the buffer height
1848         */
1849        if (q_data->flags & Q_IS_SEQ_XX)
1850                height = pix->height / 2;
1851        else
1852                height = pix->height;
1853
1854        if (s->r.top < 0 || s->r.left < 0) {
1855                vpe_err(ctx->dev, "negative values for top and left\n");
1856                s->r.top = s->r.left = 0;
1857        }
1858
1859        v4l_bound_align_image(&s->r.width, MIN_W, pix->width, 1,
1860                &s->r.height, MIN_H, height, H_ALIGN, S_ALIGN);
1861
1862        /* adjust left/top if cropping rectangle is out of bounds */
1863        if (s->r.left + s->r.width > pix->width)
1864                s->r.left = pix->width - s->r.width;
1865        if (s->r.top + s->r.height > pix->height)
1866                s->r.top = pix->height - s->r.height;
1867
1868        return 0;
1869}
1870
1871static int vpe_g_selection(struct file *file, void *fh,
1872                struct v4l2_selection *s)
1873{
1874        struct vpe_ctx *ctx = file->private_data;
1875        struct vpe_q_data *q_data;
1876        struct v4l2_pix_format_mplane *pix;
1877        bool use_c_rect = false;
1878
1879        if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
1880            (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
1881                return -EINVAL;
1882
1883        q_data = get_q_data(ctx, s->type);
1884        if (!q_data)
1885                return -EINVAL;
1886
1887        pix = &q_data->format.fmt.pix_mp;
1888
1889        switch (s->target) {
1890        case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1891        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1892                if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1893                        return -EINVAL;
1894                break;
1895        case V4L2_SEL_TGT_CROP_BOUNDS:
1896        case V4L2_SEL_TGT_CROP_DEFAULT:
1897                if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1898                        return -EINVAL;
1899                break;
1900        case V4L2_SEL_TGT_COMPOSE:
1901                if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1902                        return -EINVAL;
1903                use_c_rect = true;
1904                break;
1905        case V4L2_SEL_TGT_CROP:
1906                if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1907                        return -EINVAL;
1908                use_c_rect = true;
1909                break;
1910        default:
1911                return -EINVAL;
1912        }
1913
1914        if (use_c_rect) {
1915                /*
1916                 * for CROP/COMPOSE target type, return c_rect params from the
1917                 * respective buffer type
1918                 */
1919                s->r = q_data->c_rect;
1920        } else {
1921                /*
1922                 * for DEFAULT/BOUNDS target type, return width and height from
1923                 * S_FMT of the respective buffer type
1924                 */
1925                s->r.left = 0;
1926                s->r.top = 0;
1927                s->r.width = pix->width;
1928                s->r.height = pix->height;
1929        }
1930
1931        return 0;
1932}
1933
1934
1935static int vpe_s_selection(struct file *file, void *fh,
1936                struct v4l2_selection *s)
1937{
1938        struct vpe_ctx *ctx = file->private_data;
1939        struct vpe_q_data *q_data;
1940        struct v4l2_selection sel = *s;
1941        int ret;
1942
1943        ret = __vpe_try_selection(ctx, &sel);
1944        if (ret)
1945                return ret;
1946
1947        q_data = get_q_data(ctx, sel.type);
1948        if (!q_data)
1949                return -EINVAL;
1950
1951        if ((q_data->c_rect.left == sel.r.left) &&
1952                        (q_data->c_rect.top == sel.r.top) &&
1953                        (q_data->c_rect.width == sel.r.width) &&
1954                        (q_data->c_rect.height == sel.r.height)) {
1955                vpe_dbg(ctx->dev,
1956                        "requested crop/compose values are already set\n");
1957                return 0;
1958        }
1959
1960        q_data->c_rect = sel.r;
1961
1962        return set_srcdst_params(ctx);
1963}
1964
1965/*
1966 * defines number of buffers/frames a context can process with VPE before
1967 * switching to a different context. default value is 1 buffer per context
1968 */
1969#define V4L2_CID_VPE_BUFS_PER_JOB               (V4L2_CID_USER_TI_VPE_BASE + 0)
1970
1971static int vpe_s_ctrl(struct v4l2_ctrl *ctrl)
1972{
1973        struct vpe_ctx *ctx =
1974                container_of(ctrl->handler, struct vpe_ctx, hdl);
1975
1976        switch (ctrl->id) {
1977        case V4L2_CID_VPE_BUFS_PER_JOB:
1978                ctx->bufs_per_job = ctrl->val;
1979                break;
1980
1981        default:
1982                vpe_err(ctx->dev, "Invalid control\n");
1983                return -EINVAL;
1984        }
1985
1986        return 0;
1987}
1988
1989static const struct v4l2_ctrl_ops vpe_ctrl_ops = {
1990        .s_ctrl = vpe_s_ctrl,
1991};
1992
1993static const struct v4l2_ioctl_ops vpe_ioctl_ops = {
1994        .vidioc_querycap                = vpe_querycap,
1995
1996        .vidioc_enum_fmt_vid_cap        = vpe_enum_fmt,
1997        .vidioc_g_fmt_vid_cap_mplane    = vpe_g_fmt,
1998        .vidioc_try_fmt_vid_cap_mplane  = vpe_try_fmt,
1999        .vidioc_s_fmt_vid_cap_mplane    = vpe_s_fmt,
2000
2001        .vidioc_enum_fmt_vid_out        = vpe_enum_fmt,
2002        .vidioc_g_fmt_vid_out_mplane    = vpe_g_fmt,
2003        .vidioc_try_fmt_vid_out_mplane  = vpe_try_fmt,
2004        .vidioc_s_fmt_vid_out_mplane    = vpe_s_fmt,
2005
2006        .vidioc_g_selection             = vpe_g_selection,
2007        .vidioc_s_selection             = vpe_s_selection,
2008
2009        .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
2010        .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
2011        .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
2012        .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
2013        .vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
2014        .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
2015        .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
2016
2017        .vidioc_subscribe_event         = v4l2_ctrl_subscribe_event,
2018        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
2019};
2020
2021/*
2022 * Queue operations
2023 */
2024static int vpe_queue_setup(struct vb2_queue *vq,
2025                           unsigned int *nbuffers, unsigned int *nplanes,
2026                           unsigned int sizes[], struct device *alloc_devs[])
2027{
2028        int i;
2029        struct vpe_ctx *ctx = vb2_get_drv_priv(vq);
2030        struct vpe_q_data *q_data;
2031        struct v4l2_pix_format_mplane *pix;
2032
2033        q_data = get_q_data(ctx, vq->type);
2034        if (!q_data)
2035                return -EINVAL;
2036
2037        pix = &q_data->format.fmt.pix_mp;
2038        *nplanes = pix->num_planes;
2039
2040        for (i = 0; i < *nplanes; i++)
2041                sizes[i] = pix->plane_fmt[i].sizeimage;
2042
2043        vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers,
2044                sizes[VPE_LUMA]);
2045        if (*nplanes == 2)
2046                vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]);
2047
2048        return 0;
2049}
2050
2051static int vpe_buf_prepare(struct vb2_buffer *vb)
2052{
2053        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2054        struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2055        struct vpe_q_data *q_data;
2056        struct v4l2_pix_format_mplane *pix;
2057        int i;
2058
2059        vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type);
2060
2061        q_data = get_q_data(ctx, vb->vb2_queue->type);
2062        if (!q_data)
2063                return -EINVAL;
2064
2065        pix = &q_data->format.fmt.pix_mp;
2066
2067        if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
2068                if (!(q_data->flags & Q_IS_INTERLACED)) {
2069                        vbuf->field = V4L2_FIELD_NONE;
2070                } else {
2071                        if (vbuf->field != V4L2_FIELD_TOP &&
2072                            vbuf->field != V4L2_FIELD_BOTTOM &&
2073                            vbuf->field != V4L2_FIELD_SEQ_TB &&
2074                            vbuf->field != V4L2_FIELD_SEQ_BT)
2075                                return -EINVAL;
2076                }
2077        }
2078
2079        for (i = 0; i < pix->num_planes; i++) {
2080                if (vb2_plane_size(vb, i) < pix->plane_fmt[i].sizeimage) {
2081                        vpe_err(ctx->dev,
2082                                "data will not fit into plane (%lu < %lu)\n",
2083                                vb2_plane_size(vb, i),
2084                                (long)pix->plane_fmt[i].sizeimage);
2085                        return -EINVAL;
2086                }
2087        }
2088
2089        for (i = 0; i < pix->num_planes; i++)
2090                vb2_set_plane_payload(vb, i, pix->plane_fmt[i].sizeimage);
2091
2092        return 0;
2093}
2094
2095static void vpe_buf_queue(struct vb2_buffer *vb)
2096{
2097        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2098        struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2099
2100        v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2101}
2102
2103static int check_srcdst_sizes(struct vpe_ctx *ctx)
2104{
2105        struct vpe_q_data *s_q_data =  &ctx->q_data[Q_DATA_SRC];
2106        struct vpe_q_data *d_q_data =  &ctx->q_data[Q_DATA_DST];
2107        unsigned int src_w = s_q_data->c_rect.width;
2108        unsigned int src_h = s_q_data->c_rect.height;
2109        unsigned int dst_w = d_q_data->c_rect.width;
2110        unsigned int dst_h = d_q_data->c_rect.height;
2111
2112        if (src_w == dst_w && src_h == dst_h)
2113                return 0;
2114
2115        if (src_h <= SC_MAX_PIXEL_HEIGHT &&
2116            src_w <= SC_MAX_PIXEL_WIDTH &&
2117            dst_h <= SC_MAX_PIXEL_HEIGHT &&
2118            dst_w <= SC_MAX_PIXEL_WIDTH)
2119                return 0;
2120
2121        return -1;
2122}
2123
2124static void vpe_return_all_buffers(struct vpe_ctx *ctx,  struct vb2_queue *q,
2125                                   enum vb2_buffer_state state)
2126{
2127        struct vb2_v4l2_buffer *vb;
2128        unsigned long flags;
2129
2130        for (;;) {
2131                if (V4L2_TYPE_IS_OUTPUT(q->type))
2132                        vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
2133                else
2134                        vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
2135                if (!vb)
2136                        break;
2137                spin_lock_irqsave(&ctx->dev->lock, flags);
2138                v4l2_m2m_buf_done(vb, state);
2139                spin_unlock_irqrestore(&ctx->dev->lock, flags);
2140        }
2141
2142        /*
2143         * Cleanup the in-transit vb2 buffers that have been
2144         * removed from their respective queue already but for
2145         * which procecessing has not been completed yet.
2146         */
2147        if (V4L2_TYPE_IS_OUTPUT(q->type)) {
2148                spin_lock_irqsave(&ctx->dev->lock, flags);
2149
2150                if (ctx->src_vbs[2])
2151                        v4l2_m2m_buf_done(ctx->src_vbs[2], state);
2152
2153                if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
2154                        v4l2_m2m_buf_done(ctx->src_vbs[1], state);
2155
2156                if (ctx->src_vbs[0] &&
2157                    (ctx->src_vbs[0] != ctx->src_vbs[1]) &&
2158                    (ctx->src_vbs[0] != ctx->src_vbs[2]))
2159                        v4l2_m2m_buf_done(ctx->src_vbs[0], state);
2160
2161                ctx->src_vbs[2] = NULL;
2162                ctx->src_vbs[1] = NULL;
2163                ctx->src_vbs[0] = NULL;
2164
2165                spin_unlock_irqrestore(&ctx->dev->lock, flags);
2166        } else {
2167                if (ctx->dst_vb) {
2168                        spin_lock_irqsave(&ctx->dev->lock, flags);
2169
2170                        v4l2_m2m_buf_done(ctx->dst_vb, state);
2171                        ctx->dst_vb = NULL;
2172                        spin_unlock_irqrestore(&ctx->dev->lock, flags);
2173                }
2174        }
2175}
2176
2177static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
2178{
2179        struct vpe_ctx *ctx = vb2_get_drv_priv(q);
2180
2181        /* Check any of the size exceed maximum scaling sizes */
2182        if (check_srcdst_sizes(ctx)) {
2183                vpe_err(ctx->dev,
2184                        "Conversion setup failed, check source and destination parameters\n"
2185                        );
2186                vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_QUEUED);
2187                return -EINVAL;
2188        }
2189
2190        if (ctx->deinterlacing)
2191                config_edi_input_mode(ctx, 0x0);
2192
2193        if (ctx->sequence != 0)
2194                set_srcdst_params(ctx);
2195
2196        return 0;
2197}
2198
2199static void vpe_stop_streaming(struct vb2_queue *q)
2200{
2201        struct vpe_ctx *ctx = vb2_get_drv_priv(q);
2202
2203        vpe_dump_regs(ctx->dev);
2204        vpdma_dump_regs(ctx->dev->vpdma);
2205
2206        vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_ERROR);
2207}
2208
2209static const struct vb2_ops vpe_qops = {
2210        .queue_setup     = vpe_queue_setup,
2211        .buf_prepare     = vpe_buf_prepare,
2212        .buf_queue       = vpe_buf_queue,
2213        .wait_prepare    = vb2_ops_wait_prepare,
2214        .wait_finish     = vb2_ops_wait_finish,
2215        .start_streaming = vpe_start_streaming,
2216        .stop_streaming  = vpe_stop_streaming,
2217};
2218
2219static int queue_init(void *priv, struct vb2_queue *src_vq,
2220                      struct vb2_queue *dst_vq)
2221{
2222        struct vpe_ctx *ctx = priv;
2223        struct vpe_dev *dev = ctx->dev;
2224        int ret;
2225
2226        memset(src_vq, 0, sizeof(*src_vq));
2227        src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2228        src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2229        src_vq->drv_priv = ctx;
2230        src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2231        src_vq->ops = &vpe_qops;
2232        src_vq->mem_ops = &vb2_dma_contig_memops;
2233        src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2234        src_vq->lock = &dev->dev_mutex;
2235        src_vq->dev = dev->v4l2_dev.dev;
2236
2237        ret = vb2_queue_init(src_vq);
2238        if (ret)
2239                return ret;
2240
2241        memset(dst_vq, 0, sizeof(*dst_vq));
2242        dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2243        dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2244        dst_vq->drv_priv = ctx;
2245        dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2246        dst_vq->ops = &vpe_qops;
2247        dst_vq->mem_ops = &vb2_dma_contig_memops;
2248        dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2249        dst_vq->lock = &dev->dev_mutex;
2250        dst_vq->dev = dev->v4l2_dev.dev;
2251
2252        return vb2_queue_init(dst_vq);
2253}
2254
2255static const struct v4l2_ctrl_config vpe_bufs_per_job = {
2256        .ops = &vpe_ctrl_ops,
2257        .id = V4L2_CID_VPE_BUFS_PER_JOB,
2258        .name = "Buffers Per Transaction",
2259        .type = V4L2_CTRL_TYPE_INTEGER,
2260        .def = VPE_DEF_BUFS_PER_JOB,
2261        .min = 1,
2262        .max = VIDEO_MAX_FRAME,
2263        .step = 1,
2264};
2265
2266/*
2267 * File operations
2268 */
2269static int vpe_open(struct file *file)
2270{
2271        struct vpe_dev *dev = video_drvdata(file);
2272        struct vpe_q_data *s_q_data;
2273        struct v4l2_ctrl_handler *hdl;
2274        struct vpe_ctx *ctx;
2275        struct v4l2_pix_format_mplane *pix;
2276        int ret;
2277
2278        vpe_dbg(dev, "vpe_open\n");
2279
2280        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2281        if (!ctx)
2282                return -ENOMEM;
2283
2284        ctx->dev = dev;
2285
2286        if (mutex_lock_interruptible(&dev->dev_mutex)) {
2287                ret = -ERESTARTSYS;
2288                goto free_ctx;
2289        }
2290
2291        ret = vpdma_create_desc_list(&ctx->desc_list, VPE_DESC_LIST_SIZE,
2292                        VPDMA_LIST_TYPE_NORMAL);
2293        if (ret != 0)
2294                goto unlock;
2295
2296        ret = vpdma_alloc_desc_buf(&ctx->mmr_adb, sizeof(struct vpe_mmr_adb));
2297        if (ret != 0)
2298                goto free_desc_list;
2299
2300        ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_h, SC_COEF_SRAM_SIZE);
2301        if (ret != 0)
2302                goto free_mmr_adb;
2303
2304        ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_v, SC_COEF_SRAM_SIZE);
2305        if (ret != 0)
2306                goto free_sc_h;
2307
2308        init_adb_hdrs(ctx);
2309
2310        v4l2_fh_init(&ctx->fh, video_devdata(file));
2311        file->private_data = ctx;
2312
2313        hdl = &ctx->hdl;
2314        v4l2_ctrl_handler_init(hdl, 1);
2315        v4l2_ctrl_new_custom(hdl, &vpe_bufs_per_job, NULL);
2316        if (hdl->error) {
2317                ret = hdl->error;
2318                goto exit_fh;
2319        }
2320        ctx->fh.ctrl_handler = hdl;
2321        v4l2_ctrl_handler_setup(hdl);
2322
2323        s_q_data = &ctx->q_data[Q_DATA_SRC];
2324        pix = &s_q_data->format.fmt.pix_mp;
2325        s_q_data->fmt = __find_format(V4L2_PIX_FMT_YUYV);
2326        pix->pixelformat = s_q_data->fmt->fourcc;
2327        s_q_data->format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2328        pix->width = 1920;
2329        pix->height = 1080;
2330        pix->num_planes = 1;
2331        pix->plane_fmt[VPE_LUMA].bytesperline = (pix->width *
2332                        s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
2333        pix->plane_fmt[VPE_LUMA].sizeimage =
2334                        pix->plane_fmt[VPE_LUMA].bytesperline *
2335                        pix->height;
2336        pix->colorspace = V4L2_COLORSPACE_REC709;
2337        pix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
2338        pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
2339        pix->quantization = V4L2_QUANTIZATION_DEFAULT;
2340        pix->field = V4L2_FIELD_NONE;
2341        s_q_data->c_rect.left = 0;
2342        s_q_data->c_rect.top = 0;
2343        s_q_data->c_rect.width = pix->width;
2344        s_q_data->c_rect.height = pix->height;
2345        s_q_data->flags = 0;
2346
2347        ctx->q_data[Q_DATA_DST] = *s_q_data;
2348        ctx->q_data[Q_DATA_DST].format.type =
2349                        V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2350
2351        set_dei_shadow_registers(ctx);
2352        set_src_registers(ctx);
2353        set_dst_registers(ctx);
2354        ret = set_srcdst_params(ctx);
2355        if (ret)
2356                goto exit_fh;
2357
2358        ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
2359
2360        if (IS_ERR(ctx->fh.m2m_ctx)) {
2361                ret = PTR_ERR(ctx->fh.m2m_ctx);
2362                goto exit_fh;
2363        }
2364
2365        v4l2_fh_add(&ctx->fh);
2366
2367        /*
2368         * for now, just report the creation of the first instance, we can later
2369         * optimize the driver to enable or disable clocks when the first
2370         * instance is created or the last instance released
2371         */
2372        if (atomic_inc_return(&dev->num_instances) == 1)
2373                vpe_dbg(dev, "first instance created\n");
2374
2375        ctx->bufs_per_job = VPE_DEF_BUFS_PER_JOB;
2376
2377        ctx->load_mmrs = true;
2378
2379        vpe_dbg(dev, "created instance %p, m2m_ctx: %p\n",
2380                ctx, ctx->fh.m2m_ctx);
2381
2382        mutex_unlock(&dev->dev_mutex);
2383
2384        return 0;
2385exit_fh:
2386        v4l2_ctrl_handler_free(hdl);
2387        v4l2_fh_exit(&ctx->fh);
2388        vpdma_free_desc_buf(&ctx->sc_coeff_v);
2389free_sc_h:
2390        vpdma_free_desc_buf(&ctx->sc_coeff_h);
2391free_mmr_adb:
2392        vpdma_free_desc_buf(&ctx->mmr_adb);
2393free_desc_list:
2394        vpdma_free_desc_list(&ctx->desc_list);
2395unlock:
2396        mutex_unlock(&dev->dev_mutex);
2397free_ctx:
2398        kfree(ctx);
2399        return ret;
2400}
2401
2402static int vpe_release(struct file *file)
2403{
2404        struct vpe_dev *dev = video_drvdata(file);
2405        struct vpe_ctx *ctx = file->private_data;
2406
2407        vpe_dbg(dev, "releasing instance %p\n", ctx);
2408
2409        mutex_lock(&dev->dev_mutex);
2410        free_mv_buffers(ctx);
2411
2412        vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
2413        vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb);
2414        vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h);
2415        vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v);
2416
2417        vpdma_free_desc_list(&ctx->desc_list);
2418        vpdma_free_desc_buf(&ctx->mmr_adb);
2419
2420        vpdma_free_desc_buf(&ctx->sc_coeff_v);
2421        vpdma_free_desc_buf(&ctx->sc_coeff_h);
2422
2423        v4l2_fh_del(&ctx->fh);
2424        v4l2_fh_exit(&ctx->fh);
2425        v4l2_ctrl_handler_free(&ctx->hdl);
2426        v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2427
2428        kfree(ctx);
2429
2430        /*
2431         * for now, just report the release of the last instance, we can later
2432         * optimize the driver to enable or disable clocks when the first
2433         * instance is created or the last instance released
2434         */
2435        if (atomic_dec_return(&dev->num_instances) == 0)
2436                vpe_dbg(dev, "last instance released\n");
2437
2438        mutex_unlock(&dev->dev_mutex);
2439
2440        return 0;
2441}
2442
2443static const struct v4l2_file_operations vpe_fops = {
2444        .owner          = THIS_MODULE,
2445        .open           = vpe_open,
2446        .release        = vpe_release,
2447        .poll           = v4l2_m2m_fop_poll,
2448        .unlocked_ioctl = video_ioctl2,
2449        .mmap           = v4l2_m2m_fop_mmap,
2450};
2451
2452static const struct video_device vpe_videodev = {
2453        .name           = VPE_MODULE_NAME,
2454        .fops           = &vpe_fops,
2455        .ioctl_ops      = &vpe_ioctl_ops,
2456        .minor          = -1,
2457        .release        = video_device_release_empty,
2458        .vfl_dir        = VFL_DIR_M2M,
2459        .device_caps    = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
2460};
2461
2462static const struct v4l2_m2m_ops m2m_ops = {
2463        .device_run     = device_run,
2464        .job_ready      = job_ready,
2465        .job_abort      = job_abort,
2466};
2467
2468static int vpe_runtime_get(struct platform_device *pdev)
2469{
2470        int r;
2471
2472        dev_dbg(&pdev->dev, "vpe_runtime_get\n");
2473
2474        r = pm_runtime_resume_and_get(&pdev->dev);
2475        WARN_ON(r < 0);
2476        return r;
2477}
2478
2479static void vpe_runtime_put(struct platform_device *pdev)
2480{
2481
2482        int r;
2483
2484        dev_dbg(&pdev->dev, "vpe_runtime_put\n");
2485
2486        r = pm_runtime_put_sync(&pdev->dev);
2487        WARN_ON(r < 0 && r != -ENOSYS);
2488}
2489
2490static void vpe_fw_cb(struct platform_device *pdev)
2491{
2492        struct vpe_dev *dev = platform_get_drvdata(pdev);
2493        struct video_device *vfd;
2494        int ret;
2495
2496        vfd = &dev->vfd;
2497        *vfd = vpe_videodev;
2498        vfd->lock = &dev->dev_mutex;
2499        vfd->v4l2_dev = &dev->v4l2_dev;
2500
2501        ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2502        if (ret) {
2503                vpe_err(dev, "Failed to register video device\n");
2504
2505                vpe_set_clock_enable(dev, 0);
2506                vpe_runtime_put(pdev);
2507                pm_runtime_disable(&pdev->dev);
2508                v4l2_m2m_release(dev->m2m_dev);
2509                v4l2_device_unregister(&dev->v4l2_dev);
2510
2511                return;
2512        }
2513
2514        video_set_drvdata(vfd, dev);
2515        dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n",
2516                vfd->num);
2517}
2518
2519static int vpe_probe(struct platform_device *pdev)
2520{
2521        struct vpe_dev *dev;
2522        int ret, irq, func;
2523
2524        ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
2525        if (ret) {
2526                dev_err(&pdev->dev,
2527                        "32-bit consistent DMA enable failed\n");
2528                return ret;
2529        }
2530
2531        dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
2532        if (!dev)
2533                return -ENOMEM;
2534
2535        spin_lock_init(&dev->lock);
2536
2537        ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
2538        if (ret)
2539                return ret;
2540
2541        atomic_set(&dev->num_instances, 0);
2542        mutex_init(&dev->dev_mutex);
2543
2544        dev->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2545                                                "vpe_top");
2546        if (!dev->res) {
2547                dev_err(&pdev->dev, "missing 'vpe_top' resources data\n");
2548                return -ENODEV;
2549        }
2550
2551        /*
2552         * HACK: we get resource info from device tree in the form of a list of
2553         * VPE sub blocks, the driver currently uses only the base of vpe_top
2554         * for register access, the driver should be changed later to access
2555         * registers based on the sub block base addresses
2556         */
2557        dev->base = devm_ioremap(&pdev->dev, dev->res->start, SZ_32K);
2558        if (!dev->base) {
2559                ret = -ENOMEM;
2560                goto v4l2_dev_unreg;
2561        }
2562
2563        irq = platform_get_irq(pdev, 0);
2564        ret = devm_request_irq(&pdev->dev, irq, vpe_irq, 0, VPE_MODULE_NAME,
2565                        dev);
2566        if (ret)
2567                goto v4l2_dev_unreg;
2568
2569        platform_set_drvdata(pdev, dev);
2570
2571        dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
2572        if (IS_ERR(dev->m2m_dev)) {
2573                vpe_err(dev, "Failed to init mem2mem device\n");
2574                ret = PTR_ERR(dev->m2m_dev);
2575                goto v4l2_dev_unreg;
2576        }
2577
2578        pm_runtime_enable(&pdev->dev);
2579
2580        ret = vpe_runtime_get(pdev);
2581        if (ret < 0)
2582                goto rel_m2m;
2583
2584        /* Perform clk enable followed by reset */
2585        vpe_set_clock_enable(dev, 1);
2586
2587        vpe_top_reset(dev);
2588
2589        func = read_field_reg(dev, VPE_PID, VPE_PID_FUNC_MASK,
2590                VPE_PID_FUNC_SHIFT);
2591        vpe_dbg(dev, "VPE PID function %x\n", func);
2592
2593        vpe_top_vpdma_reset(dev);
2594
2595        dev->sc = sc_create(pdev, "sc");
2596        if (IS_ERR(dev->sc)) {
2597                ret = PTR_ERR(dev->sc);
2598                goto runtime_put;
2599        }
2600
2601        dev->csc = csc_create(pdev, "csc");
2602        if (IS_ERR(dev->csc)) {
2603                ret = PTR_ERR(dev->csc);
2604                goto runtime_put;
2605        }
2606
2607        dev->vpdma = &dev->vpdma_data;
2608        ret = vpdma_create(pdev, dev->vpdma, vpe_fw_cb);
2609        if (ret)
2610                goto runtime_put;
2611
2612        return 0;
2613
2614runtime_put:
2615        vpe_runtime_put(pdev);
2616rel_m2m:
2617        pm_runtime_disable(&pdev->dev);
2618        v4l2_m2m_release(dev->m2m_dev);
2619v4l2_dev_unreg:
2620        v4l2_device_unregister(&dev->v4l2_dev);
2621
2622        return ret;
2623}
2624
2625static int vpe_remove(struct platform_device *pdev)
2626{
2627        struct vpe_dev *dev = platform_get_drvdata(pdev);
2628
2629        v4l2_info(&dev->v4l2_dev, "Removing " VPE_MODULE_NAME);
2630
2631        v4l2_m2m_release(dev->m2m_dev);
2632        video_unregister_device(&dev->vfd);
2633        v4l2_device_unregister(&dev->v4l2_dev);
2634
2635        vpe_set_clock_enable(dev, 0);
2636        vpe_runtime_put(pdev);
2637        pm_runtime_disable(&pdev->dev);
2638
2639        return 0;
2640}
2641
2642#if defined(CONFIG_OF)
2643static const struct of_device_id vpe_of_match[] = {
2644        {
2645                .compatible = "ti,dra7-vpe",
2646        },
2647        {},
2648};
2649MODULE_DEVICE_TABLE(of, vpe_of_match);
2650#endif
2651
2652static struct platform_driver vpe_pdrv = {
2653        .probe          = vpe_probe,
2654        .remove         = vpe_remove,
2655        .driver         = {
2656                .name   = VPE_MODULE_NAME,
2657                .of_match_table = of_match_ptr(vpe_of_match),
2658        },
2659};
2660
2661module_platform_driver(vpe_pdrv);
2662
2663MODULE_DESCRIPTION("TI VPE driver");
2664MODULE_AUTHOR("Dale Farnsworth, <dale@farnsworth.org>");
2665MODULE_LICENSE("GPL");
2666