linux/drivers/media/video/s5p-fimc/fimc-lite.c
<<
>>
Prefs
   1/*
   2 * Samsung EXYNOS FIMC-LITE (camera host interface) driver
   3*
   4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
   5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
  12
  13#include <linux/bug.h>
  14#include <linux/device.h>
  15#include <linux/errno.h>
  16#include <linux/interrupt.h>
  17#include <linux/kernel.h>
  18#include <linux/list.h>
  19#include <linux/module.h>
  20#include <linux/types.h>
  21#include <linux/platform_device.h>
  22#include <linux/pm_runtime.h>
  23#include <linux/slab.h>
  24#include <linux/videodev2.h>
  25
  26#include <media/v4l2-device.h>
  27#include <media/v4l2-ioctl.h>
  28#include <media/v4l2-mem2mem.h>
  29#include <media/videobuf2-core.h>
  30#include <media/videobuf2-dma-contig.h>
  31
  32#include "fimc-mdevice.h"
  33#include "fimc-core.h"
  34#include "fimc-lite-reg.h"
  35
  36static int debug;
  37module_param(debug, int, 0644);
  38
  39static const struct fimc_fmt fimc_lite_formats[] = {
  40        {
  41                .name           = "YUV 4:2:2 packed, YCbYCr",
  42                .fourcc         = V4L2_PIX_FMT_YUYV,
  43                .depth          = { 16 },
  44                .color          = FIMC_FMT_YCBYCR422,
  45                .memplanes      = 1,
  46                .mbus_code      = V4L2_MBUS_FMT_YUYV8_2X8,
  47        }, {
  48                .name           = "YUV 4:2:2 packed, CbYCrY",
  49                .fourcc         = V4L2_PIX_FMT_UYVY,
  50                .depth          = { 16 },
  51                .color          = FIMC_FMT_CBYCRY422,
  52                .memplanes      = 1,
  53                .mbus_code      = V4L2_MBUS_FMT_UYVY8_2X8,
  54        }, {
  55                .name           = "YUV 4:2:2 packed, CrYCbY",
  56                .fourcc         = V4L2_PIX_FMT_VYUY,
  57                .depth          = { 16 },
  58                .color          = FIMC_FMT_CRYCBY422,
  59                .memplanes      = 1,
  60                .mbus_code      = V4L2_MBUS_FMT_VYUY8_2X8,
  61        }, {
  62                .name           = "YUV 4:2:2 packed, YCrYCb",
  63                .fourcc         = V4L2_PIX_FMT_YVYU,
  64                .depth          = { 16 },
  65                .color          = FIMC_FMT_YCRYCB422,
  66                .memplanes      = 1,
  67                .mbus_code      = V4L2_MBUS_FMT_YVYU8_2X8,
  68        }, {
  69                .name           = "RAW8 (GRBG)",
  70                .fourcc         = V4L2_PIX_FMT_SGRBG8,
  71                .depth          = { 8 },
  72                .color          = FIMC_FMT_RAW8,
  73                .memplanes      = 1,
  74                .mbus_code      = V4L2_MBUS_FMT_SGRBG8_1X8,
  75        }, {
  76                .name           = "RAW10 (GRBG)",
  77                .fourcc         = V4L2_PIX_FMT_SGRBG10,
  78                .depth          = { 10 },
  79                .color          = FIMC_FMT_RAW10,
  80                .memplanes      = 1,
  81                .mbus_code      = V4L2_MBUS_FMT_SGRBG10_1X10,
  82        }, {
  83                .name           = "RAW12 (GRBG)",
  84                .fourcc         = V4L2_PIX_FMT_SGRBG12,
  85                .depth          = { 12 },
  86                .color          = FIMC_FMT_RAW12,
  87                .memplanes      = 1,
  88                .mbus_code      = V4L2_MBUS_FMT_SGRBG12_1X12,
  89        },
  90};
  91
  92/**
  93 * fimc_lite_find_format - lookup fimc color format by fourcc or media bus code
  94 * @pixelformat: fourcc to match, ignored if null
  95 * @mbus_code: media bus code to match, ignored if null
  96 * @index: index to the fimc_lite_formats array, ignored if negative
  97 */
  98static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
  99                                        const u32 *mbus_code, int index)
 100{
 101        const struct fimc_fmt *fmt, *def_fmt = NULL;
 102        unsigned int i;
 103        int id = 0;
 104
 105        if (index >= (int)ARRAY_SIZE(fimc_lite_formats))
 106                return NULL;
 107
 108        for (i = 0; i < ARRAY_SIZE(fimc_lite_formats); ++i) {
 109                fmt = &fimc_lite_formats[i];
 110                if (pixelformat && fmt->fourcc == *pixelformat)
 111                        return fmt;
 112                if (mbus_code && fmt->mbus_code == *mbus_code)
 113                        return fmt;
 114                if (index == id)
 115                        def_fmt = fmt;
 116                id++;
 117        }
 118        return def_fmt;
 119}
 120
 121static int fimc_lite_hw_init(struct fimc_lite *fimc)
 122{
 123        struct fimc_pipeline *pipeline = &fimc->pipeline;
 124        struct fimc_sensor_info *sensor;
 125        unsigned long flags;
 126
 127        if (pipeline->subdevs[IDX_SENSOR] == NULL)
 128                return -ENXIO;
 129
 130        if (fimc->fmt == NULL)
 131                return -EINVAL;
 132
 133        sensor = v4l2_get_subdev_hostdata(pipeline->subdevs[IDX_SENSOR]);
 134        spin_lock_irqsave(&fimc->slock, flags);
 135
 136        flite_hw_set_camera_bus(fimc, sensor->pdata);
 137        flite_hw_set_source_format(fimc, &fimc->inp_frame);
 138        flite_hw_set_window_offset(fimc, &fimc->inp_frame);
 139        flite_hw_set_output_dma(fimc, &fimc->out_frame, true);
 140        flite_hw_set_interrupt_mask(fimc);
 141        flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
 142
 143        if (debug > 0)
 144                flite_hw_dump_regs(fimc, __func__);
 145
 146        spin_unlock_irqrestore(&fimc->slock, flags);
 147        return 0;
 148}
 149
 150/*
 151 * Reinitialize the driver so it is ready to start the streaming again.
 152 * Set fimc->state to indicate stream off and the hardware shut down state.
 153 * If not suspending (@suspend is false), return any buffers to videobuf2.
 154 * Otherwise put any owned buffers onto the pending buffers queue, so they
 155 * can be re-spun when the device is being resumed. Also perform FIMC
 156 * software reset and disable streaming on the whole pipeline if required.
 157 */
 158static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
 159{
 160        struct flite_buffer *buf;
 161        unsigned long flags;
 162        bool streaming;
 163
 164        spin_lock_irqsave(&fimc->slock, flags);
 165        streaming = fimc->state & (1 << ST_SENSOR_STREAM);
 166
 167        fimc->state &= ~(1 << ST_FLITE_RUN | 1 << ST_FLITE_OFF |
 168                         1 << ST_FLITE_STREAM | 1 << ST_SENSOR_STREAM);
 169        if (suspend)
 170                fimc->state |= (1 << ST_FLITE_SUSPENDED);
 171        else
 172                fimc->state &= ~(1 << ST_FLITE_PENDING |
 173                                 1 << ST_FLITE_SUSPENDED);
 174
 175        /* Release unused buffers */
 176        while (!suspend && !list_empty(&fimc->pending_buf_q)) {
 177                buf = fimc_lite_pending_queue_pop(fimc);
 178                vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
 179        }
 180        /* If suspending put unused buffers onto pending queue */
 181        while (!list_empty(&fimc->active_buf_q)) {
 182                buf = fimc_lite_active_queue_pop(fimc);
 183                if (suspend)
 184                        fimc_lite_pending_queue_add(fimc, buf);
 185                else
 186                        vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
 187        }
 188
 189        spin_unlock_irqrestore(&fimc->slock, flags);
 190
 191        flite_hw_reset(fimc);
 192
 193        if (!streaming)
 194                return 0;
 195
 196        return fimc_pipeline_s_stream(&fimc->pipeline, 0);
 197}
 198
 199static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
 200{
 201        unsigned long flags;
 202
 203        if (!fimc_lite_active(fimc))
 204                return 0;
 205
 206        spin_lock_irqsave(&fimc->slock, flags);
 207        set_bit(ST_FLITE_OFF, &fimc->state);
 208        flite_hw_capture_stop(fimc);
 209        spin_unlock_irqrestore(&fimc->slock, flags);
 210
 211        wait_event_timeout(fimc->irq_queue,
 212                           !test_bit(ST_FLITE_OFF, &fimc->state),
 213                           (2*HZ/10)); /* 200 ms */
 214
 215        return fimc_lite_reinit(fimc, suspend);
 216}
 217
 218/* Must be called  with fimc.slock spinlock held. */
 219static void fimc_lite_config_update(struct fimc_lite *fimc)
 220{
 221        flite_hw_set_window_offset(fimc, &fimc->inp_frame);
 222        flite_hw_set_dma_window(fimc, &fimc->out_frame);
 223        flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
 224        clear_bit(ST_FLITE_CONFIG, &fimc->state);
 225}
 226
 227static irqreturn_t flite_irq_handler(int irq, void *priv)
 228{
 229        struct fimc_lite *fimc = priv;
 230        struct flite_buffer *vbuf;
 231        unsigned long flags;
 232        struct timeval *tv;
 233        struct timespec ts;
 234        u32 intsrc;
 235
 236        spin_lock_irqsave(&fimc->slock, flags);
 237
 238        intsrc = flite_hw_get_interrupt_source(fimc);
 239        flite_hw_clear_pending_irq(fimc);
 240
 241        if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
 242                wake_up(&fimc->irq_queue);
 243                goto done;
 244        }
 245
 246        if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
 247                clear_bit(ST_FLITE_RUN, &fimc->state);
 248                fimc->events.data_overflow++;
 249        }
 250
 251        if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
 252                flite_hw_clear_last_capture_end(fimc);
 253                clear_bit(ST_FLITE_STREAM, &fimc->state);
 254                wake_up(&fimc->irq_queue);
 255        }
 256
 257        if (fimc->out_path != FIMC_IO_DMA)
 258                goto done;
 259
 260        if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
 261            test_bit(ST_FLITE_RUN, &fimc->state) &&
 262            !list_empty(&fimc->active_buf_q) &&
 263            !list_empty(&fimc->pending_buf_q)) {
 264                vbuf = fimc_lite_active_queue_pop(fimc);
 265                ktime_get_ts(&ts);
 266                tv = &vbuf->vb.v4l2_buf.timestamp;
 267                tv->tv_sec = ts.tv_sec;
 268                tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 269                vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
 270                vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
 271
 272                vbuf = fimc_lite_pending_queue_pop(fimc);
 273                flite_hw_set_output_addr(fimc, vbuf->paddr);
 274                fimc_lite_active_queue_add(fimc, vbuf);
 275        }
 276
 277        if (test_bit(ST_FLITE_CONFIG, &fimc->state))
 278                fimc_lite_config_update(fimc);
 279
 280        if (list_empty(&fimc->pending_buf_q)) {
 281                flite_hw_capture_stop(fimc);
 282                clear_bit(ST_FLITE_STREAM, &fimc->state);
 283        }
 284done:
 285        set_bit(ST_FLITE_RUN, &fimc->state);
 286        spin_unlock_irqrestore(&fimc->slock, flags);
 287        return IRQ_HANDLED;
 288}
 289
 290static int start_streaming(struct vb2_queue *q, unsigned int count)
 291{
 292        struct fimc_lite *fimc = q->drv_priv;
 293        int ret;
 294
 295        fimc->frame_count = 0;
 296
 297        ret = fimc_lite_hw_init(fimc);
 298        if (ret) {
 299                fimc_lite_reinit(fimc, false);
 300                return ret;
 301        }
 302
 303        set_bit(ST_FLITE_PENDING, &fimc->state);
 304
 305        if (!list_empty(&fimc->active_buf_q) &&
 306            !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
 307                flite_hw_capture_start(fimc);
 308
 309                if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
 310                        fimc_pipeline_s_stream(&fimc->pipeline, 1);
 311        }
 312        if (debug > 0)
 313                flite_hw_dump_regs(fimc, __func__);
 314
 315        return 0;
 316}
 317
 318static int stop_streaming(struct vb2_queue *q)
 319{
 320        struct fimc_lite *fimc = q->drv_priv;
 321
 322        if (!fimc_lite_active(fimc))
 323                return -EINVAL;
 324
 325        return fimc_lite_stop_capture(fimc, false);
 326}
 327
 328static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
 329                       unsigned int *num_buffers, unsigned int *num_planes,
 330                       unsigned int sizes[], void *allocators[])
 331{
 332        const struct v4l2_pix_format_mplane *pixm = NULL;
 333        struct fimc_lite *fimc = vq->drv_priv;
 334        struct flite_frame *frame = &fimc->out_frame;
 335        const struct fimc_fmt *fmt = fimc->fmt;
 336        unsigned long wh;
 337        int i;
 338
 339        if (pfmt) {
 340                pixm = &pfmt->fmt.pix_mp;
 341                fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, -1);
 342                wh = pixm->width * pixm->height;
 343        } else {
 344                wh = frame->f_width * frame->f_height;
 345        }
 346
 347        if (fmt == NULL)
 348                return -EINVAL;
 349
 350        *num_planes = fmt->memplanes;
 351
 352        for (i = 0; i < fmt->memplanes; i++) {
 353                unsigned int size = (wh * fmt->depth[i]) / 8;
 354                if (pixm)
 355                        sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
 356                else
 357                        sizes[i] = size;
 358                allocators[i] = fimc->alloc_ctx;
 359        }
 360
 361        return 0;
 362}
 363
 364static int buffer_prepare(struct vb2_buffer *vb)
 365{
 366        struct vb2_queue *vq = vb->vb2_queue;
 367        struct fimc_lite *fimc = vq->drv_priv;
 368        int i;
 369
 370        if (fimc->fmt == NULL)
 371                return -EINVAL;
 372
 373        for (i = 0; i < fimc->fmt->memplanes; i++) {
 374                unsigned long size = fimc->payload[i];
 375
 376                if (vb2_plane_size(vb, i) < size) {
 377                        v4l2_err(fimc->vfd,
 378                                 "User buffer too small (%ld < %ld)\n",
 379                                 vb2_plane_size(vb, i), size);
 380                        return -EINVAL;
 381                }
 382                vb2_set_plane_payload(vb, i, size);
 383        }
 384
 385        return 0;
 386}
 387
 388static void buffer_queue(struct vb2_buffer *vb)
 389{
 390        struct flite_buffer *buf
 391                = container_of(vb, struct flite_buffer, vb);
 392        struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
 393        unsigned long flags;
 394
 395        spin_lock_irqsave(&fimc->slock, flags);
 396        buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
 397
 398        if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
 399            !test_bit(ST_FLITE_STREAM, &fimc->state) &&
 400            list_empty(&fimc->active_buf_q)) {
 401                flite_hw_set_output_addr(fimc, buf->paddr);
 402                fimc_lite_active_queue_add(fimc, buf);
 403        } else {
 404                fimc_lite_pending_queue_add(fimc, buf);
 405        }
 406
 407        if (vb2_is_streaming(&fimc->vb_queue) &&
 408            !list_empty(&fimc->pending_buf_q) &&
 409            !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
 410                flite_hw_capture_start(fimc);
 411                spin_unlock_irqrestore(&fimc->slock, flags);
 412
 413                if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
 414                        fimc_pipeline_s_stream(&fimc->pipeline, 1);
 415                return;
 416        }
 417        spin_unlock_irqrestore(&fimc->slock, flags);
 418}
 419
 420static void fimc_lock(struct vb2_queue *vq)
 421{
 422        struct fimc_lite *fimc = vb2_get_drv_priv(vq);
 423        mutex_lock(&fimc->lock);
 424}
 425
 426static void fimc_unlock(struct vb2_queue *vq)
 427{
 428        struct fimc_lite *fimc = vb2_get_drv_priv(vq);
 429        mutex_unlock(&fimc->lock);
 430}
 431
 432static const struct vb2_ops fimc_lite_qops = {
 433        .queue_setup     = queue_setup,
 434        .buf_prepare     = buffer_prepare,
 435        .buf_queue       = buffer_queue,
 436        .wait_prepare    = fimc_unlock,
 437        .wait_finish     = fimc_lock,
 438        .start_streaming = start_streaming,
 439        .stop_streaming  = stop_streaming,
 440};
 441
 442static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
 443{
 444        unsigned long flags;
 445
 446        spin_lock_irqsave(&fimc->slock, flags);
 447        memset(&fimc->events, 0, sizeof(fimc->events));
 448        spin_unlock_irqrestore(&fimc->slock, flags);
 449}
 450
 451static int fimc_lite_open(struct file *file)
 452{
 453        struct fimc_lite *fimc = video_drvdata(file);
 454        int ret;
 455
 456        if (mutex_lock_interruptible(&fimc->lock))
 457                return -ERESTARTSYS;
 458
 459        set_bit(ST_FLITE_IN_USE, &fimc->state);
 460        ret = pm_runtime_get_sync(&fimc->pdev->dev);
 461        if (ret < 0)
 462                goto done;
 463
 464        ret = v4l2_fh_open(file);
 465        if (ret < 0)
 466                goto done;
 467
 468        if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
 469                ret = fimc_pipeline_initialize(&fimc->pipeline,
 470                                               &fimc->vfd->entity, true);
 471                if (ret < 0) {
 472                        pm_runtime_put_sync(&fimc->pdev->dev);
 473                        fimc->ref_count--;
 474                        v4l2_fh_release(file);
 475                        clear_bit(ST_FLITE_IN_USE, &fimc->state);
 476                }
 477
 478                fimc_lite_clear_event_counters(fimc);
 479        }
 480done:
 481        mutex_unlock(&fimc->lock);
 482        return ret;
 483}
 484
 485static int fimc_lite_close(struct file *file)
 486{
 487        struct fimc_lite *fimc = video_drvdata(file);
 488        int ret;
 489
 490        if (mutex_lock_interruptible(&fimc->lock))
 491                return -ERESTARTSYS;
 492
 493        if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
 494                clear_bit(ST_FLITE_IN_USE, &fimc->state);
 495                fimc_lite_stop_capture(fimc, false);
 496                fimc_pipeline_shutdown(&fimc->pipeline);
 497                clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
 498        }
 499
 500        pm_runtime_put(&fimc->pdev->dev);
 501
 502        if (fimc->ref_count == 0)
 503                vb2_queue_release(&fimc->vb_queue);
 504
 505        ret = v4l2_fh_release(file);
 506
 507        mutex_unlock(&fimc->lock);
 508        return ret;
 509}
 510
 511static unsigned int fimc_lite_poll(struct file *file,
 512                                   struct poll_table_struct *wait)
 513{
 514        struct fimc_lite *fimc = video_drvdata(file);
 515        int ret;
 516
 517        if (mutex_lock_interruptible(&fimc->lock))
 518                return POLL_ERR;
 519
 520        ret = vb2_poll(&fimc->vb_queue, file, wait);
 521        mutex_unlock(&fimc->lock);
 522
 523        return ret;
 524}
 525
 526static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma)
 527{
 528        struct fimc_lite *fimc = video_drvdata(file);
 529        int ret;
 530
 531        if (mutex_lock_interruptible(&fimc->lock))
 532                return -ERESTARTSYS;
 533
 534        ret = vb2_mmap(&fimc->vb_queue, vma);
 535        mutex_unlock(&fimc->lock);
 536
 537        return ret;
 538}
 539
 540static const struct v4l2_file_operations fimc_lite_fops = {
 541        .owner          = THIS_MODULE,
 542        .open           = fimc_lite_open,
 543        .release        = fimc_lite_close,
 544        .poll           = fimc_lite_poll,
 545        .unlocked_ioctl = video_ioctl2,
 546        .mmap           = fimc_lite_mmap,
 547};
 548
 549/*
 550 * Format and crop negotiation helpers
 551 */
 552
 553static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
 554                                        u32 *width, u32 *height,
 555                                        u32 *code, u32 *fourcc, int pad)
 556{
 557        struct flite_variant *variant = fimc->variant;
 558        const struct fimc_fmt *fmt;
 559
 560        fmt = fimc_lite_find_format(fourcc, code, 0);
 561        if (WARN_ON(!fmt))
 562                return NULL;
 563
 564        if (code)
 565                *code = fmt->mbus_code;
 566        if (fourcc)
 567                *fourcc = fmt->fourcc;
 568
 569        if (pad == FLITE_SD_PAD_SINK) {
 570                v4l_bound_align_image(width, 8, variant->max_width,
 571                                      ffs(variant->out_width_align) - 1,
 572                                      height, 0, variant->max_height, 0, 0);
 573        } else {
 574                v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
 575                                      ffs(variant->out_width_align) - 1,
 576                                      height, 0, fimc->inp_frame.rect.height,
 577                                      0, 0);
 578        }
 579
 580        v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
 581                 code ? *code : 0, *width, *height);
 582
 583        return fmt;
 584}
 585
 586static void fimc_lite_try_crop(struct fimc_lite *fimc, struct v4l2_rect *r)
 587{
 588        struct flite_frame *frame = &fimc->inp_frame;
 589
 590        v4l_bound_align_image(&r->width, 0, frame->f_width, 0,
 591                              &r->height, 0, frame->f_height, 0, 0);
 592
 593        /* Adjust left/top if cropping rectangle got out of bounds */
 594        r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
 595        r->left = round_down(r->left, fimc->variant->win_hor_offs_align);
 596        r->top  = clamp_t(u32, r->top, 0, frame->f_height - r->height);
 597
 598        v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, sink fmt: %dx%d",
 599                 r->left, r->top, r->width, r->height,
 600                 frame->f_width, frame->f_height);
 601}
 602
 603static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
 604{
 605        struct flite_frame *frame = &fimc->out_frame;
 606        struct v4l2_rect *crop_rect = &fimc->inp_frame.rect;
 607
 608        /* Scaling is not supported so we enforce compose rectangle size
 609           same as size of the sink crop rectangle. */
 610        r->width = crop_rect->width;
 611        r->height = crop_rect->height;
 612
 613        /* Adjust left/top if the composing rectangle got out of bounds */
 614        r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
 615        r->left = round_down(r->left, fimc->variant->out_hor_offs_align);
 616        r->top  = clamp_t(u32, r->top, 0, fimc->out_frame.f_height - r->height);
 617
 618        v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, source fmt: %dx%d",
 619                 r->left, r->top, r->width, r->height,
 620                 frame->f_width, frame->f_height);
 621}
 622
 623/*
 624 * Video node ioctl operations
 625 */
 626static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
 627                                        struct v4l2_capability *cap)
 628{
 629        strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
 630        cap->bus_info[0] = 0;
 631        cap->card[0] = 0;
 632        cap->capabilities = V4L2_CAP_STREAMING;
 633        return 0;
 634}
 635
 636static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv,
 637                                     struct v4l2_fmtdesc *f)
 638{
 639        const struct fimc_fmt *fmt;
 640
 641        if (f->index >= ARRAY_SIZE(fimc_lite_formats))
 642                return -EINVAL;
 643
 644        fmt = &fimc_lite_formats[f->index];
 645        strlcpy(f->description, fmt->name, sizeof(f->description));
 646        f->pixelformat = fmt->fourcc;
 647
 648        return 0;
 649}
 650
 651static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
 652                                  struct v4l2_format *f)
 653{
 654        struct fimc_lite *fimc = video_drvdata(file);
 655        struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
 656        struct v4l2_plane_pix_format *plane_fmt = &pixm->plane_fmt[0];
 657        struct flite_frame *frame = &fimc->out_frame;
 658        const struct fimc_fmt *fmt = fimc->fmt;
 659
 660        plane_fmt->bytesperline = (frame->f_width * fmt->depth[0]) / 8;
 661        plane_fmt->sizeimage = plane_fmt->bytesperline * frame->f_height;
 662
 663        pixm->num_planes = fmt->memplanes;
 664        pixm->pixelformat = fmt->fourcc;
 665        pixm->width = frame->f_width;
 666        pixm->height = frame->f_height;
 667        pixm->field = V4L2_FIELD_NONE;
 668        pixm->colorspace = V4L2_COLORSPACE_JPEG;
 669        return 0;
 670}
 671
 672static int fimc_lite_try_fmt(struct fimc_lite *fimc,
 673                             struct v4l2_pix_format_mplane *pixm,
 674                             const struct fimc_fmt **ffmt)
 675{
 676        struct flite_variant *variant = fimc->variant;
 677        u32 bpl = pixm->plane_fmt[0].bytesperline;
 678        const struct fimc_fmt *fmt;
 679
 680        fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, 0);
 681        if (WARN_ON(fmt == NULL))
 682                return -EINVAL;
 683        if (ffmt)
 684                *ffmt = fmt;
 685        v4l_bound_align_image(&pixm->width, 8, variant->max_width,
 686                              ffs(variant->out_width_align) - 1,
 687                              &pixm->height, 0, variant->max_height, 0, 0);
 688
 689        if ((bpl == 0 || ((bpl * 8) / fmt->depth[0]) < pixm->width))
 690                pixm->plane_fmt[0].bytesperline = (pixm->width *
 691                                                   fmt->depth[0]) / 8;
 692
 693        if (pixm->plane_fmt[0].sizeimage == 0)
 694                pixm->plane_fmt[0].sizeimage = (pixm->width * pixm->height *
 695                                                fmt->depth[0]) / 8;
 696        pixm->num_planes = fmt->memplanes;
 697        pixm->pixelformat = fmt->fourcc;
 698        pixm->colorspace = V4L2_COLORSPACE_JPEG;
 699        pixm->field = V4L2_FIELD_NONE;
 700        return 0;
 701}
 702
 703static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
 704                                    struct v4l2_format *f)
 705{
 706        struct fimc_lite *fimc = video_drvdata(file);
 707
 708        return fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, NULL);
 709}
 710
 711static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
 712                                  struct v4l2_format *f)
 713{
 714        struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
 715        struct fimc_lite *fimc = video_drvdata(file);
 716        struct flite_frame *frame = &fimc->out_frame;
 717        const struct fimc_fmt *fmt = NULL;
 718        int ret;
 719
 720        if (vb2_is_busy(&fimc->vb_queue))
 721                return -EBUSY;
 722
 723        ret = fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, &fmt);
 724        if (ret < 0)
 725                return ret;
 726
 727        fimc->fmt = fmt;
 728        fimc->payload[0] = max((pixm->width * pixm->height * fmt->depth[0]) / 8,
 729                               pixm->plane_fmt[0].sizeimage);
 730        frame->f_width = pixm->width;
 731        frame->f_height = pixm->height;
 732
 733        return 0;
 734}
 735
 736static int fimc_pipeline_validate(struct fimc_lite *fimc)
 737{
 738        struct v4l2_subdev *sd = &fimc->subdev;
 739        struct v4l2_subdev_format sink_fmt, src_fmt;
 740        struct media_pad *pad;
 741        int ret;
 742
 743        while (1) {
 744                /* Retrieve format at the sink pad */
 745                pad = &sd->entity.pads[0];
 746                if (!(pad->flags & MEDIA_PAD_FL_SINK))
 747                        break;
 748                /* Don't call FIMC subdev operation to avoid nested locking */
 749                if (sd == &fimc->subdev) {
 750                        struct flite_frame *ff = &fimc->out_frame;
 751                        sink_fmt.format.width = ff->f_width;
 752                        sink_fmt.format.height = ff->f_height;
 753                        sink_fmt.format.code = fimc->fmt->mbus_code;
 754                } else {
 755                        sink_fmt.pad = pad->index;
 756                        sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
 757                        ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
 758                                               &sink_fmt);
 759                        if (ret < 0 && ret != -ENOIOCTLCMD)
 760                                return -EPIPE;
 761                }
 762                /* Retrieve format at the source pad */
 763                pad = media_entity_remote_source(pad);
 764                if (pad == NULL ||
 765                    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 766                        break;
 767
 768                sd = media_entity_to_v4l2_subdev(pad->entity);
 769                src_fmt.pad = pad->index;
 770                src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
 771                ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
 772                if (ret < 0 && ret != -ENOIOCTLCMD)
 773                        return -EPIPE;
 774
 775                if (src_fmt.format.width != sink_fmt.format.width ||
 776                    src_fmt.format.height != sink_fmt.format.height ||
 777                    src_fmt.format.code != sink_fmt.format.code)
 778                        return -EPIPE;
 779        }
 780        return 0;
 781}
 782
 783static int fimc_lite_streamon(struct file *file, void *priv,
 784                              enum v4l2_buf_type type)
 785{
 786        struct fimc_lite *fimc = video_drvdata(file);
 787        struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
 788        struct fimc_pipeline *p = &fimc->pipeline;
 789        int ret;
 790
 791        if (fimc_lite_active(fimc))
 792                return -EBUSY;
 793
 794        ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline);
 795        if (ret < 0)
 796                return ret;
 797
 798        ret = fimc_pipeline_validate(fimc);
 799        if (ret) {
 800                media_entity_pipeline_stop(&sensor->entity);
 801                return ret;
 802        }
 803
 804        return vb2_streamon(&fimc->vb_queue, type);
 805}
 806
 807static int fimc_lite_streamoff(struct file *file, void *priv,
 808                               enum v4l2_buf_type type)
 809{
 810        struct fimc_lite *fimc = video_drvdata(file);
 811        struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
 812        int ret;
 813
 814        ret = vb2_streamoff(&fimc->vb_queue, type);
 815        if (ret == 0)
 816                media_entity_pipeline_stop(&sd->entity);
 817        return ret;
 818}
 819
 820static int fimc_lite_reqbufs(struct file *file, void *priv,
 821                             struct v4l2_requestbuffers *reqbufs)
 822{
 823        struct fimc_lite *fimc = video_drvdata(file);
 824        int ret;
 825
 826        reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
 827        ret = vb2_reqbufs(&fimc->vb_queue, reqbufs);
 828        if (!ret < 0)
 829                fimc->reqbufs_count = reqbufs->count;
 830
 831        return ret;
 832}
 833
 834static int fimc_lite_querybuf(struct file *file, void *priv,
 835                              struct v4l2_buffer *buf)
 836{
 837        struct fimc_lite *fimc = video_drvdata(file);
 838
 839        return vb2_querybuf(&fimc->vb_queue, buf);
 840}
 841
 842static int fimc_lite_qbuf(struct file *file, void *priv,
 843                          struct v4l2_buffer *buf)
 844{
 845        struct fimc_lite *fimc = video_drvdata(file);
 846
 847        return vb2_qbuf(&fimc->vb_queue, buf);
 848}
 849
 850static int fimc_lite_dqbuf(struct file *file, void *priv,
 851                           struct v4l2_buffer *buf)
 852{
 853        struct fimc_lite *fimc = video_drvdata(file);
 854
 855        return vb2_dqbuf(&fimc->vb_queue, buf, file->f_flags & O_NONBLOCK);
 856}
 857
 858static int fimc_lite_create_bufs(struct file *file, void *priv,
 859                                 struct v4l2_create_buffers *create)
 860{
 861        struct fimc_lite *fimc = video_drvdata(file);
 862
 863        return vb2_create_bufs(&fimc->vb_queue, create);
 864}
 865
 866static int fimc_lite_prepare_buf(struct file *file, void *priv,
 867                                 struct v4l2_buffer *b)
 868{
 869        struct fimc_lite *fimc = video_drvdata(file);
 870
 871        return vb2_prepare_buf(&fimc->vb_queue, b);
 872}
 873
 874/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
 875static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
 876{
 877        if (a->left < b->left || a->top < b->top)
 878                return 0;
 879        if (a->left + a->width > b->left + b->width)
 880                return 0;
 881        if (a->top + a->height > b->top + b->height)
 882                return 0;
 883
 884        return 1;
 885}
 886
 887static int fimc_lite_g_selection(struct file *file, void *fh,
 888                                 struct v4l2_selection *sel)
 889{
 890        struct fimc_lite *fimc = video_drvdata(file);
 891        struct flite_frame *f = &fimc->out_frame;
 892
 893        if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 894                return -EINVAL;
 895
 896        switch (sel->target) {
 897        case V4L2_SEL_TGT_COMPOSE_BOUNDS:
 898        case V4L2_SEL_TGT_COMPOSE_DEFAULT:
 899                sel->r.left = 0;
 900                sel->r.top = 0;
 901                sel->r.width = f->f_width;
 902                sel->r.height = f->f_height;
 903                return 0;
 904
 905        case V4L2_SEL_TGT_COMPOSE:
 906                sel->r = f->rect;
 907                return 0;
 908        }
 909
 910        return -EINVAL;
 911}
 912
 913static int fimc_lite_s_selection(struct file *file, void *fh,
 914                                 struct v4l2_selection *sel)
 915{
 916        struct fimc_lite *fimc = video_drvdata(file);
 917        struct flite_frame *f = &fimc->out_frame;
 918        struct v4l2_rect rect = sel->r;
 919        unsigned long flags;
 920
 921        if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
 922            sel->target != V4L2_SEL_TGT_COMPOSE)
 923                return -EINVAL;
 924
 925        fimc_lite_try_compose(fimc, &rect);
 926
 927        if ((sel->flags & V4L2_SEL_FLAG_LE) &&
 928            !enclosed_rectangle(&rect, &sel->r))
 929                return -ERANGE;
 930
 931        if ((sel->flags & V4L2_SEL_FLAG_GE) &&
 932            !enclosed_rectangle(&sel->r, &rect))
 933                return -ERANGE;
 934
 935        sel->r = rect;
 936        spin_lock_irqsave(&fimc->slock, flags);
 937        f->rect = rect;
 938        set_bit(ST_FLITE_CONFIG, &fimc->state);
 939        spin_unlock_irqrestore(&fimc->slock, flags);
 940
 941        return 0;
 942}
 943
 944static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
 945        .vidioc_querycap                = fimc_vidioc_querycap_capture,
 946        .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
 947        .vidioc_try_fmt_vid_cap_mplane  = fimc_lite_try_fmt_mplane,
 948        .vidioc_s_fmt_vid_cap_mplane    = fimc_lite_s_fmt_mplane,
 949        .vidioc_g_fmt_vid_cap_mplane    = fimc_lite_g_fmt_mplane,
 950        .vidioc_g_selection             = fimc_lite_g_selection,
 951        .vidioc_s_selection             = fimc_lite_s_selection,
 952        .vidioc_reqbufs                 = fimc_lite_reqbufs,
 953        .vidioc_querybuf                = fimc_lite_querybuf,
 954        .vidioc_prepare_buf             = fimc_lite_prepare_buf,
 955        .vidioc_create_bufs             = fimc_lite_create_bufs,
 956        .vidioc_qbuf                    = fimc_lite_qbuf,
 957        .vidioc_dqbuf                   = fimc_lite_dqbuf,
 958        .vidioc_streamon                = fimc_lite_streamon,
 959        .vidioc_streamoff               = fimc_lite_streamoff,
 960};
 961
 962/* Capture subdev media entity operations */
 963static int fimc_lite_link_setup(struct media_entity *entity,
 964                                const struct media_pad *local,
 965                                const struct media_pad *remote, u32 flags)
 966{
 967        struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 968        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
 969        unsigned int remote_ent_type = media_entity_type(remote->entity);
 970
 971        if (WARN_ON(fimc == NULL))
 972                return 0;
 973
 974        v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x",
 975                 __func__, local->entity->name, remote->entity->name,
 976                 flags, fimc->source_subdev_grp_id);
 977
 978        switch (local->index) {
 979        case FIMC_SD_PAD_SINK:
 980                if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV)
 981                        return -EINVAL;
 982
 983                if (flags & MEDIA_LNK_FL_ENABLED) {
 984                        if (fimc->source_subdev_grp_id != 0)
 985                                return -EBUSY;
 986                        fimc->source_subdev_grp_id = sd->grp_id;
 987                        return 0;
 988                }
 989
 990                fimc->source_subdev_grp_id = 0;
 991                break;
 992
 993        case FIMC_SD_PAD_SOURCE:
 994                if (!(flags & MEDIA_LNK_FL_ENABLED)) {
 995                        fimc->out_path = FIMC_IO_NONE;
 996                        return 0;
 997                }
 998                if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
 999                        fimc->out_path = FIMC_IO_ISP;
1000                else
1001                        fimc->out_path = FIMC_IO_DMA;
1002                break;
1003
1004        default:
1005                v4l2_err(sd, "Invalid pad index\n");
1006                return -EINVAL;
1007        }
1008
1009        return 0;
1010}
1011
1012static const struct media_entity_operations fimc_lite_subdev_media_ops = {
1013        .link_setup = fimc_lite_link_setup,
1014};
1015
1016static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1017                                           struct v4l2_subdev_fh *fh,
1018                                           struct v4l2_subdev_mbus_code_enum *code)
1019{
1020        const struct fimc_fmt *fmt;
1021
1022        fmt = fimc_lite_find_format(NULL, NULL, code->index);
1023        if (!fmt)
1024                return -EINVAL;
1025        code->code = fmt->mbus_code;
1026        return 0;
1027}
1028
1029static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1030                                    struct v4l2_subdev_fh *fh,
1031                                    struct v4l2_subdev_format *fmt)
1032{
1033        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1034        struct v4l2_mbus_framefmt *mf = &fmt->format;
1035        struct flite_frame *f = &fimc->out_frame;
1036
1037        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1038                mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1039                fmt->format = *mf;
1040                return 0;
1041        }
1042        mf->colorspace = V4L2_COLORSPACE_JPEG;
1043
1044        mutex_lock(&fimc->lock);
1045        mf->code = fimc->fmt->mbus_code;
1046
1047        if (fmt->pad == FLITE_SD_PAD_SINK) {
1048                /* full camera input frame size */
1049                mf->width = f->f_width;
1050                mf->height = f->f_height;
1051        } else {
1052                /* crop size */
1053                mf->width = f->rect.width;
1054                mf->height = f->rect.height;
1055        }
1056        mutex_unlock(&fimc->lock);
1057        return 0;
1058}
1059
1060static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1061                                    struct v4l2_subdev_fh *fh,
1062                                    struct v4l2_subdev_format *fmt)
1063{
1064        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1065        struct v4l2_mbus_framefmt *mf = &fmt->format;
1066        struct flite_frame *sink = &fimc->inp_frame;
1067        const struct fimc_fmt *ffmt;
1068
1069        v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d",
1070                 fmt->pad, mf->code, mf->width, mf->height);
1071
1072        mf->colorspace = V4L2_COLORSPACE_JPEG;
1073        mutex_lock(&fimc->lock);
1074
1075        if ((fimc->out_path == FIMC_IO_ISP && sd->entity.stream_count > 0) ||
1076            (fimc->out_path == FIMC_IO_DMA && vb2_is_busy(&fimc->vb_queue))) {
1077                mutex_unlock(&fimc->lock);
1078                return -EBUSY;
1079        }
1080
1081        ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
1082                                    &mf->code, NULL, fmt->pad);
1083
1084        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1085                mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1086                *mf = fmt->format;
1087                mutex_unlock(&fimc->lock);
1088                return 0;
1089        }
1090
1091        if (fmt->pad == FLITE_SD_PAD_SINK) {
1092                sink->f_width = mf->width;
1093                sink->f_height = mf->height;
1094                fimc->fmt = ffmt;
1095                /* Set sink crop rectangle */
1096                sink->rect.width = mf->width;
1097                sink->rect.height = mf->height;
1098                sink->rect.left = 0;
1099                sink->rect.top = 0;
1100                /* Reset source crop rectangle */
1101                fimc->out_frame.rect = sink->rect;
1102        } else {
1103                /* Allow changing format only on sink pad */
1104                mf->code = fimc->fmt->mbus_code;
1105                mf->width = sink->rect.width;
1106                mf->height = sink->rect.height;
1107        }
1108
1109        mutex_unlock(&fimc->lock);
1110        return 0;
1111}
1112
1113static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1114                                          struct v4l2_subdev_fh *fh,
1115                                          struct v4l2_subdev_selection *sel)
1116{
1117        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1118        struct flite_frame *f = &fimc->inp_frame;
1119
1120        if ((sel->target != V4L2_SEL_TGT_CROP &&
1121             sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
1122             sel->pad != FLITE_SD_PAD_SINK)
1123                return -EINVAL;
1124
1125        if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1126                sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
1127                return 0;
1128        }
1129
1130        mutex_lock(&fimc->lock);
1131        if (sel->target == V4L2_SEL_TGT_CROP) {
1132                sel->r = f->rect;
1133        } else {
1134                sel->r.left = 0;
1135                sel->r.top = 0;
1136                sel->r.width = f->f_width;
1137                sel->r.height = f->f_height;
1138        }
1139        mutex_unlock(&fimc->lock);
1140
1141        v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1142                 __func__, f->rect.left, f->rect.top, f->rect.width,
1143                 f->rect.height, f->f_width, f->f_height);
1144
1145        return 0;
1146}
1147
1148static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
1149                                          struct v4l2_subdev_fh *fh,
1150                                          struct v4l2_subdev_selection *sel)
1151{
1152        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1153        struct flite_frame *f = &fimc->inp_frame;
1154        int ret = 0;
1155
1156        if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
1157                return -EINVAL;
1158
1159        mutex_lock(&fimc->lock);
1160        fimc_lite_try_crop(fimc, &sel->r);
1161
1162        if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1163                *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
1164        } else {
1165                unsigned long flags;
1166                spin_lock_irqsave(&fimc->slock, flags);
1167                f->rect = sel->r;
1168                /* Same crop rectangle on the source pad */
1169                fimc->out_frame.rect = sel->r;
1170                set_bit(ST_FLITE_CONFIG, &fimc->state);
1171                spin_unlock_irqrestore(&fimc->slock, flags);
1172        }
1173        mutex_unlock(&fimc->lock);
1174
1175        v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1176                 __func__, f->rect.left, f->rect.top, f->rect.width,
1177                 f->rect.height, f->f_width, f->f_height);
1178
1179        return ret;
1180}
1181
1182static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
1183{
1184        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1185
1186        if (fimc->out_path == FIMC_IO_DMA)
1187                return -ENOIOCTLCMD;
1188
1189        /* TODO: */
1190
1191        return 0;
1192}
1193
1194static int fimc_lite_subdev_s_power(struct v4l2_subdev *sd, int on)
1195{
1196        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1197
1198        if (fimc->out_path == FIMC_IO_DMA)
1199                return -ENOIOCTLCMD;
1200
1201        /* TODO: */
1202
1203        return 0;
1204}
1205
1206static int fimc_lite_log_status(struct v4l2_subdev *sd)
1207{
1208        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1209
1210        flite_hw_dump_regs(fimc, __func__);
1211        return 0;
1212}
1213
1214static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
1215{
1216        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1217        struct vb2_queue *q = &fimc->vb_queue;
1218        struct video_device *vfd;
1219        int ret;
1220
1221        fimc->fmt = &fimc_lite_formats[0];
1222        fimc->out_path = FIMC_IO_DMA;
1223
1224        vfd = video_device_alloc();
1225        if (!vfd) {
1226                v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n");
1227                return -ENOMEM;
1228        }
1229
1230        snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
1231                 fimc->index);
1232
1233        vfd->fops = &fimc_lite_fops;
1234        vfd->ioctl_ops = &fimc_lite_ioctl_ops;
1235        vfd->v4l2_dev = sd->v4l2_dev;
1236        vfd->minor = -1;
1237        vfd->release = video_device_release;
1238        vfd->lock = &fimc->lock;
1239        fimc->vfd = vfd;
1240        fimc->ref_count = 0;
1241        fimc->reqbufs_count = 0;
1242
1243        INIT_LIST_HEAD(&fimc->pending_buf_q);
1244        INIT_LIST_HEAD(&fimc->active_buf_q);
1245
1246        memset(q, 0, sizeof(*q));
1247        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1248        q->io_modes = VB2_MMAP | VB2_USERPTR;
1249        q->ops = &fimc_lite_qops;
1250        q->mem_ops = &vb2_dma_contig_memops;
1251        q->buf_struct_size = sizeof(struct flite_buffer);
1252        q->drv_priv = fimc;
1253
1254        vb2_queue_init(q);
1255
1256        fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
1257        ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
1258        if (ret)
1259                goto err;
1260
1261        video_set_drvdata(vfd, fimc);
1262
1263        ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1264        if (ret)
1265                goto err_vd;
1266
1267        v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
1268                  vfd->name, video_device_node_name(vfd));
1269        return 0;
1270
1271 err_vd:
1272        media_entity_cleanup(&vfd->entity);
1273 err:
1274        video_device_release(vfd);
1275        return ret;
1276}
1277
1278static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
1279{
1280        struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1281
1282        if (fimc == NULL)
1283                return;
1284
1285        if (fimc->vfd) {
1286                video_unregister_device(fimc->vfd);
1287                media_entity_cleanup(&fimc->vfd->entity);
1288                fimc->vfd = NULL;
1289        }
1290}
1291
1292static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
1293        .registered = fimc_lite_subdev_registered,
1294        .unregistered = fimc_lite_subdev_unregistered,
1295};
1296
1297static const struct v4l2_subdev_pad_ops fimc_lite_subdev_pad_ops = {
1298        .enum_mbus_code = fimc_lite_subdev_enum_mbus_code,
1299        .get_selection = fimc_lite_subdev_get_selection,
1300        .set_selection = fimc_lite_subdev_set_selection,
1301        .get_fmt = fimc_lite_subdev_get_fmt,
1302        .set_fmt = fimc_lite_subdev_set_fmt,
1303};
1304
1305static const struct v4l2_subdev_video_ops fimc_lite_subdev_video_ops = {
1306        .s_stream = fimc_lite_subdev_s_stream,
1307};
1308
1309static const struct v4l2_subdev_core_ops fimc_lite_core_ops = {
1310        .s_power = fimc_lite_subdev_s_power,
1311        .log_status = fimc_lite_log_status,
1312};
1313
1314static struct v4l2_subdev_ops fimc_lite_subdev_ops = {
1315        .core = &fimc_lite_core_ops,
1316        .video = &fimc_lite_subdev_video_ops,
1317        .pad = &fimc_lite_subdev_pad_ops,
1318};
1319
1320static int fimc_lite_s_ctrl(struct v4l2_ctrl *ctrl)
1321{
1322        struct fimc_lite *fimc = container_of(ctrl->handler, struct fimc_lite,
1323                                              ctrl_handler);
1324        set_bit(ST_FLITE_CONFIG, &fimc->state);
1325        return 0;
1326}
1327
1328static const struct v4l2_ctrl_ops fimc_lite_ctrl_ops = {
1329        .s_ctrl = fimc_lite_s_ctrl,
1330};
1331
1332static const struct v4l2_ctrl_config fimc_lite_ctrl = {
1333        .ops    = &fimc_lite_ctrl_ops,
1334        .id     = V4L2_CTRL_CLASS_USER | 0x1001,
1335        .type   = V4L2_CTRL_TYPE_BOOLEAN,
1336        .name   = "Test Pattern 640x480",
1337};
1338
1339static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
1340{
1341        struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
1342        struct v4l2_subdev *sd = &fimc->subdev;
1343        int ret;
1344
1345        v4l2_subdev_init(sd, &fimc_lite_subdev_ops);
1346        sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1347        snprintf(sd->name, sizeof(sd->name), "FIMC-LITE.%d", fimc->index);
1348
1349        fimc->subdev_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1350        fimc->subdev_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1351        ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1352                                fimc->subdev_pads, 0);
1353        if (ret)
1354                return ret;
1355
1356        v4l2_ctrl_handler_init(handler, 1);
1357        fimc->test_pattern = v4l2_ctrl_new_custom(handler, &fimc_lite_ctrl,
1358                                                  NULL);
1359        if (handler->error) {
1360                media_entity_cleanup(&sd->entity);
1361                return handler->error;
1362        }
1363
1364        sd->ctrl_handler = handler;
1365        sd->internal_ops = &fimc_lite_subdev_internal_ops;
1366        sd->entity.ops = &fimc_lite_subdev_media_ops;
1367        v4l2_set_subdevdata(sd, fimc);
1368
1369        return 0;
1370}
1371
1372static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
1373{
1374        struct v4l2_subdev *sd = &fimc->subdev;
1375
1376        v4l2_device_unregister_subdev(sd);
1377        media_entity_cleanup(&sd->entity);
1378        v4l2_ctrl_handler_free(&fimc->ctrl_handler);
1379        v4l2_set_subdevdata(sd, NULL);
1380}
1381
1382static void fimc_lite_clk_put(struct fimc_lite *fimc)
1383{
1384        if (IS_ERR_OR_NULL(fimc->clock))
1385                return;
1386
1387        clk_unprepare(fimc->clock);
1388        clk_put(fimc->clock);
1389        fimc->clock = NULL;
1390}
1391
1392static int fimc_lite_clk_get(struct fimc_lite *fimc)
1393{
1394        int ret;
1395
1396        fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
1397        if (IS_ERR(fimc->clock))
1398                return PTR_ERR(fimc->clock);
1399
1400        ret = clk_prepare(fimc->clock);
1401        if (ret < 0) {
1402                clk_put(fimc->clock);
1403                fimc->clock = NULL;
1404        }
1405        return ret;
1406}
1407
1408static int __devinit fimc_lite_probe(struct platform_device *pdev)
1409{
1410        struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev);
1411        struct fimc_lite *fimc;
1412        struct resource *res;
1413        int ret;
1414
1415        fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
1416        if (!fimc)
1417                return -ENOMEM;
1418
1419        fimc->index = pdev->id;
1420        fimc->variant = drv_data->variant[fimc->index];
1421        fimc->pdev = pdev;
1422
1423        init_waitqueue_head(&fimc->irq_queue);
1424        spin_lock_init(&fimc->slock);
1425        mutex_init(&fimc->lock);
1426
1427        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1428        fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
1429        if (fimc->regs == NULL) {
1430                dev_err(&pdev->dev, "Failed to obtain io memory\n");
1431                return -ENOENT;
1432        }
1433
1434        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1435        if (res == NULL) {
1436                dev_err(&pdev->dev, "Failed to get IRQ resource\n");
1437                return -ENXIO;
1438        }
1439
1440        ret = fimc_lite_clk_get(fimc);
1441        if (ret)
1442                return ret;
1443
1444        ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler,
1445                               0, dev_name(&pdev->dev), fimc);
1446        if (ret) {
1447                dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
1448                goto err_clk;
1449        }
1450
1451        /* The video node will be created within the subdev's registered() op */
1452        ret = fimc_lite_create_capture_subdev(fimc);
1453        if (ret)
1454                goto err_clk;
1455
1456        platform_set_drvdata(pdev, fimc);
1457        pm_runtime_enable(&pdev->dev);
1458        ret = pm_runtime_get_sync(&pdev->dev);
1459        if (ret < 0)
1460                goto err_sd;
1461
1462        fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1463        if (IS_ERR(fimc->alloc_ctx)) {
1464                ret = PTR_ERR(fimc->alloc_ctx);
1465                goto err_pm;
1466        }
1467        pm_runtime_put(&pdev->dev);
1468
1469        dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n",
1470                fimc->index);
1471        return 0;
1472err_pm:
1473        pm_runtime_put(&pdev->dev);
1474err_sd:
1475        fimc_lite_unregister_capture_subdev(fimc);
1476err_clk:
1477        fimc_lite_clk_put(fimc);
1478        return ret;
1479}
1480
1481static int fimc_lite_runtime_resume(struct device *dev)
1482{
1483        struct fimc_lite *fimc = dev_get_drvdata(dev);
1484
1485        clk_enable(fimc->clock);
1486        return 0;
1487}
1488
1489static int fimc_lite_runtime_suspend(struct device *dev)
1490{
1491        struct fimc_lite *fimc = dev_get_drvdata(dev);
1492
1493        clk_disable(fimc->clock);
1494        return 0;
1495}
1496
1497#ifdef CONFIG_PM_SLEEP
1498static int fimc_lite_resume(struct device *dev)
1499{
1500        struct fimc_lite *fimc = dev_get_drvdata(dev);
1501        struct flite_buffer *buf;
1502        unsigned long flags;
1503        int i;
1504
1505        spin_lock_irqsave(&fimc->slock, flags);
1506        if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
1507            !test_bit(ST_FLITE_IN_USE, &fimc->state)) {
1508                spin_unlock_irqrestore(&fimc->slock, flags);
1509                return 0;
1510        }
1511        flite_hw_reset(fimc);
1512        spin_unlock_irqrestore(&fimc->slock, flags);
1513
1514        if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state))
1515                return 0;
1516
1517        INIT_LIST_HEAD(&fimc->active_buf_q);
1518        fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, false);
1519        fimc_lite_hw_init(fimc);
1520        clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
1521
1522        for (i = 0; i < fimc->reqbufs_count; i++) {
1523                if (list_empty(&fimc->pending_buf_q))
1524                        break;
1525                buf = fimc_lite_pending_queue_pop(fimc);
1526                buffer_queue(&buf->vb);
1527        }
1528        return 0;
1529}
1530
1531static int fimc_lite_suspend(struct device *dev)
1532{
1533        struct fimc_lite *fimc = dev_get_drvdata(dev);
1534        bool suspend = test_bit(ST_FLITE_IN_USE, &fimc->state);
1535        int ret;
1536
1537        if (test_and_set_bit(ST_LPM, &fimc->state))
1538                return 0;
1539
1540        ret = fimc_lite_stop_capture(fimc, suspend);
1541        if (ret < 0 || !fimc_lite_active(fimc))
1542                return ret;
1543
1544        return fimc_pipeline_shutdown(&fimc->pipeline);
1545}
1546#endif /* CONFIG_PM_SLEEP */
1547
1548static int __devexit fimc_lite_remove(struct platform_device *pdev)
1549{
1550        struct fimc_lite *fimc = platform_get_drvdata(pdev);
1551        struct device *dev = &pdev->dev;
1552
1553        pm_runtime_disable(dev);
1554        pm_runtime_set_suspended(dev);
1555        fimc_lite_unregister_capture_subdev(fimc);
1556        vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1557        fimc_lite_clk_put(fimc);
1558
1559        dev_info(dev, "Driver unloaded\n");
1560        return 0;
1561}
1562
1563static struct flite_variant fimc_lite0_variant_exynos4 = {
1564        .max_width              = 8192,
1565        .max_height             = 8192,
1566        .out_width_align        = 8,
1567        .win_hor_offs_align     = 2,
1568        .out_hor_offs_align     = 8,
1569};
1570
1571/* EXYNOS4212, EXYNOS4412 */
1572static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
1573        .variant = {
1574                [0] = &fimc_lite0_variant_exynos4,
1575                [1] = &fimc_lite0_variant_exynos4,
1576        },
1577};
1578
1579static struct platform_device_id fimc_lite_driver_ids[] = {
1580        {
1581                .name           = "exynos-fimc-lite",
1582                .driver_data    = (unsigned long)&fimc_lite_drvdata_exynos4,
1583        },
1584        { /* sentinel */ },
1585};
1586MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
1587
1588static const struct dev_pm_ops fimc_lite_pm_ops = {
1589        SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume)
1590        SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume,
1591                           NULL)
1592};
1593
1594static struct platform_driver fimc_lite_driver = {
1595        .probe          = fimc_lite_probe,
1596        .remove         = __devexit_p(fimc_lite_remove),
1597        .id_table       = fimc_lite_driver_ids,
1598        .driver = {
1599                .name           = FIMC_LITE_DRV_NAME,
1600                .owner          = THIS_MODULE,
1601                .pm             = &fimc_lite_pm_ops,
1602        }
1603};
1604module_platform_driver(fimc_lite_driver);
1605MODULE_LICENSE("GPL");
1606MODULE_ALIAS("platform:" FIMC_LITE_DRV_NAME);
1607