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