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