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