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