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